Skip to content

Commit 5367673

Browse files
committed
Auto merge of rust-lang#128352 - Oneirical:daLTOnist-vision, r=jieyouxu
Migrate `cross-lang-lto` `run-make` test to rmake Part of rust-lang#121876 and the associated [Google Summer of Code project](https://blog.rust-lang.org/2024/05/01/gsoc-2024-selected-projects.html). Please try: try-job: x86_64-msvc try-job: i686-mingw try-job: x86_64-mingw try-job: armhf-gnu try-job: test-various try-job: aarch64-apple try-job: x86_64-gnu-llvm-18
2 parents 1932602 + 152db27 commit 5367673

File tree

5 files changed

+148
-60
lines changed

5 files changed

+148
-60
lines changed

src/tools/run-make-support/src/external_deps/llvm.rs

+36
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,12 @@ pub fn llvm_nm() -> LlvmNm {
4242
LlvmNm::new()
4343
}
4444

45+
/// Construct a new `llvm-bcanalyzer` invocation. This assumes that `llvm-bcanalyzer` is available
46+
/// at `$LLVM_BIN_DIR/llvm-bcanalyzer`.
47+
pub fn llvm_bcanalyzer() -> LlvmBcanalyzer {
48+
LlvmBcanalyzer::new()
49+
}
50+
4551
/// A `llvm-readobj` invocation builder.
4652
#[derive(Debug)]
4753
#[must_use]
@@ -84,12 +90,20 @@ pub struct LlvmNm {
8490
cmd: Command,
8591
}
8692

93+
/// A `llvm-bcanalyzer` invocation builder.
94+
#[derive(Debug)]
95+
#[must_use]
96+
pub struct LlvmBcanalyzer {
97+
cmd: Command,
98+
}
99+
87100
crate::macros::impl_common_helpers!(LlvmReadobj);
88101
crate::macros::impl_common_helpers!(LlvmProfdata);
89102
crate::macros::impl_common_helpers!(LlvmFilecheck);
90103
crate::macros::impl_common_helpers!(LlvmObjdump);
91104
crate::macros::impl_common_helpers!(LlvmAr);
92105
crate::macros::impl_common_helpers!(LlvmNm);
106+
crate::macros::impl_common_helpers!(LlvmBcanalyzer);
93107

94108
/// Generate the path to the bin directory of LLVM.
95109
#[must_use]
@@ -250,6 +264,12 @@ impl LlvmAr {
250264
self
251265
}
252266

267+
/// Extract archive members back to files.
268+
pub fn extract(&mut self) -> &mut Self {
269+
self.cmd.arg("x");
270+
self
271+
}
272+
253273
/// Provide an output, then an input file. Bundled in one function, as llvm-ar has
254274
/// no "--output"-style flag.
255275
pub fn output_input(&mut self, out: impl AsRef<Path>, input: impl AsRef<Path>) -> &mut Self {
@@ -274,3 +294,19 @@ impl LlvmNm {
274294
self
275295
}
276296
}
297+
298+
impl LlvmBcanalyzer {
299+
/// Construct a new `llvm-bcanalyzer` invocation. This assumes that `llvm-bcanalyzer` is available
300+
/// at `$LLVM_BIN_DIR/llvm-bcanalyzer`.
301+
pub fn new() -> Self {
302+
let llvm_bcanalyzer = llvm_bin_dir().join("llvm-bcanalyzer");
303+
let cmd = Command::new(llvm_bcanalyzer);
304+
Self { cmd }
305+
}
306+
307+
/// Provide an input file.
308+
pub fn input<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
309+
self.cmd.arg(path.as_ref());
310+
self
311+
}
312+
}

src/tools/run-make-support/src/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ pub use cc::{cc, cxx, extra_c_flags, extra_cxx_flags, Cc};
4949
pub use clang::{clang, Clang};
5050
pub use htmldocck::htmldocck;
5151
pub use llvm::{
52-
llvm_ar, llvm_filecheck, llvm_nm, llvm_objdump, llvm_profdata, llvm_readobj, LlvmAr,
53-
LlvmFilecheck, LlvmNm, LlvmObjdump, LlvmProfdata, LlvmReadobj,
52+
llvm_ar, llvm_bcanalyzer, llvm_filecheck, llvm_nm, llvm_objdump, llvm_profdata, llvm_readobj,
53+
LlvmAr, LlvmBcanalyzer, LlvmFilecheck, LlvmNm, LlvmObjdump, LlvmProfdata, LlvmReadobj,
5454
};
5555
pub use python::python_command;
5656
pub use rustc::{aux_build, bare_rustc, rustc, Rustc};

