CMakeLists学习二、链接库搜索路径与ld
前言
本文继续CMakeLists相关学习,链接库的相关问题。
gcc的链接
gcc链接命令
首先需要知道gcc编译时的链接指令:
gcc -o helloworld helloworld.c -I/path_to_include -i xxx.h -L/path_to_lib -lxxx
以上这行命令,-I/dir
指定了gcc搜索头文件的路径,-i
指定头文件名,-L/dir
指定搜索库文件的路径,-l
指定了库文件名(-lxxx的库文件名为libxxx.so或libxxx.a)
如果库文件路径下同时有.so和.a,则优先使用动态库链接;可以通过-static指定链接静态库。
ld搜索路径
ld的动态库搜索路径按顺序为:
gcc指令-L/dir路径 (非默认)
环境变量LD_LIBRARY_PATH路径 (默认)
配置文件/etc/ld.so.conf中的路径 (默认)
默认路径/lib,/usr/lib或者/lib64,/usr/lib64 (默认)
ld的静态库搜索路径按顺序为:
gcc指令-L/dir路径 (非默认)
环境变量LIBRARY_PATH路径 (默认)
默认路径/lib,/usr/lib,/usr/local/lib (默认)
顺便说一下头文件的搜索路径,可以通过gcc指令打印出来:
`gcc -print-prog-name=cc1plus` -v
大致有
gcc指定-I/dir路径
.cpp文件中#include给定的头文件相对路径
/usr/include
/usr/local/include
可以通过ld命令查看当前链接库搜索的默认路径:
ld --verbose |grep SEARCH
ldconfig刷新动态库缓存
每次开机时系统自动运行ldconfig命令刷新动态链接库缓存/etc/ld.so.cache
当在动态库的默认路径下安装了一个新动态库时,如果没有刷新动态库缓存,ld就找不到这个新库,然后就报ld: undefined reference.
解决办法就是手动刷新缓存:
sudo ldconfig
CMakeLists指定链接搜索路径
上篇采用find_package()可以得到OpenCV等第三方库文件的名字<Package>_LIBRARIES
,而这些库文件一般通过make install
安装到/usr/local/lib
下了(比如在OpenCV编译安装的最后一步,在/etc/ld.so.conf.d/opencv.conf中配置/usr/local/lib),因此ld可以找到这些库文件。
如果库文件没有放在默认的库文件搜索路径下,比如需要链接/path_to_xxx/libxxx.so,则需要使用link_directories
指令:
link_directories(/path_to_xxx)
该命令相当于gcc -L/dir
后记
本篇与上篇关系紧密,是使用CMakeLists最容易报错的地方。如果出现连接问题,可以在CMakeLists.txt中多使用message()命令,打印出配置包的路径。