1

我发现自己在重复以下代码段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 中是否有一种机制(更不用说版本)可以使这更容易或更简洁?

4

1 回答 1

1

选项 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}>对于将真/假 CMake 值转换为 or 是必要的10

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

如果您有许多此类选项,则另一种选择是使用该configure_file命令创建包含相关信息的标题。创建一个名为config.h.in(作为示例)的标头,其中包含以下内容:

#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

#cmakedefine VAR指令被处理以将 CMakeLists.txt 中定义的ifconfigure_file设置为真值,如果不是,则注释掉该行。变体始终定义,但将其设置为或。VARVAR01VAR01

然后在你的 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

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

于 2021-06-28T17:02:31.387 回答