CMake基础语法及应用

一、CMakeLists文件书写语法

1. CMake中条件判断语句

if(<constant>)
  ...
else()
  ...
endif()

constant1/ON/YES/TRUE/Y/Non-zero 时判别为真;

constant0/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-groupend-group两个选项,让包含在这两者间的静态库无需考虑顺序。

target_link_libraries(my_lib
    -Wl,--start-group
    libB.a
    libA.a
    libC.a
    -Wl,--end-group
    )

start-groupend-groupld的选项,是链接选项,不是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)。转载请注明出处!
限于本人水平,如果文章和代码有表述不当之处,还请不吝赐教。

posted @ 2021-04-02 10:53  coffee_tea_or_me  阅读(723)  评论(0编辑  收藏  举报