Go編譯

基本命令

編譯參數(shù)
參數(shù)名 含義
-x 打印編譯過程中的所有執(zhí)行命令,執(zhí)行生成的二進(jìn)制文件
-n 打印編譯過程中的所有執(zhí)行命令,不執(zhí)行生成的二進(jìn)制文件
-a 強(qiáng)制重新編譯所有設(shè)計的依賴
-o 指定生成的二進(jìn)制文件名稱
-p 指定編譯過程中可以并發(fā)運(yùn)行程序的而數(shù)量,默認(rèn)值為可用的CPU數(shù)量(Go語言默認(rèn)時支出并發(fā)編譯的)
-work 打印臨時工作目錄的完整路徑,在退出時不刪除該目錄
-race 啟用數(shù)據(jù)競爭檢測,目前僅支持Linux/amd64、FreeBSD/amd64、Darwin/amd64 和 Windows/amd64平臺
go run

執(zhí)行g(shù)o run -x main.go

111@111-HP:/data/wwwroot/go/src/github.com/xuanxiaox/test$ go run -x main.go 
WORK=/tmp/go-build055581630
mkdir -p $WORK/b001/
...
mkdir -p $WORK/b001/exe/
cd .
/usr/local/go/pkg/tool/linux_amd64/link -o $WORK/b001/exe/main -importcfg $WORK/b001/importcfg.link -s -w -buildmode=exe -buildid=GEGVeszUHAqGXYLcNv0o/2SbCpaYfq6SzSCXvJTLm/q0cwy47Vhg-JPg6cVY8k/GEGVeszUHAqGXYLcNv0o -extld=gcc $WORK/b001/_pkg_.a
$WORK/b001/exe/main
test

1.創(chuàng)建臨時目錄/tmp/go-build055581630
2.編譯和生成所需要的依賴。比如:會編譯和生成標(biāo)準(zhǔn)庫中的依賴,應(yīng)用程序中的外部依賴,以及自身的代碼,然后生成、連接對應(yīng)歸檔文件(各種.a文件)和編譯配置文件
3.創(chuàng)建exe/main目錄
4.利用link工具,讀取依賴文件的Go歸檔文件或?qū)ο蠹捌湟蕾図?,最終將它們組合為可執(zhí)行的二進(jìn)制文件
5.到$WORK/b001/exe/main下執(zhí)行生成的二進(jìn)制文件
以下為其中用到的參數(shù)

參數(shù)名 格式 含義
-o -o file 將輸出寫入文件(在Windows上默認(rèn)為a.out或者a.out.exe)
-importcfg -importcfg file 從文件中讀取導(dǎo)入配置,文件中通常為packagefile、packageshlib
-s -s 省略符號表并調(diào)試信息
-w -w 省略DWARF符號表
-buildmode -buildmode mode 設(shè)置構(gòu)建模式(默認(rèn)為exe)
-buildid -buildid 將ID記錄我Go工具鏈的構(gòu)建ID
-cxtld -cxtld linker 設(shè)置外部連接器(默認(rèn)為clang或gcc)
go build

執(zhí)行g(shù)o build -x

111@111-HP:/data/wwwroot/go/src/github.com/xuanxiaox/test$ go build -x
WORK=/tmp/go-build485744763
mkdir -p $WORK/b001/

...
mkdir -p $WORK/b001/exe/
cd .
/usr/local/go/pkg/tool/linux_amd64/link -o $WORK/b001/exe/a.out -importcfg $WORK/b001/importcfg.link -buildmode=exe -buildid=LKYxGY9THcaRZDYogrMN/2cYx84SdP9Zyrjipe-do/S_KOb_1Q0lzULV54e4RV/LKYxGY9THcaRZDYogrMN -extld=gcc $WORK/b001/_pkg_.a
/usr/local/go/pkg/tool/linux_amd64/buildid -w $WORK/b001/exe/a.out # internal
cp $WORK/b001/exe/a.out test
rm -r $WORK/b001/

go build的前面4步跟go run 一樣,不過后面不會執(zhí)行編譯文件,而是把a(bǔ).out重命名為當(dāng)前目錄名test,并且立刻刪除編譯時生成的臨時目錄b001

go install

執(zhí)行g(shù)o install -x

