覆盖单个文件的编译标志 [英] Override compile flags for single files

查看:97
本文介绍了覆盖单个文件的编译标志的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用一组全局标志来编译项目,这意味着我在顶层CMakeLists.txt文件中指定了以下内容:

I would like to use a global set of flags for compiling a project, meaning that at my top-level CMakeLists.txt file I have specified:

ADD_DEFINITIONS ( -Wall -Weffc++ -pedantic -std=c++0x )

但是,对于子目录中的特定文件(例如 foo.cpp),我想将
编译标志切换为不应用-Weffc ++(包括我无法更改的商业库)。为了简化只使用-Wall的情况,我尝试:

However, for a specific file (let's say "foo.cpp") in a subdirectory, I want to switch the compile flags to not apply -Weffc++ (included commercial library I cannot change). To simplify the situation to use only -Wall, I tried:

 SET_SOURCE_FILES_PROPERTIES( foo.cpp PROPERTIES COMPILE_FLAGS -Wall )
 ADD_EXECUTABLE( foo foo.cpp )

,这不起作用。
我也尝试过

, which did not work. I also tried

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 )

,但两者都不起作用。

最后,我尝试删除此定义:

Finally, I tried removing this defintion:

REMOVE_DEFINITIONS( -Weffc++ )
ADD_EXECUTABLE( foo foo.cpp )
ADD_DEFINITIONS( -Weffc++ )

,这也不起作用(这意味着,我收到了很多有关商业图书馆的样式警告)。
(**注意:如果在构建可执行文件后不重新包含-Weffc ++指令,则会取消警告。)

, which also did not work (meaning, I get a lot of style warnings about the commercial library). (**Note: The warnings ARE suppressed if I DO NOT re-include the -Weffc++ directive after the executable is built.)

我也暂时尝试过删除编译标志:
http://www.cmake。 org / pipermail / cmake / 2007-June / 014614.html
,但这没有帮助。

I also tried temporarily removing the compile flags: http://www.cmake.org/pipermail/cmake/2007-June/014614.html , but that didn't help.

没有一个优雅的解决方案

Is there not an elegant solution to this?

推荐答案

您的上述尝试正在为文件/目标添加更多标志,而不是像您期望的那样覆盖。例如,从源文件的属性-COMPILE_FLAGS

Your attempts above are adding further flags to your file/target rather than overwriting as you seem to expect. For example, from the docs for Properties on Source Files - COMPILE_FLAGS:


这些标志将添加到列表中

These flags will be added to the list of compile flags when this source file builds.

您应该能够对 -Weffc ++ 提出要求。

You should be able to countermand the -Weffc++ flag for foo.cpp by doing

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

这应该具有添加 -Wno-effc ++的效果在编译器命令中 -Weffc ++ 之后的中,后一种设置为准。要查看完整的命令并检查是否确实如此,您可以

This should have the effect of adding -Wno-effc++ after -Weffc++ in the compiler command, and the latter setting wins. To see the full command and check that this is indeed the case, you can do

make VERBOSE=1

顺便说一句,GNU C ++标准库的维护者之一对提出了非常负面的看法-Weffc ++ 此答案中。

As an aside, one of the maintainers of the GNU C++ Standard Library presents a pretty negative opinion on -Weffc++ in this answer.

另一点是您误用了 add_definitions 的文档,在某种意义上,您将其用于编译器标志而不是预期的预处理器定义。

Another point is that you're misusing add_definitions in the sense that you're using this for compiler flags rather than the intended preprocessor definitions.

最好使用 add_compile_options

add_compile_options(-Wall -Weffc++ -pedantic -std=c++0x)

或对于CMake版本< 3.0做更多类似的事情:

or for CMake versions < 3.0 to do something more like:

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Weffc++ -pedantic -std=c++0x")






针对以下评论中的其他问题,我相信无法可靠地删除单个文件上的标志。原因是对于任何给定的源文件,它具有 COMPILE_OPTIONS COMPILE_FLAGS 已应用其目标的 1 ,但这些未显示在该源文件的任何属性中。


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 中剥离问题标记,然后将其分别应用于目标的每个源,并根据需要从特定的源文件中将其省略。

You could look at stripping the problem flag from the target's COMPILE_OPTIONS, then applying it to each of the target's sources individually, omitting it from the specific source file as required.

但是,尽管这在许多情况下都可以使用,但是它有很多问题。

However, while this could work in many scenarios, it has a couple of problems.

第一-源文件的属性不包含 COMPILE_OPTIONS ,仅 COMPILE_FLAGS 。这是一个问题,因为目标的 COMPILE_OPTIONS 可以包含生成器表达式,但 COMPILE_FLAGS 不支持他们。因此,在搜索标志时,您必须容纳生成器表达式,实际上,如果您的标志包含在一个或多个标志中,您甚至可能必须解析生成器表达式,以查看是否应将其重新应用于其余标志源文件。

First - source files' properties don't include COMPILE_OPTIONS, only COMPILE_FLAGS. This is a problem because the COMPILE_OPTIONS of a target can include generator expressions, but COMPILE_FLAGS doesn't support them. So you'd have to accommodate generator expressions while searching for your flag, and indeed you'd maybe even have to "parse" generator expressions if your flag was contained in one or more to see whether it should be re-applied to the remaining source files.

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

Second - since CMake v3.0, targets can specify INTERFACE_COMPILE_OPTIONS. This means that a dependency of your target can add or override your target's COMPILE_OPTIONS via its INTERFACE_COMPILE_OPTIONS. So you'd further have to recursively iterate through all your target's dependencies (not a particularly easy task since the list of LINK_LIBRARIES for the target can also contain generator expressions) to find any which are applying the problem flag, and try and remove it from those targets' INTERFACE_COMPILE_OPTIONS too.

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

At this stage of complexity, I'd be looking to submit a patch to CMake to provide the functionality to remove a specific flag unconditionally from a source file.

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

1: Note that unlike the COMPILE_FLAGS property on source files, the COMPILE_FLAGS property on targets is deprecated.

这篇关于覆盖单个文件的编译标志的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