"package XXX is not in GOROOT" when building a Go project

huangapple go评论88阅读模式
英文:

"package XXX is not in GOROOT" when building a Go project

问题

我在这个项目中休息一段时间后遇到了一个奇怪的问题。在启动 Golang 时,当我尝试运行项目时,出现了很多错误。

具体的错误是在构建我的一个包时出现的:
start.go: package project/game is not in GOROOT (C:\Go\src\project\game)

我的文件夹结构如下所示,位于 C:\Users\username 下:

go
|-src
   |-project
        |-game
            |-entity
                 |-whatever.go
            |-game_stuff.go
        |-server

我的环境变量设置如下:

GOROOT=C:\Go 
GOPATH=C:\Users\ketchup\go 

对于每个模块(project/game/entity、project/game、project/server),我都执行了 git mod init

在构建时,Goland 将尝试运行以下命令:

C:\Go\bin\go.exe build -o C:\Users\ketchup\AppData\Local\Temp\___go_build_project_server.exe project/server

并返回错误。

有人可以帮我解决这个问题吗?我有点迷茫,因为上次打开 Goland 时一切正常。而且我不确定应该从哪个方向着手 - 我对 Go 还很陌生,不知道应该查看哪些文档 :\ 谢谢大家!

英文:

I have a weird issue that arose when I took a break from this project. Upon starting up Golang, I'm riddled with errors when trying to run my project.

The specific error, when building one of my packages, is:
start.go: package project/game is not in GOROOT (C:\Go\src\project\game)

I have a folder structure as such under C:\Users\username

go
|-src
   |-project
        |-game
            |-entity
                 |-whatever.go
            |-game_stuff.go
        |-server

and my env vars are as such:

GOROOT=C:\Go 
GOPATH=C:\Users\ketchup\go 

for each of the modules (project/game/entity, project/game, project/server), I did a git mod init.

When building, Goland will try to run this:

C:\Go\bin\go.exe build -o C:\Users\ketchup\AppData\Local\Temp\___go_build_project_server.exe project/server

and return the error.

Can anyone help me with this issue? Kind of lost since Goland was working fine the last time I opened it. Also not even sure what direction to look at - I'm pretty new to Go and I'm not really sure what documentation to look at :\ Thank you everyone!

答案1

得分: 112

在较新的Go版本(1.13之后),您不需要设置环境变量,如GOPATHGOBIN等。

您还需要在项目根目录下拥有一个go.mod文件,这将使该目录成为一个Go模块。这也是.git/所在的位置。这意味着每个存储库只需要一个go.mod文件。在项目根目录中,您可以执行go mod init remote-repo.com/username/repository来初始化远程存储库。

我在macOS上使用Homebrew安装了Go,因此GOROOT/opt/homebrew/Cellar/go/1.17.5/libexec。该位置包含Go的标准库和运行时。

testrun命令的格式为go COMMAND package_path/xxx。如果不指定package_path,只运行go COMMAND xxx,编译器会假设模块xxx位于GOROOT中,并抛出错误package xxx is not in GOROOT (path/to/GOROOT/src/xxx),因为它不存在。

这种行为是预期的,因为我们使用的包不是Go SDK的一部分,即不在GOROOT中。我们使用的包要么位于Go工作区中,要么位于当前工作目录中。运行go install会编译并将可执行二进制文件放在$GOBIN(也称为$GOPATH/bin,其中$GOPATH是Go工作区)中。从包内部运行go build会将可执行文件编译并放在该目录中。

您没有列出server/包中的文件以及哪个文件具有主函数,因此我将模拟计算器的3个工作流程,每个工作流程都展示了更多的复杂性。最后一个工作流程类似于您的目录结构。

目录结构

版本1:

  • 开始使用包

  • 基本功能

calculatorv1
├── go.mod                      <- go mod init github.com/yourname/calculatorv1
└── basic/
    ├── add.go
    ├── add_test.go
    ├── main.go
    ├── multiply.go
    └── multiply_test.go

版本2:

  • 更多功能

  • 多个包

calculatorv2
├── go.mod                      <- go mod init github.com/yourname/calculatorv2
├── main.go
└── basic/
│   ├── add.go
│   ├── add_test.go
│   ├── multiply.go
│   └── multiply_test.go
└─── advanced/
     ├── square.go
     └── square_test.go

版本3:

  • 更多更多功能

  • 嵌套包

calculatorv3
├── go.mod                      <- go mod init github.com/yourname/calculatorv3
├── main.go
└── basic/
│   ├── add.go
│   ├── add_test.go
│   ├── multiply.go
│   └── multiply_test.go
└─── advanced/
     ├── square.go
     ├── square_test.go
     └── scientific/
         ├── declog.go
         └── declog_test.go

工作流程

