diff --git a/src/comp/back/link.rs b/src/comp/back/link.rs index 36a6daeff81..ed0ddad7fe2 100644 --- a/src/comp/back/link.rs +++ b/src/comp/back/link.rs @@ -348,7 +348,7 @@ mod write { * - Define CMETA as all the non-name, non-vers exported meta tags in the * crate (in sorted order). * - * - Define CMH as hash(CMETA). + * - Define CMH as hash(CMETA + hashes of dependent crates). * * - Compile our crate to lib CNAME-CMH-CVERS.so * @@ -395,7 +395,8 @@ fn build_link_meta(sess: session::session, c: ast::crate, output: str, // This calculates CMH as defined above fn crate_meta_extras_hash(sha: sha1, _crate: ast::crate, - metas: provided_metas) -> str { + metas: provided_metas, + dep_hashes: [str]) -> str { fn len_and_str(s: str) -> str { ret #fmt["%u_%s", str::byte_len(s), s]; } @@ -421,6 +422,11 @@ fn build_link_meta(sess: session::session, c: ast::crate, output: str, } } } + + for dh in dep_hashes { + sha.input_str(len_and_str(dh)); + } + ret truncated_sha1_result(sha); } @@ -463,7 +469,9 @@ fn build_link_meta(sess: session::session, c: ast::crate, output: str, let provided_metas = provided_link_metas(sess, c); let name = crate_meta_name(sess, c, output, provided_metas); let vers = crate_meta_vers(sess, c, provided_metas); - let extras_hash = crate_meta_extras_hash(sha, c, provided_metas); + let dep_hashes = cstore::get_dep_hashes(sess.get_cstore()); + let extras_hash = + crate_meta_extras_hash(sha, c, provided_metas, dep_hashes); ret {name: name, vers: vers, extras_hash: extras_hash}; } diff --git a/src/comp/metadata/cstore.rs b/src/comp/metadata/cstore.rs index c0f8588c8a2..e7ca671fea8 100644 --- a/src/comp/metadata/cstore.rs +++ b/src/comp/metadata/cstore.rs @@ -20,6 +20,8 @@ export add_used_link_args; export get_used_link_args; export add_use_stmt_cnum; export get_use_stmt_cnum; +export get_dep_hashes; + // A map from external crate numbers (as decoded from some crate file) to // local crate numbers (as generated during this session). Each external @@ -116,6 +118,29 @@ fn get_use_stmt_cnum(cstore: cstore, use_id: ast::node_id) -> ast::crate_num { ret p(cstore).use_crate_map.get(use_id); } +// returns hashes of crates directly used by this crate. Hashes are +// sorted by crate name. +fn get_dep_hashes(cstore: cstore) -> [str] { + type crate_hash = {name: str, hash: str}; + let result = []; + + p(cstore).use_crate_map.values {|cnum| + let cdata = cstore::get_crate_data(cstore, cnum); + let hash = decoder::get_crate_hash(cdata.data); + log #fmt("Add hash[%s]: %s", cdata.name, hash); + result += [{name: cdata.name, hash: hash}]; + }; + fn lteq(a: crate_hash, b: crate_hash) -> bool { + ret a.name <= b.name; + } + let sorted = std::sort::merge_sort(lteq, result); + log "sorted:"; + for x in sorted { + log #fmt(" hash[%s]: %s", x.name, x.hash); + } + fn mapper(ch: crate_hash) -> str { ret ch.hash; } + ret vec::map(mapper, sorted); +} // Local Variables: // mode: rust // fill-column: 78;