Skip to content

Commit bb74a65

Browse files
authored
Improve handling of compile_data with mixed sources (#3176)
I'm not very well versed in starlark nor the rules_rust codebase, so feel free to ignore this and address the issue in a more fitting way, but this fixes #3171 and a related issue for me.
1 parent 5e426fa commit bb74a65

File tree

6 files changed

+94
-21
lines changed

6 files changed

+94
-21
lines changed

rust/private/rust.bzl

+12-14
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ def _rust_library_common(ctx, crate_type):
149149
crate_root = getattr(ctx.file, "crate_root", None)
150150
if not crate_root:
151151
crate_root = crate_root_src(ctx.attr.name, ctx.attr.crate_name, ctx.files.srcs, crate_type)
152-
srcs, crate_root = transform_sources(ctx, ctx.files.srcs, crate_root)
152+
srcs, compile_data, crate_root = transform_sources(ctx, ctx.files.srcs, ctx.files.compile_data, crate_root)
153153

154154
# Determine unique hash for this rlib.
155155
# Note that we don't include a hash for `cdylib` and `staticlib` since they are meant to be consumed externally
@@ -202,7 +202,7 @@ def _rust_library_common(ctx, crate_type):
202202
rustc_env_files = ctx.files.rustc_env_files,
203203
is_test = False,
204204
data = depset(ctx.files.data),
205-
compile_data = depset(ctx.files.compile_data),
205+
compile_data = depset(compile_data),
206206
compile_data_targets = depset(ctx.attr.compile_data),
207207
owner = ctx.label,
208208
),
@@ -233,7 +233,7 @@ def _rust_binary_impl(ctx):
233233
crate_root = getattr(ctx.file, "crate_root", None)
234234
if not crate_root:
235235
crate_root = crate_root_src(ctx.attr.name, ctx.attr.crate_name, ctx.files.srcs, ctx.attr.crate_type)
236-
srcs, crate_root = transform_sources(ctx, ctx.files.srcs, crate_root)
236+
srcs, compile_data, crate_root = transform_sources(ctx, ctx.files.srcs, ctx.files.compile_data, crate_root)
237237

238238
providers = rustc_compile_action(
239239
ctx = ctx,
@@ -254,7 +254,7 @@ def _rust_binary_impl(ctx):
254254
rustc_env_files = ctx.files.rustc_env_files,
255255
is_test = False,
256256
data = depset(ctx.files.data),
257-
compile_data = depset(ctx.files.compile_data),
257+
compile_data = depset(compile_data),
258258
compile_data_targets = depset(ctx.attr.compile_data),
259259
owner = ctx.label,
260260
),
@@ -330,13 +330,11 @@ def _rust_test_impl(ctx):
330330
),
331331
)
332332

333-
srcs, crate_root = transform_sources(ctx, ctx.files.srcs, getattr(ctx.file, "crate_root", None))
333+
# Need to consider all src files together when transforming
334+
srcs = depset(ctx.files.srcs, transitive = [crate.srcs]).to_list()
335+
compile_data = depset(ctx.files.compile_data, transitive = [crate.compile_data]).to_list()
336+
srcs, compile_data, crate_root = transform_sources(ctx, srcs, compile_data, getattr(ctx.file, "crate_root", None))
334337

335-
# Optionally join compile data
336-
if crate.compile_data:
337-
compile_data = depset(ctx.files.compile_data, transitive = [crate.compile_data])
338-
else:
339-
compile_data = depset(ctx.files.compile_data)
340338
if crate.compile_data_targets:
341339
compile_data_targets = depset(ctx.attr.compile_data, transitive = [crate.compile_data_targets])
342340
else:
@@ -360,7 +358,7 @@ def _rust_test_impl(ctx):
360358
name = crate_name,
361359
type = crate_type,
362360
root = crate.root,
363-
srcs = depset(srcs, transitive = [crate.srcs]),
361+
srcs = depset(srcs),
364362
deps = depset(deps, transitive = [crate.deps]),
365363
proc_macro_deps = depset(proc_macro_deps, transitive = [crate.proc_macro_deps]),
366364
aliases = aliases,
@@ -370,7 +368,7 @@ def _rust_test_impl(ctx):
370368
rustc_env = rustc_env,
371369
rustc_env_files = rustc_env_files,
372370
is_test = True,
373-
compile_data = compile_data,
371+
compile_data = depset(compile_data),
374372
compile_data_targets = compile_data_targets,
375373
wrapped_crate_type = crate.type,
376374
owner = ctx.label,
@@ -381,7 +379,7 @@ def _rust_test_impl(ctx):
381379
if not crate_root:
382380
crate_root_type = "lib" if ctx.attr.use_libtest_harness else "bin"
383381
crate_root = crate_root_src(ctx.attr.name, ctx.attr.crate_name, ctx.files.srcs, crate_root_type)
384-
srcs, crate_root = transform_sources(ctx, ctx.files.srcs, crate_root)
382+
srcs, compile_data, crate_root = transform_sources(ctx, ctx.files.srcs, ctx.files.compile_data, crate_root)
385383

386384
if toolchain._incompatible_change_rust_test_compilation_output_directory:
387385
output = ctx.actions.declare_file(
@@ -420,7 +418,7 @@ def _rust_test_impl(ctx):
420418
rustc_env = rustc_env,
421419
rustc_env_files = ctx.files.rustc_env_files,
422420
is_test = True,
423-
compile_data = depset(ctx.files.compile_data),
421+
compile_data = depset(compile_data),
424422
compile_data_targets = depset(ctx.attr.compile_data),
425423
owner = ctx.label,
426424
)

