怎么写自己的CMakeLists.txt
一、为什么要使用cmake
理论上说,任何一个C++程序都可以用G++来编译。 但当程序规模越来越大时,一个工程可能有许多个文件夹和源文件,这时输入的编译命令越来越长。 通常一个小型C++项目可能含有十几个类,各个类之间还存在着复杂的依赖关系。 其中一部分要编译成可执行文件,另一部分要编译成库文件。 如果仅靠G++命令,我们需要输入大量的编译指令,整个编译过程会变得异常繁琐。 因此,对于C++项目,使用一些工程管理工具会更加高效。历史上工程师们曾使用makefile进行自动编译,但cmake要比它更加方便。
在一个cmake工程中,我们会用cmake命令生成一个makefile文件,然后用make命令根据这个makefile文件的内容编译整个工程。
二、CmakeLists.txt文件的基本写法
# 声明cmake的最低版本需求cmake_minimum_required(VERSION 2.8)
# 声明一个cmake工程,工程名为tempproject(temp)
# 添加C++11标准支持set(CMAKE_CXX_FLAGS "-std=c++")
如果在程序中使用了C++11标准,则需要设置告诉编译器,没有可以不写。
# 设置编译器编译模式set(CMAKE_BUILD_TYPE "Debug")
对于编译用的Release
模式和调试用的Debug
模式,在Debug
模式中,程序运行较慢,此时可以在IDE中进行断点调试。
Release
模式运行较快,但没有调试信息。
注:不设置默认是Debug
模式
# 添加引用的第三方头文件,例如添加Eigen
头文件include_directories(“/usr/inclue/eigen3”)
# 编译生成库文件add_library(irfusion example.c example.cpp)
这条命令告诉cmake,我们想把这些源文件编译成一个叫做irfusion的库。
在Linux系统中,库文件分为静态库和动态库两种,静态库以.a
作后缀,共享库以.so
作后缀。
所有库都是一些函数打包后的集合,差别在于静态库每次被调用都会生成一个副本,而共享库则只有一个副本,更加节省空间。
如果像生成共享库而不是静态库,只需要使用以下语句即可add_library(irfusion_shared SHARED example.c example.cpp)
此时得到的文件就是irfusion_shared.so了。
最后,在CMakeLists.txt中添加一个可执行程序的生成命令,链接到刚才生成的库上add_executable(example example.cpp)
target_link_libraries(irfusion irfusion_shared)
通过这两行语句,irfusion程序就能顺利使用库中的代码了。
整个工程中的代码结构
使用cmake编译整个工程cd build
cmake ..
make
三、小结
- 首先,程序代码由头文件和源文件组成。
- 带有main函数的源文件编译成可执行程序,其他的编译成库文件。
- 如果可执行程序想调用库文件中的函数,它需要参考库提供的头文件,以明白调用的格式。同时,要把可执行程序链接到库文件上。