链接库
链接指定的库有两种方式
- -llibrary
- -l library
如链接LuaJIT库,可以用-lluajit-5.1,此时gcc会在库路径中查找libluajit-5.1.so或者libluajit-5.1.a。 也可以用-l llibluajit-5.1.a,第二种只能用在POXIS上,推荐使用第一种方式。而且第二种方式只会在特定的目录进行搜索,会发生找不到库的情况。
通过-llibrary链接库时,可能既有静态库如libluajit-5.1.a,也有动态库如libluajit-5.1.so,这是链接器会优先链接动态库。
指定库路径
如果需要的库不在系统的库搜索路径下,就需要通过-L指定库的搜索路径。 如lua解释器安装时会把libluajit-5.1.a,和libluajit-5.1.so等放在/usr/local/lib下,而gcc进行链接时默认不会在这个路径下搜索库,导致链接失败。通过-L/usr/local/lib指定库路径就可以解决这个问题。
1 |
|
指定运行时库搜索路径
有时通过-L指定库路径可以正常链接,运行程序时却因为找不到库报错
1 |
|
使用ldd命令可以看到运行时找不到libluajit-5.1.so.2,无法运行,对此可以通过-Wl,-rpath指定运行时库的搜索路径
1 |
|
再使用ldd命令查看,libluajit-5.1.so.2在/sur/local/lib下。
使用静态链接
对于运行时找不到动态库的问题,除了通过-Wl,-rpath指定路径外,还可以通过静态链接库的方式来解决。实际生产环境中通常只在一台机器上编译二进制程序,再将二进制程序分发到线上运行环境。程序需要的库可能实际线上环境中根本没有,也需要将库静态链接。
静态链接库有下面几种方式。
只保留静态库
如安装luajit后,在/usr/local/lib下既有静态库,也有动态库。链接时优先链接动态库。如果将动态库删除,只保留静态库,这时链接器就会链接静态库.
通过-Wl,-Bstatic对指定的库使用静态链接
gcc会对-Wl,-Bstatic 后面的库使用静态链接。对-Wl,-Bdynamic后面跟的库使用动态链接。 如果需要对指定的库使用静态链接,其他的库使用默认的动态链接,可以这样用
1 |
|
这样gcc会链接libluajit-5.1.a,而对其他库使用动态链接。
使用 -static 避免动态链接
gcc编译时使用-static参数,会阻止使用动态链接的方式。与之前两个方法不同,-static参数会导致gcc对所有的库使用静态链接,一般不推荐使用这种方式。
1 |
|
对程序使用ldd命令提示不是动态可执行文件
没有使用-static时ldd可以看到程序需要的动态库,以及库的路径。
1 |
|
使用 -static-libxxx对某些系统库进行静态链接
gcc本身提供了参数可以只对libgcc,libstdc++等库进行静态链接 主要有下面这些
1 |
|
更详细的介绍可以参见官方文档