关于gcc链接静态库的几种方式

实习遇到的静态链接的问题, 这里记录一下, 以前只知道一个static选项, 但是对这个了解也不深, 这里正好总结一下.

使用static进行链接

1. 使用-static参数, 需要注意的是-static这个选项是全局的, 也就是说一旦指定了这个选项, gcc在链接时对项目依赖的所有库都会去尝试搜索静态库, 如果找不到就会报错, 需要注意的是这里指的所有库不仅包括一些我们加了编译时选项的库,例如jpeg,opencv等等, 还包括一些gcc自带的库例如libgcc,libstdc++等等,同时包括一些间接依赖的库,也会去搜索对应的静态库,这个时候就很恐怖了,我们的应用程序可能没干啥,可执行文件就会非常大,所以这个一般也不是我们想要的,毕竟一些系统级别的库是没有必要使用静态链接的,下面是gcc对static选项的介绍:

使用有选择的链接

这个最简单的方式是指定编译参数比如/xx/xx/libxx.a,不过这个办法对小项目是没啥问题, 但是对于大项目还是显得过于笨拙, 下面介绍两个更好的办法

2. 使用-Bstatic选项

gnu的连接程序ld提供了一个-Bstatic选项用于对指定的库静态连接, 官方介绍如下:

看了英文介绍应该很明朗, 这个选项对于在这个选项后面的所有-l的库有效,也就是对跟在这个选项后面的库执行静态链接,比如向下面这样:

g++ -std=c++11 xx.cpp -o xx -lpng -Bstatic -ljpeg

ld就会去搜索libjpeg.a的静态库, 而对于png就会优先搜索动态库,找不到之后才会链接静态库.

3. -l:filename

这个方式更直接,咱们直接指定需要链接的库的名称,官方介绍如下:
这个用法很直接,咱们直接指定链接库的名称,例如我们向下面这样用:

g++ -std=c++11 xx.cpp -o xx -l:libjpeg.a -lpng

这个时候ld就会直接去寻找libjpeg.a的库,而不会去找libjpeg.so的动态库, 对于png还是默认的规则,不过这个需要注意的是由于我们只指定了名称,所以ld只会去默认的搜索路径去找,如果库不在默认搜索路径里面,我们就需要使用-L选项指定另外搜索库的路径,如果要用cmake的话就是用link_directories选项加上库的路径.