bazelbuild / bazel

a fast, scalable, multi-language and extensible build system
https://bazel.build
Apache License 2.0
23.24k stars 4.08k forks source link

Bazel parse_headers feature is incompatible with C copts #23460

Open davidben opened 2 months ago

davidben commented 2 months ago

Description of the bug:

When the parse_headers feature is enabled, Bazel tries to build headers standalone. It seems to always do so in C++ mode. While C headers are broadly expected to build as C++, Bazel's other bugs mean that a Bazel target may not be able to build with C++ mode.

In particular, C and C++ copts values are not the same. Flags like -std=c11 only work in C mode, and some warnings like -Wmissing-prototypes do not work in C++. Passing those to C++ mode causes the build to fail. Unfortunately, because Bazel lacks conlyopts at the build rule level, Bazel projects that involve C are forced to carefully split their projects into C and C++ targets, so that the C-specific copts go to the C targets. See https://github.com/bazelbuild/bazel/issues/22041 for details.

parse_headers breaks this workaround because there is no such thing as a C target in Bazel. Once that feature is enabled, every target contains some C++ by virtue of needing to parse the headers.

Which category does this issue belong to?

C++ Rules

What's the simplest, easiest way to reproduce this bug? Please provide a minimal example if possible.

$ cat MODULE.bazel
module(name = "test")
$ cat BUILD.bazel 
package(features = ["parse_headers"])

cc_library(
    name = "foo",
    srcs = ["foo.c"],
    hdrs = ["foo.h"],
    copts = [
        "-Wall",
        "-Werror",
        "-std=c11",
    ],
)
$ cat foo.h
#ifndef FOO_H_
#define FOO_H_
void foo(void);
#endif
$ cat foo.c
#include "foo.h"
void foo(void) {}
$ bazelisk build ...
[...]
cc1plus: error: command-line option '-std=c11' is valid for C/ObjC but not for C++ [-Werror]
cc1plus: all warnings being treated as errors
[...]
ERROR: Build did NOT complete successfully

Which operating system are you running Bazel on?

Linux

What is the output of bazel info release?

release 7.3.1

If bazel info release returns development version or (@non-git), tell us how you built Bazel.

No response

What's the output of git remote get-url origin; git rev-parse HEAD ?

n/a

If this is a regression, please try to identify the Bazel commit where the bug was introduced with bazelisk --bisect.

While not introduced by this, https://github.com/bazelbuild/bazel/issues/21561 made the issue more visible. (Before, it seems we thought we were enabling parse_headers but actually were not.)

Have you found anything relevant by searching the web?

No response

Any other information, logs, or outputs that you want to share?

No response

fmeum commented 2 months ago

I started to work on a fix in https://github.com/bazelbuild/bazel/pull/22971 a while back. If anybody wants to pick it up and complete it, I'm happy to help.

davidben commented 2 months ago

TBH the ideal for us would be if https://github.com/bazelbuild/bazel/issues/22041 were solved. I spent much of the day chasing after weird build issues that all stemmed from the compounding effects of us needing to work around that core Bazel problem. All other build systems that BoringSSL has to support at Google recognize that C and C++ are different languages and configure their flags separately.