我正在使用cmake 2.8.12 。
我通过调用 add_definitions()来使用具有相同定义的多个目标。 我想了解如何删除单个目标的定义,并将其替换为某些其他定义或默认定义,就像我没有调用过add_definitions()。
答案 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})