編譯並不僅僅是執行「go build」 命令,還有一些須額外注意的內容。
如習慣使用 gdb 這類偵錯程式,建議編譯時新增 -gcflags 「-n -l」 引數阻止優化和內聯,否則除錯時會有各種「找不到」的情況。
package main
func
test
(x *
int)
func
main()
go build -gcflags 「-n -l -m」
輸出:./datatest.go:3:11: test x does not escape
./datatest.go:9:7: main &x does not escape
而當發布時,引數 -ldflags 「-w -s」 會讓鏈結器剔除符號表和除錯資訊,除能減少可執行檔案大小外,還可稍微增加反彙編的難度。
go build -gcflags 「-m」 -ldflags 「-w -s」
輸出:./datatest.go:3:6: can inline test
./datatest.go:7:6: can inline main
./datatest.go:9:6: inlining call to test
./datatest.go:3:11: test x does not escape
./datatest.go:9:7: main &x does not escape
交叉編譯
所謂交叉編譯,是指在乙個平台下編譯出其他平台所需的可執行檔案。這對於 unix-like 開發人員很重要,因為我們習慣使用 mac 或 其他桌面環境。
自從 go 實現自舉後,交叉編譯變得很重要。只續使用 goos、gopath 環境變數指定目標平台和架構就行。
go env goos
輸出:darwin
go build && file datatest
輸出: datatest: mach-o 64-bit executable x86_64
goos=linux go build && file datatest
輸出:elf 64-bit lsb executable, x86-64, version 1 (sysv), statically linked, not stripped
goos=windows goarch=386 go build && file datatest.exe
輸出:pe32 executable (console) intel 80386 (stripped to external pdb), for ms windows
建議用 go install 命令為目標平台預編譯後標準庫,避免 go build 每次都須完整編譯。
goos=linux go install std
goos=linux go install cmd
注意: 交叉編譯不支援 cgo.
條件編譯
除在**中用 runtime.goos 進行判斷外,編譯器本身就支援檔案級別的條件編譯。
方法1:將平台和架構資訊新增到主檔名尾部。
main.go
package main
func
main()
hello_darwin.go
package main
func
hello()
hello_linux.go
package main
func
hello()
goos=darwin go build -x
./main
輸出: hello mac.
goos=linux go build -x
./main
輸出: hello linux.
方法2:使用 build 編譯指令。
與用檔名區分多版本類似,build 編譯指令告知編譯器:當前原始碼檔案只能用於指定環境。它一樣可用來區分多版本,切控制指令更加豐富和靈活。
a.go
// +build windows <------- 其後面必須有空格
package main
func
hello()
b.go
// +build linux darwin
package main
func
hello()
可新增多條build指令,表示多個 and 條件。在單一指令裡,空格表示or條件,逗號表示and,感嘆號表示 not。
// +build linux darwin
// +build 386,!cgo
其相當於:
(linux or darwin) and (386 and (not cgo))
除 goos、goarch 外,可用條件還有編譯器、版本號等。
// +build ignore
// +build gccgo
// +build go1.5
方法3:使用自定義 tag 指令。
除預定義build 指令外,也可通過命令列 tags 引數傳遞自定義指令。
main.go
package main
func
main()
debug.go
// +build !release
package main
func
hello()
release.go
// +build release
package main
func
hello()
log.go
// +build log
package main
func
init()
go build && ./main
輸出: debug version.
go build -tags 「release log」 && ./main
輸出:logging …
release version.
預處理
簡單點說,就是用 go generate 命令掃瞄原始碼檔案,找出所有「go:generate」注釋,提取其中的命令並執行。
//go:generate echo $gopath
//go:generate ls -lh
package main
func
hello()
b.go
//go:generate uname -a
package main
func
init()
go generate -n
輸出:echo /users/www/go
ls -lh
uname -a
工具鏈在LFS中的應用
主系統中有linux核心,源工具鏈 輔助命令及庫。編譯工具和輔助命令都依賴glibc。考慮到主系統的binutils比實際需要的版本低,低版本的binutils可能缺少需要的某些功能,所以首先生成預編譯工具。利用預編譯工具編譯生成臨時系統,把臨時系統作為過渡,就可以使用chroot命令切換到制定目錄...
go命令工具
1 go build 這個命令可以直接使用,也可以帶上 包或原始碼檔案使用。如果是直接使用,表示試圖編譯當前目錄所對應的 包,如果當前目錄不是乙個有效的 包 包含在 gopath src 目錄下 則會報錯 如果帶上 包名,則表示編譯指定的 包 如果帶上原始碼檔案,則表示編譯指定原始碼檔案。go語言的...
Go 編譯 工具
go 的工具鏈非常豐富,從獲取原始碼 編譯 文件 測試 效能分析,到原始碼格式化 原始碼提示 重構工具等應有盡有 go 的編譯速度非常快 併發編譯 並且以 gopath 作為工作目錄和一套完整的工程目錄結構規則 gopath 需要提前配置好 使用 go build 命令將原始碼編譯為可執行檔案,有很...