目录
宏定义在程序设计中几乎是不可避免会用到的,在控制程序运行上有非常重要的作用。除了在源代码中使用 #define 预处理命令定义的宏,我经常会在编译时根据具体需要选择定义某些宏或者绕过某些宏,以期同一套代码能符合多种场景需求。
对于使用 cmake 构建的软件,我们不再需要写 Makefile 也不用直接执行 gcc 等编译命令,为了满足上述需求,cmake 也提供了多种方法让用户能够在编译时自定义宏定义。
假设我们的目标是要在程序中定义一个没有具体值的宏(通常用于一些编译开关之类的),比如:
#define NONE_VALUE_MACRO
cmake 命令行
可以在使用 cmake 命令构建时,添加 /D[MACRONAME] 参数可以在编译时手动选择定义宏参数。
cmake /DNONE_VALUE_MACRO ..
这样的优点是灵活,可以完全不修改代码的情况下选择要定义的宏。缺点嘛,就是麻烦,尤其是有多个宏定义的时候。反正我是不喜欢输入太长的命令的。
需要注意的是,命令行不能直接对源代码生效,而是影响 CMakeLists.txt 文件的执行,所以要上述命令生效,还需要在 CMakeLists.txt 中添加相应语句。
add_definitions 命令
这个命令是 cmake 较早版本就实现的,特点是使用时要在宏名称前添加 "-D" 前缀。
add_definitions(-DNONE_VALUE_MACRO)
add_compile_definitions 命令
这个命令是 cmake v3.12 后添加的,相比于 add_difinitions,功能更加单一且参数使用灵活。
add_compile_definitions(NONE_VALUE_MACRO)
假设要定义一个有具体值的宏:
#define VALUE_MACRO 0x10000000
cmake 命令行
在定义有参宏时,要使用 "-D" 而非 "/D",前者遵循 [VAR:type=value] 的格式,即在定义宏要指定具体值。
cmake -DVALUE_MACRO=0x10000000 ..
add_definitions 命令
add_definitions(-DNONE_VALUE_MACRO=0x10000000)
add_compile_definitions 命令
add_compile_definitions(VALUE_MACRO=0x10000000)
注:
compile.c
#include <stdio.h>
int main()
{
printf("This process is used to testing compiler definition in cmake.\n");
#ifdef COMPILE_M1
printf("Defined macro: COMPILE_M1\n");
#endif
#if COMPILE_M2 == 0x100
printf("Macro COMPILE_M2: 0x%x\n", COMPILE_M2);
#endif
#if COMPILE_M3 == 0x200
printf("Macro COMPILE_M3: 0x%x\n", COMPILE_M3);
#endif
#ifdef COMPILE_M4
printf("Macro COMPILE_M4 is defined by cmake command\n");
#endif
return 0;
}
CMakeLists.txt
cmake_minimum_required (VERSION 3.13.0)
project (cmake_test VERSION 0.0.4)
add_definitions (-DCOMPILE_M1)
add_definitions (-DCOMPILE_M2=0x100)
add_compile_definitions (COMPILE_M3=0x200)
if(COMPILE_M4)
add_compile_definitions (COMPILE_M4)
endif()
add_executable(compile compile.c)
编译运行
mkdir build && cd build
cmake .. #或 cmake /DCOMPILE_M4 ..
make
这个命令是 cmake v3.12 版本添加的特性,用于将预处理器定义添加到源文件的编译中。
预处理器定义被添加到当前 CMakeLists 文件的 COMPILE_DEFINITIONS 目录属性中。它们也被添加到当前 CMakeLists 文件中每个目标的 COMPILE_DEFINITIONS 目标属性中。
使用语法 VAR 或 VAR=value 指定定义。不支持函数样式定义。 CMake 将自动为本机构建系统正确转义值(请注意,CMake 语言语法可能需要转义来指定某些值)。
其命令格式如下:
add_compile_definitions(<definition> ...)
add_compile_definitions 的参数可以使用语法为 $<...> 的“生成器表达式”。如:
set(VAR_TESTCASE_CONFIG_FILE \"testcases.json\") add_compile_definitions(TESTCASE_CONFIG_FILE="${VAR_TESTCASE_CONFIG_FILE}")
将 -D 定义标志添加到源文件的编译中。将定义添加到当前目录中的目标的编译器命令行,无论是在调用此命令之前还是之后添加,以及之后添加的子目录中的目标。此命令可用于添加任何标志,但它旨在添加预处理器定义。
add_definitions(-DFOO -DBAR ...)
以 -D 或 /D 开头的看起来像预处理器定义的标志会自动添加到当前目录的 COMPILE_DEFINITIONS 目录属性中。具有非平凡值的定义可能会留在标志集中,而不是出于向后兼容性的原因进行转换。
cmake 官方建议现在使用其他的命令来代替这个命令:
CMake定义宏的方式_风闲1217的博客-CSDN博客_cmake 宏定义