in src/compiler/rust.rs [3363:3490]
fn test_generate_hash_key(preprocessor_cache_mode: bool) {
use ar::{Builder, Header};
drop(env_logger::try_init());
let f = TestFixture::new();
const FAKE_DIGEST: &str = "abcd1234";
const BAZ_O_SIZE: u64 = 1024;
// We'll just use empty files for each of these.
for s in ["foo.rs", "bar.rs", "bar.rlib"].iter() {
f.touch(s).unwrap();
}
// libbaz.a needs to be a valid archive.
create_file(f.tempdir.path(), "libbaz.a", |f| {
let mut builder = Builder::new(f);
let hdr = Header::new(b"baz.o".to_vec(), BAZ_O_SIZE);
builder.append(&hdr, io::repeat(0).take(BAZ_O_SIZE))?;
Ok(())
})
.unwrap();
let mut m = Digest::new();
m.update(b"baz.o");
m.update(&vec![0; BAZ_O_SIZE as usize]);
let libbaz_a_digest = m.finish();
let mut emit = HashSet::new();
emit.insert("link".to_string());
emit.insert("metadata".to_string());
let hasher = Box::new(RustHasher {
executable: "rustc".into(),
host: "x86-64-unknown-unknown-unknown".to_owned(),
version: TEST_RUSTC_VERSION.to_string(),
sysroot: f.tempdir.path().join("sysroot"),
compiler_shlibs_digests: vec![FAKE_DIGEST.to_owned()],
#[cfg(feature = "dist-client")]
rlib_dep_reader: None,
parsed_args: ParsedArguments {
arguments: vec![
Argument::Raw("a".into()),
Argument::WithValue(
"--cfg",
ArgData::PassThrough("xyz".into()),
ArgDisposition::Separated,
),
Argument::Raw("b".into()),
Argument::WithValue(
"--cfg",
ArgData::PassThrough("abc".into()),
ArgDisposition::Separated,
),
],
output_dir: "foo/".into(),
externs: vec!["bar.rlib".into()],
crate_link_paths: vec![],
staticlibs: vec![f.tempdir.path().join("libbaz.a")],
crate_name: "foo".into(),
crate_types: CrateTypes {
rlib: true,
staticlib: false,
},
dep_info: None,
emit,
color_mode: ColorMode::Auto,
has_json: false,
profile: None,
gcno: None,
target_json: None,
},
});
let creator = new_creator();
mock_dep_info(&creator, &["foo.rs", "bar.rs"]);
mock_file_names(&creator, &["foo.rlib", "foo.a"]);
let runtime = single_threaded_runtime();
let pool = runtime.handle().clone();
let res = hasher
.generate_hash_key(
&creator,
f.tempdir.path().to_owned(),
[
(OsString::from("CARGO_PKG_NAME"), OsString::from("foo")),
(OsString::from("FOO"), OsString::from("bar")),
(OsString::from("CARGO_BLAH"), OsString::from("abc")),
(
OsString::from("CARGO_REGISTRIES_A_TOKEN"),
OsString::from("ignored"),
),
]
.to_vec(),
false,
&pool,
false,
Arc::new(MockStorage::new(None, preprocessor_cache_mode)),
CacheControl::Default,
)
.wait()
.unwrap();
let m = Digest::new();
let empty_digest = m.finish();
let mut m = Digest::new();
// Version.
m.update(CACHE_VERSION);
// sysroot shlibs digests.
m.update(FAKE_DIGEST.as_bytes());
// Arguments, with cfgs sorted at the end.
OsStr::new("ab--cfgabc--cfgxyz").hash(&mut HashToDigest { digest: &mut m });
// bar.rs (source file, from dep-info)
m.update(empty_digest.as_bytes());
// foo.rs (source file, from dep-info)
m.update(empty_digest.as_bytes());
// bar.rlib (extern crate, from externs)
m.update(empty_digest.as_bytes());
// libbaz.a (static library, from staticlibs), containing a single
// file, baz.o, consisting of 1024 bytes of zeroes.
m.update(libbaz_a_digest.as_bytes());
// Env vars
OsStr::new("CARGO_BLAH").hash(&mut HashToDigest { digest: &mut m });
m.update(b"=");
OsStr::new("abc").hash(&mut HashToDigest { digest: &mut m });
OsStr::new("CARGO_PKG_NAME").hash(&mut HashToDigest { digest: &mut m });
m.update(b"=");
OsStr::new("foo").hash(&mut HashToDigest { digest: &mut m });
f.tempdir.path().hash(&mut HashToDigest { digest: &mut m });
TEST_RUSTC_VERSION.hash(&mut HashToDigest { digest: &mut m });
let digest = m.finish();
assert_eq!(res.key, digest);
let mut out = res.compilation.outputs().map(|k| k.key).collect::<Vec<_>>();
out.sort();
assert_eq!(out, vec!["foo.a", "foo.rlib", "foo.rmeta"]);
}