Go 中的工具鏈

2021-09-28 14:58:14 字數 3722 閱讀 1488

編譯並不僅僅是執行「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 命令將原始碼編譯為可執行檔案,有很...