Skip to content

Commit f4eaa71

Browse files
committed
Added tests for pipelining with custom rules
1 parent 4e01fa0 commit f4eaa71

File tree

5 files changed

+191
-21
lines changed

5 files changed

+191
-21
lines changed

test/unit/force_all_deps_direct/generator.bzl

-13
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,6 @@ load("//rust/private:providers.bzl", "BuildInfo", "CrateInfo", "DepInfo", "DepVa
99
# buildifier: disable=bzl-visibility
1010
load("//rust/private:rustc.bzl", "rustc_compile_action")
1111

12-
# buildifier: disable=bzl-visibility
13-
load("//rust/private:utils.bzl", "can_build_metadata")
14-
1512
def _generator_impl(ctx):
1613
rs_file = ctx.actions.declare_file(ctx.label.name + "_generated.rs")
1714
ctx.actions.run_shell(
@@ -42,12 +39,6 @@ EOF
4239
lib_hash = output_hash,
4340
extension = ".rlib",
4441
)
45-
rust_metadata_name = "{prefix}{name}-{lib_hash}{extension}".format(
46-
prefix = "lib",
47-
name = crate_name,
48-
lib_hash = output_hash,
49-
extension = ".rmeta",
50-
)
5142

5243
deps = [DepVariantInfo(
5344
crate_info = dep[CrateInfo] if CrateInfo in dep else None,
@@ -57,9 +48,6 @@ EOF
5748
) for dep in ctx.attr.deps]
5849

5950
rust_lib = ctx.actions.declare_file(rust_lib_name)
60-
rust_metadata = None
61-
if can_build_metadata(toolchain, ctx, crate_type):
62-
rust_metadata = ctx.actions.declare_file(rust_metadata_name)
6351
return rustc_compile_action(
6452
ctx = ctx,
6553
attr = ctx.attr,
@@ -73,7 +61,6 @@ EOF
7361
proc_macro_deps = depset([]),
7462
aliases = {},
7563
output = rust_lib,
76-
metadata = rust_metadata,
7764
owner = ctx.label,
7865
edition = "2018",
7966
compile_data = depset([]),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
pub fn to_wrap() {
2+
eprintln!("something");
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
use wrapper::wrap;
2+
3+
pub fn calls_wrap() {
4+
wrap();
5+
}

test/unit/pipelined_compilation/pipelined_compilation_test.bzl

+77-8
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,17 @@
33
load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts")
44
load("//rust:defs.bzl", "rust_binary", "rust_library", "rust_proc_macro")
55
load("//test/unit:common.bzl", "assert_argv_contains", "assert_list_contains_adjacent_elements", "assert_list_contains_adjacent_elements_not")
6+
load(":wrap.bzl", "wrap")
7+
8+
NOT_WINDOWS = select({
9+
"@platforms//os:linux": [],
10+
"@platforms//os:macos": [],
11+
"//conditions:default": ["@platforms//:incompatible"],
12+
})
13+
14+
ENABLE_PIPELINING = {
15+
"@//rust/settings:pipelined_compilation": True,
16+
}
617

718
def _second_lib_test_impl(ctx):
819
env = analysistest.begin(ctx)
@@ -67,9 +78,6 @@ def _bin_test_impl(ctx):
6778

6879
return analysistest.end(env)
6980

70-
ENABLE_PIPELINING = {
71-
"@//rust/settings:pipelined_compilation": True,
72-
}
7381
bin_test = analysistest.make(_bin_test_impl, config_settings = ENABLE_PIPELINING)
7482
second_lib_test = analysistest.make(_second_lib_test_impl, config_settings = ENABLE_PIPELINING)
7583

@@ -101,26 +109,87 @@ def _pipelined_compilation_test():
101109
deps = [":second"],
102110
)
103111

104-
NOT_WINDOWS = select({
105-
"@platforms//os:linux": [],
106-
"@platforms//os:macos": [],
107-
"//conditions:default": ["@platforms//:incompatible"],
108-
})
109112
second_lib_test(name = "second_lib_test", target_under_test = ":second", target_compatible_with = NOT_WINDOWS)
110113
bin_test(name = "bin_test", target_under_test = ":bin", target_compatible_with = NOT_WINDOWS)
111114

115+
def _custom_rule_test_impl(ctx):
116+
env = analysistest.begin(ctx)
117+
tut = analysistest.target_under_test(env)
118+
119+
# This is the metadata-generating action. It should depend on metadata for the library and, if generate_metadata is set
120+
# also depend on metadata for 'wrapper'.
121+
rust_action = [act for act in tut.actions if act.mnemonic == "RustcMetadata"][0]
122+
123+
metadata_inputs = [i for i in rust_action.inputs.to_list() if i.path.endswith(".rmeta")]
124+
rlib_inputs = [i for i in rust_action.inputs.to_list() if i.path.endswith(".rlib")]
125+
126+
seen_wrapper_metadata = False
127+
seen_to_wrap = False
128+
for mi in metadata_inputs:
129+
if "libwrapper" in mi.path:
130+
seen_wrapper_metadata = True
131+
if "libto_wrap" in mi.path:
132+
seen_to_wrap = True
133+
134+
seen_wrapper_rlib = True
135+
for ri in rlib_inputs:
136+
if "libwrapper" in ri.path:
137+
seen_wrapper_rlib = True
138+
139+
if ctx.attr.generate_metadata:
140+
asserts.true(env, seen_wrapper_metadata, "expected dependency on metadata for 'wrapper' but not found")
141+
else:
142+
asserts.true(env, seen_wrapper_rlib, "expected dependency on rlib for 'wrapper' but not found")
143+
144+
asserts.true(env, seen_to_wrap, "expected dependency on metadata for 'to_wrap' but not found")
145+
146+
return analysistest.end(env)
147+
148+
custom_rule_test = analysistest.make(_custom_rule_test_impl, attrs = {"generate_metadata": attr.bool()}, config_settings = ENABLE_PIPELINING)
149+
150+
def _custom_rule_test(generate_metadata, prefix):
151+
rust_library(
152+
name = "to_wrap" + prefix,
153+
crate_name = "to_wrap",
154+
srcs = ["custom_rule_test/to_wrap.rs"],
155+
edition = "2021",
156+
)
157+
wrap(
158+
name = "wrapper" + prefix,
159+
crate_name = "wrapper",
160+
target = ":to_wrap" + prefix,
161+
generate_metadata = generate_metadata,
162+
)
163+
rust_library(
164+
name = "uses_wrapper" + prefix,
165+
srcs = ["custom_rule_test/uses_wrapper.rs"],
166+
deps = [":wrapper" + prefix],
167+
edition = "2021",
168+
)
169+
170+
custom_rule_test(
171+
name = "custom_rule_test" + prefix,
172+
generate_metadata = generate_metadata,
173+
target_compatible_with = NOT_WINDOWS,
174+
target_under_test = ":uses_wrapper" + prefix,
175+
)
176+
112177
def pipelined_compilation_test_suite(name):
113178
"""Entry-point macro called from the BUILD file.
114179
115180
Args:
116181
name: Name of the macro.
117182
"""
118183
_pipelined_compilation_test()
184+
_custom_rule_test(generate_metadata = True, prefix = "_with_metadata")
185+
_custom_rule_test(generate_metadata = False, prefix = "_without_metadata")
119186

120187
native.test_suite(
121188
name = name,
122189
tests = [
123190
":bin_test",
124191
":second_lib_test",
192+
":custom_rule_test_with_metadata",
193+
":custom_rule_test_without_metadata",
125194
],
126195
)
+106
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
"""A custom rule that wraps a crate called to_wrap."""
2+
3+
# buildifier: disable=bzl-visibility
4+
load("//rust/private:common.bzl", "rust_common")
5+
6+
# buildifier: disable=bzl-visibility
7+
load("//rust/private:providers.bzl", "BuildInfo", "CrateInfo", "DepInfo", "DepVariantInfo")
8+
9+
# buildifier: disable=bzl-visibility
10+
load("//rust/private:rustc.bzl", "rustc_compile_action")
11+
12+
def _wrap_impl(ctx):
13+
rs_file = ctx.actions.declare_file(ctx.label.name + "_wrapped.rs")
14+
crate_name = ctx.attr.crate_name if ctx.attr.crate_name else ctx.label.name
15+
ctx.actions.run_shell(
16+
outputs = [rs_file],
17+
command = """cat <<EOF > {}
18+
// crate_name: {}
19+
use to_wrap::to_wrap;
20+
21+
pub fn wrap() {{
22+
to_wrap();
23+
}}
24+
EOF
25+
""".format(rs_file.path, crate_name),
26+
mnemonic = "WriteWrapperRsFile",
27+
)
28+
29+
toolchain = ctx.toolchains[Label("//rust:toolchain")]
30+
31+
# Determine unique hash for this rlib
32+
output_hash = repr(hash(rs_file.path))
33+
crate_type = "rlib"
34+
35+
rust_lib_name = "{prefix}{name}-{lib_hash}{extension}".format(
36+
prefix = "lib",
37+
name = crate_name,
38+
lib_hash = output_hash,
39+
extension = ".rlib",
40+
)
41+
rust_metadata_name = "{prefix}{name}-{lib_hash}{extension}".format(
42+
prefix = "lib",
43+
name = crate_name,
44+
lib_hash = output_hash,
45+
extension = ".rmeta",
46+
)
47+
48+
tgt = ctx.attr.target
49+
deps = [DepVariantInfo(
50+
crate_info = tgt[CrateInfo] if CrateInfo in tgt else None,
51+
dep_info = tgt[DepInfo] if DepInfo in tgt else None,
52+
build_info = tgt[BuildInfo] if BuildInfo in tgt else None,
53+
cc_info = tgt[CcInfo] if CcInfo in tgt else None,
54+
)]
55+
56+
rust_lib = ctx.actions.declare_file(rust_lib_name)
57+
rust_metadata = None
58+
if ctx.attr.generate_metadata:
59+
rust_metadata = ctx.actions.declare_file(rust_metadata_name)
60+
return rustc_compile_action(
61+
ctx = ctx,
62+
attr = ctx.attr,
63+
toolchain = toolchain,
64+
crate_info = rust_common.create_crate_info(
65+
name = crate_name,
66+
type = crate_type,
67+
root = rs_file,
68+
srcs = depset([rs_file]),
69+
deps = depset(deps),
70+
proc_macro_deps = depset([]),
71+
aliases = {},
72+
output = rust_lib,
73+
metadata = rust_metadata,
74+
owner = ctx.label,
75+
edition = "2018",
76+
compile_data = depset([]),
77+
rustc_env = {},
78+
is_test = False,
79+
),
80+
output_hash = output_hash,
81+
force_all_deps_direct = True,
82+
)
83+
84+
wrap = rule(
85+
implementation = _wrap_impl,
86+
attrs = {
87+
"target": attr.label(),
88+
"crate_name": attr.string(),
89+
"generate_metadata": attr.bool(default = False),
90+
"_cc_toolchain": attr.label(
91+
default = Label("@bazel_tools//tools/cpp:current_cc_toolchain"),
92+
),
93+
"_error_format": attr.label(
94+
default = Label("//:error_format"),
95+
),
96+
"_process_wrapper": attr.label(
97+
default = Label("//util/process_wrapper"),
98+
executable = True,
99+
allow_single_file = True,
100+
cfg = "exec",
101+
),
102+
},
103+
toolchains = ["@rules_rust//rust:toolchain", "@bazel_tools//tools/cpp:toolchain_type"],
104+
incompatible_use_toolchain_transition = True,
105+
fragments = ["cpp"],
106+
)

0 commit comments

Comments
 (0)