登录
首页 >  Golang >  Go问答

Go构建项目报错:“XXX包不在GOROOT中”

来源:stackoverflow

时间:2024-03-16 10:00:36 119浏览 收藏

构建 Go 项目时遇到“包不在 GOROOT 中”的错误可能是由于以下原因: * 每个模块都执行了 `go mod init`,导致每个文件夹中都生成了 `go.mod` 和 `go.dep` 文件。 * 在 GoLand 中启用了 Go 模块,导致 GoLand 无法检测到外部包和自己的包。

问题内容

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

构建我的一个包时的具体错误是: start.go: 包项目/游戏不在 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

对于每个模块(项目/游戏/实体、项目/游戏、项目/服务器),我做了一个 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 还很陌生,我不太确定该看什么文档:\ 谢谢大家!


解决方案


一个相当愚蠢的结论(主要是我的部分),但我的问题来自于在每个文件夹中完成了 go mod init 。从我执行 go mod init 的每个文件夹中删除 go.modgo.dep 后,我可以毫无问题地构建(通过终端)

此外,我在 goland 中的包未被检测到,因为我在“设置”中启用了 go 模块。我禁用了它,goland 能够索引外部包和我自己的包。

在 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 初始化项目目录中的 go 模块(calculatorv1calculatorv2calculatorv3 之一)

  • 运行测试

    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)
        }
    })
    
}

ma​​in.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

ma​​in.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

ma​​in.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构建项目报错:“XXX包不在GOROOT中”》的介绍就到此结束啦,但是学无止境,想要了解学习更多关于Golang的相关知识,请关注golang学习网公众号!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>