Auto merge of #128456 - Oneirical:clantestine-operations, r= · rust-lang/rust@f3c4813 (original) (raw)
``
1
`+
// This test case makes sure that two identical invocations of the compiler
`
``
2
`+
// (i.e. same code base, same compile-flags, same compiler-versions, etc.)
`
``
3
`+
// produce the same output. In the past, symbol names of monomorphized functions
`
``
4
`+
// were not deterministic (which we want to avoid).
`
``
5
`+
//
`
``
6
`+
// The test tries to exercise as many different paths into symbol name
`
``
7
`+
// generation as possible:
`
``
8
`+
//
`
``
9
`+
// - regular functions
`
``
10
`+
// - generic functions
`
``
11
`+
// - methods
`
``
12
`+
// - statics
`
``
13
`+
// - closures
`
``
14
`+
// - enum variant constructors
`
``
15
`+
// - tuple struct constructors
`
``
16
`+
// - drop glue
`
``
17
`+
// - FnOnce adapters
`
``
18
`+
// - Trait object shims
`
``
19
`+
// - Fn Pointer shims
`
``
20
`+
// See https://github.com/rust-lang/rust/pull/32293
`
``
21
`+
// Tracking Issue: https://github.com/rust-lang/rust/issues/129080
`
``
22
+
``
23
`+
// FIXME(Oneirical): ignore-windows
`
``
24
`` +
// # FIXME: Builds of bin
crate types are not deterministic with debuginfo=2 on
``
``
25
`+
// # Windows.
`
``
26
`+
// # See: https://github.com/rust-lang/rust/pull/87320#issuecomment-920105533
`
``
27
`+
// # Issue: https://github.com/rust-lang/rust/issues/88982
`
``
28
+
``
29
`+
use run_make_support::{
`
``
30
`+
bin_name, cwd, diff, is_darwin, is_windows, rfs, run_in_tmpdir, rust_lib_name, rustc,
`
``
31
`+
};
`
``
32
+
``
33
`+
fn main() {
`
``
34
`+
// Smoke tests. Simple flags, build should be reproducible.
`
``
35
`+
eprintln!("smoke_test => None");
`
``
36
`+
smoke_test(None);
`
``
37
`+
eprintln!("smoke_test => SmokeFlag::Debug");
`
``
38
`+
smoke_test(Some(SmokeFlag::Debug));
`
``
39
`+
eprintln!("smoke_test => SmokeFlag::Opt");
`
``
40
`+
smoke_test(Some(SmokeFlag::Opt));
`
``
41
+
``
42
`+
// Builds should be reproducible even through custom library search paths
`
``
43
`+
// or remap path prefixes.
`
``
44
`+
eprintln!("paths_test => PathsFlag::Link");
`
``
45
`+
paths_test(PathsFlag::Link);
`
``
46
`+
eprintln!("paths_test => PathsFlag::Remap");
`
``
47
`+
paths_test(PathsFlag::Remap);
`
``
48
+
``
49
`+
// Builds should be reproducible even if each build is done in a different directory,
`
``
50
`+
// with both --remap-path-prefix and -Z remap-cwd-prefix.
`
``
51
+
``
52
`` +
// FIXME(Oneirical): Building with crate type set to bin
AND having -Cdebuginfo=2
``
``
53
`` +
// (or -g
, the shorthand form) enabled will cause reproducibility failures.
``
``
54
`+
// See https://github.com/rust-lang/rust/issues/89911
`
``
55
+
``
56
`+
if !is_darwin() && !is_windows() {
`
``
57
`+
// FIXME(Oneirical): Bin builds are not reproducible on non-Linux targets.
`
``
58
`+
eprintln!("diff_dir_test => Bin, Path");
`
``
59
`+
diff_dir_test(CrateType::Bin, RemapType::Path);
`
``
60
`+
}
`
``
61
+
``
62
`+
eprintln!("diff_dir_test => Rlib, Path");
`
``
63
`+
diff_dir_test(CrateType::Rlib, RemapType::Path);
`
``
64
+
``
65
`+
// FIXME(Oneirical): This specific case would fail on Linux, should -Cdebuginfo=2
`
``
66
`+
// be added.
`
``
67
`+
// FIXME(Oneirical): Bin builds are not reproducible on non-Linux targets.
`
``
68
`+
// See https://github.com/rust-lang/rust/issues/89911
`
``
69
`+
if !is_darwin() && !is_windows() {
`
``
70
`+
eprintln!("diff_dir_test => Bin, Cwd false");
`
``
71
`+
diff_dir_test(CrateType::Bin, RemapType::Cwd { is_empty: false });
`
``
72
`+
}
`
``
73
+
``
74
`+
eprintln!("diff_dir_test => Rlib, Cwd false");
`
``
75
`+
diff_dir_test(CrateType::Rlib, RemapType::Cwd { is_empty: false });
`
``
76
`+
eprintln!("diff_dir_test => Rlib, Cwd true");
`
``
77
`+
diff_dir_test(CrateType::Rlib, RemapType::Cwd { is_empty: true });
`
``
78
+
``
79
`+
eprintln!("final extern test");
`
``
80
`+
// Builds should be reproducible when using the --extern flag.
`
``
81
`+
run_in_tmpdir(|| {
`
``
82
`+
rustc().input("reproducible-build-aux.rs").run();
`
``
83
`+
rustc()
`
``
84
`+
.input("reproducible-build.rs")
`
``
85
`+
.crate_type("rlib")
`
``
86
`+
.extern_("reproducible_build_aux", rust_lib_name("reproducible_build_aux"))
`
``
87
`+
.run();
`
``
88
`+
rfs::copy(rust_lib_name("reproducible_build"), rust_lib_name("foo"));
`
``
89
`+
rfs::copy(rust_lib_name("reproducible_build_aux"), rust_lib_name("bar"));
`
``
90
`+
rustc()
`
``
91
`+
.input("reproducible-build.rs")
`
``
92
`+
.crate_type("rlib")
`
``
93
`+
.extern_("reproducible_build_aux", rust_lib_name("bar"))
`
``
94
`+
.run();
`
``
95
`+
assert!(rfs::read(rust_lib_name("foo")) == rfs::read(rust_lib_name("reproducible_build")))
`
``
96
`+
});
`
``
97
`+
}
`
``
98
+
``
99
`+
#[track_caller]
`
``
100
`+
fn smoke_test(flag: Option) {
`
``
101
`+
run_in_tmpdir(|| {
`
``
102
`+
rustc().input("linker.rs").opt().run();
`
``
103
`+
rustc().input("reproducible-build-aux.rs").run();
`
``
104
`+
let mut compiler1 = rustc();
`
``
105
`+
let mut compiler2 = rustc();
`
``
106
`+
if let Some(flag) = flag {
`
``
107
`+
match flag {
`
``
108
`+
SmokeFlag::Debug => {
`
``
109
`+
compiler1.arg("-g");
`
``
110
`+
compiler2.arg("-g");
`
``
111
`+
}
`
``
112
`+
SmokeFlag::Opt => {
`
``
113
`+
compiler1.opt();
`
``
114
`+
compiler2.opt();
`
``
115
`+
}
`
``
116
`+
};
`
``
117
`+
};
`
``
118
`+
compiler1
`
``
119
`+
.input("reproducible-build.rs")
`
``
120
`+
.linker(&cwd().join(bin_name("linker")).display().to_string())
`
``
121
`+
.run();
`
``
122
`+
compiler2
`
``
123
`+
.input("reproducible-build.rs")
`
``
124
`+
.linker(&cwd().join(bin_name("linker")).display().to_string())
`
``
125
`+
.run();
`
``
126
`+
diff().actual_file("linker-arguments1").expected_file("linker-arguments2").run();
`
``
127
`+
});
`
``
128
`+
}
`
``
129
+
``
130
`+
#[track_caller]
`
``
131
`+
fn paths_test(flag: PathsFlag) {
`
``
132
`+
run_in_tmpdir(|| {
`
``
133
`+
rustc().input("reproducible-build-aux.rs").run();
`
``
134
`+
let mut compiler1 = rustc();
`
``
135
`+
let mut compiler2 = rustc();
`
``
136
`+
match flag {
`
``
137
`+
PathsFlag::Link => {
`
``
138
`+
compiler1.library_search_path("a");
`
``
139
`+
compiler2.library_search_path("b");
`
``
140
`+
}
`
``
141
`+
PathsFlag::Remap => {
`
``
142
`+
compiler1.arg("--remap-path-prefix=/a=/c");
`
``
143
`+
compiler2.arg("--remap-path-prefix=/b=/c");
`
``
144
`+
}
`
``
145
`+
}
`
``
146
`+
compiler1.input("reproducible-build.rs").crate_type("rlib").run();
`
``
147
`+
rfs::rename(rust_lib_name("reproducible_build"), rust_lib_name("foo"));
`
``
148
`+
compiler2.input("reproducible-build.rs").crate_type("rlib").run();
`
``
149
`+
assert!(rfs::read(rust_lib_name("foo")) == rfs::read(rust_lib_name("reproducible_build")))
`
``
150
`+
});
`
``
151
`+
}
`
``
152
+
``
153
`+
#[track_caller]
`
``
154
`+
fn diff_dir_test(crate_type: CrateType, remap_type: RemapType) {
`
``
155
`+
run_in_tmpdir(|| {
`
``
156
`+
let base_dir = cwd();
`
``
157
`+
rustc().input("reproducible-build-aux.rs").run();
`
``
158
`+
rfs::create_dir("test");
`
``
159
`+
rfs::copy("reproducible-build.rs", "test/reproducible-build.rs");
`
``
160
`+
let mut compiler1 = rustc();
`
``
161
`+
let mut compiler2 = rustc();
`
``
162
`+
match crate_type {
`
``
163
`+
CrateType::Bin => {
`
``
164
`+
compiler1.crate_type("bin");
`
``
165
`+
compiler2.crate_type("bin");
`
``
166
`+
}
`
``
167
`+
CrateType::Rlib => {
`
``
168
`+
compiler1.crate_type("rlib");
`
``
169
`+
compiler2.crate_type("rlib");
`
``
170
`+
}
`
``
171
`+
}
`
``
172
`+
match remap_type {
`
``
173
`+
RemapType::Path => {
`
``
174
`+
compiler1.arg(&format!("--remap-path-prefix={}=/b", cwd().display()));
`
``
175
`+
compiler2
`
``
176
`+
.arg(format!("--remap-path-prefix={}=/b", base_dir.join("test").display()));
`
``
177
`+
}
`
``
178
`+
RemapType::Cwd { is_empty } => {
`
``
179
`` +
// FIXME(Oneirical): Building with crate type set to bin
AND having -Cdebuginfo=2
``
``
180
`` +
// (or -g
, the shorthand form) enabled will cause reproducibility failures
``
``
181
`+
// for multiple platforms.
`
``
182
`+
// See https://github.com/rust-lang/rust/issues/89911
`
``
183
`` +
// FIXME(#129117): Windows rlib + -Cdebuginfo=2
+ -Z remap-cwd-prefix=.
seems
``
``
184
`+
// to be unreproducible.
`
``
185
`+
if !matches!(crate_type, CrateType::Bin) && !is_windows() {
`
``
186
`+
compiler1.arg("-Cdebuginfo=2");
`
``
187
`+
compiler2.arg("-Cdebuginfo=2");
`
``
188
`+
}
`
``
189
`+
if is_empty {
`
``
190
`+
compiler1.arg("-Zremap-cwd-prefix=");
`
``
191
`+
compiler2.arg("-Zremap-cwd-prefix=");
`
``
192
`+
} else {
`
``
193
`+
compiler1.arg("-Zremap-cwd-prefix=.");
`
``
194
`+
compiler2.arg("-Zremap-cwd-prefix=.");
`
``
195
`+
}
`
``
196
`+
}
`
``
197
`+
}
`
``
198
`+
compiler1.input("reproducible-build.rs").run();
`
``
199
`+
match crate_type {
`
``
200
`+
CrateType::Bin => {
`
``
201
`+
rfs::rename(bin_name("reproducible-build"), bin_name("foo"));
`
``
202
`+
}
`
``
203
`+
CrateType::Rlib => {
`
``
204
`+
rfs::rename(rust_lib_name("reproducible_build"), rust_lib_name("foo"));
`
``
205
`+
}
`
``
206
`+
}
`
``
207
`+
std::env::set_current_dir("test").unwrap();
`
``
208
`+
compiler2
`
``
209
`+
.input("reproducible-build.rs")
`
``
210
`+
.library_search_path(&base_dir)
`
``
211
`+
.out_dir(&base_dir)
`
``
212
`+
.run();
`
``
213
`+
std::env::set_current_dir(&base_dir).unwrap();
`
``
214
`+
match crate_type {
`
``
215
`+
CrateType::Bin => {
`
``
216
`+
assert!(rfs::read(bin_name("reproducible-build")) == rfs::read(bin_name("foo")));
`
``
217
`+
}
`
``
218
`+
CrateType::Rlib => {
`
``
219
`+
assert!(
`
``
220
`+
rfs::read(rust_lib_name("foo"))
`
``
221
`+
== rfs::read(rust_lib_name("reproducible_build"))
`
``
222
`+
);
`
``
223
`+
}
`
``
224
`+
}
`
``
225
`+
});
`
``
226
`+
}
`
``
227
+
``
228
`+
enum SmokeFlag {
`
``
229
`+
Debug,
`
``
230
`+
Opt,
`
``
231
`+
}
`
``
232
+
``
233
`+
enum PathsFlag {
`
``
234
`+
Link,
`
``
235
`+
Remap,
`
``
236
`+
}
`
``
237
+
``
238
`+
enum CrateType {
`
``
239
`+
Bin,
`
``
240
`+
Rlib,
`
``
241
`+
}
`
``
242
+
``
243
`+
enum RemapType {
`
``
244
`+
Path,
`
``
245
`+
Cwd { is_empty: bool },
`
``
246
`+
}
`