CMake基础语法及应用
一、CMakeLists文件书写语法
1. CMake中条件判断语句
if(<constant>)
...
else()
...
endif()
当 constant
为 1/ON/YES/TRUE/Y/Non-zero
时判别为真;
当 constant
为 0/OFF/NO/FALSE/N/IGNORE/NOTFOUND
或者为空字符串或后缀为 -NOTFOUND
时判断为假。
大小写敏感,当不是上述列举出来的这些常量时,作为变量对待。
字符串的比较可以使用 STREQUAL
来进行,例如我们想通过编译类型来进行不同的操作,可以用类似下面的方式
if(${CMAKE_BUILD_TYPE} STREQUAL "Release")
...
elseif(${CMAKE_BUILD_TYPE} STREQUAL "Debug")
...
endif()
# 等价于下面的用法
#if(CMAKE_BUILD_TYPE MATCHES Release)
# ...
#elseif(CMAKE_BUILD_TYPE MATCHES Debug)
# ...
#endif()
2. 设置编译选项
CMake 可以通过 CMAKE_BUILD_TYPE
来对编译方式进行控制,使产生 Debug
类型的可执行程序或者 Release
类型的可执行程序,方便我们进行调试或者优化。
SET(CMAKE_BUILD_TYPE "MYTYPE")
MYTYPE
可以选择的类型有:空, Debug, Release, RelWithDebInfo, MinSizeRel
。
3. 打印信息到屏幕
当我们需要在文件中向屏幕输出一些提示信息或者警告,可以使用 MESSAGE
来实现。
MESSAGE([OPTION] "Description of the message")
OPTION
可以是 STATUS/WARNING/FATAL_ERROR
中任意一个,也可以保持缺省状态。默认是STATUS
。
MESSAGE(STATUS "Status test!")
MESSAGE(WARNING "Waning test!")
MESSAGE(FATAL_ERROR "Fatal error test!")
三种类型的输出显示如下,当设置为 FATAL_ERROR
并触发输出时,会使得编译被终止。
-- Status test!
CMake Warning at CMakeLists.txt:16 (MESSAGE):
Waning test!
CMake Error at CMakeLists.txt:17 (MESSAGE):
Fatal error test!
-- Configuring incomplete, errors occurred!
4. 获取当前工作绝对路径
CMake 中有一些固定的变量名称,用来指代与项目有关的信息。如果我们想在 CMakeLists 文件中让其自动获取到它所在的路径,可以使用 CMAKE_CURRENT_SOURCE_DIR
变量,该变量是用绝对路径表示的。
MESSAGE(STATUS "Working directory now: ${CMAKE_CURRENT_SOURCE_DIR}")
SET(BUILD_DIR "${CMAKE_CURRENT_SOURCE_DIR}/build")
二、cmake 编译命令行参数详解
1. 编译动态链接库
如果想要将项目编译成动态链接库的形式,可以在命令行通过参数控制
cmake -DBUILD_SHARED_LIBS=ON ..
2. 指定编译安装路径
通过在编译命令行中使用指令 CMAKE_INSTALL_PREFIX
来控制。
cmake -DCMAKE_INSTALL_PREFIX=/path/to/install ..
3. 忽略静态链接库依赖顺序
在cmake链接静态库时,如果多个静态库之间存在依赖关系,则有依赖关系的静态库之间存在顺序问题,否则会报符号找不到问题。
target_link_libraries(my_lib
libA.a
libB.a
libC.a
)
myve_lib依赖libA 编译libA依赖libB 编译libB依赖libC。
写C/C++程序的同学经常需要折腾静态库的依赖,因为默认情况下要求被依赖的库放在依赖它的库后面,当一个程序或共享库依赖的静态库较多时,可能会陷入解决链接问题的坑中。
cmake提供了一种静态库顺序依赖问题的解决方法,使用ld
提供的start-group
和end-group
两个选项,让包含在这两者间的静态库无需考虑顺序。
target_link_libraries(my_lib
-Wl,--start-group
libB.a
libA.a
libC.a
-Wl,--end-group
)
start-group
和end-group
是ld
的选项,是链接选项,不是gcc/g++的编译选项。
三、CMake项目应用案例
1. Eigen、Ceres-solver 等数学运算库
下载及安装可参考openMVS build wiki
附:各种不同的 GPU 架构对应的 sm 标志
TODO
- Improve compile time using forward declaration of options
- 借鉴并学习COLMAP 提升编译速度的技巧!
(全文完)
参考资料
[1] Cmake中查找并使用其他程序库 https://blog.csdn.net/laolu1573/article/details/60573511
[2] 配置eigen3和ceres为thirdparty https://blog.csdn.net/billbliss/article/details/88585171
[3] Detecting Cuda Architecture required by CMake using NVCC https://wagonhelm.github.io/articles/2018-03/detecting-cuda-capability-with-cmake
[4] Matching SM architectures (CUDA arch and CUDA gencode) for various NVIDIA cardshttp://arnon.dk/matching-sm-architectures-arch-and-gencode-for-various-nvidia-cards/
本文作者 :phillee
发表日期 :2021年4月2日
本文链接 :https://www.cnblogs.com/phillee/p/12831765.html
版权声明 :自由转载-非商用-非衍生-保持署名(创意共享3.0许可协议/CC BY-NC-SA 3.0)。转载请注明出处!
限于本人水平,如果文章和代码有表述不当之处,还请不吝赐教。