关于GOROOT、GOPATH、GOBIN、project目录

本文详细介绍了Go语言中的GOROOT、GOPATH、GOBIN等环境变量的设置与使用方法,包括如何配置这些变量来管理Go项目及其依赖包,以及在多项目开发场景下的最佳实践。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://www.jb51.net/article/56779.htm

http://blog.youkuaiyun.com/Alsmile/article/details/48290223

GOROOT、GOPATH、GOBIN、project目录


前言:我觉得java程序员学golang很容易上手。关于GOROOT、GOPATH、GOBIN这些环境变量的设置,我隐约感觉到了java的影子(尽管我是一个C++程序员),唯一和java不同的是不能设置“.”。

另外,golang的设计也很明显的透露着“约定优于配置”的原则。这在java很多框架里面很常见。golang的环境变量设计也是如此。从Android和golang我觉得google喜欢java。

不了解java的C++程序员,可以尝试全新去理解golang。

GOROOT

golang安装路径。

GOPATH

官方解释,请google。go工作环境中常常用到的一个很重要的环境变量(这种设计类似java)。具体用途:go命令常常需要用到的,如go run,go install, go get等。允许设置多个路径,和各个系统环境多路径设置一样,windows用“;”,linux(mac)用“:”分隔。

在linux(Mac)下,为了方便,一般配置在~/.bash_profile中。

book:~ wukebing$ vi ~/.bash_profile  //编辑

book:~ wukebing$ source ~/.bash_profile //编辑完成后,使立即生效

例如:我的GOPATH设置(MAC下)

