CMake的条件预处理定义上的代码(CMake conditional preprocessor d

2019-08-17 07:29发布

我迁移生成文件项目的CMake。 谁写的makefile文件中第一次的人做了一个模块,包含文件中写入某些值。

有包括config_in.h主的config.h文件。 在config.h文件包含了这样的事情:

#ifndef USE_FEATURE_A
#define USE_FEATURE_A 0
#endif

#ifndef USE_FEATURE_B
#define USE_FEATURE_B 0
#endif

在生成文件中有像假目标with_feature_a在config_in.h写道:

#define USE_FEATURE_A 1

这样的人可以键入

make with_feature_a
make

得到正确的版本。

我想复制这样的事情使用这个代码库,但使用CMake的。 我尝试了几个在网上建议的方法,但我没有得到它的工作。

set_target_properties(with_feature_a PROPERTIES COMPILE_DEFINITIONS 
    "WITH_FEATURE_A=1"
)

这是行不通的,因为如果我跑

make with_feature_a

我没有看到with_feature_a在预处理命令行。

我做了第二次尝试是直接到任何我想要的内容设置写入文件,但我不明白如何将连接file()命令,我的目标。

我把这个在我的CMakeLists.txt

file(WRITE 
local/config_in.h 
    "#define WITH_FEATURE_A 1"
)

但这不是执行每次和我不知道如何将它设置为一个单一的目标。

任何帮助表示赞赏。 感谢您阅读这一切的东西。 很抱歉的很长的故事:)

UPDATE

提供的解决方案在这里是走向解决方案的一大enhacement。 问题是,是不允许递归定义。 我展示一个例子:

在我的CMakeLists.txt放置:

if (WITH_FEATURE_A)
MESSAGE(STATUS "WITH_FEATURE_A")
add_definitions(-DUSE_FEATURE_A=1)
    add_definitions(-DWITH_FEABURE_B=1)
endif()

if (WITH_FEABURE_B)
MESSAGE(STATUS "WITH_FEATURE_B")
add_definitions(-DUSE_FEATURE_D=1)
endif()


if (WITH_FEABURE_C)
MESSAGE(STATUS "WITH_FEATURE_C")
add_definitions(-DUSE_FEATURE_D=1)
endif()


if (WITH_FEABURE_D)
MESSAGE(STATUS "WITH_FEATURE_D")
endif()

在这种情况下,如果我执行与-DWITH_FEATURE_A的cmake = 1我喜欢在输出中看到:

WITH_FEATURE_A
WITH_FEATURE_B
WITH_FEATURE_D

其实这个代码仅打印

WITH_FEATURE_A

Answer 1:

您可以通过避免创建虚拟目标和去除这个配置文件来简化事情。 相反,如果你通过通过命令行的要求,当你调用CMake的(或通过CMake的GUI),就可以运行make一次。

例如,您可以添加以下到您的CMakeLists.txt:

option(WITH_FEATURE_A "Option description" ON)
option(WITH_FEATURE_B "Option description" OFF)

if(WITH_FEATURE_A)
  add_definitions(-DUSE_FEATURE_A)
endif()
if(WITH_FEATURE_B)
  add_definitions(-DUSE_FEATURE_B)
endif()

默认情况下,如果你只是运行CMake的,它会设置CMake的变量WITH_FEATURE_AON这因此增加了USE_FEATURE_A作为预处理定义的版本。 USE_FEATURE_B在代码中未定义。

这将等同于做#define USE_FEATURE_A在你的代码。


如果你真的需要相当于

#define USE_FEATURE_A 1
#define USE_FEATURE_B 0

然后在您的CMakeLists.txt,你可以这样做:

option(WITH_FEATURE_A "Option description" ON)
option(WITH_FEATURE_B "Option description" OFF)

if(WITH_FEATURE_A)
  add_definitions(-DUSE_FEATURE_A=1)
else()
  add_definitions(-DUSE_FEATURE_A=0)
