Skip to content

Commit d0db10e

Browse files
hvadehracopybara-github
authored andcommitted
Fork cc_test.bzl
PiperOrigin-RevId: 791587137 Change-Id: I36c0cb6bb3200ceb661efb769166ce6fe42225a0
1 parent 3b780fa commit d0db10e

File tree

2 files changed

+161
-4
lines changed

2 files changed

+161
-4
lines changed

cc/common/cc_helper.bzl

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1034,6 +1034,14 @@ def _is_stamping_enabled(ctx):
10341034
stamp = ctx.attr.stamp
10351035
return stamp
10361036

1037+
def _has_target_constraints(ctx, constraints):
1038+
# Constraints is a label_list.
1039+
for constraint in constraints:
1040+
constraint_value = constraint[platform_common.ConstraintValueInfo]
1041+
if ctx.target_platform_has_constraint(constraint_value):
1042+
return True
1043+
return False
1044+
10371045
cc_helper = struct(
10381046
create_strip_action = _create_strip_action,
10391047
get_expanded_env = _get_expanded_env,
@@ -1081,5 +1089,6 @@ cc_helper = struct(
10811089
is_test_target = _is_test_target,
10821090
get_linked_artifact = _get_linked_artifact,
10831091
should_create_per_object_debug_info = should_create_per_object_debug_info,
1092+
has_target_constraints = _has_target_constraints,
10841093
)
10851094
# LINT.ThenChange(https://github.com/bazelbuild/bazel/blob/master/src/main/starlark/builtins_bzl/common/cc/cc_helper.bzl:forked_exports)

cc/private/rules_impl/cc_test.bzl

Lines changed: 152 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright 2025 The Bazel Authors. All rights reserved.
1+
# Copyright 2021 The Bazel Authors. All rights reserved.
22
#
33
# Licensed under the Apache License, Version 2.0 (the "License");
44
# you may not use this file except in compliance with the License.
@@ -11,7 +11,155 @@
1111
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
14-
"""cc_test rule without a macro"""
1514

16-
# buildifier: disable=native-cc-test
17-
cc_test = native.cc_test
15+
"""cc_test Starlark implementation."""
16+
17+
load("//cc:find_cc_toolchain.bzl", "use_cc_toolchain")
18+
load("//cc/common:cc_helper.bzl", "cc_helper")
19+
load("//cc/common:cc_info.bzl", "CcInfo")
20+
load("//cc/common:semantics.bzl", "semantics")
21+
load(":attrs.bzl", "cc_binary_attrs", "linkstatic_doc", "stamp_doc")
22+
load(":cc_binary.bzl", "cc_binary_impl")
23+
load(":cc_shared_library.bzl", "dynamic_deps_initializer")
24+
25+
_CC_TEST_TOOLCHAIN_TYPE = "@bazel_tools//tools/cpp:test_runner_toolchain_type"
26+
27+
def _legacy_cc_test_impl(ctx):
28+
binary_info, providers = cc_binary_impl(ctx, [])
29+
test_env = {}
30+
test_env.update(cc_helper.get_expanded_env(ctx, {}))
31+
32+
coverage_runfiles, coverage_env = semantics.get_coverage_env(ctx)
33+
34+
runfiles_list = [binary_info.runfiles]
35+
if coverage_runfiles:
36+
runfiles_list.append(coverage_runfiles)
37+
38+
runfiles = ctx.runfiles()
39+
runfiles = runfiles.merge_all(runfiles_list)
40+
41+
test_env.update(coverage_env)
42+
providers.append(testing.TestEnvironment(
43+
environment = test_env,
44+
inherited_environment = ctx.attr.env_inherit,
45+
))
46+
providers.append(DefaultInfo(
47+
files = binary_info.files,
48+
runfiles = runfiles,
49+
executable = binary_info.executable,
50+
))
51+
52+
if cc_helper.has_target_constraints(ctx, ctx.attr._apple_constraints):
53+
# When built for Apple platforms, require the execution to be on a Mac.
54+
providers.append(testing.ExecutionInfo({"requires-darwin": ""}))
55+
return providers
56+
57+
def _impl(ctx):
58+
semantics.validate(ctx, "cc_test")
59+
cc_test_toolchain = ctx.exec_groups["test"].toolchains[_CC_TEST_TOOLCHAIN_TYPE]
60+
if cc_test_toolchain:
61+
cc_test_info = cc_test_toolchain.cc_test_info
62+
else:
63+
# This is the "legacy" cc_test flow
64+
return _legacy_cc_test_impl(ctx)
65+
66+
binary_info, providers = cc_binary_impl(ctx, cc_test_info.linkopts, cc_test_info.linkstatic)
67+
processed_environment = cc_helper.get_expanded_env(ctx, {})
68+
69+
test_providers = cc_test_info.get_runner.func(
70+
ctx,
71+
binary_info,
72+
processed_environment = processed_environment,
73+
**cc_test_info.get_runner.args
74+
)
75+
providers.extend(test_providers)
76+
return providers
77+
78+
_cc_test_attrs = dict(cc_binary_attrs)
79+
80+
# Update cc_test defaults:
81+
_cc_test_attrs.update(
82+
_is_test = attr.bool(default = True),
83+
_apple_constraints = attr.label_list(
84+
default = [
85+
"@platforms//os:ios",
86+
"@platforms//os:macos",
87+
"@platforms//os:tvos",
88+
"@platforms//os:watchos",
89+
],
90+
),
91+
# Starlark tests don't get `env_inherit` by default.
92+
env_inherit = attr.string_list(),
93+
stamp = attr.int(values = [-1, 0, 1], default = 0, doc = stamp_doc),
94+
linkstatic = attr.bool(default = False, doc = linkstatic_doc),
95+
)
96+
_cc_test_attrs.update(semantics.get_test_malloc_attr())
97+
_cc_test_attrs.update(semantics.get_coverage_attrs())
98+
99+
def cc_test_initializer(**kwargs):
100+
"""Entry point for cc_test rules.
101+
102+
It serves to detect if the `linkstatic` attribute was explicitly set or not.
103+
This is to workaround a deficiency in Starlark attributes.
104+
(See: https://github.com/bazelbuild/bazel/issues/14434)
105+
106+
Args:
107+
**kwargs: Arguments suitable for cc_test.
108+
"""
109+
110+
if "linkstatic" not in kwargs:
111+
kwargs["linkstatic"] = semantics.get_linkstatic_default_for_test()
112+
113+
return dynamic_deps_initializer(**kwargs)
114+
115+
cc_test = rule(
116+
initializer = cc_test_initializer,
117+
implementation = _impl,
118+
doc = """
119+
<p>
120+
A <code>cc_test()</code> rule compiles a test. Here, a test
121+
is a binary wrapper around some testing code.
122+
</p>
123+
124+
<p><i>By default, C++ tests are dynamically linked.</i><br/>
125+
To statically link a unit test, specify
126+
<a href="${link cc_binary.linkstatic}"><code>linkstatic=True</code></a>.
127+
It would probably be good to comment why your test needs
128+
<code>linkstatic</code>; this is probably not obvious.</p>
129+
130+
<h4>Implicit output targets</h4>
131+
<ul>
132+
<li><code><var>name</var>.stripped</code> (only built if explicitly requested): A stripped
133+
version of the binary. <code>strip -g</code> is run on the binary to remove debug
134+
symbols. Additional strip options can be provided on the command line using
135+
<code>--stripopt=-foo</code>.</li>
136+
<li><code><var>name</var>.dwp</code> (only built if explicitly requested): If
137+
<a href="https://gcc.gnu.org/wiki/DebugFission">Fission</a> is enabled: a debug
138+
information package file suitable for debugging remotely deployed binaries. Else: an
139+
empty file.</li>
140+
</ul>
141+
142+
<p>
143+
See the <a href="${link cc_binary_args}">cc_binary()</a> arguments, except that
144+
the <code>stamp</code> argument is set to 0 by default for tests and
145+
that <code>cc_test</code> has extra <a href="${link common-definitions#common-attributes-tests}">
146+
attributes common to all test rules (*_test)</a>.</p>
147+
""" + semantics.cc_test_extra_docs,
148+
attrs = _cc_test_attrs,
149+
outputs = {
150+
"dwp_file": "%{name}.dwp",
151+
# TODO(b/198254254): Handle case for windows.
152+
"stripped_binary": "%{name}.stripped",
153+
},
154+
fragments = ["cpp", "coverage"] + semantics.additional_fragments(),
155+
exec_groups = {
156+
"cpp_link": exec_group(toolchains = use_cc_toolchain()),
157+
# testing.ExecutionInfo defaults to an exec_group of "test".
158+
"test": exec_group(toolchains = [config_common.toolchain_type(_CC_TEST_TOOLCHAIN_TYPE, mandatory = False)]),
159+
} | semantics.extra_exec_groups,
160+
toolchains = [] +
161+
use_cc_toolchain() +
162+
semantics.get_runtimes_toolchain(),
163+
test = True,
164+
provides = [CcInfo],
165+
)

0 commit comments

Comments
 (0)