[Golang] GOROOT、GOPATH和Project目录说明
go env環(huán)境查看
用go env 可查看當(dāng)前go環(huán)境變量。
$ go env GOARCH="amd64" GOBIN="" GOEXE="" GOHOSTARCH="amd64" GOHOSTOS="darwin" GOOS="darwin" GOPATH="/Users/mac/MyCodeBase/Go-project/master" GORACE="" GOROOT="/usr/local/go" GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64" GCCGO="gccgo" CC="clang" GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/dg/1_zsnh6n2md7y5kpjj318fk00000gp/T/go-build668952288=/tmp/go-build -gno-record-gcc-switches -fno-common" CXX="clang++" CGO_ENABLED="1" CGO_CFLAGS="-g -O2" CGO_CPPFLAGS="" CGO_CXXFLAGS="-g -O2" CGO_FFLAGS="-g -O2" CGO_LDFLAGS="-g -O2" PKG_CONFIG="pkg-config"?
GOROOT
GOROOT就是go的安裝路徑
在~/.bash_profile中添加下面語句:
當(dāng)然, 要執(zhí)行g(shù)o命令和go工具, 就要配置go的可執(zhí)行文件的路徑:
操作如下:
在~/.bash_profile中配置如下:
export $PATH:$GOROOT/bin
GOPATH
o install/go get和 go的工具等會用到GOPATH環(huán)境變量.GOPATH是作為編譯后二進(jìn)制的存放目的地和import包時的搜索路徑 (其實也是你的工作目錄, 你可以在src下創(chuàng)建你自己的go源文件, 然后開始工作)。GOPATH之下主要包含三個目錄: bin、pkg、srcbin目錄主要存放可執(zhí)行文件; pkg目錄存放編譯好的庫文件, 主要是*.a文件; src目錄下主要存放go的源文件不要把GOPATH設(shè)置成go的安裝路徑,可以自己在用戶目錄下面創(chuàng)建一個目錄, 如gopath操作如下:cd ~mkdir gopath在~/.bash_profile中添加如下語句:GOPATH=/Users/username/gopathGOPATH可以是一個目錄列表, go get下載的第三方庫, 一般都會下載到列表的第一個目錄里面需要把GOPATH中的可執(zhí)行目錄也配置到環(huán)境變量中, 否則你自行下載的第三方go工具就無法使用了, 操作如下:在~/bash_profile中配置,export $PATH:$GOPATH/bin創(chuàng)建一個go項目, 并且編譯運(yùn)行:mkdir goprojectcd goprojecttouch hello.go在hello.go中輸入:package mainimport "fmt"func main() {fmt.Println("Hello, GO !")}在項目根目錄下執(zhí)行g(shù)o build命令來構(gòu)建你的項目, 構(gòu)建后會生成hello文件運(yùn)行生成的文件./hello, terminal中輸出: Hello, GO !當(dāng)然你也可以直接運(yùn)行命令go run hello.go來執(zhí)行程序.?
如果要上述設(shè)置生效, 可以執(zhí)行命令: source ~/.bash_profile, 上述所有操作均為mac系統(tǒng)下的操作, 如果是非mac系統(tǒng), 請自行變通.
當(dāng)存在多個路徑時,好像優(yōu)先采用第一個路徑。這個無關(guān)緊要了,只有需要的第三方包(庫)都能正確下載和使用就ok了。GOBIN
go install編譯存放路徑。不允許設(shè)置多個路徑。可以為空。為空時則遵循“約定優(yōu)于配置”原則,可執(zhí)行文件放在各自GOPATH目錄的bin文件夾中(前提是:package main的main函數(shù)文件不能直接放到GOPATH的src下面。
GOPATH目錄結(jié)構(gòu)
goWorkSpace // (goWorkSpace為GOPATH目錄)-- bin // golang編譯可執(zhí)行文件存放路徑,可自動生成。-- pkg // golang編譯的.a中間文件存放路徑,可自動生成。-- src // 源碼路徑。按照golang默認(rèn)約定,go run,go install等命令的當(dāng)前工作路徑(即在此路徑下執(zhí)行上述命令)。go目錄結(jié)構(gòu)1:
project1 // (project1添加到GOPATH目錄了)-- bin-- pkg-- src -- models // package-- controllers // package-- main.go // package main[注意,本文所有main.go均指包main的入口函數(shù)main所在文件] project2 // (project2添加到GOPATH目錄了)-- bin-- pkg-- src-- models // package-- controllers // package-- main.go // package main?
?
package main文件直接在GOPATH目錄到src下。
使用go build可以在src文件夾下編譯生成名為“src”的可執(zhí)行文件。這是golang默認(rèn)約定。一般我個人不怎么用這個命令。因為它會生成可執(zhí)行文件在src目錄下面。
我一般用:go get 和 go install。
go get [main.go所在路徑]
參數(shù) [main.go所在路徑]:可選。相對GOPATH/src路徑。 缺省是.(src自己)。可指定src下面的子文件夾路徑。
go get會做2件事:1. 從遠(yuǎn)程下載需要用到的包。2.執(zhí)行g(shù)o install。(從這里也可以看出golang處處為了簡潔而遵循的“約定優(yōu)于配置”原則)
go install [main.go所在路徑]
參數(shù) [main.go所在路徑]:可選。 相對GOPATH/src路徑。缺省是.(即當(dāng)前所在目錄或工作目錄)。可指定src下面的子文件夾。
go install編譯生成名稱為[main.go父文件夾名]的可執(zhí)行文件,放到GOBIN路徑下。當(dāng)GOBIN為空時,默認(rèn)約定是:生成的可執(zhí)行文件放到GOPATH/bin文件夾中。產(chǎn)生的中間文件(.a)放在project/pkg中(沒有變化時,不重新生成.a)。
我們再看此go目錄結(jié)構(gòu)1,執(zhí)行g(shù)o install(以及go get的第二階段go install)會報錯:
注意:如果不用額外方式改變環(huán)境變量(公司目前用的是sh腳本編譯),是編譯不過的。報錯:can’t load package: package .: no buildable Go source files in *
解決方法1:
曾經(jīng)我也因為這個錯誤感到迷惑,認(rèn)為所有都環(huán)境變量都沒有問題。網(wǎng)上也沒怎么看到直接明確都解答。看了一些帖子后,觸類旁通,設(shè)置了GOBIN環(huán)境變量后解決。(好吧,我至今也沒有完整讀過英文官方文檔。這種默認(rèn)約定,官方文檔上應(yīng)該有。)
此解決方法有個弊端,多個project會導(dǎo)致多個GOPATH目錄。多個project下的目錄結(jié)構(gòu)和包一致的話,直接編譯會導(dǎo)致編譯問題。因為go優(yōu)先使用第一個GOPATH目錄,導(dǎo)致編譯沖突。(當(dāng)然,你也可以每次手工或腳步修改GOPATH環(huán)境變量,感覺很麻煩。)不建議多個project直接設(shè)置到茫茫多的GOPATH中。當(dāng)然有解決方法2,我認(rèn)為是標(biāo)準(zhǔn)合理的解決方法,就是下面go目錄結(jié)構(gòu)2了。
go目錄結(jié)構(gòu)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
這時才是大家都認(rèn)為的,把可執(zhí)行程序myApp1、myApp2、myApp3生成在goWorkSpace/bin下面。多個GOPATH也就有了上面的“把每個GOPATH下的bin都加入到PATH中”。
提示:相同結(jié)構(gòu)的project下同名包怎么辦?
有同事在初學(xué)時,習(xí)慣按照go目錄結(jié)構(gòu)1,了解到go目錄結(jié)構(gòu)2后(以為僅僅是把main放到了子文件夾,其他controllers等包結(jié)構(gòu)不變),有這樣的疑惑。他們原來就有這樣的問題,同時把go目錄加入到GOPATH后,編譯就出現(xiàn)問題,因為包名和路徑相同(相對GOPATH下的src),go只會優(yōu)先查找第一個符合的GOPATH)。只會每次編譯時手工修改GOPATH,或?qū)懩_本編譯。(我看著就覺得累,還徒增腳本維護(hù)煩惱。)
解決方案就是:除了通用的,公有的工具、組件外,屬于各個project自己的東西,統(tǒng)統(tǒng)隨著main.go一起移到project目錄下。go目錄結(jié)構(gòu)2就是這樣的。
導(dǎo)入各個project下的controllers方法:import myApp1/controllers,import myApp2/controllers這樣的。go的import查找的是包的路徑,并不是包名。你只用告訴go,你的包都放在哪了,go會從這些路徑下查找有沒有所需要的包。只是大家一般習(xí)慣包名和文件夾名相同,容易誤解。只需要注意,一個文件夾下只允許有一個包名,允許有子文件夾定義不同的包。
import 采用的是相對路徑寫法:路徑是 相對GOROOT和GOPATH下的src。
也可以設(shè)置GOBIN,而且這時,由于可執(zhí)行文件名稱不同,也不大容易產(chǎn)生覆蓋(需要避免的時多個GOPATH用相同的“myApp”project名稱。)
具體的還是看個人喜好和實際情況。我個人本地的環(huán)境大致是:
-- my-goWorkSpace // 主要是為了區(qū)分自己的鼓搗的一些東西和工作上的項目-- work-goWorkSpace-- bin-- pkg-- src -- myApp1-- .git-- models-- controllers-- main.go -- myApp2-- .git-- models-- controllers-- main.go -- myApp3-- .git-- models-- controllers-- main.go本地是有多個GOPATH路徑的
注意:GOPATH目錄和GOPATH下的src不應(yīng)該添加到源代碼管理中,而是各個project目錄myApp1、myApp2、myApp3各自時獨(dú)立的進(jìn)行源代碼管理
我一般不設(shè)置GOBIN,把每個GOPATH下的bin都加入到PATH中。
個人理解,有任何問題,歡迎指正。
總結(jié)
以上是生活随笔為你收集整理的[Golang] GOROOT、GOPATH和Project目录说明的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 沪股通进入意味着什么
- 下一篇: 2022十一股市休市安排,10月1日至1