如何禁用 Bazel 中的 C/C++ `-Werror` 构建错误? (又名:如何关闭已由 `-Wall -Werror` 打开的特定警告)

How can I disable a C/C++ `-Werror` build error in Bazel? (AKA: how to turn OFF specific warnings already turned on by `-Wall -Werror`)

构建时出现以下错误:

...has undefined behavior [-Werror,-Wundefined-reinterpret-cast]

Bazel 构建完全停止,因为此 clang (llvm compiler) -Wundefined-reinterpret-cast warning-Werror 转换为构建错误。

尽管出现此构建错误,我如何强制构建继续并生成二进制可执行文件?

请注意,我的 bazel 构建命令具有以下形式:

time bazel build //my/src/...

答案是使用-Wno-error=<name>构建标志,as described by gcc here(注意clang的选项仿照gcc):

-Werror=

Make the specified warning into an error. The specifier for a warning is appended; for example -Werror=switch turns the warnings controlled by -Wswitch into errors. This switch takes a negative form, to be used to negate -Werror for specific warnings; for example -Wno-error=switch makes -Wswitch warnings not be errors, even when -Werror is in effect.

The warning message for each controllable warning includes the option that controls the warning. That option can then be used with -Werror= and -Wno-error= as described above.

来源:https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html(强调已添加)。

因此,对于这种情况,添加构建选项 -Wno-error=undefined-reinterpret-cast 以关闭 -Werror=undefined-reinterpret-cast 标志。

在 Bazel 中,您可以使用 --copt="<flag>" 选项传递 C/C++ 构建选项(参见 here) (see also the --per_file_copt option (see here and here)),在这种情况下,最终命令如下所示:

time bazel build --copt="-Wno-error=undefined-reinterpret-cast" //my/src/...

这行得通! Bazel 构建现在运行完成,再次仅将这些问题显示为警告(注意现在警告语句中缺少 -Werror):

...has undefined behavior [-Wundefined-reinterpret-cast]

请注意,如果您需要一次传递多个构建标志,请多次调用 --copt=。例如:

time bazel build --copt="-Wno-error=undefined-reinterpret-cast" \
--copt="-Wno-error=switch" --copt="-ggdb" --copt="-O0" //my/src/...

注意:永远不要在生产代码上为 potentially-serious 这样的警告执行此操作(例如:未定义的行为)。对于更多良性警告,如果您确实需要禁用警告,这是正确的技术。对于未定义的行为,这应该只是为了学习。请参阅此答案下方的评论。

更多阅读:

  1. 我在我的 eRCaGuy_hello_world repo under the section titled "Additional C and C++ build notes (ex: w/gcc or clang compilers)", here 中记录了很多上述信息以及更多信息。阅读此处了解更多信息。
  2. [我仍然需要尝试和测试它] https://nelkinda.com/blog/suppress-warnings-in-gcc-and-clang/ - 参见 esp。 “3.3 通过控制诊断堆栈来抑制警告”一节。了解 enable/disable GCC 和 Clang 编译器警告和选项,仅适用于某些文件或代码部分。考虑将必要的 #pragma 语句放在头文件 #include 语句的上方和下方,以仅影响这些文件。