我想使用一组全局标志来编译项目,这意味着在我的顶级 CMakeLists.txt 文件中我已指定:
ADD_DEFINITIONS ( -Wall -Weffc++ -pedantic -std=c++0x )
但是,对于子目录中的特定文件(比如说“foo.cpp”),我想切换 编译标志以不应用 -Weffc++(包括商业库,我无法更改)。为了简化只使用 -Wall 的情况,我尝试了:
SET_SOURCE_FILES_PROPERTIES( foo.cpp PROPERTIES COMPILE_FLAGS -Wall )
ADD_EXECUTABLE( foo foo.cpp )
,这不起作用。 我也试过了
SET_PROPERTY( SOURCE foo.cpp PROPERTY COMPILE_FLAGS -Wall )
ADD_EXECUTABLE( foo foo.cpp )
和
ADD_EXECUTABLE( foo foo.cpp )
SET_TARGET_PROPERTIES( foo PROPERTIES COMPILE_FLAGS -Wall )
,两者都不起作用。
最后,我尝试删除这个定义:
REMOVE_DEFINITIONS( -Weffc++ )
ADD_EXECUTABLE( foo foo.cpp )
ADD_DEFINITIONS( -Weffc++ )
,这也不起作用(意思是,我收到了很多关于商业图书馆的风格警告)。 (**注意:如果我在构建可执行文件后不重新包含 -Weffc++ 指令,则会抑制警告。)
我还尝试暂时删除编译标志: http://www.cmake.org/pipermail/cmake/2007-June/014614.html ,但这没有帮助。
难道没有一个优雅的解决方案吗?
最佳答案
您在上面的尝试是在您的文件/目标中添加更多标志,而不是像您预期的那样覆盖。例如,来自 Properties on Source Files - COMPILE_FLAGS 的文档:
These flags will be added to the list of compile flags when this source file builds.
您应该能够通过执行来抵消 foo.cpp 的 -Weffc++
标志
set_source_files_properties(foo.cpp PROPERTIES COMPILE_FLAGS -Wno-effc++)
这个应该有在编译命令中-Weffc++
后面加上-Wno-effc++
的效果,后面的设置胜出。要查看完整的命令并检查是否确实如此,您可以这样做
make VERBOSE=1
顺便说一句,GNU C++ 标准库的维护者之一在 this answer 中对 -Weffc++
提出了相当负面的看法。 .
还有一点是你误用了 add_definitions
从某种意义上说,您将其用于编译器标志而不是预期的预处理器定义。
最好使用 add_compile_options
add_compile_options(-Wall -Weffc++ -pedantic -std=c++0x)
或者对于 CMake 版本 < 3.0 来做更多类似的事情:
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Weffc++ -pedantic -std=c++0x")
为了回答下面评论中的进一步问题,我认为不可能可靠地删除单个文件上的标志。原因是对于任何给定的源文件,它都有 COMPILE_OPTIONS
和 COMPILE_FLAGS
应用了 1 个目标,但这些不会显示在该源文件的任何属性中。
您可以查看从目标的 COMPILE_OPTIONS
中剥离问题标志,然后将其分别应用于目标的每个源,并根据需要从特定源文件中省略它。
然而,虽然这可以在许多情况下工作,但它有几个问题。
第一 - source files' properties不包括 COMPILE_OPTIONS
,仅包括 COMPILE_FLAGS
。这是一个问题,因为目标的 COMPILE_OPTIONS
可能包含 generator expressions ,但 COMPILE_FLAGS
不支持它们。所以你必须在搜索你的标志时适应生成器表达式,事实上,如果你的标志包含在一个或多个中,你甚至可能不得不“解析”生成器表达式,以查看它是否应该重新应用于剩余的源文件。
第二 - 从 CMake v3.0 开始,目标可以指定 INTERFACE_COMPILE_OPTIONS
.这意味着目标的依赖项可以通过其INTERFACE_COMPILE_OPTIONS
添加或覆盖目标的COMPILE_OPTIONS
。因此,您还必须递归地遍历所有目标的依赖项(这不是一项特别容易的任务,因为目标的 LINK_LIBRARIES
列表也可以包含生成器表达式)以找到应用问题标志的任何内容,并尝试删除它也来自那些目标的 INTERFACE_COMPILE_OPTIONS
。
在这个复杂的阶段,我希望向 CMake 提交一个补丁,以提供从源文件中无条件删除特定标志的功能。
1:请注意,与源文件上的 COMPILE_FLAGS
属性不同,目标上的 COMPILE_FLAGS
属性已被弃用。
关于c++ - 覆盖单个文件的编译标志,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13638408/