src/tools/tidy/src/allowed_run_make_makefiles.txt

-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ run-make/cdylib-dylib-linkage/Makefile
44
run-make/cross-lang-lto-clang/Makefile
55
run-make/cross-lang-lto-pgo-smoketest/Makefile
66
run-make/cross-lang-lto-upstream-rlibs/Makefile
7-
run-make/cross-lang-lto/Makefile
87
run-make/dep-info-doesnt-run-much/Makefile
98
run-make/dep-info-spaces/Makefile
109
run-make/dep-info/Makefile

tests/run-make/cross-lang-lto/Makefile

-57
This file was deleted.
+110
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
// This test checks that the object files we generate are actually
2+
// LLVM bitcode files (as used by linker LTO plugins) when compiling with
3+
// -Clinker-plugin-lto.
4+
// See https://github.com/rust-lang/rust/pull/50000
5+
6+
#![feature(path_file_prefix)]
7+
8+
use std::path::PathBuf;
9+
10+
use run_make_support::{
11+
cwd, has_extension, has_prefix, llvm_ar, llvm_bcanalyzer, path, rfs, rust_lib_name, rustc,
12+
shallow_find_files, static_lib_name,
13+
};
14+
15+
fn main() {
16+
check_bitcode(LibBuild {
17+
source: path("lib.rs"),
18+
crate_type: Some("staticlib"),
19+
output: path(static_lib_name("liblib")),
20+
lto: None,
21+
emit_obj: false,
22+
});
23+
check_bitcode(LibBuild {
24+
source: path("lib.rs"),
25+
crate_type: Some("staticlib"),
26+
output: path(static_lib_name("liblib-fat-lto")),
27+
lto: Some("fat"),
28+
emit_obj: false,
29+
});
30+
check_bitcode(LibBuild {
31+
source: path("lib.rs"),
32+
crate_type: Some("staticlib"),
33+
output: path(static_lib_name("liblib-thin-lto")),
34+
lto: Some("thin"),
35+
emit_obj: false,
36+
});
37+
check_bitcode(LibBuild {
38+
source: path("lib.rs"),
39+
crate_type: Some("rlib"),
40+
output: path(rust_lib_name("liblib")),
41+
lto: None,
42+
emit_obj: false,
43+
});
44+
check_bitcode(LibBuild {
45+
source: path("lib.rs"),
46+
crate_type: Some("cdylib"),
47+
output: path("cdylib.o"),
48+
lto: None,
49+
emit_obj: true,
50+
});
51+
check_bitcode(LibBuild {
52+
source: path("lib.rs"),
53+
crate_type: Some("dylib"),
54+
output: path("rdylib.o"),
55+
lto: None,
56+
emit_obj: true,
57+
});
58+
check_bitcode(LibBuild {
59+
source: path("main.rs"),
60+
crate_type: None,
61+
output: path("exe.o"),
62+
lto: None,
63+
emit_obj: true,
64+
});
65+
}
66+
67+
#[track_caller]
68+
fn check_bitcode(instructions: LibBuild) {
69+
let mut rustc = rustc();
70+
rustc
71+
.input(instructions.source)
72+
.output(&instructions.output)
73+
.opt_level("2")
74+
.codegen_units(1)
75+
.arg("-Clinker-plugin-lto");
76+
if instructions.emit_obj {
77+
rustc.emit("obj");
78+
}
79+
if let Some(crate_type) = instructions.crate_type {
80+
rustc.crate_type(crate_type);
81+
}
82+
if let Some(lto) = instructions.lto {
83+
rustc.arg(format!("-Clto={lto}"));
84+
}
85+
rustc.run();
86+
87+
if instructions.output.extension().unwrap() != "o" {
88+
// Remove all potential leftover object files, then turn the output into an object file.
89+
for object in shallow_find_files(cwd(), |path| has_extension(path, "o")) {
90+
rfs::remove_file(object);
91+
}
92+
llvm_ar().extract().arg(&instructions.output).run();
93+
}
94+
95+
for object in shallow_find_files(cwd(), |path| {
96+
has_prefix(path, instructions.output.file_prefix().unwrap().to_str().unwrap())
97+
&& has_extension(path, "o")
98+
}) {
99+
// All generated object files should be LLVM bitcode files - this will fail otherwise.
100+
llvm_bcanalyzer().input(object).run();
101+
}
102+
}
103+
104+
struct LibBuild {
105+
source: PathBuf,
106+
crate_type: Option<&'static str>,
107+
output: PathBuf,
108+
lto: Option<&'static str>,
109+
emit_obj: bool,
110+
}

0 commit comments

Comments
 (0)