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

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

问题描述

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


$ b

, in which neither worked.

最后,我尝试删除这个定义:

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.

您应该能够通过执行

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.

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

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