Skip to content

Commit

Permalink
rewrite cross-lang-lto to rmake
Browse files Browse the repository at this point in the history
  • Loading branch information
Oneirical committed Jul 30, 2024
1 parent 4db3d12 commit fbd930b
Show file tree
Hide file tree
Showing 5 changed files with 148 additions and 60 deletions.
36 changes: 36 additions & 0 deletions src/tools/run-make-support/src/external_deps/llvm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ pub fn llvm_ar() -> LlvmAr {
LlvmAr::new()
}

/// Construct a new `llvm-bcanalyzer` invocation. This assumes that `llvm-bcanalyzer` is available
/// at `$LLVM_BIN_DIR/llvm-bcanalyzer`.
pub fn llvm_bcanalyzer() -> LlvmBcanalyzer {
LlvmBcanalyzer::new()
}

/// A `llvm-readobj` invocation builder.
#[derive(Debug)]
#[must_use]
Expand Down Expand Up @@ -71,11 +77,19 @@ pub struct LlvmAr {
cmd: Command,
}

/// A `llvm-bcanalyzer` invocation builder.
#[derive(Debug)]
#[must_use]
pub struct LlvmBcanalyzer {
cmd: Command,
}

crate::macros::impl_common_helpers!(LlvmReadobj);
crate::macros::impl_common_helpers!(LlvmProfdata);
crate::macros::impl_common_helpers!(LlvmFilecheck);
crate::macros::impl_common_helpers!(LlvmObjdump);
crate::macros::impl_common_helpers!(LlvmAr);
crate::macros::impl_common_helpers!(LlvmBcanalyzer);

/// Generate the path to the bin directory of LLVM.
#[must_use]
Expand Down Expand Up @@ -236,6 +250,12 @@ impl LlvmAr {
self
}

/// Extract archive members back to files.
pub fn extract(&mut self) -> &mut Self {
self.cmd.arg("x");
self
}

/// Provide an output, then an input file. Bundled in one function, as llvm-ar has
/// no "--output"-style flag.
pub fn output_input(&mut self, out: impl AsRef<Path>, input: impl AsRef<Path>) -> &mut Self {
Expand All @@ -244,3 +264,19 @@ impl LlvmAr {
self
}
}

impl LlvmBcanalyzer {
/// Construct a new `llvm-bcanalyzer` invocation. This assumes that `llvm-bcanalyzer` is available
/// at `$LLVM_BIN_DIR/llvm-bcanalyzer`.
pub fn new() -> Self {
let llvm_bcanalyzer = llvm_bin_dir().join("llvm-bcanalyzer");
let cmd = Command::new(llvm_bcanalyzer);
Self { cmd }
}

/// Provide an input file.
pub fn input<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
self.cmd.arg(path.as_ref());
self
}
}
4 changes: 2 additions & 2 deletions src/tools/run-make-support/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ pub use cc::{cc, cxx, extra_c_flags, extra_cxx_flags, Cc};
pub use clang::{clang, Clang};
pub use htmldocck::htmldocck;
pub use llvm::{
llvm_ar, llvm_filecheck, llvm_objdump, llvm_profdata, llvm_readobj, LlvmAr, LlvmFilecheck,
LlvmObjdump, LlvmProfdata, LlvmReadobj,
llvm_ar, llvm_bcanalyzer, llvm_filecheck, llvm_objdump, llvm_profdata, llvm_readobj, LlvmAr,
LlvmBcanalyzer, LlvmFilecheck, LlvmObjdump, LlvmProfdata, LlvmReadobj,
};
pub use python::python_command;
pub use rustc::{aux_build, bare_rustc, rustc, Rustc};
Expand Down
1 change: 0 additions & 1 deletion src/tools/tidy/src/allowed_run_make_makefiles.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ run-make/cdylib-dylib-linkage/Makefile
run-make/cross-lang-lto-clang/Makefile
run-make/cross-lang-lto-pgo-smoketest/Makefile
run-make/cross-lang-lto-upstream-rlibs/Makefile
run-make/cross-lang-lto/Makefile
run-make/dep-info-doesnt-run-much/Makefile
run-make/dep-info-spaces/Makefile
run-make/dep-info/Makefile
Expand Down
57 changes: 0 additions & 57 deletions tests/run-make/cross-lang-lto/Makefile

This file was deleted.

110 changes: 110 additions & 0 deletions tests/run-make/cross-lang-lto/rmake.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
// This test checks that the object files we generate are actually
// LLVM bitcode files (as used by linker LTO plugins) when compiling with
// -Clinker-plugin-lto.
// See https://github.com/rust-lang/rust/pull/50000

#![feature(path_file_prefix)]

use std::path::PathBuf;

use run_make_support::{
cwd, has_extension, has_prefix, llvm_ar, llvm_bcanalyzer, path, rfs, rust_lib_name, rustc,
shallow_find_files, static_lib_name,
};

fn main() {
check_bitcode(LibBuild {
source: path("lib.rs"),
crate_type: Some("staticlib"),
output: path(static_lib_name("liblib")),
lto: None,
emit_obj: false,
});
check_bitcode(LibBuild {
source: path("lib.rs"),
crate_type: Some("staticlib"),
output: path(static_lib_name("liblib-fat-lto")),
lto: Some("fat"),
emit_obj: false,
});
check_bitcode(LibBuild {
source: path("lib.rs"),
crate_type: Some("staticlib"),
output: path(static_lib_name("liblib-thin-lto")),
lto: Some("thin"),
emit_obj: false,
});
check_bitcode(LibBuild {
source: path("lib.rs"),
crate_type: Some("rlib"),
output: path(rust_lib_name("liblib")),
lto: None,
emit_obj: false,
});
check_bitcode(LibBuild {
source: path("lib.rs"),
crate_type: Some("cdylib"),
output: path("cdylib.o"),
lto: None,
emit_obj: true,
});
check_bitcode(LibBuild {
source: path("lib.rs"),
crate_type: Some("dylib"),
output: path("rdylib.o"),
lto: None,
emit_obj: true,
});
check_bitcode(LibBuild {
source: path("main.rs"),
crate_type: None,
output: path("exe.o"),
lto: None,
emit_obj: true,
});
}

#[track_caller]
fn check_bitcode(instructions: LibBuild) {
let mut rustc = rustc();
rustc
.input(instructions.source)
.output(&instructions.output)
.opt_level("2")
.codegen_units(1)
.arg("-Clinker-plugin-lto");
if instructions.emit_obj {
rustc.emit("obj");
}
if let Some(crate_type) = instructions.crate_type {
rustc.crate_type(crate_type);
}
if let Some(lto) = instructions.lto {
rustc.arg(format!("-Clto={lto}"));
}
rustc.run();

if instructions.output.extension().unwrap() != "o" {
// Remove all potential leftover object files, then turn the output into an object file.
for object in shallow_find_files(cwd(), |path| has_extension(path, "o")) {
rfs::remove_file(object);
}
llvm_ar().extract().arg(&instructions.output).run();
}

for object in shallow_find_files(cwd(), |path| {
has_prefix(path, instructions.output.file_prefix().unwrap().to_str().unwrap())
&& has_extension(path, "o")
}) {
// All generated object files should be LLVM bitcode files - this will fail otherwise.
llvm_bcanalyzer().input(object).run();
}
}

struct LibBuild {
source: PathBuf,
crate_type: Option<&'static str>,
output: PathBuf,
lto: Option<&'static str>,
emit_obj: bool,
}

0 comments on commit fbd930b

Please sign in to comment.