Go項目目錄管理

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

Go的官網文檔How to Write Go Code中,已經介紹了Go的項目目錄一般包含以下幾個:

  • src 包含項目的原始碼檔案;
  • pkg 包含編譯後產生的包/庫檔案;
  • bin 包含編譯後產生的可執行檔案。

可以通過下面的例子來說明工程目錄的組織管理。(Windows 7 64位,go version go1.3.3 windows/amd64)

1. 建立一個庫檔案

建立一個庫檔案a.go並儲存在scr目錄的一個子目錄下面。

package myfuncimport "fmt"func Afunc(str string) {fmt.Println("a.go is package mufunc.")fmt.Println(str)}

這時候目錄結構如下:

<dirtest>     |--<src>          |--<mufunc>                 |--a.go

2. 建立main

關於main包的位置,可以參照參考資料2,個人建議放在scr/main下面,畢竟官方推薦包名和檔案存放的檔案夾名稱最好相同(雖然包名和檔案夾名可以不相同,也就是說一個檔案夾下可以包含多個包的.go檔案)。

package mainimport "myfunc"func main() {myfunc.Afunc("b.go is package main.")}

這時候目錄結構如下:

<dirtest>     |--<src>          |--<mufunc>                 |--a.go          |--<main>                 |--b.go

3. 使用go build

如果這時候使用go build,你會發現下面的輸出:

E:\dirtest>go build src\main\b.gosrc\main\b.go:3:8: cannot find package "myfunc" in any of:        C:\Program Files\go\src\pkg\myfunc (from $GOROOT)        D:\GoLang\src\myfunc (from $GOPATH)

從輸出中我們可以看到,Go先是從$GOROOT中尋找包myfunc,如果沒找到就從$GOPATH中尋找,結果都沒有找到,我們可以使用go env輸出Go的環境變數設定:

E:\dirtest>go envset GOARCH=amd64set GOBIN=set GOCHAR=6set GOEXE=.exeset GOHOSTARCH=amd64set GOHOSTOS=windowsset GOOS=windowsset GOPATH=D:\GoLangset GORACE=set GOROOT=C:\Program Files\goset GOTOOLDIR=C:\Program Files\go\pkg\tool\windows_amd64set CC=gccset GOGCCFLAGS=-m64 -mthreads -fmessage-length=0set CXX=g++set CGO_ENABLED=1

顯然E:\dirtest這個目錄沒有加到$GOPATH中,在環境變數中添加該目錄:

儲存後,重新執行(可能需要重新開啟控制台,讓環境變數生效)go build,就在目前的目錄產生了一個可執行檔b.exe

E:\dirtest\src\main>go envset GOARCH=amd64set GOBIN=set GOCHAR=6set GOEXE=.exeset GOHOSTARCH=amd64set GOHOSTOS=windowsset GOOS=windowsset GOPATH=D:\GoLang;E:\dirtestset GORACE=set GOROOT=C:\Program Files\goset GOTOOLDIR=C:\Program Files\go\pkg\tool\windows_amd64set CC=gccset GOGCCFLAGS=-m64 -mthreads -fmessage-length=0set CXX=g++set CGO_ENABLED=1E:\dirtest>go build src\main\b.goE:\dirtest>dir E:\dirtest 的目錄2015/01/13  23:11    <DIR>          .2015/01/13  23:11    <DIR>          ..2015/01/13  23:11    1,958,912      b.exe2015/01/13  22:52    <DIR>          srcE:\dirtest>b.exea.go is package mufunc.b.go is package main.

雖然成功運行,但是沒有按照期待的那樣產生在bin目錄下面。為了達到這樣的效果,你需要go install。注意go install是針對package,而不是針對單個.go檔案。

但是如果是目前狀態執行go install,雖然可以成功,但你會發現,並沒有在項目根目錄E:\dirtest中建立bin\main.exe,反而是在D:\GoLang中建立了。

如果對main包執行go install呢?

E:\dirtest\src\main>go installgo install: no install location for E:\dirtest\src\main: hidden by D:\GoLang\src\main

可以看到,輸出提示目前的目錄被隱藏。顯然這個順序是對應$GOPATH的設定的,把$GOPATH中的路徑順序改一下:

然後在執行go install myfunc,發現成功地在pkg目錄下面產生了myfunc.a。同樣執行go install main,也成功的在bin目錄下產生了main.exe。此時的目錄結構如下:

<dirtest>     |--<src>          |--<mufunc>                 |--a.go          |--<main>                 |--b.go     |--<pkg>          |--<windows_amd64>                 |--myfunc.a     |--<bin>          |--main.exe

現在就算是成功完成了一個樣本“項目”吧...

4. 常見錯誤

