diff --git a/.bazelrc b/.bazelrc index 1acff8b9f..29c13b257 100644 --- a/.bazelrc +++ b/.bazelrc @@ -1,2 +1,3 @@ # Required by googletest 1.17. common --cxxopt=-std=c++17 +common --incompatible_autoload_externally=+@rules_cc diff --git a/cc/private/rules_impl/cc_toolchain.bzl b/cc/private/rules_impl/cc_toolchain.bzl index 16c13ea9b..2db25f37d 100644 --- a/cc/private/rules_impl/cc_toolchain.bzl +++ b/cc/private/rules_impl/cc_toolchain.bzl @@ -19,6 +19,9 @@ load("//cc/common:cc_helper.bzl", "cc_helper") load("//cc/common:semantics.bzl", "semantics") load("//cc/private/rules_impl/fdo:fdo_context.bzl", "create_fdo_context") load("//cc/toolchains:cc_toolchain_config_info.bzl", "CcToolchainConfigInfo") +load("//cc/toolchains:cc_toolchain_info.bzl", "ToolConfigInfo") +load("//cc/toolchains/impl:collect.bzl", "collect_action_types") +load("//cc/toolchains/impl:toolchain_config.bzl", "CC_TOOLCHAIN_CONFIG_PUBLIC_ATTRS", "cc_toolchain_config_impl_helper") load(":cc_toolchain_provider_helper.bzl", "get_cc_toolchain_provider") ToolchainInfo = platform_common.ToolchainInfo @@ -74,6 +77,38 @@ def _single_file(ctx, attr_name): return files[0] return None +# Taken from https://bazel.build/docs/cc-toolchain-config-reference#actions +# TODO: This is best-effort. Update this with the correct file groups once we +# work out what actions correspond to what file groups. +LEGACY_FILE_GROUPS = { + "ar_files": [ + Label("//cc/toolchains/actions:ar_actions"), + ], + "as_files": [ + Label("//cc/toolchains/actions:assembly_actions"), + ], + "compiler_files": [ + Label("//cc/toolchains/actions:cc_flags_make_variable"), + Label("//cc/toolchains/actions:c_compile"), + Label("//cc/toolchains/actions:cpp_compile"), + Label("//cc/toolchains/actions:cpp_header_parsing"), + ], + # There are no actions listed for coverage and objcopy in action_names.bzl. + "coverage_files": [], + "dwp_files": [ + Label("//cc/toolchains/actions:dwp"), + ], + "linker_files": [ + Label("//cc/toolchains/actions:cpp_link_dynamic_library"), + Label("//cc/toolchains/actions:cpp_link_nodeps_dynamic_library"), + Label("//cc/toolchains/actions:cpp_link_executable"), + ], + "objcopy_files": [], + "strip_files": [ + Label("//cc/toolchains/actions:strip"), + ], +} + def _attributes(ctx): grep_includes = None if not semantics.is_bazel: @@ -81,42 +116,72 @@ def _attributes(ctx): latebound_libc = _latebound_libc(ctx, "libc_top", "_libc_top") - all_files = _files(ctx, "all_files") + if ctx.attr.toolchain_config: + for key in CC_TOOLCHAIN_CONFIG_PUBLIC_ATTRS.keys(): + if getattr(ctx.attr, key): + fail("Must not pass %s when passing `toolchain_config`" % key) + + cc_toolchain_config_info = ctx.attr.toolchain_config[CcToolchainConfigInfo] + all_files = _files(ctx, "all_files") + + legacy_file_groups = { + "as_files": _files(ctx, "as_files"), + "ar_files": _files(ctx, "ar_files"), + "dwp_files": _files(ctx, "dwp_files"), + "compiler_files": _files(ctx, "compiler_files"), + "strip_files": _files(ctx, "strip_files"), + "objcopy_files": _files(ctx, "objcopy_files"), + "coverage_files": _files(ctx, "coverage_files") or all_files, + } + + linker_files = _files(ctx, "linker_files") + + else: + if not ctx.attr.tool_map: + fail("Must pass `tool_map` when not passing `toolchain_config`") + toolchain_config_info, cc_toolchain_config_info = cc_toolchain_config_impl_helper(ctx) + + legacy_file_groups = {} + for group, actions in LEGACY_FILE_GROUPS.items(): + legacy_file_groups[group] = depset(transitive = [ + toolchain_config_info.files[action] + for action in collect_action_types(actions).to_list() + if action in toolchain_config_info.files + ]) + + all_files = depset(transitive = [legacy_file_groups.values()]) + legacy_file_groups["coverage_files"] = legacy_file_groups["coverage_files"] or all_files + linker_files = legacy_file_groups.pop("linker_files") + return struct( supports_param_files = ctx.attr.supports_param_files, runtime_solib_dir_base = "_solib__" + cc_common.escape_label(label = ctx.label), - cc_toolchain_config_info = _provider(ctx.attr.toolchain_config, CcToolchainConfigInfo), + cc_toolchain_config_info = cc_toolchain_config_info, static_runtime_lib = ctx.attr.static_runtime_lib, dynamic_runtime_lib = ctx.attr.dynamic_runtime_lib, supports_header_parsing = ctx.attr.supports_header_parsing, all_files = all_files, - compiler_files = _files(ctx, "compiler_files"), - strip_files = _files(ctx, "strip_files"), - objcopy_files = _files(ctx, "objcopy_files"), link_dynamic_library_tool = ctx.file._link_dynamic_library_tool, grep_includes = grep_includes, aggregate_ddi = _single_file(ctx, "_aggregate_ddi"), generate_modmap = _single_file(ctx, "_generate_modmap"), module_map = ctx.attr.module_map, - as_files = _files(ctx, "as_files"), - ar_files = _files(ctx, "ar_files"), - dwp_files = _files(ctx, "dwp_files"), module_map_artifact = _single_file(ctx, "module_map"), - all_files_including_libc = depset(transitive = [_files(ctx, "all_files"), _files(ctx, latebound_libc)]), + all_files_including_libc = depset(transitive = [all_files, _files(ctx, latebound_libc)]), zipper = ctx.file._zipper, linker_files = _full_inputs_for_link( ctx, - _files(ctx, "linker_files"), + linker_files, _files(ctx, latebound_libc), ), cc_toolchain_label = ctx.label, - coverage_files = _files(ctx, "coverage_files") or all_files, compiler_files_without_includes = _files(ctx, "compiler_files_without_includes"), libc = _files(ctx, latebound_libc), libc_top_label = _label(ctx, latebound_libc), if_so_builder = ctx.file._interface_library_builder, allowlist_for_layering_check = _package_specification_provider(ctx, "disabling_parse_headers_and_layering_check_allowed"), build_info_files = _provider(ctx.attr._build_info_translator, OutputGroupInfo), + **legacy_file_groups ) def _cc_toolchain_impl(ctx): @@ -200,7 +265,6 @@ crosstool_config.toolchain. ), "all_files": attr.label( allow_files = True, - mandatory = True, doc = """ Collection of all cc_toolchain artifacts. These artifacts will be added as inputs to all rules_cc related actions (with the exception of actions that are using more precise sets of @@ -214,7 +278,6 @@ rules using C++ toolchain.

