如何在go構建工具中使用條件編譯

當開發依賴底層平臺或處理器特定特性的圍棋包時,通常需要提供專門的實現。

Go沒有預處理器、宏系統或#定義聲明來控制平臺特定代碼的包含。取而代之的是標籤和命名約定系統定義在去/建包裹並得到了去工具允許Go包為它們正在編譯的特定平臺定製自己。

如何在go構建工具中使用條件編譯

這篇文章解釋了條件編譯是如何實現的,並向您展示瞭如何在項目中使用它。

但首先,列出清單

在我們討論條件編譯之前,我們需要了解一點go列表命令。go列表允許您訪問為構建過程提供動力的內部數據結構。

go列表接受大多數與去建吧,試驗,和安裝但是不執行任何編譯。使用-f,格式標誌,我們可以提供文本/模板在包含去/建。包裹結構。

使用格式標誌,我們可以詢問go列表告訴我們將要編譯的文件的名字。

% go列表-f“{ 0 }”。“操作系統/執行[執行。運行lp_unix。運行]

在上面的例子中,我在os/exec將在此基礎上編譯的包linux/arm系統。結果是兩個文件,exec.go它包含所有平臺共享的公共代碼,並且lp_unix.go同時包含的實現高管。LookPath適用於unix類系統。

如果我在一個視窗系統上運行相同的命令,結果會是

C:\go%3E go列表-f '{。“操作系統/執行[執行。運行lp_windows。運行] 

這個簡短的示例演示了Go條件編譯系統的兩個部分,稱為構建約束,我們現在將對此進行更詳細的探討。

構建標籤

條件編譯的第一種方法是通過源代碼中的註釋,通常稱為構建標記。

構建標記被實現為註釋,並且應該儘可能靠近文件的頂部。

當...的時候去建吧它將分析包中的每個源文件,尋找構建標籤。這些標籤控制是否去建吧將文件傳遞給編譯器。

構建標籤遵循這三個規則

  1. 構建標記被評估為空格分隔選項的“或”
  2. 每個選項評估為逗號分隔術語的“與”
  3. 每個術語都是字母數字單詞,或者,前面是!,它的否定

例如,源文件頂部的構建標記

//+構建達爾文freebsd netbsd openbsd 

會將該文件限制為僅建立在支持kqueue。

一個文件可能有多個構建標記。總體約束是單個約束的邏輯與。例如

//+構建linux達爾文//+構建386

將構建限制為linux/386或者達爾文/386僅限平臺。

關於評論的註釋

當人們第一次試圖讓構建標籤發揮作用時,有一件事通常會引起人們的注意,那就是

//+構建!linuxpackage mypkg //錯誤

在這個例子中,沒有換行來分隔構建標記和包聲明。因此,構建標記作為描述包的註釋與包聲明相關聯,因此被忽略。

//+構建!linuxpackage mypkg //正確

這是正確的形式,帶有尾隨換行符的註釋是獨立的,與任何聲明和去看獸醫將檢測丟失的新行。

% go vet mypkgmypkg . go:1:+生成註釋在文件退出狀態1中出現太晚

當此功能添加到去看獸醫它在標準庫和sub repos中發現了幾個錯誤,所以如果你第一次做錯了,不要難過。

作為參考,這裡有一個示例,顯示了一個許可證前導、一個構建標籤和一個包聲明

% head head pin . go//版權所有2013出路企業。保留所有權利。//此源代碼的使用受BSD樣式// license的控制,該許可證可以在license文件中找到。//+建造一些人,另一些人,第三!amd64//包裝大頭針工具計算的數字太大//它們會讓你頭暈。包裝大頭針

文件後綴

提供條件編譯的第二個選項是源文件本身的名稱。這個方案比構建標記簡單,並且允許去/建包來排除文件,而不必處理文件。

的文檔中描述了命名約定去/建包裹。簡單地說,如果源文件包含後綴,_$GOOS.go那麼它只會建立在那個平臺上。所有其他平臺的行為就像文件不存在一樣。這同樣適用於_$GOARCH.go。這兩者可以結合為_$GOOS_$GOARCH.go,但是不 _$GOARCH_$GOOS.go。

文件後綴的一些例子是,

mypkg_freebsd_arm.go //僅構建於freebsd/arm系統mypkg_plan9.go //僅構建於plan9

您的源文件仍然需要名稱,例如後綴是不夠的

_linux.go_freebsd_386.go 

將被忽略,即使在linux或freebsd系統上,因為去/建包忽略任何以句點或下劃線開頭的文件。

在構建標籤和文件後綴之間進行選擇

構建標籤和文件後綴在功能上重疊。例如,一個名為mypkg_linux.go包含構建標記的//+構建linux是多餘的。

通常,當在構建標記或文件後綴之間進行選擇時,當平臺或體系結構與您想要包含的文件完全匹配時,您應該選擇文件後綴。例如,

mypkg_linux.go //僅構建於linux系統mypkg_windows_amd64.go //僅構建於windows 64位平臺

相反,如果您的文件適用於多個平臺或架構,或者您需要排除應該使用特定的平臺、構建標籤。例如,

% grep '+build ' $ HOME/go/src/pkg/OS/exec/LP _ UNIX . go//+build Darwin dragonfly FreeBSD Linux netbsd open BSD

構建在所有unix平臺上。

% grep '+build ' $ HOME/go/src/pkg/OS/type _ not win . go//+build!窗子

建立在除視窗以外的所有平臺上。

包紮

雖然這篇文章只關注Go源文件,但是構建標記和文件後綴可以用於去工具可以構建。這包括。c和。s文件。圍棋標準庫,特別是運行時間,syscall,os和網包包含了很好的例子,我建議研究它們。

測試文件也支持構建標籤和文件後綴,並以與Go源文件相同的方式運行,有條件地包括基於每個平臺的測試用例。同樣,標準庫包含許多很好的例子。

最後,雖然本文的標題討論了去工具,條件編譯功能不僅限於該工具。您可以構建自己的工具來使用和分析具有相同文件後綴的圍棋代碼,並使用去/建包裹。

看go語言,關注VX公眾號:studytogo

聲明:轉載此文是出於網絡的。若有來源標註錯誤或侵犯了您的合法權益,請作者持權屬證明與本網聯繫,我們將及時更正、刪除,謝謝。


分享到:


相關文章: