ch10-7-3: review

This commit is contained in:
chai2010 2016-01-08 21:32:31 +08:00
parent 8c235ad220
commit e7ec8acc1f

View File

@ -1,32 +1,31 @@
### 10.7.3. 構建包 ### 10.7.3. 構建包
`go build` 命令編譯參數指定的每個包. 如果包是一個庫, 則忽略輸出結果; 這可以用於檢測包的可以正確編譯的. `go build`命令編譯命令行參數指定的每個包。如果包是一個庫則忽略輸出結果這可以用於檢測包的可以正確編譯的。如果包的名字是main`go build`將調用連接器在當前目録創建一個可執行程序;以導入路徑的最後一段作爲可執行程序的名字。
如果包的名字是 main, `go build` 將調用連接器在當前目録創建一個可執行程序; 導入路徑的最後一段作爲可執行程序的名字.
因爲每個目録隻包含一個包, 因此每個可執行程序後者叫Unix術語中的命令, 會要求放到一個獨立的目録. 這些目録有時候會放在名叫 cmd 目録的子目録下面, 例如用於提供Go文檔服務的 golang.org/x/tools/cmd/godoc 命令 (§10.7.4). 因爲每個目録隻包含一個包因此每個對應可執行程序或者叫Unix術語中的命令的包會要求放到一個獨立的目録中。這些目録有時候會放在名叫cmd目録的子目録下面例如用於提供Go文檔服務的golang.org/x/tools/cmd/godoc命令就是放在cmd子目録§10.7.4)。
每個包可以由它們的導入路徑指定, 就像前面看到的那樣, 或者有一個相對目録的路徑知道, 必鬚以 `.``..` 開頭. 如果沒有指定參數, 那麽默認指定爲當前的目録. 下面的命令用於構建同一個包, 雖然它們的寫法各不相同: 每個包可以由它們的導入路徑指定,就像前面看到的那樣,或者用一個相對目録的路徑知指定,相對路徑必鬚以`.`或`..`開頭。如果沒有指定參數,那麽默認指定爲當前目録對應的包。 下面的命令用於構建同一個包, 雖然它們的寫法各不相同:
``` ```
$ cd $GOPATH/src/gopl.io/ch1/helloworld $ cd $GOPATH/src/gopl.io/ch1/helloworld
$ go build $ go build
``` ```
或者: 或者
``` ```
$ cd anywhere $ cd anywhere
$ go build gopl.io/ch1/helloworld $ go build gopl.io/ch1/helloworld
``` ```
或者: 或者
``` ```
$ cd $GOPATH $ cd $GOPATH
$ go build ./src/gopl.io/ch1/helloworld $ go build ./src/gopl.io/ch1/helloworld
``` ```
但不能這樣: 但不能這樣
``` ```
$ cd $GOPATH $ cd $GOPATH
@ -34,7 +33,7 @@ $ go build src/gopl.io/ch1/helloworld
Error: cannot find package "src/gopl.io/ch1/helloworld". Error: cannot find package "src/gopl.io/ch1/helloworld".
``` ```
也可以指定包的源文件列表, 一般這隻用於構建一些小程序或臨時性的實驗. 如果是main包, 將以第一個Go源文件的基礎文件名作爲可執行程序的名字. 也可以指定包的源文件列表這一般這隻用於構建一些小程序或做一些臨時性的實驗。如果是main包將會以第一個Go源文件的基礎文件名作爲最終的可執行程序的名字。
``` ```
$ cat quoteargs.go $ cat quoteargs.go
@ -53,22 +52,22 @@ $ ./quoteargs one "two three" four\ five
["one" "two three" "four five"] ["one" "two three" "four five"]
``` ```
特别是對於這類一次性的程序, 我們繫統盡快的構建併運行它. `go run` 命令結合了構建和運行的兩個步驟: 特别是對於這類一次性運行的程序,我們希望盡快的構建併運行它。`go run`命令實際上是結合了構建和運行的兩個步驟:
``` ```
$ go run quoteargs.go one "two three" four\ five $ go run quoteargs.go one "two three" four\ five
["one" "two three" "four five"] ["one" "two three" "four five"]
``` ```
第一行的參數列表中第一個不是以 .go 結尾的將作爲可執行程序的參數運行. 第一行的參數列表中,第一個不是以`.go`結尾的將作爲可執行程序的參數運行。
默認情況下, `go build` 命令構建指定的包和它依賴的包, 然後丟棄所有除了最後的可執行文件之外的中間編譯結果. 依賴分析和編譯都是很快的, 但是隨着項目增加到幾十個包和成韆上萬行代碼, 依賴關繫分析和編譯時間的消耗將變的可觀, 可能需要幾秒種, 卽使這些依賴項沒有改變. 默認情況下`go build`命令構建指定的包和它依賴的包,然後丟棄除了最後的可執行文件之外所有的中間編譯結果。依賴分析和編譯過程雖然都是很快的,但是隨着項目增加到幾十個包和成韆上萬行代碼,依賴關繫分析和編譯時間的消耗將變的可觀,有時候可能需要幾秒種,卽使這些依賴項沒有改變。
`go install` 命令和 `go build` 命令很相似, 但是它保存每個包的編譯成果, 而不是將它們都丟棄. 被編譯的包被保存到 $GOPATH/pkg 目録下和 src 目録對應, 可執行程序被保存到 $GOPATH/bin 目録. (很多用戶將 $GOPATH/bin 添加到可執行程序的蒐索列表中.) 還有, `go install` 命令和 `go build` 命令都不會重新編譯沒有發生變化的包, 這可以使後續構建更快捷. 爲了方便, `go build -i` 將安裝每個目標所依賴的包. `go install`命令和`go build`命令很相似,但是它會保存每個包的編譯成果,而不是將它們都丟棄。被編譯的包會被保存到$GOPATH/pkg目録下目録路徑和 src目録路徑對應可執行程序被保存到$GOPATH/bin目録。很多用戶會將$GOPATH/bin添加到可執行程序的蒐索列表中。還有`go install`命令和`go build`命令都不會重新編譯沒有發生變化的包,這可以使後續構建更快捷。爲了方便編譯依賴的包,`go build -i`命令將安裝每個目標所依賴的包。
因爲編譯對應不同的操作繫統平台和CPU架構, `go install` 會將編譯結果安裝到 GOOS 和 GOARCH 對應的目録. 例如, 在 Mac 繫統 golang.org/x/net/html 包將被安裝到 $GOPATH/pkg/darwin_amd64 目録下的 golang.org/x/net/html.a 文件. 因爲編譯對應不同的操作繫統平台和CPU架構`go install`命令會將編譯結果安裝到GOOS和GOARCH對應的目録。例如在Mac繫統golang.org/x/net/html包將被安裝到$GOPATH/pkg/darwin_amd64目録下的golang.org/x/net/html.a文件。
針對不同操作繫統或CPU的交叉構建也是很簡單的. 隻需要設置好目標對應的GOOS 和 GOARCH, 然後運行構建目録卽可. 下面交叉編譯的程序將輸出它在編譯時操作繫統和CPU類型: 針對不同操作繫統或CPU的交叉構建也是很簡單的。隻需要設置好目標對應的GOOS和GOARCH然後運行構建命令卽可。下面交叉編譯的程序將輸出它在編譯時操作繫統和CPU類型
```Go ```Go
gopl.io/ch10/cross gopl.io/ch10/cross
@ -78,7 +77,7 @@ func main() {
} }
``` ```
下面以64位和32位環境分别執行程序: 下面以64位和32位環境分别執行程序
``` ```
$ go build gopl.io/ch10/cross $ go build gopl.io/ch10/cross
@ -89,24 +88,20 @@ $ ./cross
darwin 386 darwin 386
``` ```
有些包可能需要針對不同平台和處理器類型輸出不同版本的代碼, 以便於處理底層的可移植性問題或提供爲一些特點代碼提供優化. 如果一個文件名包含了一個操作繫統或處理器類型名字, 例如 net_linux.go 或 asm_amd64.s, Go工具將隻在對應的平台編譯這些文件. 還有一個特别的構建註釋註釋可以提供更多的構建控製. 例如, 文件中如果包含下面的註釋: 有些包可能需要針對不同平台和處理器類型使用不同版本的代碼文件以便於處理底層的可移植性問題或提供爲一些特定代碼提供優化。如果一個文件名包含了一個操作繫統或處理器類型名字例如net_linux.go或asm_amd64.sGo語言的構建工具將隻在對應的平台編譯這些文件。還有一個特别的構建註釋註釋可以提供更多的構建過程控製。例如文件中可能包含下面的註釋
```Go ```Go
// +build linux darwin // +build linux darwin
``` ```
在包聲明的前面(含包的註釋), 告訴 `go build` 隻在針對 Linux 或 Mac OS X 是才編譯這個文件. 下面的構建註釋表示不編譯這個文件: 在包聲明和包註釋的前面,該構建註釋參數告訴`go build`隻在編譯程序對應的目標操作繫統是Linux或Mac OS X時才編譯這個文件。下面的構建註釋則表示不編譯這個文件
```Go ```Go
// +build ignore // +build ignore
``` ```
For more details, see the Build Constraints section of the go/build packages documentation: 更多細節可以參考go/build包的構建約束部分的文檔。
更多細節, 可以參考 go/build 包的構建約束部分的文檔.
``` ```
$ go doc go/build $ go doc go/build
``` ```