""", ), "compiler_files": attr.label( allow_files = True, - mandatory = True, doc = """ Collection of all cc_toolchain artifacts required for compile actions.""", ), @@ -226,13 +289,11 @@ input discovery is supported (currently Google-only).""", ), "strip_files": attr.label( allow_files = True, - mandatory = True, doc = """ Collection of all cc_toolchain artifacts required for strip actions.""", ), "objcopy_files": attr.label( allow_files = True, - mandatory = True, doc = """ Collection of all cc_toolchain artifacts required for objcopy actions.""", ), @@ -248,13 +309,11 @@ Collection of all cc_toolchain artifacts required for archiving actions.""", ), "linker_files": attr.label( allow_files = True, - mandatory = True, doc = """ Collection of all cc_toolchain artifacts required for linking actions.""", ), "dwp_files": attr.label( allow_files = True, - mandatory = True, doc = """ Collection of all cc_toolchain artifacts required for dwp actions.""", ), @@ -307,7 +366,6 @@ Set to True when cc_toolchain supports header parsing actions.""", ), "toolchain_config": attr.label( allow_files = False, - mandatory = True, providers = [CcToolchainConfigInfo], doc = """ The label of the rule providing cc_toolchain_config_info.""", @@ -340,5 +398,12 @@ The label of the rule providing cc_toolchain_config_info.""", default = semantics.BUILD_INFO_TRANLATOR_LABEL, providers = [OutputGroupInfo], ), + } | CC_TOOLCHAIN_CONFIG_PUBLIC_ATTRS | { + # Override tool_map to make it optional. + "tool_map": attr.label( + cfg = "exec", + providers = [ToolConfigInfo], + ), + "_builtin_features": attr.label(default = "//cc/toolchains/features:all_builtin_features"), } | semantics.cpp_modules_tools(), # buildifier: disable=unsorted-dict-items ) diff --git a/cc/toolchains/BUILD b/cc/toolchains/BUILD index 5ebf9c8f3..365b3fef2 100644 --- a/cc/toolchains/BUILD +++ b/cc/toolchains/BUILD @@ -22,12 +22,15 @@ bzl_library( "//cc:action_names_bzl", "//cc:cc_toolchain_config_lib_bzl", "//cc:find_cc_toolchain_bzl", + "//cc/common:cc_helper_bzl", + "//cc/common:semantics_bzl", "//cc/private:paths_bzl", "//cc/private/rules_impl:cc_flags_supplier_lib_bzl", "//cc/private/rules_impl:native_bzl", "//cc/private/rules_impl:toolchain_rules", "//cc/private/rules_impl/fdo:fdo_rules", "//cc/toolchains/impl:toolchain_impl_rules", + "@bazel_features//:features", "@bazel_skylib//rules/directory:glob", "@cc_compatibility_proxy//:proxy_bzl", ], diff --git a/cc/toolchains/cc_toolchain_info.bzl b/cc/toolchains/cc_toolchain_info.bzl index 38148b463..3f2ae55b4 100644 --- a/cc/toolchains/cc_toolchain_info.bzl +++ b/cc/toolchains/cc_toolchain_info.bzl @@ -18,6 +18,7 @@ # Once it's stabilized, we *may* consider opening up parts of the API, or we may # decide to just require users to use the public user-facing rules. visibility([ + "//cc/private/rules_impl/...", "//cc/toolchains/...", "//tests/rule_based_toolchain/...", ]) diff --git a/cc/toolchains/impl/collect.bzl b/cc/toolchains/impl/collect.bzl index 671bb65b4..de06c8791 100644 --- a/cc/toolchains/impl/collect.bzl +++ b/cc/toolchains/impl/collect.bzl @@ -22,6 +22,7 @@ load( ) visibility([ + "//cc/private/rules_impl/...", "//cc/toolchains/...", "//tests/rule_based_toolchain/...", ]) diff --git a/cc/toolchains/impl/toolchain_config.bzl b/cc/toolchains/impl/toolchain_config.bzl index 1f6efefe5..0057c0f1f 100644 --- a/cc/toolchains/impl/toolchain_config.bzl +++ b/cc/toolchains/impl/toolchain_config.bzl @@ -29,6 +29,7 @@ load(":legacy_converter.bzl", "convert_toolchain") load(":toolchain_config_info.bzl", "toolchain_config_info") visibility([ + "//cc/private/rules_impl/...", "//cc/toolchains/...", "//tests/rule_based_toolchain/...", ]) @@ -50,7 +51,14 @@ cc_legacy_file_group = rule( }, ) -def _cc_toolchain_config_impl(ctx): +def cc_toolchain_config_impl_helper(ctx): + """Main implementation for _cc_toolchain_config_impl, reused for rules-based toolchains + + Args: + ctx: Rule context + Returns: + toolchain_config_info and cc_toolchain_config_info providers""" + if ctx.attr.features: fail("Features is a reserved attribute in bazel. Did you mean 'known_features' or 'enabled_features'?") @@ -66,7 +74,7 @@ def _cc_toolchain_config_impl(ctx): legacy = convert_toolchain(toolchain_config) - return [ + return ( toolchain_config, cc_common.create_cc_toolchain_config_info( ctx = ctx, @@ -90,6 +98,13 @@ def _cc_toolchain_config_impl(ctx): abi_version = "", abi_libc_version = "", ), + ) + +def _cc_toolchain_config_impl(ctx): + toolchain_config, cc_toolchain_config_info = cc_toolchain_config_impl_helper(ctx) + return [ + toolchain_config, + cc_toolchain_config_info, # This allows us to support all_files. # If all_files was simply an alias to # //cc/toolchains/actions:all_actions, @@ -98,19 +113,21 @@ def _cc_toolchain_config_impl(ctx): DefaultInfo(files = depset(transitive = toolchain_config.files.values())), ] +CC_TOOLCHAIN_CONFIG_PUBLIC_ATTRS = { + # Attributes new to this rule. + "compiler": attr.string(default = ""), + "cpu": attr.string(default = ""), + "tool_map": attr.label(providers = [ToolConfigInfo], mandatory = True), + "args": attr.label_list(providers = [ArgsListInfo]), + "known_features": attr.label_list(providers = [FeatureSetInfo]), + "enabled_features": attr.label_list(providers = [FeatureSetInfo]), + "artifact_name_patterns": attr.label_list(providers = [ArtifactNamePatternInfo]), + "make_variables": attr.label_list(providers = [MakeVariableInfo]), +} + cc_toolchain_config = rule( implementation = _cc_toolchain_config_impl, - # @unsorted-dict-items - attrs = { - # Attributes new to this rule. - "compiler": attr.string(default = ""), - "cpu": attr.string(default = ""), - "tool_map": attr.label(providers = [ToolConfigInfo], mandatory = True), - "args": attr.label_list(providers = [ArgsListInfo]), - "known_features": attr.label_list(providers = [FeatureSetInfo]), - "enabled_features": attr.label_list(providers = [FeatureSetInfo]), - "artifact_name_patterns": attr.label_list(providers = [ArtifactNamePatternInfo]), - "make_variables": attr.label_list(providers = [MakeVariableInfo]), + attrs = CC_TOOLCHAIN_CONFIG_PUBLIC_ATTRS | { "_builtin_features": attr.label(default = "//cc/toolchains/features:all_builtin_features"), }, provides = [ToolchainConfigInfo], diff --git a/cc/toolchains/toolchain.bzl b/cc/toolchains/toolchain.bzl index fa41163ab..8fb3dbe84 100644 --- a/cc/toolchains/toolchain.bzl +++ b/cc/toolchains/toolchain.bzl @@ -13,6 +13,8 @@ # limitations under the License. """Implementation of the cc_toolchain rule.""" +load("@bazel_features//private:util.bzl", _bazel_version_ge = "ge") +load("//cc/private/rules_impl:cc_toolchain.bzl", "LEGACY_FILE_GROUPS") load("//cc/toolchains:cc_toolchain.bzl", _cc_toolchain = "cc_toolchain") load( "//cc/toolchains/impl:toolchain_config.bzl", @@ -22,38 +24,6 @@ load( visibility("public") -# Taken from https://bazel.build/docs/cc-toolchain-config-reference#actions -# TODO: This is best-effort. Update this with the correct file groups once we -# work out what actions correspond to what file groups. -_LEGACY_FILE_GROUPS = { - "ar_files": [ - Label("//cc/toolchains/actions:ar_actions"), - ], - "as_files": [ - Label("//cc/toolchains/actions:assembly_actions"), - ], - "compiler_files": [ - Label("//cc/toolchains/actions:cc_flags_make_variable"), - Label("//cc/toolchains/actions:c_compile"), - Label("//cc/toolchains/actions:cpp_compile"), - Label("//cc/toolchains/actions:cpp_header_parsing"), - ], - # There are no actions listed for coverage and objcopy in action_names.bzl. - "coverage_files": [], - "dwp_files": [ - Label("//cc/toolchains/actions:dwp"), - ], - "linker_files": [ - Label("//cc/toolchains/actions:cpp_link_dynamic_library"), - Label("//cc/toolchains/actions:cpp_link_nodeps_dynamic_library"), - Label("//cc/toolchains/actions:cpp_link_executable"), - ], - "objcopy_files": [], - "strip_files": [ - Label("//cc/toolchains/actions:strip"), - ], -} - def cc_toolchain( *, name, @@ -161,9 +131,40 @@ def cc_toolchain( **kwargs: [common attributes](https://bazel.build/reference/be/common-definitions#common-attributes) that should be applied to all rules created by this macro. """ + cc_toolchain_visibility = kwargs.pop("visibility", default = None) - for group in _LEGACY_FILE_GROUPS: + if _bazel_version_ge("9.0.0-pre.20250911"): + _cc_toolchain( + name = name, + tool_map = tool_map, + args = args, + artifact_name_patterns = artifact_name_patterns, + make_variables = make_variables, + known_features = known_features, + enabled_features = enabled_features, + compiler = compiler, + cpu = select({ + Label("//cc/toolchains/impl:darwin_aarch64"): "darwin_arm64", + Label("//cc/toolchains/impl:darwin_x86_64"): "darwin_x86_64", + Label("//cc/toolchains/impl:linux_aarch64"): "aarch64", + Label("//cc/toolchains/impl:linux_x86_64"): "k8", + Label("//cc/toolchains/impl:windows_x86_32"): "win32", + Label("//cc/toolchains/impl:windows_x86_64"): "win64", + "//conditions:default": "", + }), + dynamic_runtime_lib = dynamic_runtime_lib, + libc_top = libc_top, + module_map = module_map, + static_runtime_lib = static_runtime_lib, + supports_header_parsing = supports_header_parsing, + supports_param_files = supports_param_files, + visibility = cc_toolchain_visibility, + **kwargs + ) + return + + for group in LEGACY_FILE_GROUPS: if group in kwargs: fail("Don't use legacy file groups such as %s. Instead, associate files with `cc_tool` or `cc_args` rules." % group) @@ -192,7 +193,7 @@ def cc_toolchain( # Provides ar_files, compiler_files, linker_files, ... legacy_file_groups = {} - for group, actions in _LEGACY_FILE_GROUPS.items(): + for group, actions in LEGACY_FILE_GROUPS.items(): group_name = "_{}_{}".format(name, group) cc_legacy_file_group( name = group_name, diff --git a/examples/rule_based_toolchain/.bazelversion b/examples/rule_based_toolchain/.bazelversion index b26a34e47..5c9df55c0 100644 --- a/examples/rule_based_toolchain/.bazelversion +++ b/examples/rule_based_toolchain/.bazelversion @@ -1 +1 @@ -7.2.1 +9.0.0rc3 \ No newline at end of file diff --git a/tests/rule_based_toolchain/toolchain_config/BUILD b/tests/rule_based_toolchain/toolchain_config/BUILD index 08b5f8380..4a83f1826 100644 --- a/tests/rule_based_toolchain/toolchain_config/BUILD +++ b/tests/rule_based_toolchain/toolchain_config/BUILD @@ -6,7 +6,7 @@ load("//cc/toolchains:tool.bzl", "cc_tool") load("//cc/toolchains:tool_map.bzl", "cc_tool_map") load("//cc/toolchains/args:sysroot.bzl", "cc_sysroot") load("//cc/toolchains/impl:external_feature.bzl", "cc_external_feature") -load("//cc/toolchains/impl:toolchain_config.bzl", "cc_legacy_file_group", "cc_toolchain_config") +load("//cc/toolchains/impl:toolchain_config.bzl", "cc_toolchain_config") load("//tests/rule_based_toolchain:analysis_test_suite.bzl", "analysis_test_suite") load(":toolchain_config_test.bzl", "TARGETS", "TESTS") @@ -74,20 +74,6 @@ util.helper_target( tool_map = ":compile_tool_map", ) -util.helper_target( - cc_legacy_file_group, - name = "collects_files_c_compile", - actions = ["//tests/rule_based_toolchain/actions:c_compile"], - config = ":collects_files_toolchain_config", -) - -util.helper_target( - cc_legacy_file_group, - name = "collects_files_cpp_compile", - actions = ["//tests/rule_based_toolchain/actions:cpp_compile"], - config = ":collects_files_toolchain_config", -) - util.helper_target( cc_args, name = "compile_args", diff --git a/tests/rule_based_toolchain/toolchain_config/toolchain_config_test.bzl b/tests/rule_based_toolchain/toolchain_config/toolchain_config_test.bzl index 1047203c4..2b9b286fc 100644 --- a/tests/rule_based_toolchain/toolchain_config/toolchain_config_test.bzl +++ b/tests/rule_based_toolchain/toolchain_config/toolchain_config_test.bzl @@ -178,13 +178,6 @@ def _toolchain_collects_files_test(env, targets): tc.files().get(targets.c_compile[ActionTypeInfo]).contains_exactly(_COLLECTED_C_COMPILE_FILES) tc.files().get(targets.cpp_compile[ActionTypeInfo]).contains_exactly(_COLLECTED_CPP_COMPILE_FILES) - env.expect.that_target( - targets.collects_files_c_compile, - ).default_outputs().contains_exactly(_COLLECTED_C_COMPILE_FILES) - env.expect.that_target( - targets.collects_files_cpp_compile, - ).default_outputs().contains_exactly(_COLLECTED_CPP_COMPILE_FILES) - legacy = convert_toolchain(tc.actual) env.expect.that_collection(legacy.features).contains_exactly([ legacy_feature( @@ -263,8 +256,6 @@ TARGETS = [ "//tests/rule_based_toolchain/actions:cpp_compile", ":builtin_feature", ":compile_tool_map", - ":collects_files_c_compile", - ":collects_files_cpp_compile", ":collects_files_toolchain_config", ":compile_feature", ":c_compile_args",