日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

使用go build 进行条件编译

發布時間:2025/1/21 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 使用go build 进行条件编译 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

轉自:http://studygolang.com/wr?u=http%3a%2f%2fblog.csdn.net%2fvarding%2farticle%2fdetails%2f12675971


當我們編寫的go代碼依賴特定平臺或者cpu架構的時候,我們需要給出不同的實現


C語言有預處理器,可以通過宏或者#define包含特定平臺指定的代碼進行編譯


但是Go沒有預處理器,他是通過 go/build包 里定義的tags命名約定來讓Go的包可以管理不同平臺的代碼


這篇文章將講述Go的條件編譯系統是如何實現的,并且通過實例來說明如何使用


1. 預備知識:go list命令的使用

在講條件編譯之前需要了解go list的簡單用法

go list訪問源文件里那些能夠影響編譯進程內部的數據結構

go list與go build ,test,install大部分的參數相同,但是go list不會執行編譯操作。使用-f參數可以讓我們提供的text/template里的代碼在包含go/build.Package上下文的環境里正確執行(就是讓go/build.Package里的上下文去格式化 text/template里這種格式?'{{.GoFiles}}'里的占位符,寫過http server程序的同學看到應該很熟悉)


使用格式化參數,我們能通過go list獲取將會被編譯的文件名


  • %?go?list?-f?'{{.GoFiles}}'?os/exec??
  • [exec.go?lp_unix.go]??
  • 上面這個例子里我們用go list來查看在linux/arm平臺下 os/exec包里有哪些文件將會被編譯。

    結果顯示:exec.go包含了通用的代碼在所有的平臺下可用,lp_unix.go包含了*nix系統里的exec.LookPath


    在windows系統下運行同樣的命令,結果如下:


  • C:\go>?go?list?-f?'{{.GoFiles}}'?os/exec??
  • [exec.go?lp_windows.go]??
  • 上面這個例子是Go 條件編譯系統的兩個部分,稱之為:編譯約束,下面將詳細描述


    2. 第一種條件編譯的方法:編譯標簽

    在源代碼里添加標注,通常稱之為編譯標簽( build tag)

    編譯標簽是在盡量靠近源代碼文件頂部的地方用注釋的方式添加

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


    編譯標簽添加的規則(附上原文):

    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). 每個條件項的名字用字母+數字表示,在前面加!表示否定的意思


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


  • //?+build?darwin?freebsd?netbsd?openbsd??
  • 這個將會讓這個源文件只能在支持kqueue的BSD系統里編譯


    一個源文件里可以有多個編譯標簽,多個編譯標簽之間是邏輯"與"的關系


  • //?+build?linux?darwin??
  • //?+build?386??
  • 這個將限制此源文件只能在 linux/386或者darwin/386平臺下編譯


    關于注釋的說明

    剛開始使用編譯標簽經常會犯下面這個錯誤


  • //?+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??


  • 3. 第二種條件編譯方法:文件后綴

    這個方法通過改變文件名的后綴來提供條件編譯,這種方案比編譯標簽要簡單,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??

  • 源文件不能只提供條件編譯后綴,還必須有文件名:


  • _linux.go??
  • _freebsd_386.go??
  • 這兩個源文件在所有平臺下都會被忽略掉,因為go/build將會忽略所有以下劃線或者開頭的源文件?


    4. 編譯標簽和文件后綴的選擇

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


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


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

  • 相反,如果這個源文件可以在超過一個平臺或者超過一個cpu架構下可以使用或者需要去除指定平臺,那么使用編譯標簽,例如下面的編譯標簽可以在所有*nix平臺上編譯:


  • %?grep?'+build'?$HOME/go/src/pkg/os/exec/lp_unix.go???
  • //?+build?darwin?dragonfly?freebsd?linux?netbsd?openbsd??

  • 下面是可以在除了windows的所有平臺下編譯


  • %?grep?'+build'?$HOME/go/src/pkg/os/types_notwin.go???
  • //?+build?!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 进行条件编译的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。