Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
b4c649c
Proper handling for windows mingw flags
dzbarsky Dec 23, 2025
5403348
Properly handle artifact_name_patterns
dzbarsky Dec 18, 2025
4dc9ac6
Rearrange link paths on Windows to reduce size overruns and fix errors
dzbarsky Jan 20, 2026
09cc477
Fix some triple-mapping errors
dzbarsky Jan 31, 2026
93206e6
Strip -pthread for Windows link args
dzbarsky Feb 7, 2026
e0f1c13
Revert "Fix stamping for rules that don't have a stamp attribute (#38…
dzbarsky Feb 7, 2026
f8d867c
Revert "Switch stamping detection to ctx.configuration.stamp_binaries…
dzbarsky Feb 7, 2026
8efa3fa
Fix process-wrapper link lib handling when using argfiles
dzbarsky Feb 16, 2026
70777e4
Rewrite process_wrapper_bootstrap to cc
dzbarsky Feb 18, 2026
c24d82e
Attempt to fix CopyFile for windows
dzbarsky Feb 18, 2026
53fb4fa
Apply lint config in exec configuration (#2)
isaacparker0 Feb 20, 2026
775d23a
Fix up rules_rust bzl_library targets
dzbarsky Feb 20, 2026
81cbd5d
rust-analyzer: include Bazel package dir in crate source include_dirs…
isaacparker0 Feb 20, 2026
fa7a428
Improve proc_macro_deps ergonomics
dzbarsky Sep 9, 2025
e1d254a
Always use param file for process wrapper
dzbarsky Feb 25, 2026
c69567d
Avoid hashing RustAnalyzerInfo in rust_analyzer alias mapping
dzbarsky Feb 26, 2026
1272c03
Convert wrappers to symbolic macros
dzbarsky Feb 26, 2026
8e568ba
Add missing system keys to `triple_mappings.bzl` (#5)
ArchangelX360 Feb 28, 2026
333382b
Handle toolchain registration when not registered as a bazel_dep
dzbarsky Feb 28, 2026
627b424
Switch pipelining metadata action to hollow rlib (-Zno-codegen)
walter-zeromatter Feb 26, 2026
6f3357c
Cleanup some process_wrapper code
dzbarsky Mar 2, 2026
7ed8a24
Fix prost to be compatible with multiplatform
dzbarsky Mar 13, 2026
3bba328
Add worker-managed pipelined compilation and incremental build support
walter-zeromatter Mar 26, 2026
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
1 change: 1 addition & 0 deletions MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ module(
## Core
###############################################################################

bazel_dep(name = "bazel_lib", version = "3.0.0")
bazel_dep(name = "bazel_features", version = "1.32.0")
bazel_dep(name = "bazel_skylib", version = "1.8.2")
bazel_dep(name = "platforms", version = "1.0.0")
Expand Down
7 changes: 5 additions & 2 deletions cargo/private/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
load("@bazel_lib//lib:copy_file.bzl", "copy_file")
load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
load("@bazel_skylib//rules:copy_file.bzl", "copy_file")
load("//rust:defs.bzl", "rust_binary")

rust_binary(
Expand Down Expand Up @@ -40,5 +40,8 @@ copy_file(
bzl_library(
name = "bzl_lib",
srcs = glob(["**/*.bzl"]),
visibility = ["//:__subpackages__"],
visibility = ["//visibility:public"],
deps = [
"//rust:bzl_lib",
],
)
6 changes: 6 additions & 0 deletions cargo/private/cargo_build_script.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -632,6 +632,9 @@ def _cargo_build_script_impl(ctx):

if experimental_symlink_execroot:
env["RULES_RUST_SYMLINK_EXEC_ROOT"] = "1"
skip_patterns = ctx.attr._symlink_exec_root_skip_patterns[BuildSettingInfo].value
if skip_patterns:
env["RULES_RUST_SYMLINK_EXEC_ROOT_SKIP_PATTERNS"] = ",".join(skip_patterns)

ctx.actions.run(
executable = ctx.executable._cargo_build_script_runner,
Expand Down Expand Up @@ -787,6 +790,9 @@ cargo_build_script = rule(
"_experimental_symlink_execroot": attr.label(
default = Label("//cargo/settings:experimental_symlink_execroot"),
),
"_symlink_exec_root_skip_patterns": attr.label(
default = Label("//cargo/settings:symlink_exec_root_skip_patterns"),
),
"_fallback_ar": attr.label(
cfg = "exec",
executable = True,
Expand Down
105 changes: 84 additions & 21 deletions cargo/private/cargo_build_script_runner/bin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ fn run_buildrs() -> Result<(), String> {

let mut exec_root_links = Vec::new();
if should_symlink_exec_root() {
let exec_root_skip_patterns = symlink_exec_root_skip_patterns();
// Symlink the execroot to the manifest_dir so that we can use relative paths in the arguments.
let exec_root_paths = std::fs::read_dir(&exec_root)
.map_err(|err| format!("Failed while listing exec root: {err:?}"))?;
Expand All @@ -75,12 +76,26 @@ fn run_buildrs() -> Result<(), String> {
let file_name = path
.file_name()
.ok_or_else(|| "Failed while getting file name".to_string())?;

// Skip entries matching user-configurable patterns from
// RULES_RUST_SYMLINK_EXEC_ROOT_SKIP_PATTERNS (comma-separated).
// Patterns support trailing '*' as a prefix glob.
let name = file_name.to_string_lossy();
if exec_root_skip_patterns
.iter()
.any(|p| match_skip_pattern(p, &name))
{
continue;
}

let link = manifest_dir.join(file_name);

symlink_if_not_exists(&path, &link)
let created = symlink_if_not_exists(&path, &link)
.map_err(|err| format!("Failed to symlink {path:?} to {link:?}: {err}"))?;

exec_root_links.push(link)
if created {
exec_root_links.push(link);
}
}
}

Expand Down Expand Up @@ -219,15 +234,25 @@ fn run_buildrs() -> Result<(), String> {
)
});

if !exec_root_links.is_empty() {
for link in exec_root_links {
remove_symlink(&link).map_err(|e| {
format!(
"Failed to remove exec_root link '{}' with {:?}",
for link in exec_root_links {
if let Err(e) = remove_symlink(&link) {
if cfg!(target_family = "windows") {
// On Windows, symlink removal can fail with PermissionDenied if
// another process still holds a handle to the target directory.
// These are temporary symlinks in the build sandbox that Bazel
// will clean up, so we log and continue rather than failing.
eprintln!(
"Warning: could not remove exec_root link '{}': {:?}",
link.display(),
e
)
})?;
);
} else {
return Err(format!(
"Failed to remove exec_root link '{}': {:?}",
link.display(),
e
));
}
}
}

Expand All @@ -246,11 +271,34 @@ fn should_symlink_exec_root() -> bool {
.unwrap_or(false)
}

/// Parse skip patterns from `RULES_RUST_SYMLINK_EXEC_ROOT_SKIP_PATTERNS`.
/// Returns a comma-separated list of patterns. Each pattern is either an exact
/// match or a prefix glob (trailing `*`).
fn symlink_exec_root_skip_patterns() -> Vec<String> {
env::var("RULES_RUST_SYMLINK_EXEC_ROOT_SKIP_PATTERNS")
.map(|s| s.split(',').map(|p| p.to_owned()).collect())
.unwrap_or_default()
}

/// Match a skip pattern against a file name. Supports exact match and
/// trailing `*` as a prefix glob (e.g. `local-spawn-runner.*` matches
/// `local-spawn-runner.12345`).
fn match_skip_pattern(pattern: &str, name: &str) -> bool {
if let Some(prefix) = pattern.strip_suffix('*') {
name.starts_with(prefix)
} else {
name == pattern
}
}

/// Create a symlink from `link` to `original` if `link` doesn't already exist.
fn symlink_if_not_exists(original: &Path, link: &Path) -> Result<(), String> {
symlink(original, link)
.or_else(swallow_already_exists)
.map_err(|err| format!("Failed to create symlink: {err}"))
/// Returns `true` if a new symlink was created, `false` if the path already existed.
fn symlink_if_not_exists(original: &Path, link: &Path) -> Result<bool, String> {
match symlink(original, link) {
Ok(()) => Ok(true),
Err(err) if err.kind() == std::io::ErrorKind::AlreadyExists => Ok(false),
Err(err) => Err(format!("Failed to create symlink: {err}")),
}
}

fn resolve_rundir(rundir: &str, exec_root: &Path, manifest_dir: &Path) -> Result<PathBuf, String> {
Expand All @@ -270,14 +318,6 @@ fn resolve_rundir(rundir: &str, exec_root: &Path, manifest_dir: &Path) -> Result
Ok(exec_root.join(rundir_path))
}

fn swallow_already_exists(err: std::io::Error) -> std::io::Result<()> {
if err.kind() == std::io::ErrorKind::AlreadyExists {
Ok(())
} else {
Err(err)
}
}

/// A representation of expected command line arguments.
struct Args {
progname: String,
Expand Down Expand Up @@ -470,4 +510,27 @@ windows
assert_eq!(tree["CARGO_CFG_WINDOWS"], "");
assert_eq!(tree["CARGO_CFG_TARGET_FAMILY"], "windows");
}

#[test]
fn skip_pattern_exact_match() {
assert!(match_skip_pattern(".git", ".git"));
assert!(!match_skip_pattern(".git", ".github"));
assert!(!match_skip_pattern(".git", ".gi"));
assert!(!match_skip_pattern(".git", ""));
}

#[test]
fn skip_pattern_prefix_glob() {
assert!(match_skip_pattern("local-spawn-runner.*", "local-spawn-runner.12345"));
assert!(match_skip_pattern("local-spawn-runner.*", "local-spawn-runner."));
assert!(!match_skip_pattern("local-spawn-runner.*", "local-spawn-runner"));
assert!(!match_skip_pattern("local-spawn-runner.*", "other-thing"));
}

#[test]
fn skip_pattern_star_alone() {
// A bare "*" pattern matches everything.
assert!(match_skip_pattern("*", "anything"));
assert!(match_skip_pattern("*", ""));
}
}
Loading