注意:根据您使用的版本,将xxx替换为basicadvancedadvanced/scientific

  • 使用go mod init在项目目录(calculatorv1calculatorv2calculatorv3之一)中初始化Go模块。

  • 运行测试

    go test -v ./... (从项目根目录递归执行所有测试套件)

    或者

    go test -v ./xxx (从项目根目录运行“xxx”包中的测试套件)

    或者

    cd xxx/
    go test -v            # (从包内部运行)
    
  • 编译和执行包

    go run ./... (从项目根目录递归运行所有.go文件,不包括测试文件)

    或者

    go run ./xxx (从项目根目录运行“xxx”包中的所有.go文件,不包括测试文件)

    或者

    cd xxx
    go run .              # (从包内部运行)
    

    注意:只有主包中的文件才可执行,即具有package main声明的文件。这意味着go run ./xxx只适用于版本1,而不适用于版本2和3。因此,对于版本2和3,应该运行go run main.go


代码

非常容易填写不完整的部分

版本1

add.go

package main

func addition(x int, y int) int {
    return x + y
}

add_test.go

package main

import "testing"

func TestAdd(t *testing.T) {

    t.Run("adding two positive numbers", func(t *testing.T) {
        sum := addition(2, 2)
        expected := 4
        
        if sum != expected {
            t.Errorf("Expected %d; but got %d", expected, sum)
        }
    })
    
    t.Run("adding two negative numbers", func(t *testing.T) {
        sum := addition(-3, -4)
        expected := -7

        if sum != expected {
            t.Errorf("Expected %d; but got %d", expected, sum)
        }
    })

    t.Run("adding one positive and one negative integer", func(t *testing.T) {
        sum := addition(1, -3)
        expected := -2

        if sum != expected {
            t.Errorf("Expected %d; but got %d", expected, sum)
        }
    })
    
}

main.go

package main

import "fmt"

func main() {
    var num1 int = 1
    var num2 int = 2
    
    sum := addition(num1, num2)
    product := multiplication(num1, num2)

    fmt.Printf("The sum of %d and %d is %d\n", num1, num2, sum)
    fmt.Printf("The multiplication of %d and %d is %d\n", num1, num2, product)
}

版本2

main.go

package main

import (
    "fmt"
    "github.com/yourname/calculatorv2/basic"
    "github.com/yourname/calculatorv2/advanced"
)

func main() {
    var num1 int = 1
    var num2 int = 2
    
    product := basic.Multiplication(num1, num2)
    square := advanced.Square(num2)

    fmt.Printf("The product of %d and %d is %d\n", num1, num2, product)
    fmt.Printf("The square of %d is %d\n", num2, square)
}

multiply.go

package basic

func Multiplication(x int, y int) int {
    return x * y
}

multiply_test.go

package basic

import "testing"

func TestMultiply(t *testing.T) {

    t.Run("multiplying two positive numbers", func(t *testing.T) {
        sum := Multiplication(2, 2)
        expected := 4
        
        if sum != expected {
            t.Errorf("Expected %d; but got %d", expected, sum)
        }
    })
    
    t.Run("multiplying two negative numbers", func(t *testing.T) {
        sum := Multiplication(-3, -4)
        expected := 12

        if sum != expected {
            t.Errorf("Expected %d; but got %d", expected, sum)
        }
    })

    t.Run("multiplying one positive and one negative integer", func(t *testing.T) {
        sum := Multiplication(1, -3)
        expected := -3

        if sum != expected {
            t.Errorf("Expected %d; but got %d", expected, sum)
        }
    })
    
}

square.go

package advanced

func Square(x int) int {
    return x * x
}

版本3

main.go

package main

import (
    "fmt"
    "github.com/yourname/calculatorv3/basic"
    "github.com/yourname/calculatorv3/advanced"
    "github.com/yourname/calculatorv3/advanced/scientific"
)

func main() {
    var num1 int = 1
    var num2 int = 2
    var num3 float64 = 2
    
    product := basic.Multiplication(num1, num2)
    square := advanced.Square(num2)
    decimallog := scientific.DecimalLog(num3)

    fmt.Printf("The product of %d and %d is %d\n", num1, num2, product)
    fmt.Printf("The square of %d is %d\n", num2, square)
    fmt.Printf("The decimal log (base 10) of %f is %f\n", num3, decimallog)
}

square.go

package advanced

func Square(x int) int {
    return x * x
}

declog.go

package scientific

import "math"

func DecimalLog(x float64) float64 {
    return math.Log10(x)
}

declog_test.go

package scientific

import "testing"

func TestDecimalLog(t *testing.T) {

    t.Run("adding two positive numbers", func(t *testing.T) {
        sum := DecimalLog(100)
        expected := 2.0
        
        if sum != expected {
            t.Errorf("Expected %f; but got %f", expected, sum)
        }
    })
    
    t.Run("adding two negative numbers", func(t *testing.T) {
        sum := DecimalLog(10)
        expected := 1.0

        if sum != expected {
            t.Errorf("Expected %f; but got %f", expected, sum)
        }
    })
}
英文:

In newer versions (post 1.13) of Go, you don't need to set environment variables like GOPATH, GOBIN, etc.

You also need to have a go.mod file at the project root. This will make the directory a Go module. This is also where the .git/ is located. This means that only one go.mod is needed per repository. Inside the project root you could do a go mod init remote-repo.com/username/repository

I installed Go using Homebrew on macOS so GOROOT is /opt/homebrew/Cellar/go/1.17.5/libexec. This location contains the standard library and runtimes for Go.

test and run commands are run in the format go COMMAND package_path/xxx. Without specifying the package_path ./ and just running go COMMAND xxx, the compiler assumes that the module xxx is located in GOROOT, and throws error package xxx is not in GOROOT (path/to/GOROOT/src/xxx) because it doesn't exist.

This behavior is expected because the package we are working with is not part of the Go SDK, i.e., not in GOROOT. The package we are working with will either end up in the go workspace or in the current working directory. Running go install compiles and puts an executable binary in $GOBIN (a.k.a $GOPATH/bin - here $GOPATH is the Go workspace). Running go build from inside a package compiles and puts an execuatble in that directory.

You haven't listed the files inside the server/ package and which file has the main function, so I'll emulate 3 workflows of a calculator each demonstrating more complexity. The last workflow is similar to your directory structure.

Directory Structure

Version 1:

  • Getting started with packages

  • Basic functionality

calculatorv1
├── go.mod                      &lt;- go mod init github.com/yourname/calculatorv1
└── basic/
    ├── add.go
    ├── add_test.go
    ├── main.go
    ├── multiply.go
    └── multiply_test.go

Version 2:

  • More functionality

  • Multiple packages

calculatorv2
├── go.mod                      &lt;- go mod init github.com/yourname/calculatorv2
├── main.go
└── basic/
│   ├── add.go
│   ├── add_test.go
│   ├── multiply.go
│   └── multiply_test.go
└─── advanced/
     ├── square.go
     └── square_test.go

Version 3:

  • Even more functionality

  • Nested packages

calculatorv3
├── go.mod                      &lt;- go mod init github.com/yourname/calculatorv3
├── main.go
└── basic/
│   ├── add.go
│   ├── add_test.go
│   ├── multiply.go
│   └── multiply_test.go
└─── advanced/
     ├── square.go
     ├── square_test.go
     └── scientific/
         ├── declog.go
         └── declog_test.go

Workflow

Note: Substitute xxx with basic, advanced, or advanced/scientific depending on the version you're working with.

  • Initialize Go module in the project directory (one of calculatorv1, calculatorv2, or calculatorv3) using go mod init

  • Run tests

    go test -v ./... (from the project root, recursively execute all test suites)

    OR

    go test -v ./xxx (from the project root, run the test suite in package "xxx")

    OR

    cd xxx/
    go test -v            # (from inside the package)
    
  • Compile and execute package

    go run ./... (from the project root, recursively run all .go files except tests)

    OR

    go run ./xxx (from the project root, run all .go files in "xxx" package except tests)

    OR

    cd xxx
    go run .              # (from inside the package)
    

    NOTE: Only files in the main package are executable, i.e., files having declaration package main. This means that go run ./xxx will only work with version1, and not versions 2 and 3. So instead for versions 2 and 3, run go run main.go


Code

Very easy to fill in incomplete bits

Version 1

add.go

package main

func addition(x int, y int) int {
    return x + y
}

add_test.go

package main

import &quot;testing&quot;

func TestAdd(t *testing.T) {

    t.Run(&quot;adding two positive numbers&quot;, func(t *testing.T) {
        sum := addition(2, 2)
        expected := 4
        
        if sum != expected {
            t.Errorf(&quot;Expected %d; but got %d&quot;, expected, sum)
        }
    })
    
    t.Run(&quot;adding two negative numbers&quot;, func(t *testing.T) {
        sum := addition(-3, -4)
        expected := -7

        if sum != expected {
            t.Errorf(&quot;Expected %d; but got %d&quot;, expected, sum)
        }
    })

    t.Run(&quot;adding one positive and one negative integer&quot;, func(t *testing.T) {
        sum := addition(1, -3)
        expected := -2

        if sum != expected {
            t.Errorf(&quot;Expected %d; but got %d&quot;, expected, sum)
        }
    })
    
}

main.go

package main

import &quot;fmt&quot;

func main() {
    var num1 int = 1
    var num2 int = 2
    
    sum := addition(num1, num2)
    product := multiplication(num1, num2)

    fmt.Printf(&quot;The sum of %d and %d is %d\n&quot;, num1, num2, sum)
    fmt.Printf(&quot;The multiplication of %d and %d is %d\n&quot;, num1, num2, product)
}

Version 2

main.go

package main

import (
    &quot;fmt&quot;
    &quot;github.com/yourname/calculatorv2/basic&quot;
    &quot;github.com/yourname/calculatorv2/advanced&quot;
)

