成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

透過一個編譯報錯,總結兩個Go程序編譯的重要知識

開發 后端
最近調研了一下某個做 APM 的廠商的 Go 探針程序,說是引入一個包,全程不用再修改其他代碼就能在項目里引入探針。

[[437512]]

本文轉載自微信公眾號「網管叨bi叨」,作者網管。轉載本文請聯系網管叨bi叨公眾號。

最近調研了一下某個做 APM 的廠商的 Go 探針程序,說是引入一個包,全程不用再修改其他代碼就能在項目里引入探針。沒想到在剛引入包試著構建了一下就翻車了。

  1. main.go:10:2: build constraints exclude all Go files in /xxx/github.com/xxx/agnet/xxxx 

編譯器編譯的時候直接排除了某個包下的所有文件,啥意思呢?就是這個包下沒有能在當前構建環境下構建的 Go 文件。猜測應該是這個包源碼的構建標簽上聲明了不允許在Mac 環境下構建。打開源碼看了看,確實是,所有文件的構建標簽都是這么聲明的。

  1. // +build linux 
  2. // +build amd64 

這個叫做條件編譯,或者約束編譯。那想在Mac下編譯linux上才能運行的執行文件該怎么辦呢?Go 里邊還支持一個特性叫做交叉編譯,就是干跨平臺編譯這個事兒的。具體怎么用呢,比如這個例子里是需要在Mac環境下編譯能在Linux系統amd64架構下運行的執行文件,就得醬嬸進行編譯:

  1. CGO_ENABLED=0  GOOS=linux  GOARCH=amd64  go build main.go 

不過我后來想研究下為啥不讓在 Mac 上編譯,看了看這個包的探針是用CGO實現的調用了linux系統下的一個C語言實現的工具命令??吹竭@我已經不想繼續研究這個包了,那么為了讓此篇文章水的不那么明顯:),接下來咱們就把Go語言的交叉編譯和條件編譯這兩個知識點再復習一遍吧。

交叉編譯

交叉編譯是用來在一個平臺上生成另一個平臺的可執行程序。Go 的命令集是原生支持交叉編譯的,使用方法也很簡單,比如上面已經演示過的

  1. CGO_ENABLED=0  GOOS=linux  GOARCH=amd64  go build main.go 

參數說明

  • CGO_ENABLED : CGO 表示golang中的工具,CGO_ENABLED 表示CGO禁用,交叉編譯中不能使用CGO的
  • GOOS: 目標平臺
    • mac 對應 darwin
    • linux 對應 linux
    • windows 對應 windows
  • GOARCH :目標平臺的體系架構【386,amd64,arm】, 目前市面上的個人電腦一般都是amd64架構的
    • 386 也稱 x86 對應 32位操作系統
    • amd64 也稱 x64 對應 64位操作系統
    • arm 這種架構一般用于嵌入式開發。比如 Android , IOS , Win mobile , TIZEN 等

了解完這幾個參數后,我們在看下Mac、Linux、Windows這三個平臺上執行交叉編譯的例子,Windows的因為家境貧寒,條件不允許我沒有試過,命令網上找的,如果有錯誤還請同學們在評論里留言幫我改正一下。

Mac 下編譯, Linux 或者 Windows 的可執行程序

  1. # linux可執行程序 
  2. CGO_ENABLED=0  GOOS=linux  GOARCH=amd64  go build main.go 
  3. # Windows 可執行程序 
  4. CGO_ENABLED=0 GOOS=windows  GOARCH=amd64  go  build  main.go 

Linux 下編譯 , Mac 或者 Windows 下去執行

  1. # Mac 平臺可執行程序 
  2. CGO_ENABLED=0 GOOS=darwin  GOARCH=amd64  go build main.go 
  3. # Windows可執行程序 
  4. CGO_ENABLED=0 GOOS=windows  GOARCH=amd64  go build main.go 

Windows 下執行 , Mac 或 Linux 下去執行

需要寫一個批處理程序,在里面去設置,因為windows 下的 terminal 不支持shell , 這跟 Mac 和 Linux下的有點不同

  1. # Mac 下執行 
  2. SET  CGO_ENABLED=0 
  3. SET GOOS=darwin 
  4. SET GOARCH=amd64 
  5. go build main.go 
  6.  
  7. # Linux 去執行 
  8. SET CGO_ENABLED=0 
  9. SET GOOS=linux 
  10. SET GOARCH=amd64 
  11. go build main.go 

條件編譯

交叉編譯只是為了能在一個平臺上編譯出其他平臺可運行的程序,Go 作為一個跨平臺的語言,它提供的類庫勢必也是跨平臺的,比如說程序的系統調用相關的功能,能根據所處環境選擇對應的源碼進行編譯。讓編譯器只對滿足條件的代碼進行編譯,將不滿足條件的代碼舍棄,這就是另外一個概念叫---條件編譯。

在 Go 中,也稱之為Build Constraints 編譯約束,添加編譯約束的方式有2種分別:

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

編譯標簽

編譯標簽是一種通過在源碼文件頂部添加注釋,來決定文件是否參與編譯的約束方式。其格式如下:

 

  1. // +build <tags> 

注意:// +build的下一行必須是空行,否則會被解析為包注釋。

  1. // +build linux 
  2.  
  3. // main package comment 
  4. package main 

tags說明:

  • 以空格分開表示 AND
  • 以逗號分開表示 OR
  • !表示 NOT

