如何通过CMake定义预处理器变量?等价的代码是#define foo。
#define foo
6ie5vjzr1#
很长一段时间以来,CMake使用add_definitions命令来实现此目的。但是,最近该命令已被更细粒度的方法(用于编译定义、包含目录和编译器选项的单独命令)所取代。使用新的add_compile_definitions的示例:
add_definitions
add_compile_definitions(OPENCV_VERSION=${OpenCV_VERSION}) add_compile_definitions(WITH_OPENCV2)
字符串或者:
add_compile_definitions(OPENCV_VERSION=${OpenCV_VERSION} WITH_OPENCV2)
型这一点的好处是它避免了CMake为add_definitions设置的卑鄙伎俩。CMake是一个如此破旧的系统,但他们终于找到了一些理智。在这里可以找到关于哪些命令用于编译器标志的更多解释:https://cmake.org/cmake/help/latest/command/add_definitions.html同样,您可以按照Jim Hunziker的回答中所解释的那样对每个目标执行此操作。
kx1ctssn2#
要对特定目标执行此操作,可以执行以下操作:
target_compile_definitions(my_target PRIVATE FOO=1 BAR=1)
字符串如果要构建的目标不止一个,并且不希望所有目标都使用相同的标志,则应该这样做。另请参阅target_compile_definitions的官方文档。
cmssoen23#
本页提出的其他解决方案对于**某些版本的Cmake > 3.3.2**非常有用。这里是我使用的版本的解决方案(即3.3.2)。使用$ cmake --version检查Cmake的版本,并选择适合您需求的解决方案。cmake documentation可以在官方页面上找到。使用CMake版本3.3.2,为了创建
3.3.2
$ cmake --version
字符串我需要用途:
add_definitions(-Dfoo) # <--------HERE THE NEW CMAKE LINE inside CMakeLists.txt add_executable( ....) target_link_libraries(....)
型并且,为了具有像这样的预处理器宏定义:
#define foo=5
型行被这样修改:
add_definitions(-Dfoo=5) # <--------HERE THE NEW CMAKE LINE inside CMakeLists.txt add_executable( ....) target_link_libraries(....)
型
请注意(正如@squareskittles在其中一条评论中所建议的那样):“如果你使用的是CMake 3.3.2,你必须使用use add_definitions()或target_compile_definitions()。更现代的命令add_compile_definitions()直到CMake 3.12才被添加。
CMake 3.3.2
use add_definitions()
target_compile_definitions()
add_compile_definitions()
CMake 3.12
fv2wmkja4#
如果你使用的是CMake 3.X,你添加预处理宏的首选应该是target_compile_definitions。您应该优先选择这种方法而不是其他任何方法的原因是因为它的粒度是基于target的。IE宏只会被添加到你的exe/library。下面是一个常见的例子:
target
if (WIN32) target_compile_definitions(my_lib PRIVATE # Prevents Windows.h from adding unnecessary includes WIN32_LEAN_AND_MEAN # Prevents Windows.h from defining min/max as macros NOMINMAX ) endif()
字符串
在这里可以找到关于哪些命令用于编译器标志的更多解释:https://cmake.org/cmake/help/latest/command/add_definitions.htmladd_compile_definitions将宏应用于调用后定义的任何目标。这里的逻辑与上面的add_compile_definitions相同。
add_compile_definitions(WIN32_LEAN_AND_MEAN NOMINMAX) add_library(my_lib)
型如果你是top level project,那么使用这种方法时要小心。否则,如果用户使用add_subdirectory使用您的库,他们可能会遇到问题。
这些方法真的不再被推荐了。由于不是模块化的,伸缩性不好,不支持生成器表达式等。
全局应用预处理器标志(或任何编译器标志)可能会在构建中创建隐藏的依赖项。在C/C++中,add_compile_definitions本质上是全局变量。有时你需要它,但要小心。
iovurdzv5#
当您解决方案包含许多项目时,我建议使用target_***操作而不是add_***操作。
target_***
add_***
deyfvvtc6#
下面是一个可以将值从CMAKE传递到C++代码的示例。说着,就想通了:
我建议将它们作为字符串传递。因此,当您使用CMAKE构建软件时,您可以传递参数,例如,如果它是使用boost库构建的,则可以从CMAKE变量中提取软件版本(以便您仅在一个位置更改该数字),请参见下文。在CMakeLists.txt中:添加编译定义(BOOST="${BOOST}”软件版本="${PROJECT_VERSION}”)在.cpp代码中:std::cout <<“软件版本为:“<<软件版本<<“提升:“<<升压<<“\n”;希望这对你有帮助。问候。
6条答案
按热度按时间6ie5vjzr1#
很长一段时间以来,CMake使用
add_definitions
命令来实现此目的。但是,最近该命令已被更细粒度的方法(用于编译定义、包含目录和编译器选项的单独命令)所取代。使用新的add_compile_definitions的示例:
字符串
或者:
型
这一点的好处是它避免了CMake为
add_definitions
设置的卑鄙伎俩。CMake是一个如此破旧的系统,但他们终于找到了一些理智。在这里可以找到关于哪些命令用于编译器标志的更多解释:https://cmake.org/cmake/help/latest/command/add_definitions.html
同样,您可以按照Jim Hunziker的回答中所解释的那样对每个目标执行此操作。
kx1ctssn2#
要对特定目标执行此操作,可以执行以下操作:
字符串
如果要构建的目标不止一个,并且不希望所有目标都使用相同的标志,则应该这样做。另请参阅target_compile_definitions的官方文档。
cmssoen23#
本页提出的其他解决方案对于**某些版本的Cmake >
3.3.2
**非常有用。这里是我使用的版本的解决方案(即3.3.2
)。使用$ cmake --version
检查Cmake的版本,并选择适合您需求的解决方案。cmake documentation可以在官方页面上找到。使用CMake版本3.3.2,为了创建
字符串
我需要用途:
型
并且,为了具有像这样的预处理器宏定义:
型
行被这样修改:
型
请注意(正如@squareskittles在其中一条评论中所建议的那样):“如果你使用的是
CMake 3.3.2
,你必须使用use add_definitions()
或target_compile_definitions()
。更现代的命令add_compile_definitions()
直到CMake 3.12
才被添加。fv2wmkja4#
1.)target_compile_definitions
如果你使用的是CMake 3.X,你添加预处理宏的首选应该是target_compile_definitions。
您应该优先选择这种方法而不是其他任何方法的原因是因为它的粒度是基于
target
的。IE宏只会被添加到你的exe/library。下面是一个常见的例子:
字符串
2.)add_compile_definitions
在这里可以找到关于哪些命令用于编译器标志的更多解释:https://cmake.org/cmake/help/latest/command/add_definitions.html
add_compile_definitions将宏应用于调用后定义的任何目标。
这里的逻辑与上面的add_compile_definitions相同。
型
如果你是top level project,那么使用这种方法时要小心。否则,如果用户使用add_subdirectory使用您的库,他们可能会遇到问题。
3.)其他不太推荐的方式
这些方法真的不再被推荐了。由于不是模块化的,伸缩性不好,不支持生成器表达式等。
为什么target_compile_definitions更好?
全局应用预处理器标志(或任何编译器标志)可能会在构建中创建隐藏的依赖项。
在C/C++中,add_compile_definitions本质上是全局变量。有时你需要它,但要小心。
iovurdzv5#
当您解决方案包含许多项目时,我建议使用
target_***
操作而不是add_***
操作。deyfvvtc6#
下面是一个可以将值从CMAKE传递到C++代码的示例。说着,就想通了:
我建议将它们作为字符串传递。因此,当您使用CMAKE构建软件时,您可以传递参数,例如,如果它是使用boost库构建的,则可以从CMAKE变量中提取软件版本(以便您仅在一个位置更改该数字),请参见下文。
在CMakeLists.txt中:
添加编译定义(BOOST="${BOOST}”软件版本="${PROJECT_VERSION}”)
在.cpp代码中:
std::cout <<“软件版本为:“<<软件版本<<“提升:“<<升压<<“\n”;
希望这对你有帮助。问候。