Enable setting C/C++ standards as a toolchain feature
- Dominant language
- Java
- Stars
- 25.8k
- Forks
- 4.6k
- Avg merge
- 2d 20h
- Merged PRs (30d)
- 72
Description
### Description of the feature request:
Proposal to add a handful of new "features" to the default c++ toolchain that enables setting C/C++ standards (names tentative):
- default_cxx_standard (respects `BAZEL_CXXOPTS`, default `-std=c++0x`)
- cxx14_standard
- cxx17_standard
- etc...
I've got an initial implementation of this capability that currently works on linux & macos, and does not break backwards compatibility:
https://github.com/bazelbuild/bazel/pull/16552
I'd like to get some feedback from the Bazel team on if it's possible to get this merged before doing whatever else is necessary to meet the contribution requirements (design docs, testing, etc...).
### What underlying problem are you trying to solve with this feature?
The original issue I was trying to solve was to get some code to build with bazel that mixes C/C++ code in the same target:
```starlark
cc_library(
name = "example",
srcs = [
"src/foo.cpp", # requires compiling with C++14
"src/bar.c"
],
copts = [
"-Werror",
"-std=c++14",
]
)
```
It's currently not possible to build that target with Bazel. This is because there's no way to distinguish between C and C++ flags at the `cc_*` rules level. The compiler will issue a warning when `-std=c++14` is passed while compiling the C file, and -Werror will cause that warning to be propagated as a build error.
There are various alternatives but none of them are desirable:
- Using BAZEL_CXXOPTS: Not able to control the standard at the target level, no equivalent for setting the C standard
- Using --cxxopts/--copts at the command line: Also doesn't allow setting at the target level.
- Splitting the code up into mutliple targets (one for the C portions, and one for the C++ portions). The build system should be flexible/powerful enough for developers to decide how they would like to structure their build/targets.
- Writing a custom toolchain that implements the desired feature - Writing a custom toolchain is a big commitment with many other implications.
I think that the most elegant solution to this problem is to just expose a new set of features in the default toolchain that allow setting the standard. The features API enables distinguishing between C/C++ actions and avoids the scope issues above. Every target can mix and match C/C++ and decide the standard for each.
The POC branch I've linked shows that it should be possible to do this without breaking backwards compatibility of existing behavior, assuming that the order of flags is not part of the API.
### Which operating system are you running Bazel on?
Windows, Linux, and Mac
### What is the output of `bazel info release`?
5.3.2
### 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 master; git rev-parse HEAD` ?
_No response_
### Have you found anything relevant by searching the web?
Lots of research, still prefer my suggestion above.
### Any other information, logs, or outputs that you want to share?
_No response_
Contributor guide
Research direction
Start with the linked PR 16552 and the default C++ toolchain's features API, then reproduce the mixed cc_library example described here on Linux, macOS, and Windows. Done means C and C++ standards can be selected independently at target level without breaking existing behavior, with the required design and tests completed.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c, cpp
- Domain
- build-system, compilers
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 30/100