CMake的条件preprocessor定义上code [英] CMake conditional preprocessor define on code

查看:208
本文介绍了CMake的条件preprocessor定义上code的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我迁移生成文件项目CMake的。谁写Makefile中的人在第一时间做了一个模块在一个包含文件中写入特定的值。

有一个主要的config.h文件,其中包含一个config_in.h。在config.h文件包含了这样的事情:

 的#ifndef USE_FEATURE_A
#定义USE_FEATURE_A 0
#万一的#ifndef USE_FEATURE_B
#定义USE_FEATURE_B 0
#万一

在makefile中有像 with_feature_a 假目标,在config_in.h写

 的#define USE_FEATURE_A 1

在这样有人可以键入

 使with_feature_a
使

要得到正确的版本。

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

  set_target_properties(with_feature_a性能COMPILE_DEFINITIONS
    WITH_FEATURE_A = 1

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

 使with_feature_a

我不明白 with_feature_a 在preprocessor命令行。

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

我把这个在我的CMakeLists.txt

 文件(WRITE
本地/ config_in.h
    #定义WITH_FEATURE_A 1

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

任何帮助是AP preciated。感谢您阅读这一切的东西。很抱歉的很长的故事:)

更新

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

在我的CMakeLists.txt放置:

 如果(WITH_FEATURE_A)
(状态WITH_FEATURE_A)
add_definitions(-DUSE_FEATURE_A = 1)
    add_definitions(-DWITH_FEABURE_B = 1)
万一()如果(WITH_FEABURE_B)
(状态WITH_FEATURE_B)
add_definitions(-DUSE_FEATURE_D = 1)
万一()
如果(WITH_FEABURE_C)
(状态WITH_FEATURE_C)
add_definitions(-DUSE_FEATURE_D = 1)
万一()
如果(WITH_FEABURE_D)
(状态WITH_FEATURE_D)
万一()

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

  WITH_FEATURE_A
WITH_FEATURE_B
WITH_FEATURE_D

其实这code仅打印

  WITH_FEATURE_A


解决方案

您可以简化避免创建虚拟目标和删除配置文件的东西。相反,如果你通过通过命令行的要求,当你调用CMake的(或通过CMake的GU​​I),就可以运行make一次。

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

选项(WITH_FEATURE_A选项的说明ON)
选项​​(WITH_FEATURE_B选项的说明OFF)如果(WITH_FEATURE_A)
  add_definitions(-DUSE_FEATURE_A)
万一()
如果(WITH_FEATURE_B)
  add_definitions(-DUSE_FEATURE_B)
万一()

在默认情况下,如果你只是运行CMake的,它会设置CMake的变量 WITH_FEATURE_A ON 这因此增加了 USE_FEATURE_A 为preprocessor定义来构建。 USE_FEATURE_B 在code不确定。

这是等同于你的code做的#define USE_FEATURE_A


如果你真的需要相当于

 的#define USE_FEATURE_A 1
#定义USE_FEATURE_B 0

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

选项(WITH_FEATURE_A选项的说明ON)
选项​​(WITH_FEATURE_B选项的说明OFF)如果(WITH_FEATURE_A)
  add_definitions(-DUSE_FEATURE_A = 1)
其他()
  add_definitions(-DUSE_FEATURE_A = 0)
万一()
如果(WITH_FEATURE_B)
  add_definitions(-DUSE_FEATURE_B = 1)
其他()
  add_definitions(-DUSE_FEATURE_B = 0)
万一()


要在命令行中更改这些默认值,简单地做(例如):

  cmake的。 -DWITH_FEATURE_A = OFF -DWITH_FEATURE_B = ON
使

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


响应更新:

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

如果(WITH_FEATURE_A)
  消息(STATUSWITH_FEATURE_A)
  add_definitions(-DUSE_FEATURE_A = 1)
  集(WITH_FEATURE_B ON)
万一()如果(WITH_FEATURE_B)
  消息(STATUSWITH_FEATURE_B)
  add_definitions(-DUSE_FEATURE_B = 1)
  集(WITH_FEATURE_D ON)
万一()如果(WITH_FEATURE_C)
  消息(STATUSWITH_FEATURE_C)
  add_definitions(-DUSE_FEATURE_C = 1)
  集(WITH_FEATURE_D ON)
万一()如果(WITH_FEATURE_D)
  消息(STATUSWITH_FEATURE_D)
  add_definitions(-DUSE_FEATURE_D = 1)
万一()


I'm migrating a makefile project to CMake. The person who wrote the makefile the first time had done a module for writing certain values in an include file.

There's a main config.h file that includes a config_in.h. The config.h file contains something like this:

#ifndef USE_FEATURE_A
#define USE_FEATURE_A 0
#endif

#ifndef USE_FEATURE_B
#define USE_FEATURE_B 0
#endif

In the makefile there's a fake target like with_feature_a that writes in config_in.h

#define USE_FEATURE_A 1

In this way someone can type

make with_feature_a
make

to get the right build.

I want to replicate something like this using this codebase but using CMake. I tried a couple of approaches suggested on the net, but I didn't get it to work.

set_target_properties(with_feature_a PROPERTIES COMPILE_DEFINITIONS 
    "WITH_FEATURE_A=1"
)

This isn't working because if I run

make with_feature_a

I don't see with_feature_a in the preprocessor command line.

The second attempt I made is to write a file directly with the content set to whatever I want, but I didn't understand how to connect the file() command to my target.

I placed this in my CMakeLists.txt

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

but this isn't executed everytime and I don't know how to set it to a single target.

Any help is appreciated. Thank you for reading all this stuff. Sorry for the long story :)

UPDATE

The solution provided here is a big enhacement on the road to solution. The problem is that is don't allow recursive definitions. I show an example:

in CMakeLists.txt I placed:

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()

in this case if I execute cmake with -DWITH_FEATURE_A=1 I'd love to see in the output:

WITH_FEATURE_A
WITH_FEATURE_B
WITH_FEATURE_D

actually this code print just

WITH_FEATURE_A

解决方案

You can simplify things by avoiding creating the dummy targets and removing the config file. Instead, if you pass the requirements via the command line when you invoke CMake (or via the CMake GUI), you can run make only once.

For example, you could add the following to your 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()

By default, if you just run CMake, it will set the CMake variable WITH_FEATURE_A to ON which consequently adds USE_FEATURE_A as a preprocessor definition to the build. USE_FEATURE_B is undefined in the code.

This would be equivalent to doing #define USE_FEATURE_A in your code.


If you really need the equivalent of

#define USE_FEATURE_A 1
#define USE_FEATURE_B 0

then in your CMakeLists.txt you can do:

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()


To change these defaults from the command line, simply do (e.g.):

cmake . -DWITH_FEATURE_A=OFF -DWITH_FEATURE_B=ON
make

Once a variable has been set via the command line this way, it is cached and will remain unchanged until either it is overwritten with a different value on the command line, or you delete the CMakeCache.txt file in your build root.


Response to update:

As @Peter noted, you appear to be mixing up CMake variables (the WITH_FEATURE... ones) and the preprocessor definitions (the USE_FEATURE... ones). You can as suggested resolve all the dependencies between options first, then set the resulting preprocessor definitions, or in this case where the flow is quite straightforward, just do it all in one go:

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()


这篇关于CMake的条件preprocessor定义上code的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