Auto merge of #128352 - Oneirical:daLTOnist-vision, r=jieyouxu · rust-lang/rust@5367673 (original) (raw)
``
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
`+
}
`