CMake
cmake官方手册CMake Reference Documentation — CMake 3.15.7 Documentation
CmakeLists.txt文件语法
所有命令均可以在官网找到cmake-commands(7) — CMake 3.15.7 Documentation
1. 指定 cmake 的最小版本
cmake_minimum_required(VERSION 3.10)
2. 设置项目名称
project(NS3 CXX C)
3. option() (跳过)
option(<variable> "help_text" [value])
为使用者提供一个选项可选为ON或者OFF,默认value为OFF。
option(NS3_ASSERT "Enable assert on failure" OFF)
option(NS3_DES_METRICS "Enable DES Metrics event collection" OFF)
option(NS3_EXAMPLES "Enable examples to be built" OFF)
option(NS3_LOG "Enable logging to be built" OFF)
option(NS3_TESTS "Enable tests to be built" OFF)
4. set()设置变量
设置普通变量
命令格式:set(<variable> <value>... [PARENT_SCOPE]) # 设置普通变量
命令含义:将缓存条目variable设置为值<value>...
可以设置EXECUTABLE_OUTPUT_PATH的值来确定可执行文件的输出路径
设置缓存条目
命令格式:set(<variable> <value>... CACHE <type> <docstring> [FORCE])
命令含义:将缓存条目variable设置为值<value>...,除非用户进行设置或使用了选项FORCE,默认情况下缓存条目的值不会被覆盖。缓存条目可以通过CMAKE的GUI界面的add entry按钮来增加。缓存条目的实质为可以跨层级进行传递的变量,类似于全局变量。
缓存条目的<type>主要有以下几类:
BOOL:布尔值ON/OFF,CMAKE的GUI界面对此类缓存条目会提供一个复选框。FILEPATH:文件路径,CMAKE的GUI界面对此类缓存条目会提供一个文件选择框。PATH:目录路径,CMAKE的GUI界面对此类缓存条目会提供一个目录选择框。STRING / STRINGS:文本行,CMAKE的GUI界面对此类缓存条目会提供一个文本框(对应STRING)或下拉选择框(对应STRINGS)。INTERNAL:文本行,但是只用于内部,不对外呈现。主要用于运行过程中存储变量,因此使用该type意味着使用FORCE。
缓存条目的几个注意事项:
1)如果变量先前未定义或者使用了FORCE选项,则缓存条目会直接被赋值。
2)可以在使用cmake构建的使用通过-D选项来给缓存条目赋值,这样CMakeLists.txt内的set命令只会为缓存条目添加类型。
3)如果变量类型是目录或者文件路径,通过-D选项传入的若只是相对路径,那么set会给这个相对路径前添加当前的工作目录以变成绝对路径(如果已经是绝对路径则不会处理)。
而docstring应该是一个解释的作用,在GUI界面可以看到这个hint
设置环境变量
命令格式:set(ENV{<variable>} [<value>])
命令含义:将环境变量设置为值<value>(注意没有...),接着使用$ENV{<variable>}会得到新的值。cmake中的环境变量可以参考:环境变量。
环境变量设置的几个注意事项:
1)该命令设置的环境变量只在当前的cmake进程生效,既不会影响调用者的环境变量,也不会影响系统环境变量。
2)如果<value>值为空或者ENV{<variable>}后没有参数,则该命令会清除掉当前环境变量的值。
3)<value>后的参数会被忽略。
5. 添加子目录并构建
add_subdirectory(子目录路径)添加一个子目录并构建该子目录,子目录下应该包含CMakeLists.txt文件和代码文件。
- 命令形式:
add_subdirectory(子目录路径 子目录编译文件的输出路径)
# Build NS3 library core
add_subdirectory(src)
# Build NS library examples
add_subdirectory(examples)
# Build scratch/simulation scripts
add_subdirectory(scratch)
# Build test utils
add_subdirectory(utils)
6. 设置编译类型
add_executable(可执行文件名不需要exe后缀 源文件名) # 生成可执行文件
add_library(生成库文件名 SHARED/STATIC 源文件) # 生成库文件
target_link_library(可执行文件名 链接的多个共享库) # 将可执行文件连接到共享库
7. include指令
include指令一般用于语句的复用,如果有一些语句需要在很多CMakeLists.txt文件中使用,为避免重复编写,可以将其写在.cmake文件中,然后在需要的CMakeLists.txt文件中进行include操作就行了
一般在要include的.cmake文件中会定义macro宏和函数function,定义方式为:
# 宏定义
macro(<name> [args...])
...
# 命令语句
...
endmacro()
# 函数定义
function(<name> [args...])
...
# 命令语句
...
endfunction()
对于宏和函数的参数而言:
- 当宏和函数调用的时候,如果传递的是经
set设置的变量,必须通过${}取出内容; - 在宏的定义过程中,对变量进行的操作必须通过
${}取出内容,而函数就没有这个必要。
8. 添加搜索路径
include_directories(路径) # 添加所有的头文件搜索路径
target_include_directories(目标(可执行文件/库) 路径)
link_directorues(路径) # 添加多个特定的库文件搜索路径
cmake命令行
开始构建文件
项目主目录存在一个CMakeLists.txt文件
两种方式设置编译规则:
- 包含源文件的子文件夹包含CMakeLists.txt文件,主目录的CMakeLists通过
add_subdirectory()添加子目录即可。 - 包含源文件的子文件夹不包含CMakeLists.txt文件,子目录编译规则体现在主目录的CMakeLists.txt文件中。
编译流程
- 手动编写CMakeLists.txt文件
- 执行
cmake PATH命令生成Makefile(PATH是顶层CMakeLists.txt文件所在的目录),但是生成的makefile文件会放在当前目录中 - 执行命令
make进行编译
常用且推荐的编译方式:外部构建
将编译输出文件与源文件放到不同目录中。
构建的工程目录中要有CMakeLists.txt和build目录,先cd进入build文件夹,然后输入命令:
cmake .. # 编译上级目录的CMakeLists.txt生成makefile和其他文件
make # 执行make命令,生成target
关于cmake构建的参数
cmake可以带上一些选项和参数,常用:
-D为缓存条目和option赋值-S指定源文件路径-B指定构建的路径