diff --git a/tools/cpp/BUILD.tpl b/tools/cpp/BUILD.tpl index f99995d2b923eb..40e3f7a1ef1577 100644 --- a/tools/cpp/BUILD.tpl +++ b/tools/cpp/BUILD.tpl @@ -113,6 +113,7 @@ cc_toolchain_config( coverage_compile_flags = [%{coverage_compile_flags}], coverage_link_flags = [%{coverage_link_flags}], supports_start_end_lib = %{supports_start_end_lib}, + extra_flags_per_feature = %{extra_flags_per_feature}, ) # Android tooling requires a default toolchain for the armeabi-v7a cpu. diff --git a/tools/cpp/unix_cc_configure.bzl b/tools/cpp/unix_cc_configure.bzl index ef8b8b49fb6fc8..72910ec4d8d57a 100644 --- a/tools/cpp/unix_cc_configure.bzl +++ b/tools/cpp/unix_cc_configure.bzl @@ -541,6 +541,22 @@ def configure_unix_toolchain(repository_ctx, cpu_value, overriden_tools): builtin_include_directories, paths["@bazel_tools//tools/cpp:generate_system_module_map.sh"], )) + extra_flags_per_feature = {} + if is_clang: + # Only supported by LLVM 14 and later, but required with C++20 and + # layering_check as C++ modules are the default. + # https://github.com/llvm/llvm-project/commit/0556138624edf48621dd49a463dbe12e7101f17d + result = repository_ctx.execute([ + cc, + "-Xclang", + "-fno-cxx-modules", + "-o", + "/dev/null", + "-c", + str(repository_ctx.path("tools/cpp/empty.cc")), + ]) + if "-fno-cxx-modules" not in result.stderr: + extra_flags_per_feature["use_module_maps"] = ["-Xclang", "-fno-cxx-modules"] write_builtin_include_directory_paths(repository_ctx, cc, builtin_include_directories) repository_ctx.template( @@ -696,5 +712,6 @@ def configure_unix_toolchain(repository_ctx, cpu_value, overriden_tools): "%{coverage_compile_flags}": coverage_compile_flags, "%{coverage_link_flags}": coverage_link_flags, "%{supports_start_end_lib}": "True" if gold_or_lld_linker_path else "False", + "%{extra_flags_per_feature}": repr(extra_flags_per_feature), }, ) diff --git a/tools/cpp/unix_cc_toolchain_config.bzl b/tools/cpp/unix_cc_toolchain_config.bzl index 5a0cd710575076..61f656116cbdd1 100644 --- a/tools/cpp/unix_cc_toolchain_config.bzl +++ b/tools/cpp/unix_cc_toolchain_config.bzl @@ -36,7 +36,7 @@ def _target_os_version(ctx): xcode_config = ctx.attr._xcode_config[apple_common.XcodeVersionConfig] return xcode_config.minimum_os_for_platform_type(platform_type) -def layering_check_features(compiler, is_macos): +def layering_check_features(compiler, extra_flags_per_feature, is_macos): if compiler != "clang": return [] return [ @@ -58,7 +58,7 @@ def layering_check_features(compiler, is_macos): "-fmodule-name=%{module_name}", ] + (["-Xclang"] if is_macos else []) + [ "-fmodule-map-file=%{module_map_file}", - ], + ] + extra_flags_per_feature.get("use_module_maps", []), ), ], ), @@ -1489,7 +1489,7 @@ def _impl(ctx): unfiltered_compile_flags_feature, treat_warnings_as_errors_feature, archive_param_file_feature, - ] + layering_check_features(ctx.attr.compiler, is_macos = False) + ] + layering_check_features(ctx.attr.compiler, ctx.attr.extra_flags_per_feature, is_macos = False) else: # macOS artifact name patterns differ from the defaults only for dynamic # libraries. @@ -1530,7 +1530,7 @@ def _impl(ctx): treat_warnings_as_errors_feature, archive_param_file_feature, generate_linkmap_feature, - ] + layering_check_features(ctx.attr.compiler, is_macos = True) + ] + layering_check_features(ctx.attr.compiler, ctx.attr.extra_flags_per_feature, is_macos = True) parse_headers_action_configs, parse_headers_features = parse_headers_support( parse_headers_tool_path = ctx.attr.tool_paths.get("parse_headers"), @@ -1583,6 +1583,7 @@ cc_toolchain_config = rule( "coverage_link_flags": attr.string_list(), "supports_start_end_lib": attr.bool(), "builtin_sysroot": attr.string(), + "extra_flags_per_feature": attr.string_list_dict(), "_xcode_config": attr.label(default = configuration_field( fragment = "apple", name = "xcode_config_label",