Easier/terser 将 CMake 选项转换为预处理器定义的机制?

Easier/terser mechanism for translating CMake option into preprocessor definitions?

我发现自己在 CMakeLists.txt 中重复了以下代码段:

option(SOME_OPT "Some option" ON)
if (SOME_OPT)
    target_compile_definitions(my_app SOME_IDENTIFIER_HERE_RELATED_TO_OPT)
endif()

(偶尔会有类似的东西,但 -D 有一个字符串值)。

CMake 中是否有一种机制(不用管版本)使这更容易或更简洁?

选项 1:使用生成器表达式

这是一个使用目标属性和生成器表达式的选项:

option(SOME_OPT1 "Some option 1" ON)
option(SOME_OPT2 "Some option 2" OFF)
option(SOME_OPT3 "Some option 3" ON)

target_compile_definitions(my_app PRIVATE
  $<$<BOOL:${SOME_OPT1}>:SOME_IDENTIFIER_HERE_RELATED_TO_OPT1>
  $<$<BOOL:${SOME_OPT2}>:SOME_IDENTIFIER_HERE_RELATED_TO_OPT2>
  $<$<BOOL:${SOME_OPT3}>:SOME_IDENTIFIER_HERE_RELATED_TO_OPT3>
)

$<BOOL:${var}> 舞蹈是将 truthy/falsey CMake 值转换为 10 所必需的,正如生成器表达式 mini-language 所期望的那样。

选项 2:生成的“配置文件”

如果您有很多这样的选项,另一种选择是使用 configure_file 命令创建包含相关信息的 header。使用以下内容创建名为 config.h.in 的 header(作为示例):

#ifndef MYPROJ_CONFIG_H
#define MYPROJ_CONFIG_H

#cmakedefine SOME_IDENTIFIER_HERE_RELATED_TO_OPT1
#cmakedefine SOME_IDENTIFIER_HERE_RELATED_TO_OPT2
#cmakedefine01 SOME_IDENTIFIER_HERE_RELATED_TO_OPT3

#endif

如果 VAR 在 CMakeLists.txt 中定义为真值,则 #cmakedefine VAR 指令由 configure_file 处理以设置 VAR 并注释掉行如果没有。 01 变体始终定义 VAR,但将其设置为 01.

然后在你的 CMakeLists.txt 你可以写:

option(SOME_OPT1 "Some option 1" ON)
option(SOME_OPT2 "Some option 2" OFF)
option(SOME_OPT3 "Some option 3" ON)

# Setting these variables exposes them to configure_file below
set(SOME_IDENTIFIER_HERE_RELATED_TO_OPT1 "${SOME_OPT1}")
set(SOME_IDENTIFIER_HERE_RELATED_TO_OPT2 "${SOME_OPT2}")
set(SOME_IDENTIFIER_HERE_RELATED_TO_OPT3 "${SOME_OPT3}")

configure_file(config.h.in config.h)

target_include_directories(my_app PRIVATE "$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>")

然后您的源文件可以 #include <config.h>,默认情况下是:

#ifndef MYPROJ_CONFIG_H
#define MYPROJ_CONFIG_H

#define SOME_IDENTIFIER_HERE_RELATED_TO_OPT1
/* #undef SOME_IDENTIFIER_HERE_RELATED_TO_OPT2 */
#define SOME_IDENTIFIER_HERE_RELATED_TO_OPT3 1

#endif

这两个选项每个选项都需要一行开销,尽管第一种方法有点嘈杂,第二种方法需要一个文件。但是,第二种方法 允许您添加额外的预处理器代码,这些代码最好放在配置文件中。它还可以通过 @VAR@ 语法替换 CMake 变量 values。有关详细信息,请参阅文档:https://cmake.org/cmake/help/latest/command/configure_file.html