使用go build 进行条件编译
轉自:http://studygolang.com/wr?u=http%3a%2f%2fblog.csdn.net%2fvarding%2farticle%2fdetails%2f12675971
當我們編寫的go代碼依賴特定平臺或者cpu架構的時候,我們需要給出不同的實現(xiàn)
C語言有預處理器,可以通過宏或者#define包含特定平臺指定的代碼進行編譯
但是Go沒有預處理器,他是通過 go/build包 里定義的tags和命名約定來讓Go的包可以管理不同平臺的代碼
這篇文章將講述Go的條件編譯系統(tǒng)是如何實現(xiàn)的,并且通過實例來說明如何使用
1. 預備知識:go list命令的使用
在講條件編譯之前需要了解go list的簡單用法
go list訪問源文件里那些能夠影響編譯進程內(nèi)部的數(shù)據(jù)結構
go list與go build ,test,install大部分的參數(shù)相同,但是go list不會執(zhí)行編譯操作。使用-f參數(shù)可以讓我們提供的text/template里的代碼在包含go/build.Package上下文的環(huán)境里正確執(zhí)行(就是讓go/build.Package里的上下文去格式化 text/template里這種格式?'{{.GoFiles}}'里的占位符,寫過http server程序的同學看到應該很熟悉)
使用格式化參數(shù),我們能通過go list獲取將會被編譯的文件名
上面這個例子里我們用go list來查看在linux/arm平臺下 os/exec包里有哪些文件將會被編譯。
結果顯示:exec.go包含了通用的代碼在所有的平臺下可用,lp_unix.go包含了*nix系統(tǒng)里的exec.LookPath
在windows系統(tǒng)下運行同樣的命令,結果如下:
上面這個例子是Go 條件編譯系統(tǒng)的兩個部分,稱之為:編譯約束,下面將詳細描述
2. 第一種條件編譯的方法:編譯標簽
在源代碼里添加標注,通常稱之為編譯標簽( build tag)
編譯標簽是在盡量靠近源代碼文件頂部的地方用注釋的方式添加
go build在構建一個包的時候會讀取這個包里的每個源文件并且分析編譯便簽,這些標簽決定了這個源文件是否參與本次編譯
編譯標簽添加的規(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). 編譯標簽由空格分隔的編譯選項(options)以"或"的邏輯關系組成
2). 每個編譯選項由逗號分隔的條件項以邏輯"與"的關系組成
3). 每個條件項的名字用字母+數(shù)字表示,在前面加!表示否定的意思
例子(編譯標簽要放在源文件頂部)
這個將會讓這個源文件只能在支持kqueue的BSD系統(tǒng)里編譯
一個源文件里可以有多個編譯標簽,多個編譯標簽之間是邏輯"與"的關系
這個將限制此源文件只能在 linux/386或者darwin/386平臺下編譯
關于注釋的說明
剛開始使用編譯標簽經(jīng)常會犯下面這個錯誤
下面這個是正確的標簽的書寫方式,標簽的結尾添加一個空行這樣標簽就不會當做其他聲明的注釋
用go vet命令也可以檢測到這個缺少空行的錯誤,初期可以用這個命令來避免缺少空行的錯誤
作為參考,下面的例子將licence聲明,編譯標簽和包聲明放在一起,請大家注意分辨
3. 第二種條件編譯方法:文件后綴
這個方法通過改變文件名的后綴來提供條件編譯,這種方案比編譯標簽要簡單,go/build可以在不讀取源文件的情況下就可以決定哪些文件不需要參與編譯
文件命名約定可以在go/build 包里找到詳細的說明,簡單來說如果你的源文件包含后綴:_$GOOS.go,那么這個源文件只會在這個平臺下編譯,_$GOARCH.go也是如此。這兩個后綴可以結合在一起使用,但是要注意順序:_$GOOS_$GOARCH.go, ? ?不能反過來用:_$GOARCH_$GOOS.go
例子如下:
源文件不能只提供條件編譯后綴,還必須有文件名:
這兩個源文件在所有平臺下都會被忽略掉,因為go/build將會忽略所有以下劃線或者點開頭的源文件?
4. 編譯標簽和文件后綴的選擇
編譯標簽和文件后綴的功能上有重疊,例如一個文件名:mypkg_linux.go包含了// +build linux將會出現(xiàn)冗余
通常情況下,如果源文件與平臺或者cpu架構完全匹配,那么用文件后綴,例如:
相反,如果這個源文件可以在超過一個平臺或者超過一個cpu架構下可以使用或者需要去除指定平臺,那么使用編譯標簽,例如下面的編譯標簽可以在所有*nix平臺上編譯:
下面是可以在除了windows的所有平臺下編譯
5. 總結
這篇文章主要關注所有可以被go tool編譯的go源文件,編譯標簽和文件后綴名(也包括了.c 和.s文件)
Go的標準庫里包含了很多的樣例,特別是runtime,syscall,os和net包,讀者可以通過這些包來學習
Test文件也支持編譯標簽和文件后綴條件編譯,并且作用方式與go源文件相同??梢栽诓煌脚_下有條件的包含一些測試樣例。同樣,標準庫也包含了大量的例子
最后,這篇文件是講如何用go tool來達到條件編譯,但是條件編譯不限于go tool,你可以用go/build包編寫自己的條件編譯工具
轉載于:https://www.cnblogs.com/msnsj/p/4242591.html
總結
以上是生活随笔為你收集整理的使用go build 进行条件编译的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 转:使用curl来调试你的应用
- 下一篇: Oracle11g新特性注意事项