111@111-HP:/data/wwwroot/go/src/github.com/xuanxiaox/test$ go install -x
WORK=/tmp/go-build840040303
mkdir -p $WORK/b001/
...
mkdir -p $WORK/b001/exe/
cd .
/usr/local/go/pkg/tool/linux_amd64/link -o $WORK/b001/exe/a.out -importcfg $WORK/b001/importcfg.link -buildmode=exe -buildid=LKYxGY9THcaRZDYogrMN/2cYx84SdP9Zyrjipe-do/S_KOb_1Q0lzULV54e4RV/LKYxGY9THcaRZDYogrMN -extld=gcc /home/xwh/.cache/go-build/b5/b58a7bf94318a9a2730666c161edea18420617b82bd746defe2c7583950c7487-d
/usr/local/go/pkg/tool/linux_amd64/buildid -w $WORK/b001/exe/a.out # internal
mkdir -p /data/wwwroot/go/bin/
cp $WORK/b001/exe/a.out /data/wwwroot/go/bin/test
rm -r $WORK/b001/

go install的前面4步跟go run 一樣,不過后面不會執(zhí)行編譯文件,而是把a(bǔ).out重命名為Go modules的項目名,將二進(jìn)制文件移到$GOBIN下(若禁用了Go modules,將安裝到$GOPATH/pkg/$GOOS_$GOARCG下),并且立刻刪除編譯時生成的臨時目錄b001

交叉編譯

交叉編譯指通過編譯器在某個系統(tǒng)下編譯另外一個系統(tǒng)的可執(zhí)行二進(jìn)制文件,即目標(biāo)計算架構(gòu)的標(biāo)識與當(dāng)前運(yùn)行環(huán)境的目標(biāo)計算架構(gòu)的標(biāo)識不同,或者是所構(gòu)建環(huán)境的目標(biāo)操作系統(tǒng)的標(biāo)識與當(dāng)前運(yùn)行環(huán)境的目標(biāo)操作系統(tǒng)的標(biāo)識不同

常用參數(shù)
參數(shù)名 含義
CGO_ENABLED 用于標(biāo)識CGO工具是否可用,默認(rèn)開啟,可通過執(zhí)行g(shù)o env進(jìn)行查看
GOOS 用于標(biāo)識程序構(gòu)建環(huán)境的目標(biāo)操作系統(tǒng),如linux、darwin、windows
GOARCH 用于標(biāo)識程序構(gòu)建環(huán)境的目標(biāo)計算架構(gòu),若不設(shè)置,則默認(rèn)值與程序運(yùn)行環(huán)境的目標(biāo)計算架構(gòu)一致,如amd64、386
GOHOSTOS 用于標(biāo)識程序運(yùn)行環(huán)境的目標(biāo)操作系統(tǒng)
GOHOSTARCH 用于標(biāo)識程序運(yùn)行環(huán)境的目標(biāo)計算架構(gòu)

編譯

CGO_ENABLED=0 GOOS=linux go build -a  .

這條編譯命令:關(guān)閉CGO,設(shè)置構(gòu)建的操作系統(tǒng)為linux(若構(gòu)建exe,則為windows),強(qiáng)制重新編譯所有依賴,編譯后的二進(jìn)制文件名稱為與目錄名相同

二進(jìn)制文件大小

在默認(rèn)情況下,使用gc工具鏈中的連接器創(chuàng)建靜態(tài)連接的二進(jìn)制文件。所有的Go二進(jìn)制文件,包含Go運(yùn)行時的信息。并支持動態(tài)類型檢查、在異常時,拋出堆棧跟蹤所必需的運(yùn)行時的類型信息(文件名、行號)

縮小二進(jìn)制文件

1、去掉DWARF調(diào)試信息和符號表信息

go build -ldflags="-w -s"
參數(shù)名 含義 問題
-w 去除DWARF調(diào)試信息 會導(dǎo)致異常(panic)拋出時,調(diào)試堆棧信息秘鑰文件名、行號信息
-s 去除符號表信息 無法使用gdb調(diào)試

2、使用upx壓縮
https://github.com/upx/upx

編譯信息寫入

編譯完成后的二進(jìn)制文件,不方便查看版本、框架等信息,所以需要將一些編譯信息打包進(jìn)二進(jìn)制文件中

借助ldflags
package main

import "fmt"

var appName string

func main()  {
    fmt.Printf("app_name:%s\n", appName)
}

編譯

go build -ldflags "-X main.appName=test123"

執(zhí)行編譯后的文件

111@111-HP:/data/wwwroot/go/src/github.com/xuanxiaox/test$ ./test 
app_name:test123

ldflags命令的-X參數(shù)可以在連接時將信息寫入變量中,格式為package_name.variable_name=value

編譯創(chuàng)建時間、版本號、git commit ID到二進(jìn)制文件中
 go build -ldflags "-X main.buildTime=`date +%Y-%m-%d,%H:%M:%S` -X main.version=1.0.1 -X main.gitCommitID=`git rev-parse HEAD`"
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容