Skip to content

Commit 71bdd24

Browse files
dabankikrasimirgg
andauthored
Support path mapping in Rust Starlark actions (#4063)
Transition from passing raw string paths (`.path`) to passing `File` objects directly to action arguments (`Args`). This allows Bazel to mutate paths during execution, which is required for path mapping compatibility. For more details on path mapping best practices, see: bazelbuild/bazel#22658 Co-authored-by: Krasimir Georgiev <krasimir@google.com>
1 parent 0d36c00 commit 71bdd24

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
@@ -836,7 +836,10 @@ def collect_inputs(
836836

837837
def _will_emit_object_file(emit):
838838
for e in emit:
839-
if e == "obj" or e.startswith("obj="):
839+
if type(e) in ["tuple", "list"] and len(e) == 2:
840+
if e[0] == "obj":
841+
return True
842+
elif type(e) == "string" and (e == "obj" or e.startswith("obj=")):
840843
return True
841844
return False
842845

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

@@ -1565,6 +1572,23 @@ def rustc_compile_action(
15651572
if experimental_use_cc_common_link:
15661573
emit = ["obj"]
15671574

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

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