CMake - 覆盖单个文件的编译标志 [英] CMake - override compile flags for single files
问题描述
我想使用一组全局标志来编译项目,这意味着在我指定的顶层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_FLAGS
1 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屋!