endif()
if(WITH_FEATURE_B)
  add_definitions(-DUSE_FEATURE_B=1)
else()
  add_definitions(-DUSE_FEATURE_B=0)
endif()


要通过命令行更改这些默认设置,简单地做(例如):

cmake . -DWITH_FEATURE_A=OFF -DWITH_FEATURE_B=ON
make

一旦一个变量已经通过命令行这种方式设置,它被缓存,直到它与在命令行上不同的值覆盖将保持不变,或删除在构建根CMakeCache.txt文件。


响应更新:

作为@Peter注意到,你似乎是混合了CMake的变量( WITH_FEATURE...的)和预处理器定义( USE_FEATURE...的)。 您可以按照建议解决所有选项之间的依赖关系,然后设定所产生的预处理器定义,或在这种情况下流程非常简单,只需把一切都一气呵成:

if(WITH_FEATURE_A)
  message(STATUS "WITH_FEATURE_A")
  add_definitions(-DUSE_FEATURE_A=1)
  set(WITH_FEATURE_B ON)
endif()

if(WITH_FEATURE_B)
  message(STATUS "WITH_FEATURE_B")
  add_definitions(-DUSE_FEATURE_B=1)
  set(WITH_FEATURE_D ON)
endif()

if(WITH_FEATURE_C)
  message(STATUS "WITH_FEATURE_C")
  add_definitions(-DUSE_FEATURE_C=1)
  set(WITH_FEATURE_D ON)
endif()

if(WITH_FEATURE_D)
  message(STATUS "WITH_FEATURE_D")
  add_definitions(-DUSE_FEATURE_D=1)
endif()




Answer 2:

这听起来像你想介绍你的选择之间的关系。 如果你分开的步骤,这将是更容易。 首先解决的关系,然后设置C的结果确定。 请记住,WITH_FEATURE_A是cmake的变量,并且USE_FEATURE_A是C预处理限定设定ADD_DEFINITIONS:

# Specify the inter-feature dependencies
if (WITH_FEATURE_A)
    # A requires B because <somereason>
    set(WITH_FEATURE_B ON)
endif()

if (WITH_FEATURE_B)
    set(WITH_FEATURE_D ON)
endif()

if (WITH_FEATURE_C)
    set(WITH_FEATURE_D ON)
endif()

# Now generate the C defines for passing the options to the compiler
if (WITH_FEATURE_A)
    MESSAGE(STATUS "WITH_FEATURE_A")
    add_definitions(-DUSE_FEATURE_A=1)
endif()

if (WITH_FEATURE_B)
    MESSAGE(STATUS "WITH_FEATURE_B")
    add_definitions(-DUSE_FEATURE_B=1)
endif()

if (WITH_FEATURE_C)
    MESSAGE(STATUS "WITH_FEATURE_C")
    add_definitions(-DUSE_FEATURE_C=1)
endif()

if (WITH_FEATURE_D)
    MESSAGE(STATUS "WITH_FEATURE_D")
    add_definitions(-DUSE_FEATURE_D=1)
endif()


Answer 3:

我无意中发现了这个问题,我想我共享的另一种选择: TARGET_COMPILE_DEFINITIONS 。 你可以在你的CMakeLists.txt文件中的两个目标,每一个配置,并且有这样的事

ADD_EXECUTABLE (versionA, ...)
TARGET_COMPILE_DEFINITIONS (versionA, PUBLIC -DWITH_FEATURE_A=1 -DWITH_FEATURE_B=0)

ADD_EXECUTABLE (versionB, ...)
TARGET_COMPILE_DEFINITIONS (versionB, PUBLIC -DWITH_FEATURE_A=0 -DWITH_FEATURE_B=1)

这告诉CMake的添加宏的预处理器定义WITH_FEATURE_AWITH_FEATURE_B (用适当的值),就像如果您在*页文件中定义它们。 那么你可以告诉make编译的版本:

make versionA
make versionB


文章来源: CMake conditional preprocessor define on code