@@ -542,43 +542,8 @@ fn compute_metadata<'a, 'cfg>(
542542 cx : & Context < ' a , ' cfg > ,
543543 metas : & mut HashMap < Unit < ' a > , Option < Metadata > > ,
544544) -> Option < Metadata > {
545- if unit. mode . is_doc_test ( ) {
546- // Doc tests do not have metadata.
547- return None ;
548- }
549- // No metadata for dylibs because of a couple issues:
550- // - macOS encodes the dylib name in the executable,
551- // - Windows rustc multiple files of which we can't easily link all of them.
552- //
553- // No metadata for bin because of an issue:
554- // - wasm32 rustc/emcc encodes the `.wasm` name in the `.js` (rust-lang/cargo#4535).
555- // - msvc: The path to the PDB is embedded in the executable, and we don't
556- // want the PDB path to include the hash in it.
557- //
558- // Two exceptions:
559- // 1) Upstream dependencies (we aren't exporting + need to resolve name conflict),
560- // 2) `__CARGO_DEFAULT_LIB_METADATA` env var.
561- //
562- // Note, however, that the compiler's build system at least wants
563- // path dependencies (eg libstd) to have hashes in filenames. To account for
564- // that we have an extra hack here which reads the
565- // `__CARGO_DEFAULT_LIB_METADATA` environment variable and creates a
566- // hash in the filename if that's present.
567- //
568- // This environment variable should not be relied on! It's
569- // just here for rustbuild. We need a more principled method
570- // doing this eventually.
571545 let bcx = & cx. bcx ;
572- let __cargo_default_lib_metadata = env:: var ( "__CARGO_DEFAULT_LIB_METADATA" ) ;
573- let short_name = bcx. target_data . short_name ( & unit. kind ) ;
574- if !( unit. mode . is_any_test ( ) || unit. mode . is_check ( ) )
575- && ( unit. target . is_dylib ( )
576- || unit. target . is_cdylib ( )
577- || ( unit. target . is_executable ( ) && short_name. starts_with ( "wasm32-" ) )
578- || ( unit. target . is_executable ( ) && short_name. contains ( "msvc" ) ) )
579- && unit. pkg . package_id ( ) . source_id ( ) . is_path ( )
580- && __cargo_default_lib_metadata. is_err ( )
581- {
546+ if !should_use_metadata ( bcx, unit) {
582547 return None ;
583548 }
584549
@@ -641,7 +606,7 @@ fn compute_metadata<'a, 'cfg>(
641606
642607 // Seed the contents of `__CARGO_DEFAULT_LIB_METADATA` to the hasher if present.
643608 // This should be the release channel, to get a different hash for each channel.
644- if let Ok ( ref channel) = __cargo_default_lib_metadata {
609+ if let Ok ( ref channel) = env :: var ( "__CARGO_DEFAULT_LIB_METADATA" ) {
645610 channel. hash ( & mut hasher) ;
646611 }
647612
@@ -688,3 +653,53 @@ fn hash_rustc_version(bcx: &BuildContext<'_, '_>, hasher: &mut SipHasher) {
688653 // the future when cranelift sees more use, and people want to switch
689654 // between different backends without recompiling.
690655}
656+
657+ /// Returns whether or not this unit should use a metadata hash.
658+ fn should_use_metadata ( bcx : & BuildContext < ' _ , ' _ > , unit : & Unit < ' _ > ) -> bool {
659+ if unit. mode . is_doc_test ( ) {
660+ // Doc tests do not have metadata.
661+ return false ;
662+ }
663+ if unit. mode . is_any_test ( ) || unit. mode . is_check ( ) {
664+ // These always use metadata.
665+ return true ;
666+ }
667+ // No metadata in these cases:
668+ //
669+ // - dylibs:
670+ // - macOS encodes the dylib name in the executable, so it can't be renamed.
671+ // - TODO: Are there other good reasons? If not, maybe this should be macos specific?
672+ // - Windows MSVC executables: The path to the PDB is embedded in the
673+ // executable, and we don't want the PDB path to include the hash in it.
674+ // - wasm32 executables: When using emscripten, the path to the .wasm file
675+ // is embedded in the .js file, so we don't want the hash in there.
676+ // TODO: Is this necessary for wasm32-unknown-unknown?
677+ // - apple executables: The executable name is used in the dSYM directory
678+ // (such as `target/debug/foo.dSYM/Contents/Resources/DWARF/foo-64db4e4bf99c12dd`).
679+ // Unfortunately this causes problems with our current backtrace
680+ // implementation which looks for a file matching the exe name exactly.
681+ // See https://github.com/rust-lang/rust/issues/72550#issuecomment-638501691
682+ // for more details.
683+ //
684+ // This is only done for local packages, as we don't expect to export
685+ // dependencies.
686+ //
687+ // The __CARGO_DEFAULT_LIB_METADATA env var is used to override this to
688+ // force metadata in the hash. This is only used for building libstd. For
689+ // example, if libstd is placed in a common location, we don't want a file
690+ // named /usr/lib/libstd.so which could conflict with other rustc
691+ // installs. TODO: Is this still a realistic concern?
692+ // See https://github.com/rust-lang/cargo/issues/3005
693+ let short_name = bcx. target_data . short_name ( & unit. kind ) ;
694+ if ( unit. target . is_dylib ( )
695+ || unit. target . is_cdylib ( )
696+ || ( unit. target . is_executable ( ) && short_name. starts_with ( "wasm32-" ) )
697+ || ( unit. target . is_executable ( ) && short_name. contains ( "msvc" ) )
698+ || ( unit. target . is_executable ( ) && short_name. contains ( "-apple-" ) ) )
699+ && unit. pkg . package_id ( ) . source_id ( ) . is_path ( )
700+ && env:: var ( "__CARGO_DEFAULT_LIB_METADATA" ) . is_err ( )
701+ {
702+ return false ;
703+ }
704+ true
705+ }
0 commit comments