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
31 changes: 31 additions & 0 deletions rust/private/rustc.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -1193,6 +1193,18 @@ def construct_arguments(
rustc_flags.add("--remap-path-prefix=${{output_base}}={}".format(remap_path_prefix))
rustc_flags.add("--remap-path-prefix=${{pwd}}={}".format(remap_path_prefix))
rustc_flags.add("--remap-path-prefix=${{exec_root}}={}".format(remap_path_prefix))
if not crate_info.root.is_source:
# Also remap the relative bazel-out/<config>/bin/ prefix.
# file!(), Location::caller(), and tracing/log macros embed
# the literal relative path that rustc received on the command
# line. The ${pwd} remap above only matches absolute paths in
# debug info, so a second remap without ${pwd} is needed to
# strip the bin-dir prefix from these compile-time paths.
#
# Use add_all with the crate root File and a map_each callback
# so Bazel's path mapping (--experimental_output_paths=strip)
# can rewrite the config portion of the bin-dir prefix.
rustc_flags.add_all([crate_info.root], map_each = _get_bin_dir_remap_prefix)

emit_without_paths = []
for kind in emit:
Expand Down Expand Up @@ -2706,6 +2718,25 @@ def _add_native_link_flags(
format_each = "-lstatic=%s",
)

def _get_bin_dir_remap_prefix(file):
"""Derives a --remap-path-prefix flag that strips the bin-dir prefix.

For a generated file, file.path is "bazel-out/<config>/bin/<pkg>/<name>"
and file.short_path is "<pkg>/<name>". The difference is the bin-dir
prefix that needs to be stripped from file!() and similar macros.

Using the File object with add_all/map_each lets Bazel apply path mapping
(--experimental_output_paths=strip) to the config portion of the path.

Args:
file (File): The crate root file (must be a generated file).

Returns:
str: A --remap-path-prefix flag that maps the bin-dir prefix to empty.
"""
prefix = file.path[:len(file.path) - len(file.short_path)]
return "--remap-path-prefix={}=".format(prefix)

def _get_dirname(file):
"""A helper function for `_add_native_link_flags`.

Expand Down
27 changes: 27 additions & 0 deletions test/unit/remap_path_prefix/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
load("@bazel_skylib//rules:write_file.bzl", "write_file")
load("//rust:defs.bzl", "rust_binary", "rust_library", "rust_test")
load(":debug_transition.bzl", "dbg_rust_binary")
load(":remap_path_prefix_test.bzl", "remap_path_prefix_test_suite")
Expand Down Expand Up @@ -37,6 +38,32 @@ rust_test(
deps = ["//rust/runfiles"],
)

# Library with generated source to trigger transform_sources().
# Exposes file!() so a runtime test can verify the path is clean.
write_file(
name = "remap_file_macro_lib_src",
out = "remap_file_macro_lib.rs",
content = [
"pub fn get_file_path() -> &'static str {",
" file!()",
"}",
"",
],
)

rust_library(
name = "remap_file_macro_lib",
srcs = [":remap_file_macro_lib.rs"],
edition = "2021",
)

rust_test(
name = "file_macro_test",
srcs = ["file_macro_test.rs"],
edition = "2021",
deps = [":remap_file_macro_lib"],
)

remap_path_prefix_test_suite(
name = "remap_path_prefix_test_suite",
)
8 changes: 8 additions & 0 deletions test/unit/remap_path_prefix/file_macro_test.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#[test]
fn file_macro_has_no_bazel_out_prefix() {
let path = remap_file_macro_lib::get_file_path();
assert!(
!path.contains("bazel-out"),
"file!() should not contain 'bazel-out' prefix, got: {path}",
);
}
55 changes: 55 additions & 0 deletions test/unit/remap_path_prefix/remap_path_prefix_test.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ load("//rust:defs.bzl", "rust_binary", "rust_library")
load(
"//test/unit:common.bzl",
"assert_action_mnemonic",
"assert_argv_contains",
"assert_argv_contains_prefix_not",
"assert_argv_contains_prefix_suffix",
"assert_list_contains_adjacent_elements",
)

Expand All @@ -26,6 +29,38 @@ def _remap_path_prefix_test_impl(ctx):

_remap_path_prefix_test = analysistest.make(_remap_path_prefix_test_impl)

def _remap_path_prefix_source_test_impl(ctx):
"""Verify that source targets do NOT get the relative bin-dir remap."""
env = analysistest.begin(ctx)
target = analysistest.target_under_test(env)

action = target.actions[0]
assert_action_mnemonic(env, action, "Rustc")

assert_argv_contains(env, action, "--remap-path-prefix=${pwd}=.")
assert_argv_contains(env, action, "--remap-path-prefix=${exec_root}=.")
assert_argv_contains(env, action, "--remap-path-prefix=${output_base}=.")
assert_argv_contains_prefix_not(env, action, "--remap-path-prefix=bazel-out/")

return analysistest.end(env)

_remap_path_prefix_source_test = analysistest.make(_remap_path_prefix_source_test_impl)

def _remap_file_macro_generated_test_impl(ctx):
"""Verify that generated-source targets get a relative bin-dir remap for file!()."""
env = analysistest.begin(ctx)
target = analysistest.target_under_test(env)

action = target.actions[0]
assert_action_mnemonic(env, action, "Rustc")

# Should have the relative bin-dir remap (e.g. --remap-path-prefix=bazel-out/k8-fastbuild/bin/=)
assert_argv_contains_prefix_suffix(env, action, "--remap-path-prefix=bazel-out/", "/bin/=")

return analysistest.end(env)

_remap_file_macro_generated_test = analysistest.make(_remap_file_macro_generated_test_impl)

def _subst_flags_test_impl(ctx):
"""Verify that process wrapper --subst flags are present."""
env = analysistest.begin(ctx)
Expand Down Expand Up @@ -88,6 +123,23 @@ def remap_path_prefix_test_suite(name):
target_under_test = ":remap_bin",
)

# Verify source targets do NOT get the relative bin-dir remap.
_remap_path_prefix_source_test(
name = "remap_path_prefix_source_lib_test",
target_under_test = ":dep",
)

# Verify generated-source targets get the relative bin-dir remap for file!().
_remap_file_macro_generated_test(
name = "remap_file_macro_generated_lib_test",
target_under_test = ":remap_lib",
)

_remap_file_macro_generated_test(
name = "remap_file_macro_generated_bin_test",
target_under_test = ":remap_bin",
)

_subst_flags_test(
name = "subst_flags_lib_test",
target_under_test = ":remap_lib",
Expand All @@ -101,6 +153,9 @@ def remap_path_prefix_test_suite(name):
tests = [
":remap_path_prefix_lib_test",
":remap_path_prefix_bin_test",
":remap_path_prefix_source_lib_test",
":remap_file_macro_generated_lib_test",
":remap_file_macro_generated_bin_test",
":subst_flags_lib_test",
":subst_flags_bin_test",
]
Expand Down
Loading