Support the new(ish) `@//tools/cpp:cc_runtimes_toolchain_type` toolchain for adding runtimes-on-demand.
* Add `get_cc_runtimes` and `get_cc_runtimes_copts` implementations to `cc_helper[_internal]`.
* TODO update usage in `rules_python` and others to call `cc_helper` and deprecate `semantics.get_cc_runtimes*`
Basic Usage:
Define a provider like:
```
CcRuntimesInfo = provider(
doc = "Information about runtime libraries to link into c++ targets.",
fields = ["runtimes", "copts"],
)
```
Define a toolchain that returns that provider:
```
def _cc_runtimes_toolchain_impl(ctx):
return [platform_common.ToolchainInfo(
cc_runtimes_info = CcRuntimesInfo(
runtimes = ctx.attr.runtimes,
copts = ctx.attr.copts,
),
)]
```
* `runtimes` is a collection of CcInfo providing targets
* `copts` provides compilation flags that must be used alongside this toolchain, e.g. to influence include ordering.
This may be used, e.g. in rules_android_ndk: https://github.com/bazelbuild/rules_android_ndk/issues/93
PiperOrigin-RevId: 941244580
Change-Id: I31bade595714dbe44aa0d70afaa97ddd788e5635
diff --git a/cc/common/cc_helper.bzl b/cc/common/cc_helper.bzl
index 92483ac..115052a 100644
--- a/cc/common/cc_helper.bzl
+++ b/cc/common/cc_helper.bzl
@@ -26,6 +26,8 @@
"should_create_per_object_debug_info",
_artifact_category = "artifact_category_names",
_extensions = "extensions",
+ _get_cc_runtimes = "get_cc_runtimes",
+ _get_cc_runtimes_copts = "get_cc_runtimes_copts",
_is_stamping_enabled = "is_stamping_enabled",
_package_source_root = "package_source_root",
_repository_exec_path = "repository_exec_path",
@@ -1182,4 +1184,6 @@
has_target_constraints = _has_target_constraints,
package_exec_path = _package_exec_path,
should_create_test_dwp_for_statically_linked_test = _should_create_test_dwp_for_statically_linked_test,
+ get_cc_runtimes = _get_cc_runtimes,
+ get_cc_runtimes_copts = _get_cc_runtimes_copts,
)
diff --git a/cc/common/cc_helper_internal.bzl b/cc/common/cc_helper_internal.bzl
index 735e050..df6b198 100644
--- a/cc/common/cc_helper_internal.bzl
+++ b/cc/common/cc_helper_internal.bzl
@@ -43,6 +43,55 @@
CPP_SOURCE_TYPE_HEADER = "HEADER"
CPP_SOURCE_TYPE_SOURCE = "SOURCE"
CPP_SOURCE_TYPE_CLIF_INPUT_PROTO = "CLIF_INPUT_PROTO"
+CC_RUNTIMES_TOOLCHAIN_TYPE = Label("@bazel_tools//tools/cpp:cc_runtimes_toolchain_type")
+
+def get_cc_runtimes(ctx, is_library):
+ """Returns the list of C++ runtime dependency targets for the rule.
+
+ Args:
+ ctx: The rule context.
+ is_library: True if the target being evaluated is a library rule (which
+ excludes malloc and link_extra_lib), False otherwise.
+
+ Returns:
+ A list of Target objects representing the required runtime libraries.
+ """
+ runtimes = []
+
+ # Executable builds also include the "malloc" and "link_extra_lib" libraries.
+ if not is_library:
+ runtimes.append(ctx.attr.link_extra_lib)
+
+ if ctx.fragments.cpp.custom_malloc != None:
+ # ctx.attr._default_malloc is set via ctx.fragments.cpp.custom_malloc.
+ runtimes.append(ctx.attr._default_malloc)
+ else:
+ runtimes.append(ctx.attr.malloc)
+
+ cc_runtimes_toolchain = ctx.toolchains[CC_RUNTIMES_TOOLCHAIN_TYPE]
+
+ # All builds include the runtimes from the cc_runtimes_toolchain.
+ if cc_runtimes_toolchain:
+ runtimes += cc_runtimes_toolchain.cc_runtimes_info.runtimes
+ elif hasattr(ctx.attr, "tags") and "__CC_STL__" in ctx.attr.tags:
+ # TODO(b/141613846): Remove this workaround.
+ pass
+ elif getattr(ctx.attr, "_stl", None) != None:
+ runtimes.append(ctx.attr._stl)
+
+ return runtimes
+
+def get_cc_runtimes_copts(ctx):
+ """Returns the C++ compiler flags required by the C++ runtimes toolchain.
+
+ Args:
+ ctx: The rule context.
+
+ Returns:
+ A list of command-line compiler option strings from the runtimes toolchain.
+ """
+ cc_runtimes_toolchain = ctx.toolchains[CC_RUNTIMES_TOOLCHAIN_TYPE]
+ return cc_runtimes_toolchain.cc_runtimes_info.copts if cc_runtimes_toolchain else []
def get_fdo_build_stamp(cpp_configuration, fdo_context, feature_configuration):
"""Returns the FDO build stamp.
diff --git a/cc/common/semantics.bzl b/cc/common/semantics.bzl
index 0b208c7..267259a 100644
--- a/cc/common/semantics.bzl
+++ b/cc/common/semantics.bzl
@@ -14,6 +14,13 @@
"""Semantics for Bazel cc rules"""
+load(
+ ":cc_helper_internal.bzl",
+ "CC_RUNTIMES_TOOLCHAIN_TYPE",
+ _get_cc_runtimes = "get_cc_runtimes",
+ _get_cc_runtimes_copts = "get_cc_runtimes_copts",
+)
+
# Point virtual includes symlinks to the source root for better IDE integration.
# See https://github.com/bazelbuild/bazel/pull/20540.
# TODO: b/320980684 - Add a test that fails if this is flipped to True.
@@ -66,7 +73,12 @@
return attr.label()
def _get_runtimes_toolchain():
- return []
+ return [
+ config_common.toolchain_type(
+ CC_RUNTIMES_TOOLCHAIN_TYPE,
+ mandatory = False,
+ ),
+ ]
def _get_test_malloc_attr():
return {}
@@ -88,22 +100,6 @@
def _get_coverage_env(ctx):
return ctx.runfiles(), {}
-def _get_cc_runtimes(ctx, is_library):
- if is_library:
- return []
-
- runtimes = [ctx.attr.link_extra_lib]
-
- if ctx.fragments.cpp.custom_malloc != None:
- runtimes.append(ctx.attr._default_malloc)
- else:
- runtimes.append(ctx.attr.malloc)
-
- return runtimes
-
-def _get_cc_runtimes_copts(_ctx):
- return []
-
def _get_implementation_deps_allowed_attr():
return {}
diff --git a/cc/private/rules_impl/cc_binary_impl.bzl b/cc/private/rules_impl/cc_binary_impl.bzl
index 6659384..3325e93 100644
--- a/cc/private/rules_impl/cc_binary_impl.bzl
+++ b/cc/private/rules_impl/cc_binary_impl.bzl
@@ -169,10 +169,10 @@
builder = builder.merge_all([
_default_runfiles_function(ctx, runtime)
- for runtime in semantics.get_cc_runtimes(ctx, _is_link_shared(ctx))
+ for runtime in cc_helper.get_cc_runtimes(ctx, _is_link_shared(ctx))
] + [
ctx.runfiles(transitive_files = _runfiles_function(runtime, linking_mode != linker_mode.LINKING_DYNAMIC))
- for runtime in semantics.get_cc_runtimes(ctx, _is_link_shared(ctx))
+ for runtime in cc_helper.get_cc_runtimes(ctx, _is_link_shared(ctx))
])
return (builder.merge(ctx.runfiles(files = builder_artifacts, transitive_files = depset(builder_transitive_artifacts))), runtime_objects_for_coverage)
@@ -208,7 +208,7 @@
return dynamic_libraries_for_runtime
def _get_providers(ctx):
- all_deps = ctx.attr.deps + semantics.get_cc_runtimes(ctx, _is_link_shared(ctx))
+ all_deps = ctx.attr.deps + cc_helper.get_cc_runtimes(ctx, _is_link_shared(ctx))
return [dep[CcInfo] for dep in all_deps if CcInfo in dep]
def _filter_libraries_that_are_linked_dynamically(ctx, feature_configuration, cc_linking_context):
@@ -283,7 +283,7 @@
# Deps that came from cc_runtimes may have been filtered out above, so we need to re-add them.
# For example, libc++/libstdc++ or malloc-like deps should still be linked in normally
# even though they will also be a transitive dep of things in dynamic_deps.
- cc_runtimes = semantics.get_cc_runtimes(ctx, _is_link_shared(ctx))
+ cc_runtimes = cc_helper.get_cc_runtimes(ctx, _is_link_shared(ctx))
cc_runtimes_infos = [dep[CcInfo] for dep in cc_runtimes if CcInfo in dep]
return cc_common.merge_cc_infos(direct_cc_infos = [
@@ -512,10 +512,10 @@
cc_helper.check_cpp_modules(ctx, feature_configuration)
- all_deps = ctx.attr.deps + semantics.get_cc_runtimes(ctx, _is_link_shared(ctx))
+ all_deps = ctx.attr.deps + cc_helper.get_cc_runtimes(ctx, _is_link_shared(ctx))
compilation_context_deps = [dep[CcInfo].compilation_context for dep in all_deps if CcInfo in dep]
- runtimes_copts = semantics.get_cc_runtimes_copts(ctx)
+ runtimes_copts = cc_helper.get_cc_runtimes_copts(ctx)
additional_make_variable_substitutions = cc_helper.get_toolchain_global_make_variables(cc_toolchain, feature_configuration)
additional_make_variable_substitutions.update(cc_helper.get_cc_flags_make_variable(ctx, feature_configuration, cc_toolchain))
diff --git a/cc/private/rules_impl/cc_import.bzl b/cc/private/rules_impl/cc_import.bzl
index 6574b69..b1fd6fb 100644
--- a/cc/private/rules_impl/cc_import.bzl
+++ b/cc/private/rules_impl/cc_import.bzl
@@ -164,8 +164,8 @@
additional_make_variable_substitutions = cc_helper.get_toolchain_global_make_variables(cc_toolchain, feature_configuration)
additional_make_variable_substitutions.update(cc_helper.get_cc_flags_make_variable(ctx, feature_configuration, cc_toolchain))
- runtimes_deps = semantics.get_cc_runtimes(ctx, True)
- runtimes_copts = semantics.get_cc_runtimes_copts(ctx)
+ runtimes_deps = cc_helper.get_cc_runtimes(ctx, True)
+ runtimes_copts = cc_helper.get_cc_runtimes_copts(ctx)
compilation_contexts = cc_helper.get_compilation_contexts_from_deps(runtimes_deps)
(compilation_context, _) = cc_common.compile(
actions = ctx.actions,
diff --git a/cc/private/rules_impl/cc_library_impl.bzl b/cc/private/rules_impl/cc_library_impl.bzl
index 83b21c4..2005486 100755
--- a/cc/private/rules_impl/cc_library_impl.bzl
+++ b/cc/private/rules_impl/cc_library_impl.bzl
@@ -45,8 +45,8 @@
_check_no_repeated_srcs(ctx)
semantics.check_can_use_implementation_deps(ctx)
- interface_deps = ctx.attr.deps + semantics.get_cc_runtimes(ctx, True)
- runtimes_copts = semantics.get_cc_runtimes_copts(ctx)
+ interface_deps = ctx.attr.deps + cc_helper.get_cc_runtimes(ctx, True)
+ runtimes_copts = cc_helper.get_cc_runtimes_copts(ctx)
compilation_contexts = cc_helper.get_compilation_contexts_from_deps(interface_deps)
implementation_compilation_contexts = cc_helper.get_compilation_contexts_from_deps(ctx.attr.implementation_deps)
@@ -110,7 +110,7 @@
linking_contexts = cc_helper.get_linking_contexts_from_deps(ctx.attr.deps)
linking_contexts.extend(
cc_helper.get_linking_contexts_from_deps(
- ctx.attr.implementation_deps + semantics.get_cc_runtimes(ctx, True),
+ ctx.attr.implementation_deps + cc_helper.get_cc_runtimes(ctx, True),
),
)
if ctx.file.linkstamp != None:
diff --git a/cc/private/rules_impl/cc_shared_library_impl.bzl b/cc/private/rules_impl/cc_shared_library_impl.bzl
index 188b42e..905c52a 100644
--- a/cc/private/rules_impl/cc_shared_library_impl.bzl
+++ b/cc/private/rules_impl/cc_shared_library_impl.bzl
@@ -655,7 +655,7 @@
linking_context = _create_linker_context(linker_inputs)
- cc_runtimes_deps = semantics.get_cc_runtimes(ctx, True)
+ cc_runtimes_deps = cc_helper.get_cc_runtimes(ctx, True)
runtimes_linking_contexts = cc_helper.get_linking_contexts_from_deps(cc_runtimes_deps)
user_link_flags = []
diff --git a/cc/private/rules_impl/objc_compilation_support.bzl b/cc/private/rules_impl/objc_compilation_support.bzl
index 4e9bdfb..b497193 100644
--- a/cc/private/rules_impl/objc_compilation_support.bzl
+++ b/cc/private/rules_impl/objc_compilation_support.bzl
@@ -17,7 +17,6 @@
load("//cc:build_settings.bzl", "cc")
load("//cc/common:cc_common.bzl", "cc_common")
load("//cc/common:cc_helper.bzl", "cc_helper")
-load("//cc/common:semantics.bzl", cc_semantics = "semantics")
load(":objc_common.bzl", "objc_common")
load(":objc_compilation_artifacts_info.bzl", "CompilationArtifactsInfo")
load(":objc_intermediate_artifacts.bzl", "create_intermediate_artifacts")
@@ -172,10 +171,10 @@
compilation_contexts = (
objc_compilation_context.cc_compilation_contexts +
cc_helper.get_compilation_contexts_from_deps(
- cc_semantics.get_cc_runtimes(common_variables.ctx, True),
+ cc_helper.get_cc_runtimes(common_variables.ctx, True),
)
)
- runtimes_copts = cc_semantics.get_cc_runtimes_copts(common_variables.ctx)
+ runtimes_copts = cc_helper.get_cc_runtimes_copts(common_variables.ctx)
return cc_common.compile(
actions = common_variables.ctx.actions,
diff --git a/tests/cc/common/cc_binary_configured_target_tests.bzl b/tests/cc/common/cc_binary_configured_target_tests.bzl
index b4fd7c2..6d46286 100644
--- a/tests/cc/common/cc_binary_configured_target_tests.bzl
+++ b/tests/cc/common/cc_binary_configured_target_tests.bzl
@@ -1925,7 +1925,7 @@
_test_linking_mode_features_false_fully,
_test_linking_mode_features_true_off,
_test_linking_mode_features_false_off,
- # _test_cc_runtimes_added_to_libraries, # copybara-comment-this-out-please
+ _test_cc_runtimes_added_to_libraries,
])
test_suite(