覆盖单个文件的编译标志

2023-12-01

我想使用一组全局标志来编译项目,这意味着我在顶级 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 )

and

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,但这没有帮助。

难道就没有一个优雅的解决方案吗?


您的上述尝试是向您的文件/目标添加更多标志,而不是像您预期的那样进行覆盖。例如,从文档中源文件的属性 - 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目标上的属性已被弃用。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

覆盖单个文件的编译标志 的相关文章

随机推荐