golang程序如果build时不是static的话,Linux上基本会依赖glibc的动态库的,通常也不是啥问题,但是,如果你期望一个更高版本的glibc,但是目标机器上没有,就尴尬了,这时候,其实可以编译成一个静态链接的二进制程序的,这时候需要的就是编译环境上有glibc-static,centos上的安装方法为:
1 |
yum install glibc-static -y |
那么,静态链接和动态链接后的目标文件差别会非常大吗?
- 从目标文件大小上来看,应该会大一些,但是并不大的离谱:
123# ll -h ./build/manager*-rwxr-xr-x 1 junjie20 staff 24M Feb 20 11:42 ./build/manager-rwxr-xr-x 1 junjie20 staff 28M Feb 20 11:57 ./build/manager-static - 或许这个差值基本比较固定,你的程序越大,这个差值的占比就越小;但是,和你使用到的glibc中的代码的多少有关系
- 从执行的角度来看,动态链接是会启动更快一些,也比较节省内存,因为底层的动态库在内存中只需要加载一次;但是,如果我们的程序是跑在容器中的,而且,通常容器中只有一个进程,那么,扩容器共享底层动态库的可能性就很小,因为它能不是同一个文件(或许有技术可以做到这一点)。
- 编译的时候,静态链接会比动态链接要慢一点点,应该差别也不会太明显
- 所以,过时的静态链接可能真的又可以回来了
静态链接只需要添加选项:
1 |
--ldflags '--extldflags "-static -fpic"' |
注意:
- 静态链接不代表完全没有依赖,有些情况下对内核版本是有要求的