golang中沒有相似C語言中條件編譯的寫法,好比在C代碼中可使用以下語法作一些條件編譯,結合宏定義來使用能夠實現諸如按需編譯release和debug版本代碼的需求linux
#ifndef #define ... #end
可是golang支持兩種條件編譯方式golang
在源代碼裏添加標註,一般稱之爲編譯標籤( build tag),編譯標籤是在儘可能靠近源代碼文件頂部的地方用註釋的方式添加windows
go build在構建一個包的時候會讀取這個包裏的每一個源文件而且分析編譯便籤,這些標籤決定了這個源文件是否參與本次編譯架構
編譯標籤添加的規則(附上原文):app
- a build tag is evaluated as the OR of space-separated options
- each option evaluates as the AND of its comma-separated terms
- each term is an alphanumeric word or, preceded by !, its negation
1). 編譯標籤由空格分隔的編譯選項(options)以"或"的邏輯關係組成ui
2). 每一個編譯選項由逗號分隔的條件項以邏輯"與"的關係組成this
3). 每一個條件項的名字用字母+數字表示,在前面加!表示否認的意思lua
例子(編譯標籤要放在源文件頂部)spa
// +build darwin freebsd netbsd openbsd
這個將會讓這個源文件只能在支持kqueue的BSD系統裏編譯debug
一個源文件裏能夠有多個編譯標籤,多個編譯標籤之間是邏輯"與"的關係
// +build linux darwin // +build 386
這個將限制此源文件只能在 linux/386或者darwin/386平臺下編譯.
除了添加系統相關的tag,還能夠自由添加自定義tag達到其它目的。
編譯方法:
只須要在go build指令後用-tags指定編譯條件便可
go build -tags mytag1 mytag2
注意:剛開始使用編譯標籤常常會犯下面這個錯誤
// +build !linux package mypkg // wrong
這個例子裏的編譯標籤和包的聲明之間沒有用空行隔開,這樣編譯標籤會被當作包聲明的註釋而不是編譯標籤從而被忽略掉
下面這個是正確的標籤的書寫方式,標籤的結尾添加一個空行這樣標籤就不會當作其餘聲明的註釋
// +build !linux package mypkg // correct
用go vet命令也能夠檢測到這個缺乏空行的錯誤,初期能夠用這個命令來避免缺乏空行的錯誤
% go vet mypkg mypkg.go:1: +build comment appears too late in file exit status 1
做爲參考,下面的例子將licence聲明,編譯標籤和包聲明放在一塊兒,請你們注意分辨
% 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
這個方法經過改變文件名的後綴來提供條件編譯,這種方案比編譯標籤要簡單,go/build能夠在不讀取源文件的狀況下就能夠決定哪些文件不須要參與編譯。文件命名約定能夠在go/build 包裏找到詳細的說明,簡單來講若是你的源文件包含後綴:_GOOS.go,那麼這個源文件只會在這個平臺下編譯,_GOARCH.go也是如此。這兩個後綴能夠結合在一塊兒使用,可是要注意順序:_GOOS_GOARCH.go, 不能反過來用:_GOARCH_GOOS.go.
例子以下:
mypkg_freebsd_arm.go // only builds on freebsd/arm systems mypkg_plan9.go // only builds on plan9
編譯標籤和文件後綴的功能上有重疊,例如一個文件名:mypkg_linux.go包含了// +build linux將會出現冗餘
一般狀況下,若是源文件與平臺或者cpu架構徹底匹配,那麼用文件後綴,例如:
mypkg_linux.go // only builds on linux systems mypkg_windows_amd64.go // only builds on windows 64bit platforms
相反,若是知足如下任何條件,那麼使用編譯標籤: