覆盖单个文件的编译标志

新手上路,请多包涵

我想使用一组全局标志来编译项目,这意味着在我的顶级 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 ,但这没有帮助。

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

原文由 J.B. Brown 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 764
2 个回答

您上面的尝试正在向您的文件/目标添加更多标志,而不是像您预期的那样覆盖。例如,来自 源文件属性的文档 - COMPILE_FLAGS

当此源文件构建时,这些标志将添加到编译标志列表中。

您应该可以通过执行来取消 foo.cpp 的 -Weffc++ 标志

set_source_files_properties(foo.cpp PROPERTIES COMPILE_FLAGS -Wno-effc++)

这应该具有在编译器命令中在 -Weffc++ -Wno-effc++ 的效果,并且后者设置获胜。要查看完整的命令并检查是否确实如此,您可以执行

make VERBOSE=1

顺便说一句,GNU C++ 标准库的维护者之一在 这个答案 中对 -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_OPTIONSCOMPILE_FLAGS 1的目标,但这些不会显示在该源文件的任何属性中.

您可以查看从目标的 COMPILE_OPTIONS 中剥离问题标志,然后将其分别应用于目标的每个源,并根据需要从特定源文件中省略它。

然而,虽然这可以在许多情况下工作,但它有几个问题。

首先 - 源文件的属性 不包括 COMPILE_OPTIONS ,只有 COMPILE_FLAGS 。这是一个问题,因为目标的 COMPILE_OPTIONS 可以包含 生成器表达式,但 COMPILE_FLAGS 不支持它们。所以你必须在搜索你的标志时适应生成器表达式,事实上,如果你的标志包含在一个或多个中,你甚至可能不得不“解析”生成器表达式,以查看它是否应该重新应用于剩余的源文件。

第二 - 从 CMake v3.0 开始,目标可以指定 INTERFACE_COMPILE_OPTIONS 。这意味着您的目标的依赖项可以通过其 INTERFACE_COMPILE_OPTIONS 添加或覆盖目标的 COMPILE_OPTIONS 。因此,您还必须递归地遍历所有目标的依赖项(这不是一项特别容易的任务,因为目标的 LINK_LIBRARIES 列表也可以包含生成器表达式)以找到应用问题标志的任何依赖项,并尝试将其从这些目标的 INTERFACE_COMPILE_OPTIONS 中删除。

在这个复杂的阶段,我希望向 CMake 提交一个补丁,以提供从源文件中无条件删除特定标志的功能。


1:请注意,与源文件上的 COMPILE_FLAGS COMPILE_FLAGS 不同,目标上的 --- 属性已弃用。

原文由 Fraser 发布,翻译遵循 CC BY-SA 4.0 许可协议

虽然不完全是对 OPs 问题的回答,但以下提示为我解决了一个问题。一些编译器允许在源文件本身中设置或取消设置选项:

 #pragma option -Xinteger-divide-fast=0

这将禁用 diab 编译器上的 integer-divide-fast 选项,在我的情况下,这会导致它在该特定文件上崩溃。

原文由 Karsten Becker 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题