基本命令
編譯參數(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`"