您的上述尝试是向您的文件/目标添加更多标志,而不是像您预期的那样进行覆盖。例如,从文档中源文件的属性 - COMPILE_FLAGS:
构建此源文件时,这些标志将添加到编译标志列表中。
你应该能够反驳-Weffc++
通过执行以下操作标记 foo.cpp
set_source_files_properties(foo.cpp PROPERTIES COMPILE_FLAGS -Wno-effc++)
这应该具有添加的效果-Wno-effc++
after -Weffc++
在编译器命令中,后一个设置获胜。要查看完整的命令并检查情况是否确实如此,您可以执行以下操作
make VERBOSE=1
顺便说一句,GNU C++ 标准库的维护者之一对-Weffc++
in 这个答案.
另一点是你滥用了add_definitions从某种意义上说,您将其用于编译器标志而不是预期的预处理器定义。
最好使用add_compile_options
add_compile_options(-Wall -Weffc++ -pedantic -std=c++0x)
或者对于 CMake 版本
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Weffc++ -pedantic -std=c++0x")
In response to further questions in the comments below, I believe it's impossible to reliably remove a flag on a single file. The reason is that for any given source file, it has the COMPILE_OPTIONS and COMPILE_FLAGS1 of its target applied, but these don't show up in any of the properties for that source file.
您可以考虑从目标中剥离问题标志COMPILE_OPTIONS
,然后将其单独应用于每个目标的源,并根据需要从特定源文件中省略它。
然而,虽然这在许多情况下都可行,但它也存在一些问题。
First - 源文件的属性不包括COMPILE_OPTIONS
, only COMPILE_FLAGS
。这是一个问题,因为COMPILE_OPTIONS
目标的可以包括生成器表达式, but COMPILE_FLAGS
不支持他们。因此,您在搜索标志时必须适应生成器表达式,实际上,如果您的标志包含在一个或多个中,您甚至可能必须“解析”生成器表达式,以查看是否应该将其重新应用于其余的源文件。
其次 - 从 CMake v3.0 开始,目标可以指定INTERFACE_COMPILE_OPTIONS。这意味着您的目标的依赖项可以添加或覆盖您的目标的依赖项COMPILE_OPTIONS
通过其INTERFACE_COMPILE_OPTIONS
。因此,您还必须递归地迭代所有目标的依赖项(这不是一个特别容易的任务,因为列表LINK_LIBRARIES因为目标还可以包含生成器表达式)以查找任何正在应用问题标志的目标,并尝试将其从这些目标中删除INTERFACE_COMPILE_OPTIONS
too.
在这个复杂的阶段,我希望向 CMake 提交补丁,以提供无条件从源文件中删除特定标志的功能。
1:请注意,与COMPILE_FLAGS
源文件的属性,COMPILE_FLAGS
目标上的属性已被弃用。