除了上面的步驟中出現的錯誤,其實工程目錄管理稍有不慎,就會出現其他問題,例如:

1. 一個檔案夾下麵包含多個不同包的源檔案。也就是把a.gob.go都放到myfunc目錄下面會是什麼情況呢?

這時候的目錄結構如下:

<dirtest>     |--<src>          |--<mufunc>                 |--a.go                 |--b.go

那麼執行go installgo build,甚至go run都會是相同的錯誤:

E:\dirtest\src\myfunc>go installcan't load package: package myfunc: found packages myfunc (a.go) and main (b.go) in E:\dirtest\src\myfuncE:\dirtest\src\myfunc>go buildcan't load package: package myfunc: found packages myfunc (a.go) and main (b.go) in E:\dirtest\src\myfuncE:\dirtest\src\myfunc>go run b.gob.go:3:8: found packages myfunc (a.go) and main (b.go) in E:\dirtest\src\myfunc

從參考資料3中可以看到,每個子目錄中只能存在一個package,否則編譯時間會報錯,所以一個子目錄下面不能包含多個不同包的源檔案。

2. 一個項目能包含多個main()嗎?

簡單測試下,建立一個c.go,並使用myfunc包(沒有匯入其他包的情況類似):

package mainimport "fmt"import "myfunc"func main() {fmt.Println("This is single c.go")myfunc.Afunc("c.go is also package main.")}

執行相應的命令,結果如下:

E:\dirtest\src\main>go build# main.\c.go:4: main redeclared in this block        previous declaration at .\b.go:5E:\dirtest\src\main>go build c.go # 成功,目前的目錄下產生了c.exeE:\dirtest\src\main>go install# main.\c.go:4: main redeclared in this block        previous declaration at .\b.go:5E:\dirtest\src\main>go install c.gogo install: no install location for .go files listed on command line (GOBIN notset)E:\dirtest\src\main>go run c.goThis is single c.goa.go is package mufunc.c.go is also package main.

顯然只能是go rungo build c.go可行。如果把c.go移到單獨的目錄下面呢:

E:\dirtest\src\cmain>dir E:\dirtest\src\cmain 的目錄2015/01/14  11:27    <DIR>          .2015/01/14  11:27    <DIR>          ..2015/01/14  11:24               147 c.goE:\dirtest\src\cmain>go buildE:\dirtest\src\cmain>go install

均可以執行成功。go installbin目錄下面產生了對應的exe檔案。看來還是目錄管理的問題。

3. go install: no install location for .go files listed on command line (GOBIN not set)

從上面的樣本輸出中就能看到,使用go install針對單個檔案時,就會出現這個錯誤。預設情況下如果設定了$GOROOT$GOPATH,就會依次尋找$GOROOT/bin$GOPATH/bin。那麼我們如果自訂設定了$GOBIN=E:\dirtest\bin之後會怎樣?

E:\dirtest\src\cmain>go envset GOARCH=amd64set GOBIN=E:\dirtest\binset GOCHAR=6set GOEXE=.exeset GOHOSTARCH=amd64set GOHOSTOS=windowsset GOOS=windowsset GOPATH=E:\dirtest;D:\GoLangset GORACE=set GOROOT=C:\Program Files\goset GOTOOLDIR=C:\Program Files\go\pkg\tool\windows_amd64set CC=gccset GOGCCFLAGS=-m64 -mthreads -fmessage-length=0set CXX=g++set CGO_ENABLED=1E:\dirtest\src\cmain>go install c.go# 成功在 E:\dirtest\bin 下面產生 c.exe

雖然成功了,但是go install應該是作用於包層級,而非單個檔案。

4. go build、go install 和 go run 的區別

詳細的可以查看參考資料4,這裡簡單說一下:

  • go build 編譯包,如果是main包則在目前的目錄產生可執行檔,其他包不會產生.a檔案;
  • go install 編譯包,同時複製結果到$GOPATH/bin$GOPATH/pkg等對應目錄下;
  • go run gofiles... 編譯列出的檔案,並產生可執行檔然後執行。注意只能用於main包,否則會出現go run: cannot run non-main package的錯誤。

此外,go run是不需要設定$GOPATH的,但go buildgo install必須設定。go run常用來測試一些功能,這些代碼一般不包含在最終的項目中。

5. 總結

  1. 一定要管理好目錄
  2. 多重專案最好都在一個$GOPATH下面,即src/proj1src/proj2,etc
  3. 盡量使用go install,這樣能夠規範項目整體結構

6. 參考資料

  1. Golang項目目錄結構組織
  2. 關於main包放在哪的問題
  3. 關於golang中包(package)的二三事兒
  4. Running multi-file main package
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.