通过 CMake 定义预处理器宏?

新手上路,请多包涵

如何通过 CMake 定义预处理器变量?

等效代码为 #define foo

原文由 Mythli 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.4k
2 个回答

长期以来,CMake 都有 add_definitions 命令用于此目的。但是,最近该命令已被更细粒度的方法(用于编译定义、包含目录和编译器选项的单独命令)取代。

使用新的 add_compile_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 的回答中的说明对每个目标执行此操作。

原文由 ypnos 发布,翻译遵循 CC BY-SA 4.0 许可协议

1.) target_compile_definitions

如果您使用的是 CMake 3.X,则添加预处理器宏的首选应该是 target_compile_definitions

您应该比任何其他方法更喜欢这种方法的原因是因为它的粒度是基于 target 的。 IE 宏只会被添加到您的 exe/库中。

这是一个常见的例子:

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

2.) add_compile_definitions

版本 3.12 中的新功能。

在此处查找有关用于编译器标志的命令的更多说明: https ://cmake.org/cmake/help/latest/command/add_definitions.html

add_compile_definitions 将宏应用于调用后定义的任何目标。

这里的逻辑与上面的 add_compile_definitions 相同。

 add_compile_definitions(WIN32_LEAN_AND_MEAN NOMINMAX)
add_library(my_lib)

如果您是 顶级项目,请小心使用这种方法。否则,如果用户使用 add_subdirectory 使用您的库,他们可能会遇到问题。

3.) 其他不太推荐的方式

这些方法真的不再推荐了。由于不是模块化的,不能很好地扩展,不支持生成器表达式等。

为什么 target_compile_definitions 更好/更受欢迎?

  • CMake 代码的读者更清楚它是如何工作的。
  • 如果需要,允许使用 PRIVATE/PUBLIC/INTERFACE。这可以使您图书馆的消费者的生活更轻松。
  • 它更加模块化。

全局应用预处理器标志(或任何编译器标志)可以在您的构建中创建隐藏的依赖项。

本质上将 add_compile_definitions 视为 C/C++ 中的全局变量。有时你需要它们,但要小心。

原文由 user15308163 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题