一般来说,编译运行库是比较简单的。运行库在一开始就考虑到了架构的问题。

但是一些比较皮的执行文件,比如nginx这些就有很多坑了,他们并没有想过交叉编译,我只能无奈地填他们留下来的坑。但只要坚持,利用搜索引擎,这些问题倒也还可以解决,不过是耐心的问题罢了。

我现在编译东西就想着怎么把东西编译得完美

  • 兼容性,最好没有依赖
  • 性能好
  • 体积小

要做到第一点,很难,因为glibc并不适合静态链接,但glibc又是Linux默认的c库。一般cdlpthreadm这些绝大多数系统自带的库我会选择动态编译,以减小执行文件的体积和提高执行文件的兼容性。

第一点,我还要做到同时动态和静态链接,-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的剧看得有点多,感觉自己写的文章很奇怪,像是一个外国人写的。