基线用例
减小编译后的二进制的体积,能够加快程序的发布和安装过程。接下来呢,我们分别从编译选项和第三方压缩工具两方面来介绍如何有效地减小 Go 语言编译后的体积。
我们采用同一个测试工程来测试不同方式的效果。
使用的测试工程如下,该程序启动了一个 RPC 服务,引用了 log、net/http 和 net/rpc 三个 package。
package main
import (
"log"
"net/http"
"net/rpc"
)
type Result struct {
Num, Ans int
}
type Calc int
// Square calculates the square of num
func (calc *Calc) Square(num int, result *Result) error {
result.Num = num
result.Ans = num * num
return nil
}
func main() {
rpc.Register(new(Calc))
rpc.HandleHTTP()
log.Printf("Serving RPC server on port %d", 1234)
if err := http.ListenAndServe(":1234", nil); err != nil {
log.Fatal("Error serving: ", err)
}
}
使用默认选项编译该程序,编译后的程序大小约为 9.8M
编译选项
Go 编译器默认编译出来的程序会带有符号表和调试信息,一般来说 release 版本可以去除调试信息以减小二进制体积。
$ go build -ldflags="-s -w" -o server main.go
$ ls -lh server
-rwxr-xr-x 1 dj staff 7.8M Dec 8 00:29 server
- -s:忽略符号表和调试信息。
- -w:忽略DWARFv3调试信息,使用该选项后将无法使用gdb进行调试。
体积从 9.8M 下降到 7.8M,下降约 20%。
使用 upx 减小体积
upx 是一个常用的压缩动态库和可执行文件的工具,通常可减少 50-70% 的体积。
upx 的安装方式非常简单,我们可以直接从 github 下载最新的 release 版本,支持 Windows 和 Linux,在 Ubuntu 或 Mac 可以直接使用包管理工具安装。例如 Mac 下可以直接使用 brew:
$ brew install upx
$ upx
Ultimate Packer for eXecutables
Copyright (C) 1996 - 2020
UPX 3.96 Markus Oberhumer, Laszlo Molnar & John Reiser Jan 23rd 2020
Usage: upx [-123456789dlthVL] [-qvfk] [-o file] file..
...
Type 'upx --help' for more detailed help.