Cut cc_common dependencies from split build rules. Once we switch to deferred implementation, this will reduce the impact of changes transitively affecting cc_common and similar files (i.e. a change affecting cc_common will affect java rules importing rules_cc but not affect every cc_binary in the repo). The rules whose declaration/definition have been split will now no longer transitively depend on cc_common or cc_helper; this requires splitting find_cc toolchain and cc_postmark, as well as moving a function that's used only in cc_shared_library out of cc_helper. The side of find_cc_toolchain and cc_postmark that still needs cc_common also loads the more lightweight side, making this change a no-op for any files not included in the change. PiperOrigin-RevId: 875149689 Change-Id: I71b5cf5575b02cf9a8def11fb2a20d1624567979
diff --git a/cc/BUILD b/cc/BUILD index d32c646..a1d973b 100644 --- a/cc/BUILD +++ b/cc/BUILD
@@ -84,7 +84,10 @@ bzl_library( name = "find_cc_toolchain_bzl", - srcs = ["find_cc_toolchain.bzl"], + srcs = [ + "find_cc_toolchain.bzl", + "use_cc_toolchain.bzl", + ], visibility = ["//visibility:public"], deps = [ "//cc/common", @@ -128,7 +131,10 @@ bzl_library( name = "cc_postmark_bzl", - srcs = ["cc_postmark.bzl"], + srcs = [ + "cc_postmark.bzl", + "cc_postmark_initializers.bzl", + ], visibility = ["//visibility:public"], )
diff --git a/cc/cc_postmark_initializers.bzl b/cc/cc_postmark_initializers.bzl new file mode 100644 index 0000000..afb8aff --- /dev/null +++ b/cc/cc_postmark_initializers.bzl
@@ -0,0 +1,24 @@ +# Copyright 2025 The Bazel Authors. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""PostMark is not implemented in Bazel.""" + +def _get_postmark_attrs(): + return {} + +def _postmark_initializer(**kwargs): + return kwargs + +get_postmark_attrs = _get_postmark_attrs +postmark_initializer = _postmark_initializer
diff --git a/cc/common/cc_helper.bzl b/cc/common/cc_helper.bzl index 328933e..0628196 100644 --- a/cc/common/cc_helper.bzl +++ b/cc/common/cc_helper.bzl
@@ -392,14 +392,6 @@ return True return False -def _is_non_empty_list_or_select(value, attr): - if type(value) == "list": - return len(value) > 0 - elif type(value) == "select": - return True - else: - fail("Only select or list is valid for {} attr".format(attr)) - def _gen_empty_def_file(ctx): trivial_def_file = ctx.actions.declare_file(ctx.label.name + ".gen.empty.def") ctx.actions.write(trivial_def_file, "", False) @@ -1104,7 +1096,6 @@ stringify_linker_input = _stringify_linker_input, generate_def_file = _generate_def_file, get_windows_def_file_for_linking = _get_windows_def_file_for_linking, - is_non_empty_list_or_select = _is_non_empty_list_or_select, check_file_extensions = _check_file_extensions, check_srcs_extensions = _check_srcs_extensions, libraries_from_linking_context = _libraries_from_linking_context,
diff --git a/cc/find_cc_toolchain.bzl b/cc/find_cc_toolchain.bzl index 11da3ca..dffb7a9 100644 --- a/cc/find_cc_toolchain.bzl +++ b/cc/find_cc_toolchain.bzl
@@ -12,6 +12,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. + """ Helpers for CC Toolchains. @@ -52,18 +53,16 @@ Bazel version is not needed), it's enough to only keep the toolchain type. """ +load("//cc:use_cc_toolchain.bzl", _CC_TOOLCHAIN_ATTRS = "CC_TOOLCHAIN_ATTRS", _CC_TOOLCHAIN_TYPE = "CC_TOOLCHAIN_TYPE", _use_cc_toolchain = "use_cc_toolchain") load("//cc/common:cc_common.bzl", "cc_common") -CC_TOOLCHAIN_TYPE = Label("@bazel_tools//tools/cpp:toolchain_type") - -CC_TOOLCHAIN_ATTRS = { - # Needed for Bazel 6.x and 7.x compatibility. - "_cc_toolchain": attr.label(default = Label("@rules_cc//cc:current_cc_toolchain")), # copybara-uncomment-this-please -} +use_cc_toolchain = _use_cc_toolchain +CC_TOOLCHAIN_TYPE = _CC_TOOLCHAIN_TYPE +CC_TOOLCHAIN_ATTRS = _CC_TOOLCHAIN_ATTRS def find_cc_toolchain(ctx, *, mandatory = True): """ - Returns the current `CcToolchainInfo`. +Returns the current `CcToolchainInfo`. Args: ctx: The rule context for which to find a toolchain. @@ -110,22 +109,3 @@ A CcToolchainInfo. """ return find_cc_toolchain(ctx) - -def use_cc_toolchain(mandatory = True): - """ - Helper to depend on the cc toolchain. - - Usage: - ``` - my_rule = rule( - toolchains = [other toolchain types] + use_cc_toolchain(), - ) - ``` - - Args: - mandatory: Whether or not it should be an error if the toolchain cannot be resolved. - - Returns: - A list that can be used as the value for `rule.toolchains`. - """ - return [config_common.toolchain_type(CC_TOOLCHAIN_TYPE, mandatory = mandatory)]
diff --git a/cc/private/rules_impl/attrs.bzl b/cc/private/rules_impl/attrs.bzl index c703bcd..eda2163 100644 --- a/cc/private/rules_impl/attrs.bzl +++ b/cc/private/rules_impl/attrs.bzl
@@ -15,7 +15,7 @@ """Attributes for cc_binary. """ -load("//cc:cc_postmark.bzl", "postmark") +load("//cc:cc_postmark_initializers.bzl", "get_postmark_attrs") load("//cc/common:cc_info.bzl", "CcInfo") load("//cc/common:semantics.bzl", "semantics") load(":cc_shared_library.bzl", "dynamic_deps_attrs") @@ -303,7 +303,7 @@ """ + semantics.stamp_extra_docs # buildifier: disable=attr-licenses -cc_binary_attrs = common_attrs | postmark.get_attrs() | { +cc_binary_attrs = common_attrs | get_postmark_attrs() | { "deps": attr.label_list( allow_files = semantics.ALLOWED_FILES_IN_DEPS, allow_rules = semantics.ALLOWED_RULES_IN_DEPS + semantics.ALLOWED_RULES_WITH_WARNINGS_IN_DEPS,
diff --git a/cc/private/rules_impl/cc_binary.bzl b/cc/private/rules_impl/cc_binary.bzl index ab8912f..e0e2c49 100644 --- a/cc/private/rules_impl/cc_binary.bzl +++ b/cc/private/rules_impl/cc_binary.bzl
@@ -14,8 +14,8 @@ """cc_binary Starlark declaration replacing native""" -load("//cc:cc_postmark.bzl", "postmark") -load("//cc:find_cc_toolchain.bzl", "use_cc_toolchain") +load("//cc:cc_postmark_initializers.bzl", "postmark_initializer") +load("//cc:use_cc_toolchain.bzl", "use_cc_toolchain") load("//cc/common:cc_info.bzl", "CcInfo") load("//cc/common:semantics.bzl", "semantics") load(":attrs.bzl", "cc_binary_attrs") @@ -23,7 +23,7 @@ load(":function_providing_rule.bzl", "proxy") def _cc_binary_initializer(**kwargs): - kwargs = postmark.initializer(**kwargs) + kwargs = postmark_initializer(**kwargs) return dynamic_deps_initializer(**kwargs) cc_binary = rule(
diff --git a/cc/private/rules_impl/cc_library.bzl b/cc/private/rules_impl/cc_library.bzl index 31d426d..04bb5eb 100755 --- a/cc/private/rules_impl/cc_library.bzl +++ b/cc/private/rules_impl/cc_library.bzl
@@ -14,7 +14,7 @@ """cc_library Starlark declaration replacing native""" -load("//cc:find_cc_toolchain.bzl", "use_cc_toolchain") +load("//cc:use_cc_toolchain.bzl", "use_cc_toolchain") load("//cc/common:cc_info.bzl", "CcInfo") load("//cc/common:semantics.bzl", "semantics") load(":attrs.bzl", "common_attrs", "linkstatic_doc")
diff --git a/cc/private/rules_impl/cc_shared_library.bzl b/cc/private/rules_impl/cc_shared_library.bzl index 8d4f341..6822b95 100644 --- a/cc/private/rules_impl/cc_shared_library.bzl +++ b/cc/private/rules_impl/cc_shared_library.bzl
@@ -15,8 +15,7 @@ """Implementation of cc_shared_library""" load("@com_google_protobuf//bazel/common:proto_info.bzl", "ProtoInfo") -load("//cc:find_cc_toolchain.bzl", "use_cc_toolchain") -load("//cc/common:cc_helper.bzl", "cc_helper") +load("//cc:use_cc_toolchain.bzl", "use_cc_toolchain") load("//cc/common:cc_info.bzl", "CcInfo") load("//cc/common:cc_shared_library_hint_info.bzl", "CcSharedLibraryHintInfo") load("//cc/common:cc_shared_library_info.bzl", "CcSharedLibraryInfo") @@ -329,6 +328,14 @@ fragments = ["cpp"] + semantics.additional_fragments(), ) +def _is_non_empty_list_or_select(value, attr): + if type(value) == "list": + return len(value) > 0 + elif type(value) == "select": + return True + else: + fail("Only select or list is valid for {} attr".format(attr)) + def dynamic_deps_initializer(**kwargs): """Initializes dynamic_deps_attrs @@ -338,7 +345,7 @@ Returns: (dict) """ - if "dynamic_deps" in kwargs and cc_helper.is_non_empty_list_or_select(kwargs["dynamic_deps"], "dynamic_deps"): + if "dynamic_deps" in kwargs and _is_non_empty_list_or_select(kwargs["dynamic_deps"], "dynamic_deps"): # Propagate an aspect if dynamic_deps attribute is specified. # Use += for lists rather than extend or append to allow for the case where deps # is a select.
diff --git a/cc/private/rules_impl/cc_test.bzl b/cc/private/rules_impl/cc_test.bzl index b7de57e..f94600b 100644 --- a/cc/private/rules_impl/cc_test.bzl +++ b/cc/private/rules_impl/cc_test.bzl
@@ -14,8 +14,8 @@ """cc_test Starlark declaration.""" -load("//cc:cc_postmark.bzl", "postmark") -load("//cc:find_cc_toolchain.bzl", "use_cc_toolchain") +load("//cc:cc_postmark_initializers.bzl", "postmark_initializer") +load("//cc:use_cc_toolchain.bzl", "use_cc_toolchain") load("//cc/common:cc_info.bzl", "CcInfo") load("//cc/common:semantics.bzl", "semantics") load(":attrs.bzl", "cc_binary_attrs", "linkstatic_doc", "stamp_doc") @@ -64,7 +64,7 @@ if "linkstatic" not in kwargs: kwargs["linkstatic"] = semantics.get_linkstatic_default_for_test() - kwargs = postmark.initializer(**kwargs) + kwargs = postmark_initializer(**kwargs) return dynamic_deps_initializer(**kwargs)
diff --git a/cc/use_cc_toolchain.bzl b/cc/use_cc_toolchain.bzl new file mode 100644 index 0000000..8e27110 --- /dev/null +++ b/cc/use_cc_toolchain.bzl
@@ -0,0 +1,79 @@ +# pylint: disable=g-bad-file-header +# Copyright 2016 The Bazel Authors. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +""" +Helpers for CC Toolchains. + +Rules that require a CC toolchain should call `use_cc_toolchain` and `find_cc_toolchain` +to depend on and find a cc toolchain. + +* When https://github.com/bazelbuild/bazel/issues/7260 is **not** flipped, current + C++ toolchain is selected using the legacy mechanism (`--crosstool_top`, + `--cpu`, `--compiler`). For that to work the rule needs to declare an + `_cc_toolchain` attribute, e.g. + + foo = rule( + implementation = _foo_impl, + attrs = { + "_cc_toolchain": attr.label( + default = Label( + "@rules_cc//cc:current_cc_toolchain", + ), + ), + }, + ) + +* When https://github.com/bazelbuild/bazel/issues/7260 **is** flipped, current + C++ toolchain is selected using the toolchain resolution mechanism + (`--platforms`). For that to work the rule needs to declare a dependency on + C++ toolchain type: + + load(":find_cc_toolchain/bzl", "use_cc_toolchain") + + foo = rule( + implementation = _foo_impl, + toolchains = use_cc_toolchain(), + ) + +We advise to depend on both `_cc_toolchain` attr and on the toolchain type for +the duration of the migration. After +https://github.com/bazelbuild/bazel/issues/7260 is flipped (and support for old +Bazel version is not needed), it's enough to only keep the toolchain type. +""" + +CC_TOOLCHAIN_TYPE = Label("@bazel_tools//tools/cpp:toolchain_type") +CC_TOOLCHAIN_ATTRS = { + # Needed for Bazel 6.x and 7.x compatibility. + "_cc_toolchain": attr.label(default = Label("@rules_cc//cc:current_cc_toolchain")), # copybara-uncomment-this-please +} + +def use_cc_toolchain(mandatory = True): + """ + Helper to depend on the cc toolchain. + + Usage: + ``` + my_rule = rule( + toolchains = [other toolchain types] + use_cc_toolchain(), + ) + ``` + + Args: + mandatory: Whether or not it should be an error if the toolchain cannot be resolved. + + Returns: + A list that can be used as the value for `rule.toolchains`. + """ + return [config_common.toolchain_type(CC_TOOLCHAIN_TYPE, mandatory = mandatory)]