golang條件編譯

開篇

golang中沒有類似C語言中條件編譯的寫法,比如在C代碼中可以使用如下語法做一些條件編譯,結(jié)合宏定義來使用可以實現(xiàn)諸如按需編譯release和debug版本代碼的需求

#ifndef
#define
...

#end

但是golang支持兩種條件編譯方式

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

編譯標(biāo)簽( build tag)

在源代碼里添加標(biāo)注,通常稱之為編譯標(biāo)簽( build tag),編譯標(biāo)簽是在盡量靠近源代碼文件頂部的地方用注釋的方式添加

go build在構(gòu)建一個包的時候會讀取這個包里的每個源文件并且分析編譯便簽,這些標(biāo)簽決定了這個源文件是否參與本次編譯

編譯標(biāo)簽添加的規(guī)則(附上原文):

  1. a build tag is evaluated as the OR of space-separated options
  2. each option evaluates as the AND of its comma-separated terms
  3. each term is an alphanumeric word or, preceded by !, its negation

1). 編譯標(biāo)簽由空格分隔的編譯選項(options)以"或"的邏輯關(guān)系組成

2). 每個編譯選項由逗號分隔的條件項以邏輯"與"的關(guān)系組成

3). 每個條件項的名字用字母+數(shù)字表示,在前面加!表示否定的意思

例子(編譯標(biāo)簽要放在源文件頂部)

// +build darwin freebsd netbsd openbsd

這個將會讓這個源文件只能在支持kqueue的BSD系統(tǒng)里編譯

一個源文件里可以有多個編譯標(biāo)簽,多個編譯標(biāo)簽之間是邏輯"與"的關(guān)系

// +build linux darwin
// +build 386

這個將限制此源文件只能在 linux/386或者darwin/386平臺下編譯.
除了添加系統(tǒng)相關(guān)的tag,還可以自由添加自定義tag達(dá)到其它目的。
編譯方法:
只需要在go build指令后用-tags指定編譯條件即可

go build -tags mytag1 mytag2

注意:剛開始使用編譯標(biāo)簽經(jīng)常會犯下面這個錯誤

// +build !linux
package mypkg // wrong

這個例子里的編譯標(biāo)簽和包的聲明之間沒有用空行隔開,這樣編譯標(biāo)簽會被當(dāng)做包聲明的注釋而不是編譯標(biāo)簽從而被忽略掉

下面這個是正確的標(biāo)簽的書寫方式,標(biāo)簽的結(jié)尾添加一個空行這樣標(biāo)簽就不會當(dāng)做其他聲明的注釋

// +build !linux

package mypkg // correct

用go vet命令也可以檢測到這個缺少空行的錯誤,初期可以用這個命令來避免缺少空行的錯誤

% go vet mypkg
mypkg.go:1: +build comment appears too late in file
exit status 1

作為參考,下面的例子將licence聲明,編譯標(biāo)簽和包聲明放在一起,請大家注意分辨

% head headspin.go

// Copyright 2013 Way out enterprises. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build someos someotheros thirdos,!amd64

// Package headspin implements calculates numbers so large
// they will make your head spin.
package headspin

文件后綴

這個方法通過改變文件名的后綴來提供條件編譯,這種方案比編譯標(biāo)簽要簡單,go/build可以在不讀取源文件的情況下就可以決定哪些文件不需要參與編譯。文件命名約定可以在go/build 包里找到詳細(xì)的說明,簡單來說如果你的源文件包含后綴:_GOOS.go,那么這個源文件只會在這個平臺下編譯,_GOARCH.go也是如此。這兩個后綴可以結(jié)合在一起使用,但是要注意順序:_GOOS_GOARCH.go, 不能反過來用:_GOARCH_GOOS.go.
例子如下:

mypkg_freebsd_arm.go // only builds on freebsd/arm systems
mypkg_plan9.go       // only builds on plan9

編譯標(biāo)簽和文件后綴的選擇

編譯標(biāo)簽和文件后綴的功能上有重疊,例如一個文件名:mypkg_linux.go包含了// +build linux將會出現(xiàn)冗余

通常情況下,如果源文件與平臺或者cpu架構(gòu)完全匹配,那么用文件后綴,例如:

mypkg_linux.go         // only builds on linux systems
mypkg_windows_amd64.go // only builds on windows 64bit platforms

相反,如果滿足以下任何條件,那么使用編譯標(biāo)簽:

  • 這個源文件可以在超過一個平臺或者超過一個cpu架構(gòu)下可以使用
  • 需要去除指定平臺
  • 有一些自定義的編譯條件
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 編譯標(biāo)簽方式 例如: 在源碼頭部放置條件編譯標(biāo)簽,將限制文件僅能在BSD系統(tǒng)進行編譯 當(dāng)一個文件有多個編譯標(biāo)簽,總...
    殺破魂閱讀 2,568評論 0 1
  • 引言 Go 語言這兩年在語言排行榜上的上升勢頭非常猛,Go 語言雖然是靜態(tài)編譯型語言,但是它卻擁有腳本化的語法,支...
    一縷殤流化隱半邊冰霜閱讀 33,731評論 11 90
  • 本文簡單介紹 Golang 提供的命令。我們執(zhí)行 go help [command] 可以查看具體命令的幫助信息。...
    juniway閱讀 2,231評論 0 2
  • windows服務(wù)器 先本地編譯 go build main.go 編譯后會在同級目錄生成可執(zhí)行文件 main.e...
    Feng_Sir閱讀 2,714評論 0 0
  • 你們有沒有看過有一本很有名的繪本書,叫做《斯賓奇發(fā)脾氣》?我女兒很喜歡看這本繪本,已經(jīng)讓我給講了無數(shù)次了。我很好奇...
    宋柒柒閱讀 1,596評論 8 11

友情鏈接更多精彩內(nèi)容