func main() {
    var num1 int = 1
    var num2 int = 2
    
    product := basic.Multiplication(num1, num2)
    square := advanced.Square(num2)

    fmt.Printf(&quot;The product of %d and %d is %d\n&quot;, num1, num2, product)
    fmt.Printf(&quot;The square of %d is %d\n&quot;, num2, square)
}

multiply.go

package basic

func Multiplication(x int, y int) int {
    return x * y
}

multiply_test.go

package basic

import &quot;testing&quot;

func TestMultiply(t *testing.T) {

    t.Run(&quot;multiplying two positive numbers&quot;, func(t *testing.T) {
        sum := Multiplication(2, 2)
        expected := 4
        
        if sum != expected {
            t.Errorf(&quot;Expected %d; but got %d&quot;, expected, sum)
        }
    })
    
    t.Run(&quot;multiplying two negative numbers&quot;, func(t *testing.T) {
        sum := Multiplication(-3, -4)
        expected := 12

        if sum != expected {
            t.Errorf(&quot;Expected %d; but got %d&quot;, expected, sum)
        }
    })

    t.Run(&quot;multiplying one positive and one negative integer&quot;, func(t *testing.T) {
        sum := Multiplication(1, -3)
        expected := -3

        if sum != expected {
            t.Errorf(&quot;Expected %d; but got %d&quot;, expected, sum)
        }
    })
    
}

square.go

package advanced

func Square(x int) int {
    return x * x
}

Version 3

main.go

package main

import (
    &quot;fmt&quot;
    &quot;github.com/yourname/calculatorv3/basic&quot;
    &quot;github.com/yourname/calculatorv3/advanced&quot;
    &quot;github.com/yourname/calculatorv3/advanced/scientific&quot;
)

func main() {
    var num1 int = 1
    var num2 int = 2
    var num3 float64 = 2
    
    product := basic.Multiplication(num1, num2)
    square := advanced.Square(num2)
    decimallog := scientific.DecimalLog(num3)

    fmt.Printf(&quot;The product of %d and %d is %d\n&quot;, num1, num2, product)
    fmt.Printf(&quot;The square of %d is %d\n&quot;, num2, square)
    fmt.Printf(&quot;The decimal log (base 10) of %f is %f\n&quot;, num3, decimallog)
}

square.go

package advanced

func Square(x int) int {
    return x * x
}

declog.go

package scientific

import &quot;math&quot;

func DecimalLog(x float64) float64 {
    return math.Log10(x)
}

declog_test.go

package scientific

import &quot;testing&quot;

func TestDecimalLog(t *testing.T) {

    t.Run(&quot;adding two positive numbers&quot;, func(t *testing.T) {
        sum := DecimalLog(100)
        expected := 2.0
        
        if sum != expected {
            t.Errorf(&quot;Expected %f; but got %f&quot;, expected, sum)
        }
    })
    
    t.Run(&quot;adding two negative numbers&quot;, func(t *testing.T) {
        sum := DecimalLog(10)
        expected := 1.0

        if sum != expected {
            t.Errorf(&quot;Expected %f; but got %f&quot;, expected, sum)
        }
    })
}

答案2

得分: 62

你可能已经设置了GO111MODULE为"on",这将在go mod中生效。关闭GO111MODULE可能会解决这个问题。

go env -w GO111MODULE=off
英文:

You may have GO111MODULE set "on", which will be on the go mod. Turning off the GO111MODULE may resolve this problem.

go env -w GO111MODULE=off

答案3

得分: 44

一个相当愚蠢的结论(主要是我自己的问题),但我的问题是因为在每个文件夹中都执行了 go mod init。在从每个文件夹中删除 go.modgo.dep 后,我可以在终端中构建而没有问题。

此外,我的 GoLand 中的包没有被检测到,因为我在设置中启用了 Go Modules。我禁用了它,GoLand 能够索引外部包和我的自己的包。

英文:

A pretty dumb conclusion (mostly on my part) but my issue came from having done go mod init in each of the folders. after removing go.mod and go.dep from each of the folders I did go mod init in, I could build without issue (through terminal)

Also, my packages in GoLand were not being detected because I had Go Modules enabled in the Settings. I disabled it and GoLand was able to index the external packages and my own packages.

答案4

得分: 18

如果有人希望在GoLand中继续使用模块,请确保在首选项中勾选“启用Go模块集成”,如下所示:

"package XXX is not in GOROOT" when building a Go project

英文:

To anyone who does want modules to work with GoLand after they have stopped doing so, make sure 'Enable Go modules integration' is checked in the Preferences as such:

"package XXX is not in GOROOT" when building a Go project

答案5

得分: 17

看起来,如果你运行go mod init 'xxx',那么xxx就是你的项目的核心名称。在这里,主要包的完整名称是xxx/main,所以如果你的项目根目录结构如下:

root -> go mod init xxx
 |- main.go -> 包名为"main"
 |- tools
      |- helper.go -> 包名为"tools"

