关于GOROOT、GOPATH、GOBIN、project目录

前端之家收集整理的这篇文章主要介绍了关于GOROOT、GOPATH、GOBIN、project目录前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

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/work/solution1/go:$HOME/work/solution1/workspace/core-server:$HOME/work/solution1/workspace/api-server:$HOME/work/solution1/workspace/test
export PATH=$PATH:${GOPATH//://bin:}/bin
export GOBIN=

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

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

GOBIN

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

go环境查看

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

project目录结构

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

project目录结构1:

project
  -- bin
  -- pkg
  -- src
     -- common
     -- models package
     -- controllers package
     -- main.go // package main的main函数文件

package main的main函数文件直接在project到src下。

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

我一般用:go get 和 go install。

go get [文件夹名]

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

go install [文件夹名]

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

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

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

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

解决方法有个弊端,多个project,最后编译都可执行文件会覆盖前面的。而且,多个可执行文件必然时按多个project思路去做。很多人好像也不建议多个project和茫茫多的GOPATH。当然,你看了后面,似乎有种感觉,google也倾向一个project。当然有解决方法2,我认为也是google推荐的解决方法(从设计原则中感觉),这就是project目录结构2了。

project目录结构2:

project
  -- bin
     -- myApp1  // 编译生成
     -- myApp2  // 编译生成
     -- myApp3  // 编译生成
  -- pkg
  -- src
     -- common 1
     -- common 2
     -- common utils ...
     -- myApp1
        -- models
        -- controllers
        -- others
        -- main.go // package main的main函数文件
     -- myApp2
        -- models
        -- controllers
        -- others
        -- main.go // package main的main函数文件
     -- myApp3
        -- models
        -- controllers
        -- others
        -- main.go // package main的main函数文件

一个solution里面的多个project或工具组件都并列放在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生成在project/bin下面。多个project也就有了上面的“把每个project下的bin都加入到PATH中”。

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

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

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

从这种project目录结构,似乎可以看出,google似乎推荐大家所说的,避免设置多个GOPATH。

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

dir
  -- go         // 最早配置环境或有些工具需要用到,就设置了这么个项目无关go目录。这个目录也就一直这么保存了。
     -- bin  
     -- pkg  
     -- src  
  -- solution1    // 区分工作上不同的项目以及自己的鼓捣学习的一些东西
  -- solution2
     -- myProject
        -- bin
        -- pkg
        -- src
           -- common          
           -- myApp1
              -- models
              -- controllers
              -- main.go // package main的main函数文件
           -- myApp2
              -- models
              -- controllers
              -- main.go // package main的main函数文件
           -- myApp3
              -- models
              -- controllers
              -- main.go // package main的main函数文件

也就是我本地是有多个GOPATH路径的dir/go、dir/solution1、dir/solution2。

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

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

猜你在找的Go相关文章