与这个问题略有关系,但并不相同。
在 Arch Linux 上使用 clang 7.0.1。我喜欢干净的代码,所以我想启用所有警告并将它们视为错误。
问题是我的构建中有一些自动生成的文件并非没有警告,例如:
生成/foo.h
inline void foo(int unused) { // warning: unused parameter 'unused'
}
生成/foo.cc
#include "foo.h"
// There is actual code here, but it doesn't matter.
由于这些文件是由第三方工具生成的,因此我无法轻松修改它们,因此我使用-isystem
来抑制来自generated
目录的所有警告。
我还有一个依赖于生成的主文件:
main.cc
#include "foo.h"
int main() {
foo(42);
}
使用 gcc,即使启用了所有警告,我也可以很好地编译它。
$ g++ -Wall -Wextra -pedantic -Werror -isystem generated -omain main.cc generated/foo.cc
但是,使用clang,它无法编译generated/foo.cc
:
$ clang++ -Wall -Wextra -pedantic -Werror -isystem generated -omain main.cc generated/foo.cc
In file included from generated/foo.cc:1:
generated/foo.h:1:21: error: unused parameter 'unused'
[-Werror,-Wunused-parameter]
inline void foo(int unused) {
^
1 error generated.
添加--system-header-prefix
无济于事:
$ clang++ -Wall -Wextra -pedantic -Werror -isystem generated --system-header-prefix=generated/ -omain main.cc generated/foo.cc
In file included from generated/foo.cc:1:
generated/foo.h:1:21: error: unused parameter 'unused'
[-Werror,-Wunused-parameter]
inline void foo(int unused) {
^
1 error generated.
有用的是将#include "foo.h"
替换为生成的("请勿修改")代码中的#include <foo.h>
。这几乎不是一个正确的修复,但它提供了一个线索:我怀疑 clang 以某种方式在当前目录中查找foo.h
.
而不是扫描包含路径,当然.
没有标记为系统包含目录。
这实际上几乎是有据可查的:
如果将包含文件视为系统头,则查找相对于当前目录的文件的
#include
指令将被视为包含系统头。
但是,它没有说明如果包含文件根本不是标头会发生什么。
我能想到的解决方法,没有一个是好的:
在编译之前对生成的文件进行后处理。 例如,通过添加
#pragma clang system_header
.丑陋,而且以一种非常便携的方式很难做到。摆弄生成系统 CMake,以便在编译生成的
.cc
文件时不启用警告。但这可能意味着我必须为它们添加一个单独的目标,这意味着要么复制大量标志和配置,要么复制 DRY 但更复杂的CMakeLists.txt
。
我宁愿设置正确的标志,就像 gcc 一样。这可能吗?
我低估了CMake;这不会增加很多混乱:
set_source_files_properties(generated/foo.cc PROPERTIES COMPILE_FLAGS -w)