Skip to content

Commit

Permalink
## Starlark cc_test fixes.
Browse files Browse the repository at this point in the history
* 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](#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
  • Loading branch information
trybka authored and copybara-github committed Apr 13, 2022
1 parent 90fe1b2 commit 32714ee
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 14 deletions.
36 changes: 22 additions & 14 deletions src/main/starlark/builtins_bzl/common/cc/cc_test.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -47,20 +47,30 @@ _cc_test_attrs.update(
),
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)
Expand All @@ -79,13 +89,12 @@ def _handle_legacy_return(ctx, cc_info, providers):
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(
Expand Down Expand Up @@ -114,8 +123,7 @@ def make_cc_test(with_linkstatic = False):
"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,
Expand Down
59 changes: 59 additions & 0 deletions src/main/starlark/builtins_bzl/common/cc/semantics.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,60 @@ def _get_def_parser():
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 {}

Expand Down Expand Up @@ -122,4 +176,9 @@ semantics = struct(
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,
)

0 comments on commit 32714ee

Please sign in to comment.