Skip to content

Commit 2e9d9d4

Browse files
committedMar 1, 2018
rustc: More stable hashes of command line arguments
Currently rustc isn't always the best at producing deterministic builds of a crate when the source directory of a crate is changed. This is happening due to what appears two different sources: * First the `-L` paths passed to rustc are hashed into the crate hash. These paths through Cargo are typically absolute paths that can vary if the build directory changes. * Next the paths passed to `--extern` are also hashed which like `-L` can change if the build directory changes. This commit fixes these two sources of nondeterminism by ensuring that avoiding tracking the hashes of these arguments on the command line. For `-L` paths they're either related to loading crates (whose hashes are tracked elsewhere) or native librarise used in the linking phase (which isn't incremental). The `--extern` paths are similar in that they're related to crate resolution which is already tracked independently of the command line arguments. Closes #48019
1 parent a85417f commit 2e9d9d4

File tree

3 files changed

+71
-130
lines changed

3 files changed

+71
-130
lines changed
 

‎src/librustc/session/config.rs

+3-120
Original file line numberDiff line numberDiff line change
@@ -420,10 +420,7 @@ top_level_options!(
420420
lint_cap: Option<lint::Level> [TRACKED],
421421
describe_lints: bool [UNTRACKED],
422422
output_types: OutputTypes [TRACKED],
423-
// FIXME(mw): We track this for now but it actually doesn't make too
424-
// much sense: The search path can stay the same while the
425-
// things discovered there might have changed on disk.
426-
search_paths: SearchPaths [TRACKED],
423+
search_paths: SearchPaths [UNTRACKED],
427424
libs: Vec<(String, Option<String>, Option<cstore::NativeLibraryKind>)> [TRACKED],
428425
maybe_sysroot: Option<PathBuf> [TRACKED],
429426

@@ -442,10 +439,7 @@ top_level_options!(
442439
// version of `debugging_opts.borrowck`, which is just a plain string.
443440
borrowck_mode: BorrowckMode [UNTRACKED],
444441
cg: CodegenOptions [TRACKED],
445-
// FIXME(mw): We track this for now but it actually doesn't make too
446-
// much sense: The value of this option can stay the same
447-
// while the files they refer to might have changed on disk.
448-
externs: Externs [TRACKED],
442+
externs: Externs [UNTRACKED],
449443
crate_name: Option<String> [TRACKED],
450444
// An optional name to use as the crate for std during std injection,
451445
// written `extern crate std = "name"`. Default to "std". Used by
@@ -2141,13 +2135,12 @@ impl fmt::Display for CrateType {
21412135
mod dep_tracking {
21422136
use lint;
21432137
use middle::cstore;
2144-
use session::search_paths::{PathKind, SearchPaths};
21452138
use std::collections::BTreeMap;
21462139
use std::hash::Hash;
21472140
use std::path::PathBuf;
21482141
use std::collections::hash_map::DefaultHasher;
21492142
use super::{Passes, CrateType, OptLevel, DebugInfoLevel, Lto,
2150-
OutputTypes, Externs, ErrorOutputType, Sanitizer, Epoch};
2143+
OutputTypes, ErrorOutputType, Sanitizer, Epoch};
21512144
use syntax::feature_gate::UnstableFeatures;
21522145
use rustc_back::{PanicStrategy, RelroLevel};
21532146

@@ -2204,7 +2197,6 @@ mod dep_tracking {
22042197
impl_dep_tracking_hash_via_hash!(Lto);
22052198
impl_dep_tracking_hash_via_hash!(DebugInfoLevel);
22062199
impl_dep_tracking_hash_via_hash!(UnstableFeatures);
2207-
impl_dep_tracking_hash_via_hash!(Externs);
22082200
impl_dep_tracking_hash_via_hash!(OutputTypes);
22092201
impl_dep_tracking_hash_via_hash!(cstore::NativeLibraryKind);
22102202
impl_dep_tracking_hash_via_hash!(Sanitizer);
@@ -2218,15 +2210,6 @@ mod dep_tracking {
22182210
impl_dep_tracking_hash_for_sortable_vec_of!((String, Option<String>,
22192211
Option<cstore::NativeLibraryKind>));
22202212
impl_dep_tracking_hash_for_sortable_vec_of!((String, u64));
2221-
impl DepTrackingHash for SearchPaths {
2222-
fn hash(&self, hasher: &mut DefaultHasher, _: ErrorOutputType) {
2223-
let mut elems: Vec<_> = self
2224-
.iter(PathKind::All)
2225-
.collect();
2226-
elems.sort();
2227-
Hash::hash(&elems, hasher);
2228-
}
2229-
}
22302213

22312214
impl<T1, T2> DepTrackingHash for (T1, T2)
22322215
where T1: DepTrackingHash,
@@ -2413,43 +2396,6 @@ mod tests {
24132396
assert_eq!(v1.dep_tracking_hash(), v1.clone().dep_tracking_hash());
24142397
}
24152398

2416-
#[test]
2417-
fn test_externs_tracking_hash_different_values() {
2418-
let mut v1 = super::basic_options();
2419-
let mut v2 = super::basic_options();
2420-
let mut v3 = super::basic_options();
2421-
2422-
v1.externs = Externs::new(mk_map(vec![
2423-
(String::from("a"), mk_set(vec![String::from("b"),
2424-
String::from("c")])),
2425-
(String::from("d"), mk_set(vec![String::from("e"),
2426-
String::from("f")])),
2427-
]));
2428-
2429-
v2.externs = Externs::new(mk_map(vec![
2430-
(String::from("a"), mk_set(vec![String::from("b"),
2431-
String::from("c")])),
2432-
(String::from("X"), mk_set(vec![String::from("e"),
2433-
String::from("f")])),
2434-
]));
2435-
2436-
v3.externs = Externs::new(mk_map(vec![
2437-
(String::from("a"), mk_set(vec![String::from("b"),
2438-
String::from("c")])),
2439-
(String::from("d"), mk_set(vec![String::from("X"),
2440-
String::from("f")])),
2441-
]));
2442-
2443-
assert!(v1.dep_tracking_hash() != v2.dep_tracking_hash());
2444-
assert!(v1.dep_tracking_hash() != v3.dep_tracking_hash());
2445-
assert!(v2.dep_tracking_hash() != v3.dep_tracking_hash());
2446-
2447-
// Check clone
2448-
assert_eq!(v1.dep_tracking_hash(), v1.clone().dep_tracking_hash());
2449-
assert_eq!(v2.dep_tracking_hash(), v2.clone().dep_tracking_hash());
2450-
assert_eq!(v3.dep_tracking_hash(), v3.clone().dep_tracking_hash());
2451-
}
2452-
24532399
#[test]
24542400
fn test_externs_tracking_hash_different_construction_order() {
24552401
let mut v1 = super::basic_options();
@@ -2540,69 +2486,6 @@ mod tests {
25402486
assert_eq!(v2.dep_tracking_hash(), v2.clone().dep_tracking_hash());
25412487
}
25422488

2543-
#[test]
2544-
fn test_search_paths_tracking_hash_different_values() {
2545-
let mut v1 = super::basic_options();
2546-
let mut v2 = super::basic_options();
2547-
let mut v3 = super::basic_options();
2548-
let mut v4 = super::basic_options();
2549-
let mut v5 = super::basic_options();
2550-
2551-
// Reference
2552-
v1.search_paths.add_path("native=abc", super::ErrorOutputType::Json(false));
2553-
v1.search_paths.add_path("crate=def", super::ErrorOutputType::Json(false));
2554-
v1.search_paths.add_path("dependency=ghi", super::ErrorOutputType::Json(false));
2555-
v1.search_paths.add_path("framework=jkl", super::ErrorOutputType::Json(false));
2556-
v1.search_paths.add_path("all=mno", super::ErrorOutputType::Json(false));
2557-
2558-
// Native changed
2559-
v2.search_paths.add_path("native=XXX", super::ErrorOutputType::Json(false));
2560-
v2.search_paths.add_path("crate=def", super::ErrorOutputType::Json(false));
2561-
v2.search_paths.add_path("dependency=ghi", super::ErrorOutputType::Json(false));
2562-
v2.search_paths.add_path("framework=jkl", super::ErrorOutputType::Json(false));
2563-
v2.search_paths.add_path("all=mno", super::ErrorOutputType::Json(false));
2564-
2565-
// Crate changed
2566-
v2.search_paths.add_path("native=abc", super::ErrorOutputType::Json(false));
2567-
v2.search_paths.add_path("crate=XXX", super::ErrorOutputType::Json(false));
2568-
v2.search_paths.add_path("dependency=ghi", super::ErrorOutputType::Json(false));
2569-
v2.search_paths.add_path("framework=jkl", super::ErrorOutputType::Json(false));
2570-
v2.search_paths.add_path("all=mno", super::ErrorOutputType::Json(false));
2571-
2572-
// Dependency changed
2573-
v3.search_paths.add_path("native=abc", super::ErrorOutputType::Json(false));
2574-
v3.search_paths.add_path("crate=def", super::ErrorOutputType::Json(false));
2575-
v3.search_paths.add_path("dependency=XXX", super::ErrorOutputType::Json(false));
2576-
v3.search_paths.add_path("framework=jkl", super::ErrorOutputType::Json(false));
2577-
v3.search_paths.add_path("all=mno", super::ErrorOutputType::Json(false));
2578-
2579-
// Framework changed
2580-
v4.search_paths.add_path("native=abc", super::ErrorOutputType::Json(false));
2581-
v4.search_paths.add_path("crate=def", super::ErrorOutputType::Json(false));
2582-
v4.search_paths.add_path("dependency=ghi", super::ErrorOutputType::Json(false));
2583-
v4.search_paths.add_path("framework=XXX", super::ErrorOutputType::Json(false));
2584-
v4.search_paths.add_path("all=mno", super::ErrorOutputType::Json(false));
2585-
2586-
// All changed
2587-
v5.search_paths.add_path("native=abc", super::ErrorOutputType::Json(false));
2588-
v5.search_paths.add_path("crate=def", super::ErrorOutputType::Json(false));
2589-
v5.search_paths.add_path("dependency=ghi", super::ErrorOutputType::Json(false));
2590-
v5.search_paths.add_path("framework=jkl", super::ErrorOutputType::Json(false));
2591-
v5.search_paths.add_path("all=XXX", super::ErrorOutputType::Json(false));
2592-
2593-
assert!(v1.dep_tracking_hash() != v2.dep_tracking_hash());
2594-
assert!(v1.dep_tracking_hash() != v3.dep_tracking_hash());
2595-
assert!(v1.dep_tracking_hash() != v4.dep_tracking_hash());
2596-
assert!(v1.dep_tracking_hash() != v5.dep_tracking_hash());
2597-
2598-
// Check clone
2599-
assert_eq!(v1.dep_tracking_hash(), v1.clone().dep_tracking_hash());
2600-
assert_eq!(v2.dep_tracking_hash(), v2.clone().dep_tracking_hash());
2601-
assert_eq!(v3.dep_tracking_hash(), v3.clone().dep_tracking_hash());
2602-
assert_eq!(v4.dep_tracking_hash(), v4.clone().dep_tracking_hash());
2603-
assert_eq!(v5.dep_tracking_hash(), v5.clone().dep_tracking_hash());
2604-
}
2605-
26062489
#[test]
26072490
fn test_search_paths_tracking_hash_different_order() {
26082491
let mut v1 = super::basic_options();
+67-9
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,78 @@
11
-include ../tools.mk
2-
all:
2+
all: \
3+
smoke \
4+
debug \
5+
opt \
6+
link_paths \
7+
remap_paths \
8+
different_source_dirs \
9+
extern_flags
10+
11+
smoke:
12+
rm -rf $(TMPDIR) && mkdir $(TMPDIR)
313
$(RUSTC) reproducible-build-aux.rs
414
$(RUSTC) reproducible-build.rs -o"$(TMPDIR)/reproducible-build1"
515
$(RUSTC) reproducible-build.rs -o"$(TMPDIR)/reproducible-build2"
16+
$(B2)
617
nm "$(TMPDIR)/reproducible-build1" | sort > "$(TMPDIR)/reproducible-build1.nm"
718
nm "$(TMPDIR)/reproducible-build2" | sort > "$(TMPDIR)/reproducible-build2.nm"
819
cmp "$(TMPDIR)/reproducible-build1.nm" "$(TMPDIR)/reproducible-build2.nm" || exit 1
20+
21+
debug:
22+
rm -rf $(TMPDIR) && mkdir $(TMPDIR)
923
$(RUSTC) reproducible-build-aux.rs -g
10-
$(RUSTC) reproducible-build.rs -g -o"$(TMPDIR)/reproducible-build1-debug"
11-
$(RUSTC) reproducible-build.rs -g -o"$(TMPDIR)/reproducible-build2-debug"
12-
nm "$(TMPDIR)/reproducible-build1-debug" | sort > "$(TMPDIR)/reproducible-build1-debug.nm"
13-
nm "$(TMPDIR)/reproducible-build2-debug" | sort > "$(TMPDIR)/reproducible-build2-debug.nm"
24+
$(RUSTC) reproducible-build.rs -o"$(TMPDIR)/reproducible-build1" -g
25+
$(RUSTC) reproducible-build.rs -o"$(TMPDIR)/reproducible-build2" -g
26+
nm "$(TMPDIR)/reproducible-build1" | sort > "$(TMPDIR)/reproducible-build1-debug.nm"
27+
nm "$(TMPDIR)/reproducible-build2" | sort > "$(TMPDIR)/reproducible-build2-debug.nm"
1428
cmp "$(TMPDIR)/reproducible-build1-debug.nm" "$(TMPDIR)/reproducible-build2-debug.nm" || exit 1
29+
30+
opt:
31+
rm -rf $(TMPDIR) && mkdir $(TMPDIR)
1532
$(RUSTC) reproducible-build-aux.rs -O
16-
$(RUSTC) reproducible-build.rs -O -o"$(TMPDIR)/reproducible-build1-opt"
17-
$(RUSTC) reproducible-build.rs -O -o"$(TMPDIR)/reproducible-build2-opt"
18-
nm "$(TMPDIR)/reproducible-build1-opt" | sort > "$(TMPDIR)/reproducible-build1-opt.nm"
19-
nm "$(TMPDIR)/reproducible-build2-opt" | sort > "$(TMPDIR)/reproducible-build2-opt.nm"
33+
$(RUSTC) reproducible-build.rs -o"$(TMPDIR)/reproducible-build1" -O
34+
$(RUSTC) reproducible-build.rs -o"$(TMPDIR)/reproducible-build2" -O
35+
nm "$(TMPDIR)/reproducible-build1" | sort > "$(TMPDIR)/reproducible-build1-opt.nm"
36+
nm "$(TMPDIR)/reproducible-build2" | sort > "$(TMPDIR)/reproducible-build2-opt.nm"
2037
cmp "$(TMPDIR)/reproducible-build1-opt.nm" "$(TMPDIR)/reproducible-build2-opt.nm" || exit 1
38+
39+
link_paths:
40+
rm -rf $(TMPDIR) && mkdir $(TMPDIR)
41+
$(RUSTC) reproducible-build-aux.rs
42+
$(RUSTC) reproducible-build.rs --crate-type rlib -L /b
43+
cp $(TMPDIR)/libreproducible_build.rlib $(TMPDIR)/libfoo.rlib
44+
$(RUSTC) reproducible-build.rs --crate-type rlib -L /a
45+
cmp "$(TMPDIR)/libreproducible_build.rlib" "$(TMPDIR)/libfoo.rlib" || exit 1
46+
47+
remap_paths:
48+
rm -rf $(TMPDIR) && mkdir $(TMPDIR)
49+
$(RUSTC) reproducible-build-aux.rs
50+
$(RUSTC) reproducible-build.rs --crate-type rlib --remap-path-prefix=/a=/c
51+
cp $(TMPDIR)/libreproducible_build.rlib $(TMPDIR)/libfoo.rlib
52+
$(RUSTC) reproducible-build.rs --crate-type rlib --remap-path-prefix=/b=/c
53+
cmp "$(TMPDIR)/libreproducible_build.rlib" "$(TMPDIR)/libfoo.rlib" || exit 1
54+
55+
different_source_dirs:
56+
rm -rf $(TMPDIR) && mkdir $(TMPDIR)
57+
$(RUSTC) reproducible-build-aux.rs
58+
mkdir $(TMPDIR)/test
59+
cp reproducible-build.rs $(TMPDIR)/test
60+
$(RUSTC) reproducible-build.rs --crate-type rlib --remap-path-prefix=$$PWD=/b
61+
cp $(TMPDIR)/libreproducible_build.rlib $(TMPDIR)/libfoo.rlib
62+
(cd $(TMPDIR)/test && $(RUSTC) reproducible-build.rs \
63+
--remap-path-prefix=$(TMPDIR)/test=/b \
64+
--crate-type rlib)
65+
cmp "$(TMPDIR)/libreproducible_build.rlib" "$(TMPDIR)/libfoo.rlib" || exit 1
66+
67+
extern_flags:
68+
rm -rf $(TMPDIR) && mkdir $(TMPDIR)
69+
$(RUSTC) reproducible-build-aux.rs
70+
$(RUSTC) reproducible-build.rs \
71+
--extern reproducible_build_aux=$(TMPDIR)/libreproducible_build_aux.rlib \
72+
--crate-type rlib
73+
cp $(TMPDIR)/libreproducible_build_aux.rlib $(TMPDIR)/libbar.rlib
74+
cp $(TMPDIR)/libreproducible_build.rlib $(TMPDIR)/libfoo.rlib
75+
$(RUSTC) reproducible-build.rs \
76+
--extern reproducible_build_aux=$(TMPDIR)/libbar.rlib \
77+
--crate-type rlib
78+
cmp "$(TMPDIR)/libreproducible_build.rlib" "$(TMPDIR)/libfoo.rlib" || exit 1

‎src/test/run-make/reproducible-build/reproducible-build.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
// - Trait object shims
2929
// - Fn Pointer shims
3030

31-
#![allow(dead_code)]
31+
#![allow(dead_code, warnings)]
3232

3333
extern crate reproducible_build_aux;
3434

0 commit comments

Comments
 (0)
Please sign in to comment.