cmake in ubuntu

为什么用cmake

理论上说,任意一个 C++ 程序都可以用 g++ 来编译。但当程序规模越来越大时,一个工程可能有许多个文件夹和里边的源文件,这时输入的编译命令将越来越长。如果仅靠 g++ 命令,我们需要输入大量的编译指令,整个编译过程会变得异常繁琐。在历史上工程师们曾使用 makefile 进行自动编译,但下面要谈的 cmake 比它更加方便。在一个 cmake 工程中,我们会用 cmake 命令生成一个 makefile 文件,然后,用 make命令,根据这个 makefile 文件的内容,编译整个工程。
参考:cmake的使用以及相关配置(opencv、Eigen等)

CMakeLists.txt

include_directories

添加头文件搜索路径,这样可以在代码中的#include做根目录。
该命令是用来向工程添加多个指定头文件的搜索路径,路径之间用空格分隔。因为main.c里include了testFunc.h和testFunc1.h,如果没有这个命令来指定头文件所在位置,就会无法编译。当然,也可以在main.c里使用include来指定路径,只是这种写法不好看。
参考:Linux下CMake简明教程

find_package() & find_library()

find_package()命令是用来查找依赖包的,理想情况下,一句find_package()把一整个依赖包的头文件包含路径、库路径、库名字、版本号等情况都获取到。cmake会依次找 < package > Config.cmake或Find < package > .cmake文件。找到后即可执行该文件并生成相关链接信息。
.cmake文件一般在第三方包编译和安装时会自动安装到$CMAKE_PREFIX_PATH/lib/cmake/等文件夹中,比如/usr/lib/cmake/,/usr/local/lib/cmake等等。
参考:find_package() & find_library()

链接库问题

find_package()后,include_directories()基本上不会出问题,常见问题在链接库。执行cmake成功,make编译时没有找到opencv的库是很常见的报错。明明在cmake中target_link_libraries()指定了链接库,那么为什么还是会报ld错误呢?这是因为,部分第三方包的.cmake文件提供给cmake的${ < Package > _LIBRARIES}只是一个包名,而不是路径,编译器不知道库文件的路径在哪,找不到库,自然就会报ld链接错误了。

ld链接器默认会在一些标准路径中查找库文件,例如/lib和/usr/lib。除此之外,ld还会搜索LD_LIBRARY_PATH环境变量中指定的路径。如果库文件并不在标准路径或LD_LIBRARY_PATH中,可以使用-L选项来指定库文件的路径。例如,要将当前目录下的libfoo.so库文件链接到可执行文件中,可以使用以下命令:

ld -o myprogram main.o -L. -lfoo

其中,-L.选项指示ld链接器在当前目录中查找库文件,-lfoo选项指示ld链接器链接名为libfoo.so的库文件。

此外,ld链接器还支持其他选项来控制库文件的链接,例如-rpath选项可以指定运行时搜索共享库的路径,-Bstatic选项可以强制链接静态库,-Bdynamic选项可以强制链接共享库等。详情可以参考ld链接器的文档。
参考:CMakeLists学习一、find_package查找包

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指定-I/dir路径
.cpp文件中#include给定的头文件相对路径
/usr/include
/usr/local/include

ldconfig刷新动态库缓存

手动刷新缓存 sudo ldconfig

CMakeLists指定链接搜索路径

如果库文件没有放在默认的库文件搜索路径(/usr/local/lib)下,则需要使用link_directories指令:link_directories(/path_to_xxx),该命令相当于gcc -L/dir。
参考:CMakeLists学习二、链接库搜索路径与ld

camke指定包的版本

参考:CMakeLists学习三、指定OpenCV, PCL版本

CMake和QMake

参考:CMake和QMake

cmake交叉编译

参考:使用CMake交叉编译Arm Linux程序

猜你喜欢

转载自blog.csdn.net/qq_44324007/article/details/129288686