自定义变量
定义变量是一种管理和组织代码的有效方式,尤其是当涉及到重复使用相同的值或文件列表时。通过使用 set命令,你可以创建自定义变量来存储一系列值,比如文件路径、选项、或者其他数据。这样,当需要引用这些值时,只需使用变量名,而不是重复输入相同的数据,从而使得CMake脚本更加简洁、易于维护。
- 当使用变量存储文件路径或源文件列表时,确保路径正确,尤其是在跨平台项目中。
- 使用 CACHE选项时,要谨慎覆盖缓存中的值,特别是对于那些可能会被用户或其他CMake脚本修改的变量。
- 在定义和使用变量时保持一致性,避免在CMake脚本中引入不必要的复杂性。
基本语法
set(VAR[VALUE][CACHE TYPE DOCSTRING[FORCE]])
- VAR:变量名。
- VALUE:分配给变量的值。
- CACHE(可选):指定变量应该存储在CMake的缓存中,这对于跨多次运行CMake保持变量值很有用。
- TYPE(可选):变量类型,例如 STRING、 BOOL等。
- DOCSTRING(可选):变量的描述字符串,用于CMake GUI中的提示信息。
- FORCE(可选):如果变量已经在缓存中存在, FORCE会覆盖现有的缓存值。
- 示例:定义包含源文件列表的变量 SRC_LIST。
- 使用空格分隔源文件:
set(SRC_LIST add.c div.c main.c mult.c sub.c)
- 使用分号 ;分隔源文件:
set(SRC_LIST add.c;div.c;main.c;mult.c;sub.c)
使用变量
定义变量后,你可以在CMake脚本的其他地方通过 ${VAR}语法引用变量的值。例如,使用 add_executable或 add_library命令创建目标时,可以将源文件列表变量作为参数传递。
- 示例:使用 SRC_LIST变量创建一个可执行文件 app。
- add_executable(app ${SRC_LIST})
在上述例子中, ${SRC_LIST}会被替换为 add.c div.c main.c mult.csub.c,从而将这些源文件编译成名为 app的可执行文件。
指定C++标准
CMake提供了灵活的方式来设置项目所需的C++标准,确保编译器按照指定的标准来编译代码。
- 如果你的项目中有多个目标(target),可以为每个目标分别设置C++标准。使用 target_compile_features或 target_compile_options命令针对特定目标设置编译器选项。
- 除了 CMAKE_CXX_STANDARD之外,还有 CMAKE_CXX_STANDARD_REQUIRED和 CMAKE_CXX_EXTENSIONS两个相关的变量。 CMAKE_CXX_STANDARD_REQUIRED用于指定是否严格要求所选C++标准, CMAKE_CXX_EXTENSIONS用于启用或禁用编译器特定的扩展。
- 不同编译器对C++新标准的支持程度可能有所不同。确保你使用的编译器版本足够新,能够支持所需的C++标准。
方法1:在CMakeLists.txt中设置
最直接的方法是在 CMakeLists.txt文件中通过 set命令指定 CMAKE_CXX_STANDARD变量的值。这个变量控制着C++的版本标准。
# 设置C++11标准
set(CMAKE_CXX_STANDARD 11)
# 设置C++14标准
set(CMAKE_CXX_STANDARD 14)
# 设置C++17标准
set(CMAKE_CXX_STANDARD 17)
# 设置C++20标准
set(CMAKE_CXX_STANDARD 20)
设置 CMAKE_CXX_STANDARD变量后,CMake会自动添加合适的编译器标志(例如 -std=c++11)来指定C++标准。
方法2:在命令行中设置
另一种方式是在执行 cmake命令时通过 -D选项直接指定 CMAKE_CXX_STANDARD的值。这种方法适用于需要在不同的构建环境中使用不同C++标准的情况。
# 使用C++11标准
cmake -DCMAKE_CXX_STANDARD=11 /path/to/CMakeLists.txt
# 使用C++14标准
cmake -DCMAKE_CXX_STANDARD=14 /path/to/CMakeLists.txt
# 使用C++17标准
cmake -DCMAKE_CXX_STANDARD=17 /path/to/CMakeLists.txt
# 使用C++20标准
cmake -DCMAKE_CXX_STANDARD=20 /path/to/CMakeLists.txt
指定输出路径
CMake通过 EXECUTABLE_OUTPUT_PATH变量提供了一种灵活的方式来指定这些输出路径。
# 定义一个变量HOME,存储绝对路径
set(HOME /path/to/your/project)
# 设置可执行文件的输出路径
set(EXECUTABLE_OUTPUT_PATH ${HOME}/bin)
这里 ${HOME}是一个变量,它被替换为你在 set命令中指定的路径。 ${HOME}/bin表示可执行文件将被放置在 ${HOME}路径下的 bin目录中。
注意事项
- 如果输出路径中的目录不存在,CMake将自动创建这些目录,无需手动创建。
- 如果你使用的是相对路径(例如 ./bin),那么这个路径是相对于生成的 Makefile文件所在目录的。换句话说, ./代表的是当前的构建目录,而不是 CMakeLists.txt文件所在的目录。
- 你可以为不同的目标指定不同的输出路径。例如,对于库文件,CMake提供了 LIBRARY_OUTPUT_PATH变量来指定库文件的输出路径。
进阶用法
对于更复杂的项目结构,你可能需要对不同构建类型(如Debug和Release)指定不同的输出路径。这可以通过 CMAKE_RUNTIME_OUTPUT_DIRECTORY_<CONFIG>变量实现,其中 <CONFIG>是构建类型的名称:
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${HOME}/bin/debug)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${HOME}/bin/release)
这种方式允许你根据不同的构建配置将可执行文件分别放置在不同的目录下,从而更好地组织你的项目结构。