测试机器: Mac OS 10.15
Golang版本: 1.15.2

为什么要缩减Golang编译后的文件大小呢?不缩减可不可以呢。正常来说一般服务器硬盘资源相对来说都比较充足,但如果类似树莓派上的一些设备上,硬盘资源相对来说就不是那么充足,这时就需要我们斤斤计较文件大小了。首先,我们先对比一下两段Hello World代码

package main

import "fmt"

func main(){
 fmt.Println("hello world")
}


#include<stdio.h>

int main(){
    printf("Hello world!");
}

这两段代码并没有什么逻辑,仅仅是打印输入hello world,我们对这两个文件进行编译,查看编译后的文件大小。

admindeMacBook-Pro:$ go build -o main-go main.go
admindeMacBook-Pro:$ gcc main.c -o main-c
admindeMacBook-Pro:$ ls -lh
total 4312
-rwxr-xr-x  1 admin  staff    48K Nov 25 15:04 main-c
-rwxr-xr-x  1 admin  staff   2.0M Nov 25 15:04 main-go
-rw-r--r--  1 admin  staff    60B Nov 25 15:04 main.c
-rw-r--r--  1 admin  staff    71B Nov 25 14:59 main.go

看到了什么,两者编译后的大小竟然相差了43倍。仅仅只是输出Hello World,为什么Golang文件编译后的大小足足有2M呢?因为Golang程序它会静态链接某些运行时的库,而C程序则不是这种情况。那么如何缩减Golang程序大小呢,有以下三种方法

一、基于GccGo进行编译

什么是GccGo呢?GccGo是gcc专门用来编译Golang语言的。我们平常用go build来编译Golang语言的是GC,全称Golang Compiler,是Go语言官方编译器,也是自带的。两者有什么区别呢?

libgocgo

gccgo需要提前下载安装,下载安装方式参考链接:https://golang.org/doc/install/gccgo

下面比较一下GccGo编译后的文件大小

admindeMacBook-Pro:$ gccgo -g main.go -o main-gccgo
admindeMacBook-Pro:$ ls -lh
-rwxr-xr-x  1 admin  staff    48K 11 25 15:04 main-c
-rw-r--r--  1 admin  staff    83K 11 25 16:02 main-gccgo
-rwxr-xr-x  1 admin  staff   2.0M 11 25 15:04 main-go
-rw-r--r--  1 admin  staff    60B 11 25 15:04 main.c
-rw-r--r--  1 admin  staff    71B 11 25 14:59 main.go

文件的大小虽然比C语言编译后的大了一倍,但相比GC编译已经缩小了20余倍,效果非常明显。

二、指定编译参数

-s-w
admindeMacBook-Pro:$ go build -ldflags "-s -w" -o main-ldflags main.go 
admindeMacBook-Pro:GoTest admin$ ls -lh
-rwxr-xr-x  1 admin  staff    48K Nov 25 15:04 main-c
-rw-r--r--  1 admin  staff     0B Nov 25 16:02 main-gccgo
-rwxr-xr-x  1 admin  staff   2.0M Nov 25 15:04 main-go
-rwxr-xr-x  1 admin  staff   1.5M Nov 25 16:15 main-ldflags
-rw-r--r--  1 admin  staff    60B Nov 25 15:04 main.c
-rw-r--r--  1 admin  staff    71B Nov 25 14:59 main.go

通过编译制定参数,文件虽然缩小,但是缩小的并不明显,由原来的2M大小,缩减到1.5M大小

三、UPX 压缩

UPX (the Ultimate Packer for eXecutables)是一款先进的可执行程序文件,压缩过的可执行文件体积缩小50%-70% ,这样减少了占用空间、网络上传下载的时间和其它分布以及存储费用。 通过 UPX 压缩过的和程序库完全没有功能损失和压缩之前一样可正常地运行,对于支持的大多数格式没有运行时间或内存的不利后果。 UPX 支持许多不同的可执行文件格式 包含 Windows 95/98/ME/NT/2000/XP/CE 程序和动态链接库、DOS 程序、 Linux 可执行文件和核心。

yum install -y upxbrew install upx
-o-9
admindeMacBook-Pro:$ brew install upx
admindeMacBook-Pro:$ upx -9 -o main-upx main-ldflags
admindeMacBook-Pro:$ ls -lh
-rwxr-xr-x  1 admin  staff    48K 11 25 15:04 main-c
-rw-r--r--  1 admin  staff     0B 11 25 16:02 main-gccgo
-rwxr-xr-x  1 admin  staff   2.0M 11 25 15:04 main-go
-rwxr-xr-x  1 admin  staff   1.5M 11 25 16:15 main-ldflags
-rwxr-xr-x  1 admin  staff   620K 11 25 16:15 main-upx
-rw-r--r--  1 admin  staff    60B 11 25 15:04 main.c
-rw-r--r--  1 admin  staff    71B 11 25 14:59 main.go

基于通过方式二的可执行文件进行再次进行压缩,文件大小已经由原来的1.5M变为现在的620K,一般可以满足正常需求了~

以上介绍了三种方式减少Golang程序编译后的体积,可根据自己的项目灵活选择,也可以多种方式结合着使用。