如何在cmake 2.8.12中删除每个目标的定义

时间:2018-03-01 12:09:33

标签: cmake

我正在使用cmake 2.8.12

我通过调用 add_definitions()来使用具有相同定义的多个目标。 我想了解如何删除单个目标的定义,并将其替换为某些其他定义默认定义,就像我没有调用过add_definitions()。

3 个答案:

答案 0 :(得分:2)

这里更好的方法是为单个目标而不是全局添加定义。

为此,您应使用add_definitions代替add_definitions(-DSOMEMACRO) add_executable(myExecutable main.cpp)

例如,而不是

add_executable(myExecutable main.cpp)
target_compile_definitions(myExecutable PUBLIC -DSOMEMACRO)

你会用

{{1}}

这允许您对定义进行细粒度控制,并且通常是设置它们的首选方法。 我认为为每个目标添加定义比从某些目标中删除定义更容易。

答案 1 :(得分:1)

在构建大型项目并使用自己的其他3rd party项目(例如,来自Github的项目)时,这是一件非常重要的事情,因为它们通常会破坏编译定义并最终导致破坏构建的问题,要求您有选择地删除定义,而不编辑原始项目本身。

可悲的是,我还没有找到一种针对每个目标的现代化方法。

但是,remove_definitiions是执行此操作的旧方法。它适用于草率的旧样式,适用于当前子目录及以下子目录。这足以令人沮丧地泄漏到同一目录中的其他目标。

一个丑陋的解决方案是将您的CMakeLists.txt的一部分分解为单独的CMakeLists.txt以用于违规的目标,并将remove_definitions仅放置在隔离这些目标的子目录中的该辅助CMakelists.txt中。

在我看来,这是CMake本身的不足,它确实需要添加target_remove_definitions()函数。

以下是我需要此方法以及如何解决此问题的示例:

       # main_directory/CMakeLists.txt
       # Add subdir of the offending targets
       add_subdirectory(evil_dependencies)
       ....
       # main_directory/evil_dependencies/CMakeLists.txt

       # This is required or else, there are headers in the repo
       # that #define NOMINMAX which then causes a warning:
       # macro redefinition, and warnings as errors = stop the build.
       if(MSVC)
           remove_definitions(/DNOMINMAX)
        endif()

       add_subdirectory(some_evil_dependency1)
       add_subdirectory(some_evil_dependency2)

对于GCC样式问题,它看起来更像remove_definitions(-DSOMEDEFINE)。请注意,对于此旧样式调用,令人厌恶地需要/ D或-D。这要求您编写一堆额外的丑陋的if-then分支,以查看您是否在MSVC中。等或GCC / Clang。

答案 2 :(得分:1)

我在那里找到了解决方案:

https://gitlab.kitware.com/cmake/cmake/issues/19796

这是删除NOMINMAX定义的方法:

get_target_property(defs someTarget COMPILE_DEFINITIONS)
list(FILTER defs EXCLUDE REGEX [[^NOMINMAX$]])
set_property(TARGET someTarget PROPERTY COMPILE_DEFINITIONS ${defs})