Auto merge of #145207 - Kobzol:codegen-backend-clif-dist, r=jieyouxu

Ship correct Cranelift library in its dist component

The first commit adds a post-dist UI test to check that Cranelift can be used with the extracted dist x64 Linux archive.

The original codegen copy logic in the Cranelift dist step was a bit redundant, and I didn't notice in https://github.com/rust-lang/rust/pull/144787 that it's copying the codegen backend from the build compiler's sysroot, rather than the target compiler's sysroot. The second commit modifies the logic to directly access the built codegen file (there is no need to search for it in the compiler's sysroot, in fact when you run just `x dist rustc_codegen_cranelift`, it shouldn't "taint" the sysroot with the codegen backend! Which it did before https://github.com/rust-lang/rust/pull/144787) and copy it to the tarball under a normalized name. Thus we get around any similar potential issues in the future, and make previously implicit logic more explicit.

This also fixes running just `x dist rustc_codegen_cranelift` without enabling `cranelift` in `rust.codegen-backends`, which should have been enabled by https://github.com/rust-lang/rust/pull/144787, but it didn't work fully, because the dist step tried to copy the codegen backend from the compiler's sysroot, but it didn't contain the codegen backend if it was not enabled by `rust.codegen-backends`.

Fixes: https://github.com/rust-lang/rust/issues/145201

try-job: dist-x86_64-linux
This commit is contained in:
bors 2025-08-11 16:13:06 +00:00
commit 6355cd39c8
4 changed files with 56 additions and 30 deletions

View File

@ -1761,20 +1761,30 @@ fn copy_codegen_backends_to_sysroot(
}
if stamp.path().exists() {
let dylib = t!(fs::read_to_string(stamp.path()));
let file = Path::new(&dylib);
let filename = file.file_name().unwrap().to_str().unwrap();
// change `librustc_codegen_cranelift-xxxxxx.so` to
// `librustc_codegen_cranelift-release.so`
let target_filename = {
let dash = filename.find('-').unwrap();
let dot = filename.find('.').unwrap();
format!("{}-{}{}", &filename[..dash], builder.rust_release(), &filename[dot..])
};
builder.copy_link(file, &dst.join(target_filename), FileType::NativeLibrary);
let file = get_codegen_backend_file(&stamp);
builder.copy_link(
&file,
&dst.join(normalize_codegen_backend_name(builder, &file)),
FileType::NativeLibrary,
);
}
}
/// Gets the path to a dynamic codegen backend library from its build stamp.
pub fn get_codegen_backend_file(stamp: &BuildStamp) -> PathBuf {
PathBuf::from(t!(fs::read_to_string(stamp.path())))
}
/// Normalize the name of a dynamic codegen backend library.
pub fn normalize_codegen_backend_name(builder: &Builder<'_>, path: &Path) -> String {
let filename = path.file_name().unwrap().to_str().unwrap();
// change e.g. `librustc_codegen_cranelift-xxxxxx.so` to
// `librustc_codegen_cranelift-release.so`
let dash = filename.find('-').unwrap();
let dot = filename.find('.').unwrap();
format!("{}-{}{}", &filename[..dash], builder.rust_release(), &filename[dot..])
}
pub fn compiler_file(
builder: &Builder<'_>,
compiler: &Path,

View File

@ -19,6 +19,7 @@ use object::read::archive::ArchiveFile;
#[cfg(feature = "tracing")]
use tracing::instrument;
use crate::core::build_steps::compile::{get_codegen_backend_file, normalize_codegen_backend_name};
use crate::core::build_steps::doc::DocumentationFormat;
use crate::core::build_steps::tool::{self, RustcPrivateCompilers, Tool};
use crate::core::build_steps::vendor::{VENDOR_DIR, Vendor};
@ -1460,35 +1461,29 @@ impl Step for CraneliftCodegenBackend {
tarball.is_preview(true);
tarball.add_legal_and_readme_to("share/doc/rustc_codegen_cranelift");
builder.ensure(compile::CraneliftCodegenBackend { compilers });
let stamp = builder.ensure(compile::CraneliftCodegenBackend { compilers });
if builder.config.dry_run() {
return None;
}
let src = builder.sysroot(self.build_compiler);
let backends_src = builder.sysroot_codegen_backends(self.build_compiler);
let backends_rel = backends_src
.strip_prefix(src)
// Get the relative path of where the codegen backend should be stored.
let backends_dst = builder.sysroot_codegen_backends(compilers.target_compiler());
let backends_rel = backends_dst
.strip_prefix(builder.sysroot(compilers.target_compiler()))
.unwrap()
.strip_prefix(builder.sysroot_libdir_relative(self.build_compiler))
.strip_prefix(builder.sysroot_libdir_relative(compilers.target_compiler()))
.unwrap();
// Don't use custom libdir here because ^lib/ will be resolved again with installer
let backends_dst = PathBuf::from("lib").join(backends_rel);
let mut found_backend = false;
for backend in fs::read_dir(&backends_src).unwrap() {
let file_name = backend.unwrap().file_name();
if file_name.to_str().unwrap().contains("rustc_codegen_cranelift") {
tarball.add_file(
backends_src.join(file_name),
&backends_dst,
FileType::NativeLibrary,
);
found_backend = true;
}
}
assert!(found_backend);
let codegen_backend_dylib = get_codegen_backend_file(&stamp);
tarball.add_renamed_file(
&codegen_backend_dylib,
&backends_dst,
&normalize_codegen_backend_name(builder, &codegen_backend_dylib),
FileType::NativeLibrary,
);
Some(tarball.generate())
}

View File

@ -36,6 +36,16 @@ pub fn run_tests(env: &Environment) -> anyhow::Result<()> {
let cargo_dir = extract_dist_dir(&format!("cargo-{version}-{host_triple}"))?.join("cargo");
let extracted_src_dir = extract_dist_dir(&format!("rust-src-{version}"))?.join("rust-src");
// If we have a Cranelift archive, copy it to the rustc sysroot
if let Ok(_) = find_file_in_dir(&dist_dir, "rustc-codegen-cranelift-", ".tar.xz") {
let extracted_codegen_dir =
extract_dist_dir(&format!("rustc-codegen-cranelift-{version}-{host_triple}"))?
.join("rustc-codegen-cranelift-preview");
let rel_path =
Utf8Path::new("lib").join("rustlib").join(host_triple).join("codegen-backends");
copy_directory(&extracted_codegen_dir.join(&rel_path), &rustc_dir.join(&rel_path))?;
}
// We need to manually copy libstd to the extracted rustc sysroot
copy_directory(
&libstd_dir.join("lib").join("rustlib").join(host_triple).join("lib"),

View File

@ -0,0 +1,11 @@
// Ensure that Cranelift can be used to compile a simple program with `x86_64-unknown-linux-gnu`
// dist artifacts.
//@ only-dist
//@ only-x86_64-unknown-linux-gnu
//@ compile-flags: -Z codegen-backend=cranelift
//@ run-pass
fn main() {
println!("Hello world!");
}