標簽可以指定為以下內容:

  • 操作系統,環境變量中GOOS的值,如:linux、darwin、windows等等。
  • 操作系統的架構,環境變量中GOARCH的值,如:arch64、x86、i386等等。
  • 使用的編譯器,gc或者gccgo。
  • 是否開啟CGO,cgo。
  • golang版本號:比如Go Version 1.1為go1.1,Go Version 1.12版本為go1.12,以此類推。
  • 其它自定義標簽,通過go build -tags指定的值。

例如,編譯條件為(linux AND 386) OR (darwin AND (NOT cgo))

  1. // +build linux,386 darwin,!cgo 

另外一個文件可以有多個編譯約束,比如條件為(linux OR darwin) AND amd64

  1. // +build linux darwin 
  2. // +build amd64 

也可以使用ignore標簽將一個文件從編譯中排除。

  1. // +build ignore 

文件后綴

除了編譯標簽,第二種添加編譯約束的方法是通過源碼文件的文件名實現的,這種方案比構造標簽方案更簡單。編譯器也會根據文件后綴來自動選擇編譯文件:

  1. $filename_$GOOS.go 
  2. $filename_$GOARCH.go 
  3. $filename_$GOOS_$GOARCH.go 
  • $filename: 源文件名稱。
  • $GOOS: 表示操作系統,從環境變量中獲取。
  • $GOARCH: 表示系統架構,從環境變量中獲取。

后綴的順序記住不要顛倒,后綴中同時出現系統和架構名時,需要保持$filename_$GOOS_$GOARCH.go的順序。

在 Go 的每個內置庫里都有很多以不同系統名結尾的文件。下面是Go的os內置庫源代碼的部分截圖:

文件后綴添加編譯約束

兩種添加編譯限制的方式該如何選擇

構建標簽和文件名后綴在功能上是重疊的。比如,一個名為mypkg_linux.go的文件,再包含構建標簽// +build linux會顯得多余。

通常來說,當只有一個特定平臺需要指定時,我們選擇文件名后綴的方式。比如:

  1. mypkg_linux.go         // 只在 linux 系統編譯 
  2. mypkg_windows_amd64.go // 只在 windows amd 64位 平臺編譯 

相反,如果你的文件需要指定給多個平臺或體系架構使用,或者你需要排除某個特定平臺時,我們選擇構建標簽的方式。比如:

  1. // 在所有類unix平臺編譯 
  2. // +build darwin dragonfly freebsd linux netbsd openbsd 
  3.  
  4. // 在非Windows平臺編譯 
  5. // +build !windows 

一個編譯器報錯,居然水了一篇文章....啊...(咳嗽聲)引出來的交叉編譯和條件編譯(編譯約束)這兩個非常重要的知識點,其實這兩個知識點在很早之前我也寫過篇文章,這次相當于從實際遇到問題帶出從頭開始再分析一遍,希望大家能喜歡。

參考鏈接

http://www.oskip.com/post/golang/golang-build/

https://juejin.cn/post/6844903944808824845

https://mp.weixin.qq.com/s/Ys8o4arwIFYB6DPCdiGNNQ

 

責任編輯:武曉燕 來源: 網管叨bi叨
相關推薦

2021-12-16 16:20:57

GoWebSocketLinux

2020-11-13 07:16:09

線程互斥鎖死循環

2017-10-24 17:03:48

Linux驅動程序編譯

2009-08-14 00:55:21

C#程序編譯

2016-11-08 18:53:08

編譯器

2011-06-24 13:38:32

QT 編譯 安裝

2012-01-18 11:02:37

Tomcat

2021-05-26 07:53:58

Linux運維Linux系統

2021-06-25 10:38:05

JavaScript編譯器前端開發

2012-10-19 14:14:51

Ubuntu 12.1

2009-12-03 11:10:32

SMONARCHOracle

2023-07-25 15:17:38

Linux操作系統開發

2010-07-25 14:31:54

Telnet程序

2013-07-05 10:52:07

程序員結對編程

2015-02-05 09:54:13

程序員

2020-01-06 09:53:29

程序員

2010-02-25 16:45:13

WCF應用技巧

2023-10-04 20:03:46

GOkeyvalue

2020-10-26 08:19:53

算法隊列

2013-10-11 09:32:33

TD-LTELTE FDD4G
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 天天噜天天干 | 一级欧美视频 | 久草视频在线看 | 久久久久免费观看 | 日韩精品一区二区三区在线观看 | 日韩欧美一区二区三区 | 三级成人在线 | 国产超碰人人爽人人做人人爱 | 成人高清在线视频 | 波多野结衣在线观看一区二区三区 | 精品国产成人 | 九一视频在线播放 | 99免费在线视频 | 91一区二区三区 | 欧美日韩一区在线播放 | 欧美videosex性极品hd | 久久久精彩视频 | 91在线视频免费观看 | 欧美日韩精品一区二区三区蜜桃 | 日皮视频免费 | 国产精品成人一区二区三区吃奶 | 国产在线视频网 | 国产一区二区在线免费视频 | 精品粉嫩超白一线天av | 免费黄色特级片 | 五月槐花香 | 国产日韩亚洲欧美 | 免费国产一区二区 | 欧美午夜精品理论片a级按摩 | 久久首页 | 亚洲第一网站 | 91就要激情 | 一级黄色片网址 | 欧美久久久久 | 成人在线黄色 | 激情网站在线观看 | 精品一二三 | 青青99| 凹凸日日摸日日碰夜夜 | 国产精品a久久久久 | 小视频你懂得 |