Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
ddd1aab
Remove WORKSPACE support (#4005)
UebelAndre May 1, 2026
8955ed9
feat: Add BPF triple constraint mapping (#3696)
tamird May 1, 2026
b117942
Rearrange link paths on Windows to reduce size overruns and fix errors
dzbarsky Jan 20, 2026
8a6d41f
Revert "Fix stamping for rules that don't have a stamp attribute (#38…
dzbarsky Feb 7, 2026
ca4e78d
Revert "Switch stamping detection to ctx.configuration.stamp_binaries…
dzbarsky Feb 7, 2026
36966a6
Fix process-wrapper link lib handling when using argfiles
dzbarsky Feb 16, 2026
7077649
Rewrite process_wrapper_bootstrap to cc
dzbarsky Feb 18, 2026
178e8b1
Attempt to fix CopyFile for windows
dzbarsky Feb 18, 2026
cc7f729
Apply lint config in exec configuration (#2)
isaacparker0 Feb 20, 2026
36636f8
Fix up rules_rust bzl_library targets
dzbarsky Feb 20, 2026
f3ab803
rust-analyzer: include Bazel package dir in crate source include_dirs…
isaacparker0 Feb 20, 2026
c8d69c4
Improve proc_macro_deps ergonomics
dzbarsky Sep 9, 2025
b6fb8c7
Always use param file for process wrapper
dzbarsky Feb 25, 2026
9fbeb37
Avoid hashing RustAnalyzerInfo in rust_analyzer alias mapping
dzbarsky Feb 26, 2026
186642f
Convert wrappers to symbolic macros
dzbarsky Feb 26, 2026
f2c4b34
Handle toolchain registration when not registered as a bazel_dep
dzbarsky Feb 28, 2026
8e3eafb
Replace the --rustc-quit-on-rmeta / .rmeta approach with Buck2-style …
walter-zeromatter Feb 26, 2026
7415c10
Cleanup some process_wrapper code
dzbarsky Mar 2, 2026
4e77128
Fix prost to be compatible with multiplatform
dzbarsky Mar 13, 2026
b5722a2
Improve toolchain make var env expansion
dzbarsky Apr 5, 2026
b9b21ce
Improve rust compilation messages
dzbarsky Apr 9, 2026
89e434f
Add rust_test sharding support (#13)
bolinfest Apr 15, 2026
4b829aa
Add per-crate rustc flag trimming
dzbarsky Apr 26, 2026
8a5bd5e
Fix Windows GNU staticlib output naming
dzbarsky Apr 26, 2026
a4b207a
Move processwrapper to rust toolchain
dzbarsky Dec 19, 2025
baa0c9d
Capture process wrapper exit codes
dzbarsky Apr 26, 2026
df75fa2
Provision hermetic SDKROOT
dzbarsky Apr 27, 2026
c06ed3b
Internalize macos SDK dep
dzbarsky Apr 30, 2026
b14563b
rustdoc_test should not do compilation at test time
dzbarsky May 2, 2026
0634f05
Fix CcInfo collection through CrateGroupInfo
dzbarsky May 3, 2026
e53c851
Expose macOS SDK from llvm module
dzbarsky May 3, 2026
c25cb73
Loongarch64 and sparc support
dzbarsky May 3, 2026
cc7fe80
Avoid vendored crates for rust-analyzer binary
dzbarsky Apr 1, 2026
7fb67be
Don't force passing proc_macro_deps via macro
dzbarsky May 4, 2026
c66deb0
Remove cargo build script rundir support
dzbarsky May 5, 2026
224b6b2
Shorten cargo build script manifest runfiles paths
dzbarsky May 5, 2026
df4f6c8
Simplify prost/pyo3 setup
dzbarsky May 5, 2026
cf176d8
Fix dynamic_runtime_libs support in dylibs
dzbarsky May 5, 2026
d1486fa
Separate build script data from compile_data (#21)
michaelm-openai May 8, 2026
d665c66
Fix nondeterministic SVH from sandbox-local OUT_DIR/CARGO_MANIFEST_DI…
walter-zeromatter May 8, 2026
8e7bee8
Add RUSTC_BOOTSTRAP guardrail for -Zno-codegen pipelining (#19)
walter-zeromatter May 8, 2026
b31843c
Handle versioned dynamic libs when linking
dillydill123 Apr 17, 2026
7cf06bd
fix
dillydill123 May 9, 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: 0 additions & 1 deletion .bazelignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,4 @@ crate_universe/private/bootstrap
crate_universe/tests/integration
docs
examples
extensions
test/integration
9 changes: 8 additions & 1 deletion MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,21 @@ 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.1.0")
bazel_dep(name = "protobuf", version = "28.3", repo_name = "com_google_protobuf")
bazel_dep(name = "rules_cc", version = "0.2.4")
bazel_dep(name = "rules_license", version = "1.0.0")
bazel_dep(name = "rules_proto", version = "7.1.0")
bazel_dep(name = "rules_python", version = "1.6.3")
bazel_dep(name = "rules_shell", version = "0.6.1")
bazel_dep(name = "apple_support", version = "1.24.1")
bazel_dep(name = "llvm", version = "0.7.7")

osx = use_extension("@llvm//extensions:osx.bzl", "osx")
use_repo(osx, "macos_sdk")

internal_deps = use_extension("//rust/private:internal_extensions.bzl", "i")
use_repo(
Expand Down Expand Up @@ -86,7 +94,6 @@ use_repo(
"rules_rust_toolchain_test_target_json",
)

bazel_dep(name = "rules_python", version = "1.5.1", dev_dependency = True)
bazel_dep(name = "rules_testing", version = "0.7.0", dev_dependency = True)
bazel_dep(name = "bazel_ci_rules", version = "1.0.0", dev_dependency = True)

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 @@ -39,6 +39,9 @@ copy_file(

bzl_library(
name = "bzl_lib",
deps = [
"//rust:bzl_lib",
],
srcs = glob(["**/*.bzl"]),
visibility = ["//:__subpackages__"],
visibility = ["//visibility:public"],
)
71 changes: 47 additions & 24 deletions cargo/private/cargo_build_script.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ load(
# Reexport for cargo_build_script_wrapper.bzl
name_to_crate_name = _name_to_crate_name

# Keep this short: it is part of CARGO_MANIFEST_DIR on Windows.
_CARGO_MANIFEST_DIR = "m"

CargoBuildScriptRunfilesInfo = provider(
doc = "Info about a `cargo_build_script.script` target.",
fields = {
Expand Down Expand Up @@ -293,13 +296,33 @@ def _feature_enabled(ctx, feature_name, default = False):

return default

def _manifest_rlocation_prefix(workspace_name, package):
if package:
return "{}/{}".format(workspace_name, package)

return workspace_name

def _rlocationpath(file, workspace_name):
if file.short_path.startswith("../"):
return file.short_path[len("../"):]

return "{}/{}".format(workspace_name, file.short_path)

def _create_runfiles_dir(ctx, script, retain_list):
def _manifest_dir_rlocationpath(rlocationpath, manifest_rlocation_prefix):
prefix = manifest_rlocation_prefix + "/"
if rlocationpath == manifest_rlocation_prefix:
return _CARGO_MANIFEST_DIR
if rlocationpath.startswith(prefix):
return paths.join(_CARGO_MANIFEST_DIR, rlocationpath[len(prefix):])

return None

def _create_runfiles_dir(
ctx,
script,
retain_list,
workspace_name,
manifest_rlocation_prefix):
"""Create a runfiles directory to represent `CARGO_MANIFEST_DIR`.

Due to the inability to forcibly generate runfiles directories for use as inputs
Expand All @@ -314,20 +337,24 @@ def _create_runfiles_dir(ctx, script, retain_list):
ctx (ctx): The rule's context object
script (Target): The `cargo_build_script.script` target.
retain_list (list): A list of strings to keep in generated runfiles directories.
workspace_name (str): The runfiles workspace name for the current repository.
manifest_rlocation_prefix (str): The current package's runfiles path prefix.

Returns:
Tuple[File, Depset[File], Args]:
- The output directory to be created.
- Runfile inputs needed by the action.
- The args required to create the directory.
"""
runfiles_dir = ctx.actions.declare_directory("{}.cargo_runfiles".format(ctx.label.name))

# External repos always fall into the `../` branch of `_rlocationpath`.
workspace_name = ctx.workspace_name
runfiles_dir = ctx.actions.declare_directory(ctx.label.name + ".crf")

def _runfiles_map(file):
return "{}={}".format(file.path, _rlocationpath(file, workspace_name))
rlocationpath = _rlocationpath(file, workspace_name)
manifest_path = _manifest_dir_rlocationpath(rlocationpath, manifest_rlocation_prefix)
if not manifest_path:
return "{}={}".format(file.path, rlocationpath)

return "{}={}".format(file.path, manifest_path)

runfiles = script[DefaultInfo].default_runfiles

Expand Down Expand Up @@ -382,8 +409,10 @@ def _cargo_build_script_impl(ctx):
ctx = ctx,
script = ctx.attr.script,
retain_list = ctx.attr._cargo_manifest_dir_filename_suffixes_to_retain[BuildSettingInfo].value,
workspace_name = workspace_name,
manifest_rlocation_prefix = _manifest_rlocation_prefix(workspace_name, ctx.label.package),
)
manifest_dir = "{}/{}/{}".format(runfiles_dir.path, workspace_name, ctx.label.package)
manifest_dir = paths.join(runfiles_dir.path, _CARGO_MANIFEST_DIR)

pkg_name = ctx.attr.pkg_name
if pkg_name == "":
Expand Down Expand Up @@ -538,6 +567,7 @@ def _cargo_build_script_impl(ctx):
known_variables.update(variables)

if ctx.attr.build_script_env:
_fail_on_rlocationpath_env(ctx.attr.build_script_env)
_merge_env_dict(env, expand_dict_value_locations(
ctx,
ctx.attr.build_script_env,
Expand Down Expand Up @@ -573,8 +603,6 @@ def _cargo_build_script_impl(ctx):
args.add(link_flags, format = "--link_flags=%s")
args.add(link_search_paths, format = "--link_search_paths=%s")
args.add(dep_env_out, format = "--dep_env_out=%s")
args.add(ctx.attr.rundir, format = "--rundir=%s")

output_groups = {
"out_dir": depset([out_dir]),
}
Expand Down Expand Up @@ -642,7 +670,7 @@ def _cargo_build_script_impl(ctx):
tools = tools,
inputs = depset(build_script_inputs, transitive = [runfiles_inputs]),
mnemonic = "CargoBuildScriptRun",
progress_message = "Running Cargo build script {}".format(pkg_name),
progress_message = "Running Cargo build script %{label}",
env = env,
toolchain = None,
use_default_shell_env = use_default_shell_env,
Expand All @@ -660,7 +688,8 @@ def _cargo_build_script_impl(ctx):
flags = flags_out,
linker_flags = link_flags,
link_search_paths = link_search_paths,
compile_data = depset([runfiles_dir] + extra_output, transitive = script_data),
build_script_data = depset(transitive = script_data),
compile_data = depset([runfiles_dir] + extra_output),
),
OutputGroupInfo(
**output_groups
Expand Down Expand Up @@ -717,19 +746,6 @@ cargo_build_script = rule(
"pkg_name": attr.string(
doc = "The name of package being compiled, if not derived from `name`.",
),
"rundir": attr.string(
default = "",
doc = dedent("""\
A directory to cd to before the cargo_build_script is run.

This should be a pathrelative to the exec root. The default behaviour (and the
behaviour if rundir is set to the empty string) is to change to the relative
path corresponding to the cargo manifest directory, which replicates the
normal behaviour of cargo so it is easy to write compatible build scripts.

If set to `.`, the cargo build script will run in the exec root.
"""),
),
"rustc_flags": attr.string_list(
doc = dedent("""\
List of compiler flags passed to `rustc`.
Expand Down Expand Up @@ -818,6 +834,13 @@ def _merge_env_dict(prefix_dict, suffix_dict):
prefix_dict[key] += " " + suffix_dict.pop(key)
prefix_dict.update(suffix_dict)

def _fail_on_rlocationpath_env(env):
for key, value in env.items():
if "$(rlocationpath" in value:
fail(
"cargo_build_script build_script_env does not support $(rlocationpath ...) in '{}'; use $(execpath ...) or $(location ...) for files needed while running the build script".format(key),
)

def name_to_pkg_name(name):
"""Sanitize the name of cargo_build_script targets.

Expand Down
30 changes: 3 additions & 27 deletions cargo/private/cargo_build_script_runner/bin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
use std::collections::BTreeMap;
use std::env;
use std::fs::{create_dir_all, read_dir, read_to_string, remove_file, write};
use std::path::{Path, PathBuf};
use std::path::Path;
use std::process::Command;

use cargo_build_script_runner::cargo_manifest_dir::{remove_symlink, symlink, RunfilesMaker};
Expand Down Expand Up @@ -46,7 +46,6 @@ fn run_buildrs() -> Result<(), String> {
output_dep_env_path,
stdout_path,
stderr_path,
rundir,
input_dep_env_paths,
cargo_manifest_maker,
} = Args::parse();
Expand Down Expand Up @@ -85,11 +84,9 @@ fn run_buildrs() -> Result<(), String> {
let target_env_vars =
get_target_env_vars(&rustc_env).expect("Error getting target env vars from rustc");

let working_directory = resolve_rundir(&rundir, &exec_root, &manifest_dir)?;

let mut command = Command::new(exec_root.join(progname));
command
.current_dir(&working_directory)
.current_dir(&manifest_dir)
.envs(target_env_vars)
.env("OUT_DIR", &out_dir_abs)
.env("CARGO_MANIFEST_DIR", manifest_dir)
Expand Down Expand Up @@ -315,23 +312,6 @@ fn symlink_if_not_exists(original: &Path, link: &Path) -> Result<(), String> {
.map_err(|err| format!("Failed to create symlink: {err}"))
}

fn resolve_rundir(rundir: &str, exec_root: &Path, manifest_dir: &Path) -> Result<PathBuf, String> {
if rundir.is_empty() {
return Ok(manifest_dir.to_owned());
}
let rundir_path = Path::new(rundir);
if rundir_path.is_absolute() {
return Err(format!("rundir must be empty (to run in manifest path) or relative path (relative to exec root), but was {:?}", rundir));
}
if rundir_path
.components()
.any(|c| c == std::path::Component::ParentDir)
{
return Err(format!("rundir must not contain .. but was {:?}", rundir));
}
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(())
Expand All @@ -352,7 +332,6 @@ struct Args {
output_dep_env_path: String,
stdout_path: Option<String>,
stderr_path: Option<String>,
rundir: String,
input_dep_env_paths: Vec<String>,
cargo_manifest_maker: RunfilesMaker,
}
Expand All @@ -376,7 +355,6 @@ impl Args {
Err("Argument `output_dep_env_path` not provided".to_owned());
let mut stdout_path = None;
let mut stderr_path = None;
let mut rundir: Result<String, String> = Err("Argument `rundir` not provided".to_owned());
let mut input_dep_env_paths = Vec::new();
let mut cargo_manifest_maker: Result<RunfilesMaker, String> =
Err("Argument `cargo_manifest_args` not provided".to_owned());
Expand All @@ -402,8 +380,6 @@ impl Args {
stdout_path = Some(arg.split_off("--stdout=".len()));
} else if arg.starts_with("--stderr=") {
stderr_path = Some(arg.split_off("--stderr=".len()));
} else if arg.starts_with("--rundir=") {
rundir = Ok(arg.split_off("--rundir=".len()))
} else if arg.starts_with("--input_dep_env_path=") {
input_dep_env_paths.push(arg.split_off("--input_dep_env_path=".len()));
} else if arg.starts_with("--cargo_manifest_args=") {
Expand All @@ -424,7 +400,6 @@ impl Args {
output_dep_env_path: output_dep_env_path.unwrap(),
stdout_path,
stderr_path,
rundir: rundir.unwrap(),
input_dep_env_paths,
cargo_manifest_maker: cargo_manifest_maker.unwrap(),
}
Expand Down Expand Up @@ -493,6 +468,7 @@ fn main() {
mod test {
use super::*;
use std::fs::{create_dir_all, write};
use std::path::PathBuf;

fn make_temp_dir(label: &str) -> PathBuf {
let nanos = std::time::SystemTime::now()
Expand Down
24 changes: 11 additions & 13 deletions cargo/private/cargo_build_script_runner/cargo_manifest_dir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,8 @@ pub struct RunfilesMaker {
/// A list of file suffixes to retain when pruning runfiles.
filename_suffixes_to_retain: BTreeSet<String>,

/// Runfiles to include in `output_dir`.
runfiles: BTreeMap<PathBuf, RlocationPath>,
/// Runfiles to include in `output_dir`, keyed by destination path.
runfiles: BTreeMap<RlocationPath, PathBuf>,
}

impl RunfilesMaker {
Expand Down Expand Up @@ -151,7 +151,7 @@ impl RunfilesMaker {
let (src, dest) = s
.split_once('=')
.unwrap_or_else(|| panic!("Unexpected runfiles argument: {}", s));
(PathBuf::from(src), RlocationPath::from(dest))
(RlocationPath::from(dest), PathBuf::from(src))
})
.collect::<BTreeMap<_, _>>();

Expand All @@ -167,7 +167,7 @@ impl RunfilesMaker {
/// Create a runfiles directory.
#[cfg(target_family = "unix")]
pub fn create_runfiles_dir(&self) -> Result<(), String> {
for (src, dest) in &self.runfiles {
for (dest, src) in &self.runfiles {
let abs_dest = self.output_dir.join(dest);

if let Some(parent) = abs_dest.parent() {
Expand Down Expand Up @@ -213,7 +213,7 @@ impl RunfilesMaker {

let supports_symlinks = system_supports_symlinks(&self.output_dir)?;

for (src, dest) in &self.runfiles {
for (dest, src) in &self.runfiles {
let abs_dest = self.output_dir.join(dest);
if let Some(parent) = abs_dest.parent() {
if !parent.exists() {
Expand Down Expand Up @@ -258,7 +258,7 @@ impl RunfilesMaker {
/// The Unix implementation assumes symlinks are supported and that the runfiles directory
/// was created using symlinks.
fn drain_runfiles_dir_unix(&self) -> Result<(), String> {
for (src, dest) in &self.runfiles {
for (dest, src) in &self.runfiles {
let abs_dest = self.output_dir.join(dest);

remove_symlink(&abs_dest).map_err(|e| {
Expand Down Expand Up @@ -315,19 +315,17 @@ impl RunfilesMaker {
/// The Windows implementation assumes symlinks are not supported and real files will have
/// been copied into the runfiles directory.
fn drain_runfiles_dir_windows(&self) -> Result<(), String> {
for dest in self.runfiles.values() {
for dest in self.runfiles.keys() {
if !self
.filename_suffixes_to_retain
.iter()
.any(|suffix| dest.ends_with(suffix))
{
continue;
let abs_dest = self.output_dir.join(dest);
std::fs::remove_file(&abs_dest).map_err(|e| {
format!("Failed to remove file {} with {:?}", abs_dest.display(), e)
})?;
}

let abs_dest = self.output_dir.join(dest);
std::fs::remove_file(&abs_dest).map_err(|e| {
format!("Failed to remove file {} with {:?}", abs_dest.display(), e)
})?;
}
Ok(())
}
Expand Down
Loading