## Starlark `cc_test` fixes.
* Restructure `cc_test` to use a toolchain alias. This will allow `cc_test` to work in Bazel (and tests) without a "dummy" toolchain needing to be registered.
This makes `cc_test` use the legacy flow when toolchains are not registered--requiring an additional flag if they are.
This is a temporary measure to permit switching off `native.cc_test` before [Optional Toolchains](https://github.com/bazelbuild/bazel/issues/14726) lands.
* Add coverage-related tools (e.g. collect_cc_coverage.sh) necessary for Bazel to collect coverage from cc_test(s)
PiperOrigin-RevId: 441494074
diff --git a/src/main/starlark/builtins_bzl/common/cc/cc_test.bzl b/src/main/starlark/builtins_bzl/common/cc/cc_test.bzl
index eccc897..cab1d87 100644
--- a/src/main/starlark/builtins_bzl/common/cc/cc_test.bzl
+++ b/src/main/starlark/builtins_bzl/common/cc/cc_test.bzl
@@ -47,20 +47,30 @@
),
stamp = attr.int(values = [-1, 0, 1], default = 0),
linkstatic = attr.bool(default = False),
- malloc = attr.label(
- default = Label("@//tools/cpp:cc_test_malloc"),
- allow_rules = ["cc_library"],
- # TODO(b/198254254): Add aspects. in progress
- aspects = [],
- ),
)
+_cc_test_attrs.update(semantics.get_test_malloc_attr())
+_cc_test_attrs.update(semantics.get_test_toolchain_attr())
+_cc_test_attrs.update(semantics.get_coverage_attrs())
def _cc_test_impl(ctx):
binary_info, cc_info, providers = cc_binary_impl(ctx, [])
- providers.append(testing.TestEnvironment(ctx.attr.env))
+ test_env = {}
+ test_env.update(ctx.attr.env)
+
+ coverage_runfiles, coverage_env = semantics.get_coverage_env(ctx)
+
+ runfiles_list = [binary_info.runfiles]
+ if coverage_runfiles:
+ runfiles_list.append(coverage_runfiles)
+
+ runfiles = ctx.runfiles()
+ runfiles = runfiles.merge_all(runfiles_list)
+
+ test_env.update(coverage_env)
+ providers.append(testing.TestEnvironment(test_env))
providers.append(DefaultInfo(
files = binary_info.files,
- runfiles = binary_info.runfiles,
+ runfiles = runfiles,
executable = binary_info.executable,
))
return _handle_legacy_return(ctx, cc_info, providers)
@@ -79,13 +89,12 @@
return providers
def _impl(ctx):
- cpp_config = ctx.fragments.cpp
- cc_test_info = ctx.toolchains["@//tools/cpp:test_runner_toolchain_type"].cc_test_info
-
- if not cpp_config.experimental_platform_cc_test() or cc_test_info.use_legacy_cc_test:
+ if semantics.should_use_legacy_cc_test(ctx):
# This is the "legacy" cc_test flow
return _cc_test_impl(ctx)
+ cc_test_info = ctx.attr._test_toolchain.cc_test_info
+
binary_info, cc_info, providers = cc_binary_impl(ctx, cc_test_info.linkopts)
test_providers = cc_test_info.get_runner.func(
@@ -114,8 +123,7 @@
"cpp_link": exec_group(copy_from_rule = True),
},
toolchains = [
- "@//tools/cpp:toolchain_type",
- "@//tools/cpp:test_runner_toolchain_type",
+ "@" + semantics.get_repo() + "//tools/cpp:toolchain_type",
],
incompatible_use_toolchain_transition = True,
test = True,
diff --git a/src/main/starlark/builtins_bzl/common/cc/semantics.bzl b/src/main/starlark/builtins_bzl/common/cc/semantics.bzl
index 34a2908..5b9ea24 100644
--- a/src/main/starlark/builtins_bzl/common/cc/semantics.bzl
+++ b/src/main/starlark/builtins_bzl/common/cc/semantics.bzl
@@ -65,6 +65,60 @@
def _get_grep_includes():
return attr.label()
+def _get_test_toolchain_attr():
+ return {}
+
+def _get_test_malloc_attr():
+ return {}
+
+def _get_coverage_attrs():
+ return {
+ "_lcov_merger": attr.label(
+ default = "@bazel_tools//tools/test:lcov_merger",
+ executable = True,
+ cfg = "target",
+ ),
+ "_collect_cc_coverage": attr.label(
+ default = "@bazel_tools//tools/test:collect_cc_coverage",
+ executable = True,
+ cfg = "target",
+ ),
+ }
+
+def _get_coverage_env(ctx):
+ runfiles = ctx.runfiles()
+ test_env = {}
+ if ctx.configuration.coverage_enabled:
+ # Bazel’s coverage runner
+ # (https://github.com/bazelbuild/bazel/blob/3.0.0/tools/test/collect_coverage.sh)
+ # needs a binary called “lcov_merge.” Its location is passed in the
+ # LCOV_MERGER environmental variable. For builtin rules, this variable
+ # is set automatically based on a magic “$lcov_merger” or
+ # “:lcov_merger” attribute, but it’s not possible to create such
+ # attributes in Starlark. Therefore we specify the variable ourselves.
+ # Note that the coverage runner runs in the runfiles root instead of
+ # the execution root, therefore we use “path” instead of “short_path.”
+ test_env["LCOV_MERGER"] = ctx.executable._lcov_merger.path
+
+ # C/C++ coverage instrumentation needs another binary that wraps gcov;
+ # see
+ # https://github.com/bazelbuild/bazel/blob/5.0.0/tools/test/collect_coverage.sh#L199.
+ # This is normally set from a hidden “$collect_cc_coverage” attribute;
+ # see
+ # https://github.com/bazelbuild/bazel/blob/5.0.0/src/main/java/com/google/devtools/build/lib/analysis/test/TestActionBuilder.java#L253-L258.
+ test_env["CC_CODE_COVERAGE_SCRIPT"] = ctx.executable._collect_cc_coverage.path
+
+ # The test runfiles need all applicable runfiles for the tools above.
+ runfiles = runfiles.merge_all([
+ ctx.attr._lcov_merger[DefaultInfo].default_runfiles,
+ ctx.attr._collect_cc_coverage[DefaultInfo].default_runfiles,
+ ])
+
+ return runfiles, test_env
+
+def _should_use_legacy_cc_test(_):
+ return True
+
def _get_interface_deps_allowed_attr():
return {}
@@ -122,4 +176,9 @@
should_use_interface_deps_behavior = _should_use_interface_deps_behavior,
check_experimental_cc_shared_library = _check_experimental_cc_shared_library,
get_linkstatic_default = _get_linkstatic_default,
+ get_test_malloc_attr = _get_test_malloc_attr,
+ get_test_toolchain_attr = _get_test_toolchain_attr,
+ should_use_legacy_cc_test = _should_use_legacy_cc_test,
+ get_coverage_attrs = _get_coverage_attrs,
+ get_coverage_env = _get_coverage_env,
)