---
title: CMake学习笔记
date: 2017-12-27 13:54:05
tags: [cmake, visual studio]
categories: cmake
---
本文主要记录CMake学习过程的一些笔记。
## 基本文件结构
编写CMakeLists.txt
```
# CMake 最低版本号要求
cmake_minimum_required (VERSION 2.8)
# 项目信息
project (Demo1)
# 指定生成目标
add_executable(Demo main.cc)
```
## 常用命令
### 项目类型命令
- `add_executable`可执行文件
- `add_library` 静态库
### 文件依赖命令
- `aux_source_directory(
)`
查找指定目录下的所有源文件,然后将结果保存进指定的变量名。
```
# CMake 最低版本号要求
cmake_minimum_required (VERSION 2.8)
# 项目信息
project (Demo2)
# 查找当前目录下的所有源文件
# 并将名称保存到 DIR_SRCS 变量
aux_source_directory(. DIR_SRCS)
# 指定生成目标
add_executable(Demo ${DIR_SRCS})
```
这样,CMake 会将当前目录所有源文件的文件名赋值给变量`DIR_SRCS`,再指示变量`DIR_SRCS` 中的源文件需要编译成一个名称为 Demo 的可执行文件。
- `add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL])`
添加子文件夹到构建系统中。
`source_dir`子文件夹路径
`binary_dir` 输出路径
`EXCLUDE_FROM_ALL` 从Build All项目中排除
### 编译选项命令
- Visual Studio to CMake Mapping
{% asset_img VS-to-CMake-Mapping.png VS-to-CMake-Mapping %}
{% asset_img CMake-Projects.png CMake-Projects %}
> ZERO_CHECK will rerun cmake. You can/should execute this after changing something on your CMake files.
> ALL_BUILD is simply a target which builds all and everything project in the active solution, I guess one can compare it to "make all".
> 可以通过`set(CMAKE_SUPPRESS_REGENERATION true)`不生成`ZERO_CHECK`工程。
### 链接命令
- `target_link_libraries`指明链接库
`target_link_libraries( [lib1 [lib2 [...]]] [[debug|optimized|general] ] ...)`
`general`可选字段,表示所有模式都链接的库
`debug`表示debug模式才链接的库
`optimized`表示非debug模式才链接的库
```cmake
target_link_libraries(${PROJECT_NAME}
delayimp.lib libcef.lib
debug cef_module_d.lib
debug libcef_dll_wrapper_d.lib
optimized cef_module.lib
optimized libcef_dll_wrapper.lib)
```
## 项目实例
### 自定义编译选项
顶层CMakeLists.txt文件
```
# CMake 最低版本号要求
cmake_minimum_required (VERSION 2.8)
# 项目信息
project (Demo4)
# 加入一个配置头文件,用于处理 CMake 对源码的设置
configure_file (
"${PROJECT_SOURCE_DIR}/config.h.in"
"${PROJECT_BINARY_DIR}/config.h"
)
# 是否使用自己的 MathFunctions 库
option (USE_MYMATH
"Use provided math implementation" ON)
# 是否加入 MathFunctions 库
if (USE_MYMATH)
include_directories ("${PROJECT_SOURCE_DIR}/math")
add_subdirectory (math)
set (EXTRA_LIBS ${EXTRA_LIBS} MathFunctions)
endif (USE_MYMATH)
# 查找当前目录下的所有源文件
# 并将名称保存到 DIR_SRCS 变量
aux_source_directory(. DIR_SRCS)
# 指定生成目标
add_executable(Demo ${DIR_SRCS})
target_link_libraries (Demo ${EXTRA_LIBS})
```
编写`config.h.in`文件 `#cmakedefine USE_MYMATH`
### 设置编译模式
```
set(CMAKE_BUILD_TYPE "Debug")
set(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g -ggdb")
set(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall")
```
### 环境检查
首先在顶层 CMakeLists 文件中添加 CheckFunctionExists.cmake 宏,并调用 `check_function_exists` 命令测试链接器是否能够在链接阶段找到 pow 函数。
```
# 检查系统是否支持 pow 函数
include (${CMAKE_ROOT}/Modules/CheckFunctionExists.cmake)
check_function_exists (pow HAVE_POW)
```
### 设置libcurl运行时环境
```cmake
if(USE_ALLMT_)
target_compile_definitions(libcurl PRIVATE -DRTLIBCFG=static)
set_property(TARGET libcurl APPEND_STRING PROPERTY COMPILE_OPTIONS $,/MTd,/MT>)
else()
target_compile_definitions(libcurl PRIVATE -DRTLIBCFG=shared)
set_property(TARGET libcurl APPEND_STRING PROPERTY COMPILE_OPTIONS $,/MDd,/MD>)
endif()
```
## 参考链接
- [cmake-and-visual-studio](https://cognitivewaves.wordpress.com/cmake-and-visual-studio/)
- [CMake手册](https://www.zybuluo.com/khan-lau/note/254724)
- [CMakeLists.txt](http://wiki.ros.org/catkin/CMakeLists.txt)