如果你想从main.go中导入tools包,你需要导入"xxx/tools"

英文:

So it looks like if you running go mod init 'xxx' the xxx is core name of your project. In there main packages complete name is 'xxx/main' so if you have your project root folder like this:

root -&gt; go mod init xxx
 |- main.go -&gt; package &quot;main&quot;
 |- tools
      |- helper.go -&gt; package &quot;tools&quot;

and you want to import tools package from main.go you need to import this "xxx/tools"

答案6

得分: 7

我不喜欢每个人都按照github模块命名约定给出答案,好像你必须以那种方式命名它们或者将你的模块放在github上才能在本地环境中使用它,所以这是我的答案,希望能帮助澄清一些关于Go中包和模块命名方面让我感到困惑的时刻(我将使用故意不寻常的名称来命名文件和文件夹,以便你可以看到你不必以特定的方式命名你的文件才能使你的Go项目工作(但你必须按照特定的方式组织它们)):

因此,Golang项目在概念上有以下几个部分:

(这对于Go项目来说是可选的)

  • "Repository" - 在版本控制系统中存储项目源代码的位置(通常是一些远程仓库)。

(这对于Go项目来说是必需的)

  • "Module" - 在Go项目中,这个名字在概念上用于指定整个程序/库(也就是说,它指的是它的根目录,通常存储在某个远程仓库中)。

  • "Packages" - 在Go项目中,这个名字应用于字面上的文件夹,其中存储着"package 文件",这是一种组织模块内代码的方式。

实际上,上述概念意味着如果你想创建一个多包项目,为了使其编译通过,你需要按照以下步骤进行操作:

(逐步示例:)

  • 创建一个文件夹,作为项目的根文件夹,并进入该文件夹:

    $ mkdir some_amazing_project && cd some_amazing_project

  • 当根目录中有一个有效的go.mod文件时,一组Go代码就成为一个module,因此使用以下命令生成它:

    $ go mod init my_amazing_module_lib_program

(go.mod文件的内容如下):

module my_amazing_module_lib_program // 这是你的唯一模块标识符,当你使用"import"时,你将使用这个名称作为相对根目录的包名称

go 1.19
  • 现在创建一个Go程序的入口点,这是一个go文件,应该放在根文件夹中(即go.mod文件所在的位置),但你也可以将其放在该模块(根文件夹)中的任何子文件夹中,但不能更深(否则你将收到“no Go files in <absolute_path>/some_amazing_project/some_subfolder/another_folder”的错误):

    $ touch some_main_file.go

(^^ 你可以随意命名这个文件,但约定是"main.go")

  • main文件中,必须指定packagemain,并且必须在该文件中有一个名为main的函数:

    // some_main_file.go

    package main

    import "fmt"

    func main() {
    fmt.Println("hello there")
    }

(到目前为止,这是你的项目结构):

some_amazing_project/
    |- go.mod
    |- some_main_file.go

(现在,假设你想在这个模块/程序/库中创建一个包。你需要执行以下操作):

  • 创建一个新的文件夹,命名为"amazing_package",并在其中创建任何一个.go文件(文件的名称并不重要,因为只有包含文件的文件夹的名称用于在其他.go文件中引用该包):

    $ mkdir amazing_package && cd amazing_package && touch whatever_file.go

  • whatever_file.go中,使用package关键字指定该包的名称(这个包名称仅在从其他.go文件中指定要调用的函数名称时使用,稍后你会看到):

    // whatever_file.go

    package wowow

    import "fmt"

    func PrintWowow() {
    fmt.Println("this is from wowow package")
    }

^^ 以大写字母开头的变量/常量/函数/类型等(Go中的任何"标识符")是被导出的,并且可以被导入到其他包中使用。

(为了举例,让我们在这个包中创建另一个文件):

$ touch another_cool_file.go
  • another_cool_file.go中,使用相同的package关键字指定该包的名称,就像你在whatever_file.go中使用的一样(因为这些文件在概念上属于同一个"package",也就是说,它们实际上存储在同一个文件夹中(如果你在存储文件的同一个文件夹中使用不同的package关键字名称,你将在编译时收到错误)):

    // another_cool_file.go

    package wowow

    import "fmt"

    var Some_var = 42 // 这也将自动导出

    func PrintAnotherWow() {
    fmt.Println("this is also from wowow package, but from a different file")
    }

(到目前为止,这是你的项目结构):

some_amazing_project/
    |- go.mod
    |- some_main_file.go
    |- amazing_package/
            |- whatever_file.go
            |- another_cool_file.go
  • 现在,要从任何其他.go文件中引用整个模块中的"PrintWowow"和"PrintAnotherWow"函数,你需要使用go.mod文件中的唯一模块标识符以及相对于该标识符的路径,该路径指定要导入的包文件夹的位置(在这个示例中,我将使用some_main_file.go。我们将其重写如下):

    // some_main_file.go

    package main

    import (
    "fmt"
    "my_amazing_module_lib_program/amazing_package"
    )

    func main() {
    fmt.Println("hello there")

      // 现在你可以使用来自*amazing_package*文件夹中那些文件中指定的包名称
      wowow.PrintWowow()
      wowow.PrintAnotherWow()
      fmt.Println("and this is Some_var from the same imported package:", wowow.Some_var)
    

    }

