当前位置:首页 > 文章列表 > Golang > Go问答 > Go构建项目报错:“XXX包不在GOROOT中”

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

来源:stackoverflow 2024-03-16 10:00:36 0浏览 收藏

构建 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删除
揭晓:三星Galaxy A25 5G手机高清渲染图曝光,设计独具匠心揭晓:三星Galaxy A25 5G手机高清渲染图曝光,设计独具匠心
上一篇
揭晓:三星Galaxy A25 5G手机高清渲染图曝光,设计独具匠心
等效于在 MongoDB 中执行一个查询,其中 id 字段的值在给定的 ids 数组中
下一篇
等效于在 MongoDB 中执行一个查询,其中 id 字段的值在给定的 ids 数组中
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    542次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    508次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    497次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    484次学习
查看更多
AI推荐
  • AI Make Song:零门槛AI音乐创作平台,助你轻松制作个性化音乐
    AI Make Song
    AI Make Song是一款革命性的AI音乐生成平台,提供文本和歌词转音乐的双模式输入,支持多语言及商业友好版权体系。无论你是音乐爱好者、内容创作者还是广告从业者,都能在这里实现“用文字创造音乐”的梦想。平台已生成超百万首原创音乐,覆盖全球20个国家,用户满意度高达95%。
    22次使用
  • SongGenerator.io:零门槛AI音乐生成器,快速创作高质量音乐
    SongGenerator
    探索SongGenerator.io,零门槛、全免费的AI音乐生成器。无需注册,通过简单文本输入即可生成多风格音乐,适用于内容创作者、音乐爱好者和教育工作者。日均生成量超10万次,全球50国家用户信赖。
    18次使用
  •  BeArt AI换脸:免费在线工具,轻松实现照片、视频、GIF换脸
    BeArt AI换脸
    探索BeArt AI换脸工具,免费在线使用,无需下载软件,即可对照片、视频和GIF进行高质量换脸。体验快速、流畅、无水印的换脸效果,适用于娱乐创作、影视制作、广告营销等多种场景。
    18次使用
  • SEO标题协启动:AI驱动的智能对话与内容生成平台 - 提升创作效率
    协启动
    SEO摘要协启动(XieQiDong Chatbot)是由深圳协启动传媒有限公司运营的AI智能服务平台,提供多模型支持的对话服务、文档处理和图像生成工具,旨在提升用户内容创作与信息处理效率。平台支持订阅制付费,适合个人及企业用户,满足日常聊天、文案生成、学习辅助等需求。
    20次使用
  • Brev AI:零注册门槛的全功能免费AI音乐创作平台
    Brev AI
    探索Brev AI,一个无需注册即可免费使用的AI音乐创作平台,提供多功能工具如音乐生成、去人声、歌词创作等,适用于内容创作、商业配乐和个人创作,满足您的音乐需求。
    22次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议隐私政策
返回登录
  • 重置密码