export GOPATH=$HOME/workspace/go
export PATH=$PATH:${GOPATH//://bin:}/bin
export GOBIN=

其中,“export PATH=$PATH:${GOPATH//://bin:}/bin”为Linux(Mac)下把每个GOPATH下的bin都加入到PATH中。

当存在多个路径时,好像优先采用第一个路径。这个无关紧要了,只有需要的第三方包(库)都能正确下载和使用就ok了。

GOBIN

go install编译存放路径。不允许设置多个路径。可以为空。为空时则遵循“约定优于配置”原则,可执行文件放在各自GOPATH目录的bin文件夹中(前提是:package main的main函数文件不能直接放到GOPATH的src下面。

go环境查看

用go env 可查看当前go环境变量。

GOPATH目录结构

goWorkSpace  // (goWorkSpace为GOPATH目录)
  -- bin  // golang编译可执行文件存放路径,可自动生成。
  -- pkg  // golang编译的.a中间文件存放路径,可自动生成。
  -- src  // 源码路径。按照golang默认约定,go run,go install等命令的当前工作路径(即在此路径下执行上述命令)。

go目录结构1:

project1 // (project1添加到GOPATH目录了)
  -- bin
  -- pkg
  -- src  
     -- models       // package
     -- controllers  // package
     -- main.go      // package main[注意,本文所有main.go均指包main的入口函数main所在文件]
 project2 // (project2添加到GOPATH目录了)
      -- bin
      -- pkg
      -- src
         -- models       // package
         -- controllers  // package
         -- main.go      // package main
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

package main文件直接在GOPATH目录到src下。

使用go build可以在src文件夹下编译生成名为“src”的可执行文件。这是golang默认约定。一般我个人不怎么用这个命令。因为它会生成可执行文件在src目录下面。

我一般用:go get 和 go install。

go get [main.go所在路径]

参数 [main.go所在路径]:可选。相对GOPATH/src路径。 缺省是.(src自己)。可指定src下面的子文件夹路径。 
go get会做2件事:1. 从远程下载需要用到的包。2.执行go install。(从这里也可以看出golang处处为了简洁而遵循的“约定优于配置”原则)

go install [main.go所在路径]

参数 [main.go所在路径]:可选。 相对GOPATH/src路径。缺省是.(即当前所在目录或工作目录)。可指定src下面的子文件夹。 
go install编译生成名称为[main.go父文件夹名]的可执行文件,放到GOBIN路径下。当GOBIN为空时,默认约定是:生成的可执行文件放到GOPATH/bin文件夹中。产生的中间文件(.a)放在project/pkg中(没有变化时,不重新生成.a)。

我们再看此go目录结构1,执行go install(以及go get的第二阶段go install)会报错:

注意:如果不用额外方式改变环境变量(公司目前用的是sh脚本编译),是编译不过的。报错:can’t load package: package .: no buildable Go source files in *

解决方法1: 
曾经我也因为这个错误感到迷惑,认为所有都环境变量都没有问题。网上也没怎么看到直接明确都解答。看了一些帖子后,触类旁通,设置了GOBIN环境变量后解决。(好吧,我至今也没有完整读过英文官方文档。这种默认约定,官方文档上应该有。)

此解决方法有个弊端,多个project会导致多个GOPATH目录。多个project下的目录结构和包一致的话,直接编译会导致编译问题。因为go优先使用第一个GOPATH目录,导致编译冲突。(当然,你也可以每次手工或脚步修改GOPATH环境变量,感觉很麻烦。)不建议多个project直接设置到茫茫多的GOPATH中。当然有解决方法2,我认为是标准合理的解决方法,就是下面go目录结构2了。

go目录结构2:

goWorkSpace     // goWorkSpace为GOPATH目录
  -- bin
     -- myApp1  // 编译生成
     -- myApp2  // 编译生成
     -- myApp3  // 编译生成
  -- pkg
  -- src
     -- common 1
     -- common 2
     -- common utils ...
     -- myApp1     // project1
        -- models
        -- controllers
        -- others
        -- main.go 
     -- myApp2     // project2
        -- models
        -- controllers
        -- others
        -- main.go 
     -- myApp3     // project3
        -- models
        -- controllers
        -- others
        -- main.go 

一个solution里面的多个project或工具组件都并列放在GOPATH的src下,如myApp1,myApp2,myApp3,common utils。 
这时,GOBIN可以为空,编译时,可以如下: 
go install myApp1 或 go get myApp1 
go install myApp2 或 go get myApp2 
go install myApp3 或 go get myApp3

这时才是大家都认为的,把可执行程序myApp1、myApp2、myApp3生成在goWorkSpace/bin下面。多个GOPATH也就有了上面的“把每个GOPATH下的bin都加入到PATH中”。

提示:相同结构的project下同名包怎么办? 
有同事在初学时,习惯按照go目录结构1,了解到go目录结构2后(以为仅仅是把main放到了子文件夹,其他controllers等包结构不变),有这样的疑惑。他们原来就有这样的问题,同时把go目录加入到GOPATH后,编译就出现问题,因为包名和路径相同(相对GOPATH下的src),go只会优先查找第一个符合的GOPATH)。只会每次编译时手工修改GOPATH,或写脚本编译。(我看着就觉得累,还徒增脚本维护烦恼。)

解决方案就是:除了通用的,公有的工具、组件外,属于各个project自己的东西,统统随着main.go一起移到project目录下。go目录结构2就是这样的。 
导入各个project下的controllers方法:import myApp1/controllers,import myApp2/controllers这样的。go的import查找的是包的路径,并不是包名。你只用告诉go,你的包都放在哪了,go会从这些路径下查找有没有所需要的包。只是大家一般习惯包名和文件夹名相同,容易误解。只需要注意,一个文件夹下只允许有一个包名,允许有子文件夹定义不同的包。 
import 采用的是相对路径写法:路径是 相对GOROOT和GOPATH下的src。

也可以设置GOBIN,而且这时,由于可执行文件名称不同,也不大容易产生覆盖(需要避免的时多个GOPATH用相同的“myApp”project名称。)

具体的还是看个人喜好和实际情况。我个人本地的环境大致是:

dir      
  -- goWorkSpace1    // 主要是为了区分自己的鼓捣的一些东西和工作上的项目
  -- goWorkSpace2
        -- bin
        -- pkg
        -- src                  
           -- myApp1
              -- .git
              -- models
              -- controllers
              -- main.go 
           -- myApp2
              -- .git
              -- models
              -- controllers
              -- main.go 
           -- myApp3
              -- .git
              -- models
              -- controllers
              -- main.go

也就是我本地是有多个GOPATH路径的dir/goWorkSpace1、dir/goWorkSpace2。 
注意:GOPATH目录和GOPATH下的src不应该添加到源代码管理中,而是各个project目录myApp1、myApp2、myApp3各自时独立的进行源代码管理

我一般不设置GOBIN,把每个GOPATH下的bin都加入到PATH中。

个人理解,有任何问题,欢迎指正。


<think>好的,用户遇到了Go模块中标准库包缺失的问题,需要解决。首先,我需要理清可能的原因和对应的解决方案。根据用户提到的错误信息,可能涉及标准库包如delve、liner、go.starlark.net、blackfriday、telemetry等,这些可能并非Go官方标准库的一部分,而是第三方包。用户可能误解了这些包属于标准库,或者在GOPATH下找不到它们,导致构建失败。 首先,标准库包通常不需要手动安装,它们随Go安装一起提供。如果出现缺失,可能是Go环境安装不完整或版本不匹配。需要检查Go版本,使用go version确认,并考虑重新安装或升级。另外,GOPATH和GOMODULE的配置可能有问题。Go Modules启用后,依赖管理不再依赖GOPATH,但若项目未正确初始化模块,可能导致问题。用户需要确认是否在项目目录下执行了go mod init,并确保go.mod文件存在。 其次,提到的包如delve(调试工具)、blackfriday(Markdown处理器)、go.starlark.net(嵌入Starlark语言)等,都是第三方库。用户可能没有正确获取这些依赖。需要使用go get命令安装,例如go get github.com/russross/blackfriday/v2。同时,检查go.mod和go.sum是否包含这些依赖,必要时手动添加并运行go mod tidy。 另外,GOPATH的环境变量设置可能被覆盖或错误,需要检查GOPATH是否指向正确目录,并确认这些第三方包是否被下载到GOPATH下的pkg/mod中。若使用Go Modules,GOPATH的角色已经弱化,主要依赖项目内的go.mod管理。 还有可能涉及特定工具的配置问题,例如Delve调试器需要确保其版本与Go版本兼容,或者重新安装Delve(go install github.com/go-delve/delve/cmd/dlv@latest)。对于telemetry相关的错误,可能与Go 1.15+的遥测功能有关,但通常不影响构建,除非有特定环境限制,可以尝试禁用遥测(GOTELEMETRY=off)。 总结解决方案步骤:1. 确认Go环境正确安装;2. 初始化Go模块;3. 使用go get安装缺失的第三方包;4. 检查并更新依赖;5. 处理工具链问题;6. 环境变量检查。同时,用户可能需要区分标准库和第三方包,正确管理依赖。</think>### 逐步解决方案:Go模块中标准库包缺失问题 #### 1. **确认包的真实性质** - **标准库包**:Go的标准库包(如`fmt`、`net/http`)无需手动安装,随Go环境自动提供。若提示缺失,可能是环境配置问题。 - **第三方包**:例如: - `delve`:调试工具([github.com/go-delve/delve](https://github.com/go-delve/delve)) - `blackfriday`:Markdown处理器([github.com/russross/blackfriday](https://github.com/russross/blackfriday)) - `go.starlark.net`:Starlark语言嵌入库([go.starlark.net](https://github.com/google/starlark-go)) 若误将第三方包当作标准库,需通过`go get`安装: ```bash go get github.com/russross/blackfriday/v2 go get go.starlark.net/@latest ``` #### 2. **检查Go环境配置** - **确认Go版本**: ```bash go version # 需≥1.11(支持Go Modules) ``` - **重新安装Go环境**: 若标准库缺失(如`fmt`报错),重新安装Go并检查环境变量`GOROOT`和`GOPATH`[^3]。 #### 3. **初始化Go模块** - 在项目根目录执行: ```bash go mod init <module-name> # 初始化模块 go mod tidy # 自动添加/移除依赖 ``` - 手动添加缺失包到`go.mod`: ```go require ( github.com/go-delve/delve v1.20.1 go.starlark.net v0.0.0-20230831151026-0... ) ``` #### 4. **解决特定包问题** - **Delve调试工具**: ```bash go install github.com/go-delve/delve/cmd/dlv@latest ``` - **Telemetry错误**: 禁用遥测(临时): ```bash export GOTELEMETRY=off ``` #### 5. **检查GOPATH与模块兼容性** - Go Modules启用后,依赖默认存储在`$GOPATH/pkg/mod`,无需手动操作。 - 确认环境变量: ```bash go env GOPATH # 查看当前GOPATH go env GOMOD # 确认当前模块路径 ``` #### 6. **更新依赖版本** - 强制更新所有依赖: ```bash go get -u ./... ``` --- ### 关键命令总结 | 问题类型 | 命令示例 | |--------------------|--------------------------------------------------------------------------| | 安装第三方包 | `go get github.com/russross/blackfriday/v2` | | 初始化模块 | `go mod init example.com/project` | | 清理无效依赖 | `go mod tidy` | | 更新所有依赖 | `go get -u ./...` | | 重新安装Delve | `go install github.com/go-delve/delve/cmd/dlv@latest` | --- ### 相关问题 1. **如何区分Go标准库和第三方包?** > 标准库列表见[官方文档](https://pkg.go.dev/std),未列出的均为第三方包。 2. **Go Modules与GOPATH的关系是什么?** > Modules启用后,依赖优先从`go.mod`管理,存储于`$GOPATH/pkg/mod`,不再依赖`GOPATH/src`。 3. **如何修复`missing go.sum entry`错误?** > 运行`go mod tidy`或`go mod verify`同步依赖校验。 4. **Go 1.16+的默认模块行为有何变化?** > `go install`默认安装到`GOBIN`,且需显式指定`@version`(如`@latest`)。 --- ### 引用标注 [^1]: 关于Git库和中间件的引用,见Webhooks工具库说明。 [^2]: 视频处理库如FFmpeg绑定,参考相关Go包文档。 : Go Modules的官方定义和操作指南,详见Go官方博客。 [^4]: DevOps工具链的集成方法,参考Go生态工具分类。 [^5]: Go到其他语言的编译工具,如GopherJS,需注意版本兼容性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值