Skip to content

Commit d47646a

Browse files
committed
Support path mapping in Rust Starlark actions
Transition from passing raw string paths (`.path`) to passing `File` objects directly to action arguments (`Args`). Additionally, model elements of `emit` that require explicit file paths as `(string, Path)` tuples. This allows Bazel to perform path mapping on compiler outputs in an extensible way. For more details on path mapping best practices, see: bazelbuild/bazel#22658
1 parent 34ea934 commit d47646a

3 files changed

Lines changed: 30 additions & 19 deletions

File tree

rust/private/rustc.bzl

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -834,7 +834,10 @@ def collect_inputs(
834834

835835
def _will_emit_object_file(emit):
836836
for e in emit:
837-
if e == "obj" or e.startswith("obj="):
837+
if type(e) in ["tuple", "list"] and len(e) == 2:
838+
if e[0] == "obj":
839+
return True
840+
elif type(e) == "string" and (e == "obj" or e.startswith("obj=")):
838841
return True
839842
return False
840843

@@ -1173,6 +1176,10 @@ def construct_arguments(
11731176
for kind in emit:
11741177
if kind == "link" and crate_info.type == "bin" and crate_info.output != None:
11751178
rustc_flags.add(crate_info.output, format = "--emit=link=%s")
1179+
elif type(kind) in ["tuple", "list"] and len(kind) == 2:
1180+
# 'kind' is a (string, File) tuple/list. Passing the File object directly to
1181+
# Args.add allows Bazel to perform path mapping on the path.
1182+
rustc_flags.add(kind[1], format = "--emit=" + kind[0] + "=%s")
11761183
else:
11771184
emit_without_paths.append(kind)
11781185

@@ -1563,6 +1570,23 @@ def rustc_compile_action(
15631570
if experimental_use_cc_common_link:
15641571
emit = ["obj"]
15651572

1573+
# Declares the outputs of the rustc compile action.
1574+
# By default this is the binary output; if cc_common.link is used, this is
1575+
# the main `.o` file (`output_o` below).
1576+
outputs = [crate_info.output]
1577+
1578+
# The `.o` output file, only used for linking via cc_common.link.
1579+
# When output_hash is set (e.g. for rust_test targets), include it in the
1580+
# filename to avoid collisions with other targets sharing the same crate name.
1581+
output_o = None
1582+
if "obj" in emit:
1583+
obj_ext = ".o"
1584+
obj_basename = crate_info.name + ("-%s" % output_hash if output_hash else "")
1585+
output_o = ctx.actions.declare_file(obj_basename + obj_ext, sibling = crate_info.output)
1586+
outputs = [output_o]
1587+
emit.remove("obj")
1588+
emit.append(("obj", output_o))
1589+
15661590
# Determine whether to pass `--require-explicit-unstable-features true` to the process wrapper:
15671591
require_explicit_unstable_features = False
15681592
if hasattr(ctx.attr, "require_explicit_unstable_features"):
@@ -1637,21 +1661,6 @@ def rustc_compile_action(
16371661
else:
16381662
formatted_version = ""
16391663

1640-
# Declares the outputs of the rustc compile action.
1641-
# By default this is the binary output; if cc_common.link is used, this is
1642-
# the main `.o` file (`output_o` below).
1643-
outputs = [crate_info.output]
1644-
1645-
# The `.o` output file, only used for linking via cc_common.link.
1646-
# When output_hash is set (e.g. for rust_test targets), include it in the
1647-
# filename to avoid collisions with other targets sharing the same crate name.
1648-
output_o = None
1649-
if experimental_use_cc_common_link:
1650-
obj_ext = ".o"
1651-
obj_basename = crate_info.name + ("-%s" % output_hash if output_hash else "")
1652-
output_o = ctx.actions.declare_file(obj_basename + obj_ext, sibling = crate_info.output)
1653-
outputs = [output_o]
1654-
16551664
# For a cdylib that might be added as a dependency to a cc_* target on Windows, it is important to include the
16561665
# interface library that rustc generates in the output files.
16571666
interface_library = None

rust/toolchain.bzl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -645,7 +645,7 @@ def _rust_toolchain_impl(ctx):
645645
sysroot_anchor = sysroot.sysroot_anchor,
646646
sysroot_short_path = sysroot_short_path,
647647
target_arch = target_arch,
648-
target_flag_value = target_json.path if target_json else target_triple.str,
648+
target_flag_value = target_json if target_json else target_triple.str,
649649
target_json = target_json,
650650
target_os = target_os,
651651
target_abi = target_abi,

test/unit/toolchain/toolchain_test.bzl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,10 @@ def _toolchain_specifies_target_json_test_impl(ctx):
3030
asserts.equals(env, expected_basename, toolchain_info.target_json.basename)
3131

3232
# The value is expected to be to a generated file in bazel-out.
33-
asserts.true(env, toolchain_info.target_flag_value.startswith("bazel-out/"))
34-
asserts.true(env, toolchain_info.target_flag_value.endswith("/bin/{}/{}".format(ctx.label.package, expected_basename)))
33+
asserts.equals(env, "File", type(toolchain_info.target_flag_value))
34+
target_path = toolchain_info.target_flag_value.path
35+
asserts.true(env, target_path.startswith("bazel-out/"))
36+
asserts.true(env, target_path.endswith("/bin/{}/{}".format(ctx.label.package, expected_basename)))
3537

3638
return analysistest.end(env)
3739

0 commit comments

Comments
 (0)