Let the rules-based cc_toolchain be driven by a non-Xcode clang - #635
Open
AustinSchuh wants to merge 5 commits into
Open
Let the rules-based cc_toolchain be driven by a non-Xcode clang#635AustinSchuh wants to merge 5 commits into
AustinSchuh wants to merge 5 commits into
Conversation
The macro is already parameterized by tool_map and sysroot_feature, but
targeting macOS with anything other than wrapped_clang does not work:
everything behind select(//configs:apple) assumes the Xcode
configuration is the source of truth.
Most of that needs no API. The __BAZEL_* placeholders and the
STRIP_DEBUG_SYMBOLS / LINKED_BINARY= / DSYM_HINT_DSYM_PATH= sentinels
are the toolchain's argument protocol, which a consumer's tool has to
speak the way wrapped_clang does (now documented on tool_map), and
layering_check works as-is since a plain clang ignores
APPLE_SUPPORT_MODULEMAP.
What remains becomes a parameter, each defaulting to current behavior:
- target_from_xcode = False uses the "target" argument instead of
the Xcode-derived triple, for a toolchain that pins its own.
- flags_from_env = False drops the BAZEL_*OPTS features, whose
-std=c++17 default would override a toolchain's own standard and
which cannot differ between two toolchains in one workspace.
- coverage_instrumentation = False leaves the coverage-map-format
features out for a consumer that instruments from its own args,
since Bazel picks the gcc format by default.
- apple_linker_flags = False drops -no_warn_duplicate_libraries and
-reproducible, which ld64.lld only accepts from LLVM 19 on.
- extra_{enabled,known}_features and extra_include_directories as
attributes: the label_flags are global, so a repo rule stamping
out more than one toolchain cannot vary them.
- dynamic_runtime_lib / static_runtime_lib pass through to
cc_toolchain, which is how a sanitizer runtime dylib reaches a
test's runfiles.
Also make //toolchain:dynamic_toolchain_info public: the macro
references it inside the Apple branch of a select(), so an
Apple-targeting consumer fails analysis without it.
//test/... is unchanged.
Signed-off-by: Austin Schuh <austin.linux@gmail.com>
AustinSchuh
requested review from
aaronsky,
adincebic,
brentleyjones,
keith and
luispadron
as code owners
August 28, 2026 05:27
keith
reviewed
Aug 28, 2026
Two parameters turned out not to earn their keep:
- target_from_xcode is gone, along with plain_required_flags. The
-target in default_required_flags is derived from the target
platform and honors --macos_minimum_os, so it is right for a
hermetic toolchain too -- switching toolchains_llvm onto it
produced bit-identical binaries.
- apple_linker_flags is replaced by llvm_version: the consumer says
which LLVM its tools come from (None means Xcode's), and the macro
itself drops -no_warn_duplicate_libraries and -reproducible for
the versions whose ld64.lld predates them (before LLVM 19).
Also trims the parameter docstrings and drops a redundant comment, per
review.
Signed-off-by: Austin Schuh <austin.linux@gmail.com>
AustinSchuh
force-pushed
the
toolchains-llvm-prototype
branch
from
August 28, 2026 23:21
070b43f to
7ee3bb9
Compare
Signed-off-by: Austin Schuh <austin.linux@gmail.com>
AustinSchuh
force-pushed
the
toolchains-llvm-prototype
branch
from
August 29, 2026 00:09
d0f92d4 to
1a00dc0
Compare
From Clang 14 on, -std=c++20 switches the driver to C++20 modules semantics: a header covered non-textually by a module map can no longer simply be included -- "module 'X' is needed but has not been provided, and implicit use of module files is disabled". That breaks the module maps layering_check is built on; Bazel does not support C++20 modules yet. Pass -Xclang -fno-cxx-modules (and quiet the module-import-in-extern-c warning the SDK headers then trip) on the C++ compile actions whenever use_module_maps is enabled. The maps this repo's own toolchain sees are immune: wrapped_clang's generated map and the per-target maps Bazel writes are all-textual, and Xcode's clang does not switch semantics the way upstream does (verified against Apple clang 17: the repro below builds either way, while upstream 19.1.7 fails without the flag). What is not immune is a consumer driving upstream LLVM through this macro whose system module map covers its headers with umbrella directories, the way toolchains_llvm's does -- which is where this surfaced, on the first -std=c++20 compile with layering_check enabled. test/layering_check gains the repro (a non-textual module map on a C++20 compile) and command-line tests asserting the flag is emitted exactly when use_module_maps is enabled -- directly, via layering_check, and never without. The command-line tests fail if the flag is dropped; the repro additionally fails wherever the compiler follows upstream's C++20 semantics. Signed-off-by: Austin Schuh <austin.linux@gmail.com>
Drops coverage_instrumentation. Bazel's contract is the gcc format by default and the llvm one under --experimental_use_llvm_covmap; clang emits both, and a consumer's tool_map carries the collection side (llvm-cov and llvm-profdata) for the llvm format. The coverage feature lists revert to exactly what they were. Signed-off-by: Austin Schuh <austin.linux@gmail.com>
Contributor
Author
|
OK, everything should now be good to go. I pulled in a couple of the flags from toolchains_llvm up here where they seemed better. Happy to push those back into toolchains_llvm if you would prefer. Thanks Keith! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The macro is already parameterized by tool_map and sysroot_feature, but targeting macOS with anything other than wrapped_clang does not work: everything behind select(//configs:apple) assumes the Xcode configuration is the source of truth.
Most of that needs no API. The _BAZEL* placeholders and the STRIP_DEBUG_SYMBOLS / LINKED_BINARY= / DSYM_HINT_DSYM_PATH= sentinels are the toolchain's argument protocol, which a consumer's tool has to speak the way wrapped_clang does (now documented on tool_map), and layering_check works as-is since a plain clang ignores APPLE_SUPPORT_MODULEMAP.
What remains becomes a parameter, each defaulting to current behavior:
Also make //toolchain:dynamic_toolchain_info public: the macro references it inside the Apple branch of a select(), so an Apple-targeting consumer fails analysis without it.
//test/... is unchanged.