"package XXX is not in GOROOT" 在构建 Go 项目时
"package XXX is not in GOROOT" when building a Go project
当我从这个项目中休息时出现了一个奇怪的问题。启动 Goland 后,我在尝试 运行 我的项目时遇到了很多错误。
构建我的一个包时出现的具体错误是:
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
和return错误。
谁能帮我解决这个问题?自从我上次打开 Goland 时它运行良好,我有点迷茫。甚至不确定要看什么方向 - 我是 Go 的新手,我不确定要看什么文档:\ 谢谢大家!
一个非常愚蠢的结论(主要是我的部分),但我的问题来自在每个文件夹中完成 go mod init
。从我在 go mod init
中执行的每个文件夹中删除 go.mod
和 go.dep
后,我可以毫无问题地构建(通过终端)
另外,我在 GoLand 中的包没有被检测到,因为我在设置中启用了 Go 模块。我禁用了它,GoLand 能够索引外部包和我自己的包。
对于确实希望模块在停止这样做后与GoLand一起工作的任何人,请确保在首选项中检查'Enable Go modules integration':
您可能已将 GO111MODULE 设置为“开启”,它会一直运行 mod。关闭 GO111MODULE 可能会解决此问题。
go env -w GO111MODULE=off
我错误地手动更改了 go.mod
文件中的模块名称。修复后,它工作正常。
└── hello
├── go.mod
├── go.sum
├── hello.go
└── morestrings
├── reverse.go
└── reverse_test.go
摘录hello.go
import (
...
"hello/morestrings"
...
)
运行 go build
在 hello 目录中出现以下错误:
hello.go:5:2: package hello/morestrings is not in GOROOT (/usr/local/go/src/hello/morestrings)
虽然 运行 命令 go mod init
您需要添加文件夹名称,而不是 main.go 页面名称。
喜欢:go mod init confirm_enrl
。 confirm_enrl
是项目文件夹名称
我在项目布局中遇到了同样的错误
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 project layout,src
不应该在 golang 项目中。
所以看起来如果你 运行 go mod init 'xxx' xxx 是你项目的核心名称。在那里,主要包的完整名称是 'xxx/main' 所以如果你的项目根文件夹是这样的:
root -> go mod init xxx
|- main.go -> package "main"
|- tools
|- helper.go -> package "tools"
并且您想从 main.go 导入工具包,您需要导入这个“xxx/tools”
我在包名拼写错误时遇到了同样的错误。因此,这可能是此错误背后的根本原因。也许对某人有用。
我在使用 goland default awesomeProject
学习入门教程时遇到了同样的问题。
我在创建项目 运行 之后做了什么这个命令 go mod init example.com/hello
但是我的根目录名称不同于 example.com/hello
.
手动编辑 go.mod 文件并将 awesomeProject
替换为 example.com/hello
后,构建成功。
我知道这是大约一年前的事了。我只想与那些在本地文件夹中有模块的人分享相同的经验..
问题是因为您没有将模块发布到像 github 这样的中央位置。
你必须 运行 这个命令告诉 go 这个模块是一个本地模块
go mod edit --replace external_folder_module_name= ../pathItsLocated
我在构建 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/
对于我的情况,只需将我的 go 版本 更新到最新版本即可解决问题。
我 downloaded the latest binary 并安装了它,boom 一切都已排序!
就我而言,我试图从错误的目录构建。旧目录甚至没有任何 .go
个文件。
确保您的导入语句与您在 mod.
中定义的 module 名称匹配
只需使用 mod 文件初始化项目并开始处理根文件夹。
go mod init <name-anything>
在较新的 Go 版本 (post 1.13) 中,您不需要设置 GOPATH
、GOBIN
等环境变量
您还需要在项目根目录下有一个 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 的 运行 次。
test
和 run
命令在格式 go COMMAND package_path/xxx
中是 运行。在不指定 package_path ./
和 运行ning go COMMAND xxx
的情况下,编译器假定模块 xxx 位于 GOROOT 中,并且抛出错误 package xxx is not in GOROOT (path/to/GOROOT/src/xxx)
因为它不存在。
此行为是预期的,因为我们正在使用的包不是 Go SDK 的一部分,即不在 GOROOT
中。我们正在使用的包将最终位于 go 工作区或当前工作目录中。 运行ning go install
编译并将可执行二进制文件放入 $GOBIN
(a.k.a $GOPATH/bin
- 这里 $GOPATH
是 Go 工作区)。 运行ning 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
替换为 basic
、advanced
或 advanced/scientific
与.
使用go mod init
在项目目录(calculatorv1
、calculatorv2
或calculatorv3
之一)中初始化Go模块
运行 测试
go test -v ./...
(从项目根开始,递归执行所有测试套件)
或
go test -v ./xxx
(来自项目根目录,运行包“xxx”中的测试套件)
或
cd xxx/
go test -v # (from inside the package)
编译执行包
go run ./...
(从项目根目录开始,递归 运行 除了测试之外的所有 .go
文件)
或
go run ./xxx
(从项目根目录,运行 "xxx" 包中的所有 .go
文件,除了测试)
或
cd xxx
go run . # (from inside the package)
注意:只有主包中的文件是可执行的,即具有声明 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)
}
})
}
我们可以通过在终端上写这个命令来解决这个问题:go env -w GO111MODULE=off
但是执行此命令后,您将无法通过终端使用 go mod init
。您必须手动创建“go.mod”文件。
在我的例子中,这是通过更改 goroot 路径引起的。
GOROOT 是定义您的 Go SDK 所在位置的变量
如果您将 goroot 更改为安装 go sdk 的位置,它将起作用
看起来有点好笑,但我遇到了同样的错误,因为 运行ning:
go run build
而不是
go build main.go
所以它表明在 build 或 运行 之后的所有内容都应该有一个可识别的路径。
对我来说,这是因为我的主要方法不在包 main 中
package main
func main() {
{
}
当我从这个项目中休息时出现了一个奇怪的问题。启动 Goland 后,我在尝试 运行 我的项目时遇到了很多错误。
构建我的一个包时出现的具体错误是:
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
和return错误。
谁能帮我解决这个问题?自从我上次打开 Goland 时它运行良好,我有点迷茫。甚至不确定要看什么方向 - 我是 Go 的新手,我不确定要看什么文档:\ 谢谢大家!
一个非常愚蠢的结论(主要是我的部分),但我的问题来自在每个文件夹中完成 go mod init
。从我在 go mod init
中执行的每个文件夹中删除 go.mod
和 go.dep
后,我可以毫无问题地构建(通过终端)
另外,我在 GoLand 中的包没有被检测到,因为我在设置中启用了 Go 模块。我禁用了它,GoLand 能够索引外部包和我自己的包。
对于确实希望模块在停止这样做后与GoLand一起工作的任何人,请确保在首选项中检查'Enable Go modules integration':
您可能已将 GO111MODULE 设置为“开启”,它会一直运行 mod。关闭 GO111MODULE 可能会解决此问题。
go env -w GO111MODULE=off
我错误地手动更改了 go.mod
文件中的模块名称。修复后,它工作正常。
└── hello
├── go.mod
├── go.sum
├── hello.go
└── morestrings
├── reverse.go
└── reverse_test.go
摘录hello.go
import (
...
"hello/morestrings"
...
)
运行 go build
在 hello 目录中出现以下错误:
hello.go:5:2: package hello/morestrings is not in GOROOT (/usr/local/go/src/hello/morestrings)
虽然 运行 命令 go mod init
您需要添加文件夹名称,而不是 main.go 页面名称。
喜欢:go mod init confirm_enrl
。 confirm_enrl
是项目文件夹名称
我在项目布局中遇到了同样的错误
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 project layout,src
不应该在 golang 项目中。
所以看起来如果你 运行 go mod init 'xxx' xxx 是你项目的核心名称。在那里,主要包的完整名称是 'xxx/main' 所以如果你的项目根文件夹是这样的:
root -> go mod init xxx
|- main.go -> package "main"
|- tools
|- helper.go -> package "tools"
并且您想从 main.go 导入工具包,您需要导入这个“xxx/tools”
我在包名拼写错误时遇到了同样的错误。因此,这可能是此错误背后的根本原因。也许对某人有用。
我在使用 goland default awesomeProject
学习入门教程时遇到了同样的问题。
我在创建项目 运行 之后做了什么这个命令 go mod init example.com/hello
但是我的根目录名称不同于 example.com/hello
.
手动编辑 go.mod 文件并将 awesomeProject
替换为 example.com/hello
后,构建成功。
我知道这是大约一年前的事了。我只想与那些在本地文件夹中有模块的人分享相同的经验..
问题是因为您没有将模块发布到像 github 这样的中央位置。 你必须 运行 这个命令告诉 go 这个模块是一个本地模块
go mod edit --replace external_folder_module_name= ../pathItsLocated
我在构建 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/
对于我的情况,只需将我的 go 版本 更新到最新版本即可解决问题。
我 downloaded the latest binary 并安装了它,boom 一切都已排序!
就我而言,我试图从错误的目录构建。旧目录甚至没有任何 .go
个文件。
确保您的导入语句与您在 mod.
中定义的 module 名称匹配只需使用 mod 文件初始化项目并开始处理根文件夹。
go mod init <name-anything>
在较新的 Go 版本 (post 1.13) 中,您不需要设置 GOPATH
、GOBIN
等环境变量
您还需要在项目根目录下有一个 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 的 运行 次。
test
和 run
命令在格式 go COMMAND package_path/xxx
中是 运行。在不指定 package_path ./
和 运行ning go COMMAND xxx
的情况下,编译器假定模块 xxx 位于 GOROOT 中,并且抛出错误 package xxx is not in GOROOT (path/to/GOROOT/src/xxx)
因为它不存在。
此行为是预期的,因为我们正在使用的包不是 Go SDK 的一部分,即不在 GOROOT
中。我们正在使用的包将最终位于 go 工作区或当前工作目录中。 运行ning go install
编译并将可执行二进制文件放入 $GOBIN
(a.k.a $GOPATH/bin
- 这里 $GOPATH
是 Go 工作区)。 运行ning 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
替换为 basic
、advanced
或 advanced/scientific
与.
使用
在项目目录(go mod init
calculatorv1
、calculatorv2
或calculatorv3
之一)中初始化Go模块运行 测试
go test -v ./...
(从项目根开始,递归执行所有测试套件)或
go test -v ./xxx
(来自项目根目录,运行包“xxx”中的测试套件)或
cd xxx/ go test -v # (from inside the package)
编译执行包
go run ./...
(从项目根目录开始,递归 运行 除了测试之外的所有.go
文件)或
go run ./xxx
(从项目根目录,运行 "xxx" 包中的所有.go
文件,除了测试)或
cd xxx go run . # (from inside the package)
注意:只有主包中的文件是可执行的,即具有声明
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)
}
})
}
我们可以通过在终端上写这个命令来解决这个问题:go env -w GO111MODULE=off
但是执行此命令后,您将无法通过终端使用 go mod init
。您必须手动创建“go.mod”文件。
在我的例子中,这是通过更改 goroot 路径引起的。
GOROOT 是定义您的 Go SDK 所在位置的变量
如果您将 goroot 更改为安装 go sdk 的位置,它将起作用
看起来有点好笑,但我遇到了同样的错误,因为 运行ning:
go run build
而不是
go build main.go
所以它表明在 build 或 运行 之后的所有内容都应该有一个可识别的路径。
对我来说,这是因为我的主要方法不在包 main 中
package main
func main() {
{
}