@@ -542,43 +542,8 @@ fn compute_metadata<'a, 'cfg>(
542
542
cx : & Context < ' a , ' cfg > ,
543
543
metas : & mut HashMap < Unit < ' a > , Option < Metadata > > ,
544
544
) -> 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.
571
545
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) {
582
547
return None ;
583
548
}
584
549
@@ -641,7 +606,7 @@ fn compute_metadata<'a, 'cfg>(
641
606
642
607
// Seed the contents of `__CARGO_DEFAULT_LIB_METADATA` to the hasher if present.
643
608
// 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" ) {
645
610
channel. hash ( & mut hasher) ;
646
611
}
647
612
@@ -688,3 +653,53 @@ fn hash_rustc_version(bcx: &BuildContext<'_, '_>, hasher: &mut SipHasher) {
688
653
// the future when cranelift sees more use, and people want to switch
689
654
// between different backends without recompiling.
690
655
}
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