Skip to content

Commit b33fa53

Browse files
committed
Add the generated_crate_root attribute to cargo_build_script
This change allows us to declare that a build script generates a crate root. Dependent targets created with `rust_library` and `rust_binary` will respect the setting.
1 parent 982c202 commit b33fa53

File tree

5 files changed

+31
-2
lines changed

5 files changed

+31
-2
lines changed

cargo/private/cargo_build_script.bzl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,7 @@ def _cargo_build_script_impl(ctx):
610610
DefaultInfo(files = depset([out_dir])),
611611
BuildInfo(
612612
out_dir = out_dir,
613+
build_script_crate_root = ctx.attr.generated_crate_root,
613614
rustc_env = env_out,
614615
dep_env = dep_env_out,
615616
flags = flags_out,
@@ -659,6 +660,9 @@ cargo_build_script = rule(
659660
providers = [[DepInfo], [CrateGroupInfo]],
660661
cfg = "exec",
661662
),
663+
"generated_crate_root": attr.string(
664+
doc = "The location of the crate root when it is generated by the build script",
665+
),
662666
"link_deps": attr.label_list(
663667
doc = dedent("""\
664668
The subset of the Rust (normal) dependencies of the crate that

extensions/bindgen/private/bindgen.bzl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@ def _generate_cc_link_build_info(ctx, cc_lib):
185185
linker_flags = None,
186186
link_search_paths = link_search_paths,
187187
out_dir = None,
188+
build_script_crate_root = None,
188189
rustc_env = None,
189190
)
190191

rust/private/providers.bzl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ BuildInfo = provider(
8585
"link_search_paths": "Optional[File]: file containing search paths to pass to rustc and linker",
8686
"linker_flags": "Optional[File]: file containing flags to pass to the linker invoked by rustc or cc_common.link",
8787
"out_dir": "Optional[File]: directory containing the result of a build script",
88+
"build_script_crate_root": "Optional[String]: the crate root that was generated by a build script",
8889
"rustc_env": "Optional[File]: file containing additional environment variables to set for rustc.",
8990
},
9091
)

rust/private/rust.bzl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ load(
3333
"can_build_metadata",
3434
"can_use_metadata_for_pipelining",
3535
"compute_crate_name",
36+
"crate_root_from_build_scripts",
3637
"crate_root_src",
3738
"dedent",
3839
"deduplicate",
@@ -169,7 +170,7 @@ def _rust_library_common(ctx, crate_type):
169170

170171
crate_root = getattr(ctx.file, "crate_root", None)
171172
if not crate_root:
172-
crate_root = crate_root_src(ctx.attr.name, ctx.attr.crate_name, ctx.files.srcs, crate_type)
173+
crate_root = crate_root_from_build_scripts(ctx) or crate_root_src(ctx.attr.name, ctx.attr.crate_name, ctx.files.srcs, crate_type)
173174
srcs, compile_data, crate_root = transform_sources(ctx, ctx.files.srcs, ctx.files.compile_data, crate_root)
174175

175176
# Determine unique hash for this rlib.
@@ -265,7 +266,7 @@ def _rust_binary_impl(ctx):
265266

266267
crate_root = getattr(ctx.file, "crate_root", None)
267268
if not crate_root:
268-
crate_root = crate_root_src(ctx.attr.name, ctx.attr.crate_name, ctx.files.srcs, ctx.attr.crate_type)
269+
crate_root = crate_root_from_build_scripts(ctx) or crate_root_src(ctx.attr.name, ctx.attr.crate_name, ctx.files.srcs, ctx.attr.crate_type)
269270
srcs, compile_data, crate_root = transform_sources(ctx, ctx.files.srcs, ctx.files.compile_data, crate_root)
270271

271272
rust_metadata = None

rust/private/utils.bzl

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -756,6 +756,28 @@ def can_use_metadata_for_pipelining(toolchain, crate_type):
756756
return toolchain._pipelined_compilation and \
757757
crate_type in ("rlib", "lib")
758758

759+
def crate_root_from_build_scripts(ctx):
760+
"""
761+
Identify the generated crate root that comes from a build script (if any)
762+
and return a symlink to it (File).
763+
764+
Args:
765+
ctx: (ctx): The current rule's context object
766+
"""
767+
candidate_filename = None
768+
candidate_path = None
769+
for dep in ctx.attr.deps:
770+
if BuildInfo in dep:
771+
if dep[BuildInfo].build_script_crate_root:
772+
candidate_filename = dep[BuildInfo].build_script_crate_root
773+
candidate_path = dep[BuildInfo].out_dir.path + "/" + candidate_filename
774+
break
775+
if candidate_path:
776+
crate_root = ctx.actions.declare_symlink(candidate_filename)
777+
symlink_target = relativize(candidate_path, crate_root.dirname)
778+
ctx.actions.symlink(output = crate_root, target_path = symlink_target)
779+
return crate_root
780+
759781
def crate_root_src(name, crate_name, srcs, crate_type):
760782
"""Determines the source file for the crate root, should it not be specified in `attr.crate_root`.
761783

0 commit comments

Comments
 (0)