rust/private/utils.bzl

+13-5
Original file line numberDiff line numberDiff line change
@@ -789,7 +789,7 @@ def determine_lib_name(name, crate_type, toolchain, lib_hash = None):
789789
extension = extension,
790790
)
791791

792-
def transform_sources(ctx, srcs, crate_root):
792+
def transform_sources(ctx, srcs, compile_data, crate_root):
793793
"""Creates symlinks of the source files if needed.
794794
795795
Rustc assumes that the source files are located next to the crate root.
@@ -802,25 +802,33 @@ def transform_sources(ctx, srcs, crate_root):
802802
Args:
803803
ctx (struct): The current rule's context.
804804
srcs (List[File]): The sources listed in the `srcs` attribute
805+
compile_data (List[File]): The sources listed in the `compile_data`
806+
attribute
805807
crate_root (File): The file specified in the `crate_root` attribute,
806808
if it exists, otherwise None
807809
808810
Returns:
809-
Tuple(List[File], File): The transformed srcs and crate_root
811+
Tuple(List[File], List[File], File): The transformed srcs, compile_data
812+
and crate_root
810813
"""
811-
has_generated_sources = len([src for src in srcs if not src.is_source]) > 0
814+
has_generated_sources = (
815+
len([src for src in srcs if not src.is_source]) +
816+
len([src for src in compile_data if not src.is_source]) >
817+
0
818+
)
812819

813820
if not has_generated_sources:
814-
return srcs, crate_root
821+
return srcs, compile_data, crate_root
815822

816823
package_root = paths.join(ctx.label.workspace_root, ctx.label.package)
817824
generated_sources = [_symlink_for_non_generated_source(ctx, src, package_root) for src in srcs if src != crate_root]
825+
generated_compile_data = [_symlink_for_non_generated_source(ctx, src, package_root) for src in compile_data]
818826
generated_root = crate_root
819827
if crate_root:
820828
generated_root = _symlink_for_non_generated_source(ctx, crate_root, package_root)
821829
generated_sources.append(generated_root)
822830

823-
return generated_sources, generated_root
831+
return generated_sources, generated_compile_data, generated_root
824832

825833
def get_edition(attr, toolchain, label):
826834
"""Returns the Rust edition from either the current rule's attributes or the current `rust_toolchain`
+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/// Data loaded from generated compile data
2+
pub const COMPILE_DATA: &str = include_str!("generated.txt");
3+
4+
#[cfg(test)]
5+
mod test {
6+
use super::*;
7+
8+
#[test]
9+
fn test_compile_data_contents() {
10+
assert_eq!(COMPILE_DATA.trim_end(), "generated compile data contents");
11+
}
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
pub mod generated;
2+
3+
/// Data loaded from compile data
4+
pub const COMPILE_DATA: &str = include_str!("compile_data.txt");
5+
6+
#[cfg(test)]
7+
mod test {
8+
use super::*;
9+
10+
#[test]
11+
fn test_compile_data_contents() {
12+
assert_eq!(COMPILE_DATA.trim_end(), "compile data contents");
13+
}
14+
15+
#[test]
16+
fn test_generated_src() {
17+
assert_eq!(generated::GENERATED, "generated");
18+
}
19+
}

test/unit/compile_data/compile_data_test.bzl

+36
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,42 @@ def _define_test_targets():
9595
crate = ":compile_data_env",
9696
)
9797

98+
native.genrule(
99+
name = "generated_compile_data",
100+
outs = ["generated.txt"],
101+
cmd = "echo 'generated compile data contents' > $@",
102+
)
103+
104+
rust_library(
105+
name = "compile_data_gen",
106+
srcs = ["compile_data_gen.rs"],
107+
compile_data = [":generated.txt"],
108+
edition = "2021",
109+
)
110+
111+
rust_test(
112+
name = "compile_data_gen_unit_test",
113+
crate = ":compile_data_gen",
114+
)
115+
116+
native.genrule(
117+
name = "generated_src",
118+
outs = ["generated.rs"],
119+
cmd = """echo 'pub const GENERATED: &str = "generated";' > $@""",
120+
)
121+
122+
rust_library(
123+
name = "compile_data_gen_srcs",
124+
srcs = ["compile_data_gen_srcs.rs", ":generated.rs"],
125+
compile_data = ["compile_data.txt"],
126+
edition = "2021",
127+
)
128+
129+
rust_test(
130+
name = "compile_data_gen_srcs_unit_test",
131+
crate = ":compile_data_gen_srcs",
132+
)
133+
98134
def compile_data_test_suite(name):
99135
"""Entry-point macro called from the BUILD file.
100136

test/unit/location_expansion/location_expansion_test.bzl

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ load("//test/unit:common.bzl", "assert_action_mnemonic", "assert_argv_contains")
88
def _location_expansion_rustc_flags_test(ctx):
99
env = analysistest.begin(ctx)
1010
tut = analysistest.target_under_test(env)
11-
action = tut.actions[0]
11+
action = tut.actions[1]
1212
assert_action_mnemonic(env, action, "Rustc")
13-
assert_argv_contains(env, action, "test/unit/location_expansion/mylibrary.rs")
13+
assert_argv_contains(env, action, ctx.bin_dir.path + "/test/unit/location_expansion/mylibrary.rs")
1414
expected = "@${pwd}/" + ctx.bin_dir.path + "/test/unit/location_expansion/generated_flag.data"
1515
assert_argv_contains(env, action, expected)
1616
return analysistest.end(env)

0 commit comments

Comments
 (0)