my_amazing_module_lib_program(根)文件夹中运行go build . && go run .的结果如下:

hello there
this is from wowow package
this is also from wowow package, but from a different file
and this is Some_var from the same imported package: 42
英文:

I don't like that everyone is giving an answer which uses github module naming conventions as if you have to name them in that way or to have your module on github for it to be used within a local environment, so here's my answer to — hopefully — help clarify a few moments I was confused about regarding the naming of packages and modules in Go (I will use deliberately unusual names for the files and folders so you could see that you don't have to name your files a specific way for your Go project to work (you have to structure them in a specific way though)):

So, Golang project conceptually has:

(this is optional for a Go project)

  • "Repository" — a place in a version control system where the source code for a project is stored (usually some remote repo).

(this is required for a Go project to compile)

  • "Module" — this name, conceptually, in a Go project, is used to specify the program/library as a whole (meaning, it refers to its root, which is usually stored in some remote repository).

  • "Packages" — in a Go project, this name is applied to literal folders within which the "package files" are stored — It's a way of organizing code within a module.

In practice, the concepts from above imply that if you want to create a multi-package project, for it to compile, you need to do the following:

(step-by-step example:)

-- Create a folder that will serve as a root folder for the project and cd into it:

$ mkdir some_amazing_project &amp;&amp; cd some_amazing_project

-- A collection of Go code becomes a module when there's a valid go.mod file in its root directory, so use the following command to generate it:

$ go mod init my_amazing_module_lib_program

(The inside of your go.mod file looks like this):

module my_amazing_module_lib_program // this is your unique module identifier and you use this name as a relative root for your package names when you use &quot;import&quot;

go 1.19

-- Now create an entry point to your Go program which is a go file that should be placed in the root folder (where the go.mod file resides), but you could just as well place it in any subfolder within this module (the root folder), but no deeper than that (or you'll receive the "no Go files in <absolute_path>/some_amazing_project/some_subfolder/another_folder" error):

$ touch some_main_file.go

> (^^ you can call this file whatever you want, but the convention is "main.go")

-- Inside of that main file you must specify the package to be main and you must have a function within that file that is also called main:

// some_main_file.go

package main

import &quot;fmt&quot;

func main() {
	fmt.Println(&quot;hello there&quot;)
}

(This is your project structure so far):

some_amazing_project/
    |- go.mod
    |- some_main_file.go

(Now, let's say you want to create a package within this module/program/library. You would need to do the following):

-- Create a new folder, call it "amazing_package" and create any .go file in it (the name of the file doesn't really matter as only the name of the containing folder is used to refer to the package from other .go files):

$ mkdir amazing_package &amp;&amp; cd amazing_package &amp;&amp; touch whatever_file.go

-- Inside of the whatever_file.go you use the package keyword to specify the name of this package (this package name will be used only when specifying the name of the function to invoke from within other .go files — you'll see in a bit):

// whatever_file.go

package wowow

import &quot;fmt&quot;

func PrintWowow() {
	fmt.Println(&quot;this is from wowow package&quot;)
}

> ^^ The variables/constants/functions/types/etc..(any "identifier" in Go) that starts with an uppercase letter is exported and is made available to be imported into other packages.

(For the sake of example, let's create another file inside of this package):

$ touch another_cool_file.go

-- Inside of the another_cool_file.go you use the same package keyword to specify the name of this package as you've used for in the whatever_file.go (because these files are in the same "package" conceptually, meaning that in practice they are stored in the same folder (if you use a different name for the package keyword while storing the file in the same folder, you'll receive an error during compilation)):

// another_cool_file.go

package wowow

import &quot;fmt&quot;

var Some_var = 42 // this will also be automatically exported

func PrintAnotherWow() {
	fmt.Println(&quot;this is also from wowow package, but from a different file&quot;)
}

(This is your project structure so far):

some_amazing_project/
    |- go.mod
    |- some_main_file.go
    |- amazing_package/
            |- whatever_file.go
            |- another_cool_file.go

-- Now, to reference the "PrintWowow" and "PrintAnotherWow" function from ANY other .go file within this entire module you use the unique module identifier from go.mod file and a path relative to that identifier that specifies the location of a package folder to import (I'll use the some_main_file.go in this example. We re-write it like so):

// some_main_file.go

package main

import (
    &quot;fmt&quot;
	&quot;my_amazing_module_lib_program/amazing_package&quot;
)

func main() {
    fmt.Println(&quot;hello there&quot;)

    // now you use the name of the package specified inside of those files from *amazing_package* folder
    wowow.PrintWowow()
    wowow.PrintAnotherWow()
    fmt.Println(&quot;and this is Some_var from the same imported package:&quot;, wowow.Some_var)
}

And here is the result of running go build . &amp;&amp; go run . while inside of my_amazing_module_lib_program (root) folder:

hello there
this is from wowow package
this is also from wowow package, but from a different file
and this is Some_var from the same imported package: 42

答案7

得分: 4

我犯了一个错误,手动更改了go.mod文件中的模块名称。修复后,它正常工作了。

└── hello
    ├── go.mod
    ├── go.sum
    ├── hello.go
    └── morestrings
        ├── reverse.go
        └── reverse_test.go

hello.go的部分内容如下:

import (
...
"hello/morestrings"
...
)

在hello目录中运行go build时出现以下错误:

hello.go:5:2: 包hello/morestrings不在GOROOT中(/usr/local/go/src/hello/morestrings)

英文:

I made the mistake of changing the module name inside go.mod file manually. After fixing it, it worked fine.

└── hello
    ├── go.mod
    ├── go.sum
    ├── hello.go
    └── morestrings
        ├── reverse.go
        └── reverse_test.go

Excerpts of hello.go

import (
...
&quot;hello/morestrings&quot;
...
)

Running go build in hello directory was giving following error:

> hello.go:5:2: package hello/morestrings is not in GOROOT (/usr/local/go/src/hello/morestrings)

答案8

得分: 4

对我来说,这是因为我的主要方法不在main包内。

package main

func main() {
{

}
英文:

For me it was because my main method wasn't inside package main

package main

func main() {
{

}

答案9

得分: 3

在运行命令go mod init时,你需要添加文件夹名称,而不是main.go页面的名称。
例如:go mod init confirm_enrlconfirm_enrl是项目文件夹的名称。

英文:

While running command go mod init you need to add folder name, not main.go page name.
Like: go mod init confirm_enrl. confirm_enrl is project folder name

答案10

得分: 3

我遇到了与项目布局相同的错误。

     project
        |- pgk
        |- src
            |-module1
                 |- some.go
            |- main.go

some.go

package module1

...

main.go

import "project/module1"

最初,我通过./module1导入module1,出现了错误package module1 is not in GOROOT。我通过import "project/module1"解决了这个问题。

PS:根据golang项目布局src不应该在golang项目中。

英文:

I met the same error with the project layout

     project
        |- pgk
        |- src
            |-module1
                 |- some.go
            |- main.go

some.go

package module1

...

main.go

import &quot;project/module1&quot;

Originally, I import module1 through ./module1, the error package module1 is not in GOROOT comes up. I solve it through import &quot;project/module1&quot;.

PS: per golang project layout, src should NOT in golang project.

答案11

得分: 3

当我在包名中拼写错误时,我遇到了相同的错误。因此,这可能是这个错误的根本原因。也许对某人来说会有用。

英文:

I got the same error when I had a spelling mistake in the package name. Therefore, it might be the root cause behind this error. Maybe it will be useful for someone.

答案12

得分: 2

对于我的情况,只需将go版本更新到最新版本即可解决问题。

下载了最新的二进制文件并安装了它,问题迎刃而解!

英文:

For my case just updating my go version to the latest solved the issue .

I downloaded the latest binary and installed it and boom all was sorted !

答案13

得分: 2

似乎有点滑稽,但我遇到了同样的错误,原因是运行了以下命令:

go run build

而不是

go build main.go

所以这表明,在buildrun之后的所有内容都应该是Go可以识别的路径。

英文:

It seems a little funny, but I faced same error because of running:

go run build

instead of

go build main.go

So it shows that everything after build or run should have a recognized path by go.

答案14

得分: 1

我遇到了这个问题,删除了我的 go.mod 和 go.sum 文件,然后使用以下命令重新构建:

go mod init

这解决了我的问题 "package XXX is not in GOROOT" when building a Go project

英文:

Had this problem, deleted my go.mod & go.sum files then rebuilt it using

go mod init

This solved my problem "package XXX is not in GOROOT" when building a Go project

答案15

得分: 1

Windows PC用户

对我来说,问题出在我尝试运行项目的方式上。

当我在项目的根文件夹,并且我的 main.go 文件位于 /cmd/web/ 目录中时,我遇到了问题。

当我尝试运行以下命令时,出现了问题:

go run cmd/web/.
go run /cmd/web/.

只有当我使用以下命令时才起作用:

go run ./cmd/web/.

注意在开头的 .

英文:

Windows PC user

For me the issue was in how I was attempting to run the project

While at the root folder of the project and my main.go file is in /cmd/web/

I faced the issue when I tried to run both

go run cmd/web/.
go run /cmd/web/.

It only worked when I used the

go run ./cmd/web/.

Notice the . at the start

答案16

得分: 1

在我的情况下,结果证明我使用的是go run main而不是go run main.go

英文:

In my own case, it turned out that I was using go run main instead of go run main.go

答案17

得分: 0

我在按照Goland默认的"awesomeProject"进行Go入门教程时遇到了相同的问题。我在创建项目后运行了这个命令"go mod init example.com/hello",但是我的根目录名与"example.com/hello"不同。

在手动编辑go.mod文件并将"awesomeProject"替换为"example.com/hello"之后,构建成功了。

英文:

I came across the same like issue when i was following go getting started tutorial with goland default awesomeProject.
What i did after crating project run this command go mod init example.com/hello but my root directory name was different than example.com/hello.

After manually edit the go.mod file and replace awesomeProject with example.com/hello the build works successfully.

答案18

得分: 0

我知道这是大约一年前的事情。我只是想为那些在本地文件夹中有模块的人分享相同的经验。

问题是因为你没有将模块发布到像 GitHub 这样的中央位置。你需要运行以下命令告诉 Go 这个模块是一个本地模块:

go mod edit --replace external_folder_module_name=../pathItsLocated
英文:

I knew this is about one year ago. I just want to share same experience for those who have, have modules in local folders..

The problem is because you have not publish your module to a central location like github.
You have to run this command to tell go that the module is a local module

go mod edit --replace external_folder_module_name= ../pathItsLocated

答案19

得分: 0

我在构建 Docker 镜像时也遇到了类似的错误。错误信息是 #19 0.785 controllers/vasaprovider_controller.go:28:2: package vasa-operator/config/configs is not in GOROOT

在 Dockerfile 中添加了 go 文件的位置后,问题得到了解决。我添加的代码如下:

COPY config/configs config/configs/

COPY --from=builder /workspace/config/configs config/configs/
英文:

I was also faced similar error while building the docker image. The error was #19 0.785 controllers/vasaprovider_controller.go:28:2: package vasa-operator/config/configs is not in GOROOT.

After adding the go file location in Dockerfile, it worked for me. The lines I had added are:

COPY config/configs config/configs/

COPY --from=builder /workspace/config/configs config/configs/

答案20

得分: 0

在我的情况下,我试图从错误的目录构建。旧目录甚至没有任何.go文件。

英文:

In my case, I was trying to build from the wrong directory. The old directory didn't even have any .go files.

答案21

得分: 0

我们可以通过在终端上输入以下命令来解决这个问题:go env -w GO111MODULE=off

但是在执行这个命令之后,你将无法通过终端使用go mod init命令。你必须手动创建一个名为"go.mod"的文件。

英文:

We can solve this problem by writing this command on terminal: go env -w GO111MODULE=off

But after this command, you will be not able to use go mod init through terminal. You must create "go.mod" file manually.

答案22

得分: 0

在我的情况下,这是由于更改goroot路径引起的。

GOROOT是一个变量,用于定义Go SDK的位置。

如果你将goroot更改为你安装Go SDK的位置,它将起作用。

英文:

In my case, it is cause by changing goroot path.

GOROOT is a variable that defines where your Go SDK is located

it will work if you change you goroot to where go sdk you installed

答案23

得分: 0

如果你遇到了“package project/game is not in GOROOT (C:\Go\src\project\game)”的错误,并且你有一个go.mod文件...你是否检查过我的*.go文件中的导入是否正确同步了呢?如果没有的话,也许你应该从那里开始。

我偶尔也会遇到这个错误,特别是在设置新项目时。我首先确认我的导入是否正确,通常这样就可以解决问题了。谢谢Goland "package XXX is not in GOROOT" when building a Go project

英文:

if you are getting package project/game is not in GOROOT (C:\Go\src\project\game), and you have a go.mod file... have you checked the imports in my *.go files to confirm they are synching up properly. If not then perhaps you should start there.

I get this error every once in a while especially when I am setting up a new project. first thing I do is confirm my imports and that usually fixes everything. thank you goland "package XXX is not in GOROOT" when building a Go project

答案24

得分: 0

这对我有效:

which dep &amp;&gt;/dev/null || go get -u -v github.com/golang/dep/cmd/dep
dep init
英文:

This worked for me:

which dep &amp;&gt;/dev/null || go get -u -v github.com/golang/dep/cmd/dep
dep init

答案25

得分: -1

确保你的导入语句与你在 go mod 中定义的模块名匹配。

英文:

Make sure your import statement matches the module name that you defined in your go mod.

答案26

得分: -1

只需使用模块文件初始化项目,并在根目录上开始工作。

使用以下命令初始化项目:

go mod init <name-anything>
英文:

just initialise the project with mod file and start working on on root folder.

go mod init &lt;name-anything&gt;

答案27

得分: -1

在我的情况下,serverless.yaml 文件中 functions 下的函数的 handler 路径是不正确的。

英文:

in my case the handler path in serverless.yaml for the function in functions was incorrect

huangapple
  • 本文由 发表于 2020年5月17日 07:35:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/61845013.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定