编译小记(一)
一般来说,编译运行库是比较简单的。运行库在一开始就考虑到了架构的问题。
但是一些比较皮的执行文件,比如nginx
这些就有很多坑了,他们并没有想过交叉编译,我只能无奈地填他们留下来的坑。但只要坚持,利用搜索引擎,这些问题倒也还可以解决,不过是耐心的问题罢了。
我现在编译东西就想着怎么把东西编译得完美
- 兼容性,最好没有依赖
- 性能好
- 体积小
要做到第一点,很难,因为glibc
并不适合静态链接,但glibc
又是Linux
默认的c
库。一般c
dl
pthread
m
这些绝大多数系统自带的库我会选择动态编译,以减小执行文件的体积和提高执行文件的兼容性。
第一点,我还要做到同时动态和静态链接,-lssl
这个将会优先链接动态库,-l:libssl.a
这个只会链接静态库。可以这样做
gcc test.c -O3 -s -lc -ldl -lpthread -lm -l:libssl.a -l:libpthread.a
这样可以同时满足上面的三点。
但是,接触过openssl
的人都知道,openssl
包含了很多的算法,很多是我们不需要的,所以可以重新编译以减小它的体积。
./config no-afalgeng no-async no-autoalginit no-autoerrinit \
no-capieng no-cms no-comp no-ct no-deprecated \
no-devcryptoeng no-dgram no-dtls no-ec no-ec2m \
no-engine no-err no-filenames no-gost no-makedepend \
no-multiblock no-nextprotoneg no-ocsp no-pic no-pinshared \
no-psk no-rdrand no-shared no-sock no-srp \
no-srtp no-sse2 no-ssl no-ssl3 no-tests \
no-threads no-tls no-tls1 no-ts no-ui
make CFLAGS='-ffunction-sections -fdata-sections' -j8
其中-ffunction-sections -fdata-sections
是有效的,在链接openssl
库时
gcc test.c -O3 -s -lc -ldl -lpthread -lm -l:libssl.a -l:libpthread.a -Wl,--gc-section
-Wl,--gc-section
这个选项可以让-ffunction-sections -fdata-sections
生效,进一步减少体积。
还有,静态链接时,库的顺序,或者是源文件的顺序是很重要的。
还有一些not found
或者是undefined
的问题也很是让人头疼,一般就是重新编译库,检查编译参数,用网上的补丁打上,去stackflow
提问。
还要吐槽一下安卓,改的东西太多了,比如说把pthread
整合到c
库里面,没有crypt()
函数,函数的API
限制,/dev/net/tun
移动到/dev/tun
,绝望。在此向程序员致敬。
可能是最近HBO
的剧看得有点多,感觉自己写的文章很奇怪,像是一个外国人写的。