前言
最近在寫(xiě)一個(gè)cli程序,習(xí)慣性的go build之后發(fā)現(xiàn)簡(jiǎn)簡(jiǎn)單單的幾行代碼打包出來(lái)就3.0+MB了,為此被做Python的同學(xué)嘲笑了很久,于是就研究了一下go build產(chǎn)生的可執(zhí)行文件的壓縮
代碼示例
代碼如下:
package main
import (
"os"
"gopkg.in/urfave/cli.v2"
)
const (
APP_NAME = "etcd-cli"
APP_VERSION = "0.1"
APP_USAGE = "etcd-cli是一個(gè)簡(jiǎn)單實(shí)用的etcd命令行客戶端,幫助你徹底解脫一次又一次的輸入etcdctl"
)
func main() {
app := new(cli.App)
app.Name = APP_NAME
app.Version = APP_VERSION
app.Usage = APP_USAGE
app.Action = action
app.Run(os.Args)
}
func action(ctx *cli.Context) error {
return nil
}
常規(guī)打包方法及結(jié)果
$ go build
$ ls -lh
-rwxr-xr-x 1 gangan staff 3.4M Aug 18 00:38 etcd-cli
-rw-r--r-- 1 gangan staff 456B Aug 18 00:34 main.go
可以看到,區(qū)區(qū)十幾行代碼什么都還沒(méi)有實(shí)現(xiàn), go build之后就得到了一個(gè)3.4MB的可執(zhí)行文件,可想而知產(chǎn)品開(kāi)發(fā)完后go build絕不會(huì)小,那么有沒(méi)有解決辦法呢?有,見(jiàn)下文。
壓縮可執(zhí)行文件
-
首先加上編譯參數(shù)
-ldflags$ go build -ldflags '-w -s' $ ls -lh -rwxr-xr-x 1 gangan staff 2.5M Aug 18 00:45 etcd-cli -rw-r--r-- 1 gangan staff 456B Aug 18 00:34 main.go可以發(fā)現(xiàn)小了近1MB
-
使用upx壓縮,Linux、Mac和Win都有,這里以Mac為例
$ brew install upx $ upx etcd-cli # 此處省略壓縮時(shí)的打印... $ ls -lh -rwxr-xr-x 1 gangan staff 897K Aug 18 00:49 etcd-cli -rw-r--r-- 1 gangan staff 456B Aug 18 00:34 main.goOK,可執(zhí)行文件從3.4MB壓縮到了897K,效果還是很明顯的,有需要的趕緊試試吧。
寫(xiě)在最后
Golang開(kāi)發(fā)的程序都會(huì)比較大,這是因?yàn)镚olang是靜態(tài)編譯的,編譯打包之后基本就不會(huì)再對(duì)其他類(lèi)庫(kù)有依賴了,所以會(huì)比較大。舉個(gè)例子:C++程序可以調(diào)用dll,所以打包的時(shí)候可以不把dll打進(jìn)去,包自然就小了。之前還有看到過(guò)有人使用GO -> C -- dll --> C -> GO的方式間接實(shí)現(xiàn)了Golang的偽動(dòng)態(tài)鏈接,有興趣的同學(xué)可以研究一下。
補(bǔ)充
Linux、Win 系統(tǒng)下 upx https://github.com/upx/upx/releases