Golang 編譯約束/條件編譯 ( // +build )


通常對程序進行編譯的時候,可能帶一些條件(如不同平台、架構有不同的代碼實現),讓編譯器只對滿足條件的代碼進行編譯,將不滿足條件的代碼舍棄,這就是條件編譯。golang中,稱之為編譯約束,進行編譯約束的方式有2種分別:

  • 編譯標簽(build tag)
  • 文件后綴

編譯標簽 (build tag)

在源碼文件頂部添加注釋,來決定文件是否參與編譯

// +build <tags>

說明:

  • 以逗號分開表示AND
  • 以空格分開表示OR
  • !表示NOT
  • 一個文件可以有多個 +build 構建標記,它們之間的關系是邏輯 的關系

標簽可以指定為以下內容:

  • 操作系統,環境變量中GOOS的值,如:linuxdarwinwindows等等。可以通過 go env 查看 GOOS 環境變量的值。
  • 操作系統的架構,環境變量中GOARCH的值,如:arch64x86i386等等。可以通過 go env 查看 GOARCH 環境變量的值。
  • 使用的編譯器,gc或者gccgo
  • 是否開啟CGO,cgo
  • golang版本號: 比如Go Version 1.1為go1.1,Go Version 1.12版本為go1.12,以此類推。
  • 其它自定義標簽,通過go build -tags指定的值。

例如,編譯條件為(linux AND 386) OR (darwin AND (NOT cgo))

// +build linux,386 darwin,!cgo

另外一個文件可以有多個編譯約束,比如條件為(linux OR darwin) AND amd64

// +build linux darwin
// +build amd64

也可以將一個文件從編譯中排除,使用ignore標簽。

// +build ignore

注意:// +build的下一行必須是空行。

// +build linux

// main package comment
package main

下面的寫法不會識別為build tag,而會解析為包注釋:

// +build linux
package main

文件后綴

除了編譯標簽,編譯器也會根據文件后綴來自動選擇編譯文件,格式如下:

$filename_$GOOS.go
$filename_$GOARCH.go
$filename_$GOOS_$GOARCH.go
  • $filename: 源文件名稱。
  • $GOOS: 表示操作系統,從環境變量中獲取。
  • $GOARCH: 表示系統架構,從環境變量中獲取。

如在項目中有tcp.gotcp_linux_x86.go 兩個文件,執行:

GOOS=linux GOARCH=x86 go build

將選擇 tcp_linux_x86.go進行編譯。

利用ldflags在編譯過程中為變量賦值

本節為附加說明,不屬於條件編譯的范疇。有時我們需要在編譯過程中為變量賦值,此時可以利用ldflags參數完成。ldflagsgo build的一個參數,使用方式如下:

go build -ldflags "-w -s -X main.Version=${VERSION} -X github.com/demo/version.BuildNo=${BUILD_NO}"

參數說明:

-w 刪除DWARF信息:編譯出來的程序無法用gdb進行調試。

-s 刪除符號表:panic的stack trace沒有文件名/行號信息,等價於C/C++程序被strip。

-X 替換包中的變量的值。

加上-w -s可以有效減少編譯出來地程序的大小,但不利於進行調試和日志追蹤。

參考文章

本文轉載自:Go 知識點(18)— 條件編譯(編譯標簽、文件后綴)_wohu1104的博客-CSDN博客_go 條件編譯


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM