Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions cargo/private/cargo_build_script.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -610,6 +610,7 @@ def _cargo_build_script_impl(ctx):
DefaultInfo(files = depset([out_dir])),
BuildInfo(
out_dir = out_dir,
build_script_crate_root = ctx.attr.generated_crate_root,
rustc_env = env_out,
dep_env = dep_env_out,
flags = flags_out,
Expand Down Expand Up @@ -659,6 +660,9 @@ cargo_build_script = rule(
providers = [[DepInfo], [CrateGroupInfo]],
cfg = "exec",
),
"generated_crate_root": attr.string(
doc = "The location of the crate root when it is generated by the build script",
),
"link_deps": attr.label_list(
doc = dedent("""\
The subset of the Rust (normal) dependencies of the crate that
Expand Down
1 change: 1 addition & 0 deletions extensions/bindgen/private/bindgen.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ def _generate_cc_link_build_info(ctx, cc_lib):
linker_flags = None,
link_search_paths = link_search_paths,
out_dir = None,
build_script_crate_root = None,
rustc_env = None,
)

Expand Down
1 change: 1 addition & 0 deletions rust/private/providers.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ BuildInfo = provider(
"link_search_paths": "Optional[File]: file containing search paths to pass to rustc and linker",
"linker_flags": "Optional[File]: file containing flags to pass to the linker invoked by rustc or cc_common.link",
"out_dir": "Optional[File]: directory containing the result of a build script",
"build_script_crate_root": "Optional[String]: the crate root that was generated by a build script",
"rustc_env": "Optional[File]: file containing additional environment variables to set for rustc.",
},
)
Expand Down
5 changes: 3 additions & 2 deletions rust/private/rust.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ load(
"can_build_metadata",
"can_use_metadata_for_pipelining",
"compute_crate_name",
"crate_root_from_build_scripts",
"crate_root_src",
"dedent",
"deduplicate",
Expand Down Expand Up @@ -169,7 +170,7 @@ def _rust_library_common(ctx, crate_type):

crate_root = getattr(ctx.file, "crate_root", None)
if not crate_root:
crate_root = crate_root_src(ctx.attr.name, ctx.attr.crate_name, ctx.files.srcs, crate_type)
crate_root = crate_root_from_build_scripts(ctx) or crate_root_src(ctx.attr.name, ctx.attr.crate_name, ctx.files.srcs, crate_type)
srcs, compile_data, crate_root = transform_sources(ctx, ctx.files.srcs, ctx.files.compile_data, crate_root)

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

crate_root = getattr(ctx.file, "crate_root", None)
if not crate_root:
crate_root = crate_root_src(ctx.attr.name, ctx.attr.crate_name, ctx.files.srcs, ctx.attr.crate_type)
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)
srcs, compile_data, crate_root = transform_sources(ctx, ctx.files.srcs, ctx.files.compile_data, crate_root)

rust_metadata = None
Expand Down
22 changes: 22 additions & 0 deletions rust/private/utils.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -756,6 +756,28 @@ def can_use_metadata_for_pipelining(toolchain, crate_type):
return toolchain._pipelined_compilation and \
crate_type in ("rlib", "lib")

def crate_root_from_build_scripts(ctx):
"""
Identify the generated crate root that comes from a build script (if any)
and return a symlink to it (File).

Args:
ctx: (ctx): The current rule's context object
"""
candidate_filename = None
candidate_path = None
for dep in ctx.attr.deps:
if BuildInfo in dep:
if dep[BuildInfo].build_script_crate_root:
candidate_filename = dep[BuildInfo].build_script_crate_root
candidate_path = dep[BuildInfo].out_dir.path + "/" + candidate_filename
break
if candidate_path:
crate_root = ctx.actions.declare_symlink(candidate_filename)
symlink_target = relativize(candidate_path, crate_root.dirname)
ctx.actions.symlink(output = crate_root, target_path = symlink_target)
return crate_root

def crate_root_src(name, crate_name, srcs, crate_type):
"""Determines the source file for the crate root, should it not be specified in `attr.crate_root`.

Expand Down