@@ -2031,15 +2031,6 @@ fn linker_with_args<'a>(
2031
2031
tmpdir,
2032
2032
) ;
2033
2033
2034
- // Dynamic native libraries from upstream crates.
2035
- //
2036
- // FIXME: Merge this to `add_upstream_rust_crates` so that all native libraries are linked
2037
- // together with their respective upstream crates, and in their originally specified order.
2038
- // This may be slightly breaking due to our use of `--as-needed` and needs a crater run.
2039
- if sess. opts . unstable_opts . link_native_libraries {
2040
- add_upstream_native_libraries ( cmd, sess, codegen_results) ;
2041
- }
2042
-
2043
2034
// Link with the import library generated for any raw-dylib functions.
2044
2035
for ( raw_dylib_name, raw_dylib_imports) in
2045
2036
collate_raw_dylibs ( sess, & codegen_results. crate_info . used_libraries ) ?
@@ -2375,7 +2366,8 @@ fn add_upstream_rust_crates<'a>(
2375
2366
// appear statically in an existing dylib, meaning we'll pick up all the
2376
2367
// symbols from the dylib.
2377
2368
let src = & codegen_results. crate_info . used_crate_source [ & cnum] ;
2378
- match data[ cnum. as_usize ( ) - 1 ] {
2369
+ let linkage = data[ cnum. as_usize ( ) - 1 ] ;
2370
+ match linkage {
2379
2371
_ if codegen_results. crate_info . profiler_runtime == Some ( cnum) => {
2380
2372
add_static_crate (
2381
2373
cmd,
@@ -2412,89 +2404,96 @@ fn add_upstream_rust_crates<'a>(
2412
2404
cnum,
2413
2405
& bundled_libs,
2414
2406
) ;
2407
+ }
2408
+ Linkage :: Dynamic => add_dynamic_crate ( cmd, sess, & src. dylib . as_ref ( ) . unwrap ( ) . 0 ) ,
2409
+ }
2415
2410
2416
- // Link static native libs with "-bundle" modifier only if the crate they originate from
2417
- // is being linked statically to the current crate. If it's linked dynamically
2418
- // or is an rlib already included via some other dylib crate, the symbols from
2419
- // native libs will have already been included in that dylib.
2420
- //
2421
- // If `-Zlink-native-libraries=false` is set, then the assumption is that an
2422
- // external build system already has the native dependencies defined, and it
2423
- // will provide them to the linker itself.
2424
- if sess . opts . unstable_opts . link_native_libraries {
2425
- if sess . opts . unstable_opts . packed_bundled_libs {
2426
- // If rlib contains native libs as archives, unpack them to tmpdir.
2427
- let rlib = & src. rlib . as_ref ( ) . unwrap ( ) . 0 ;
2428
- archive_builder_builder
2429
- . extract_bundled_libs ( rlib, tmpdir, & bundled_libs)
2430
- . unwrap_or_else ( |e| sess. fatal ( e) ) ;
2431
- }
2411
+ if sess . opts . unstable_opts . link_native_libraries {
2412
+ if linkage == Linkage :: Static && sess . opts . unstable_opts . packed_bundled_libs {
2413
+ let bundled_libs = if sess . opts . unstable_opts . packed_bundled_libs {
2414
+ codegen_results . crate_info . native_libraries [ & cnum ]
2415
+ . iter ( )
2416
+ . filter_map ( |lib| lib . filename )
2417
+ . collect :: < FxHashSet < _ > > ( )
2418
+ } else {
2419
+ Default :: default ( )
2420
+ } ;
2421
+ // If rlib contains native libs as archives, unpack them to tmpdir.
2422
+ let rlib = & src. rlib . as_ref ( ) . unwrap ( ) . 0 ;
2423
+ archive_builder_builder
2424
+ . extract_bundled_libs ( rlib, tmpdir, & bundled_libs)
2425
+ . unwrap_or_else ( |e| sess. fatal ( e) ) ;
2426
+ }
2432
2427
2433
- let mut last = ( None , NativeLibKind :: Unspecified , None ) ;
2434
- for lib in & codegen_results. crate_info . native_libraries [ & cnum] {
2435
- let Some ( name) = lib. name else {
2436
- continue ;
2437
- } ;
2438
- let name = name. as_str ( ) ;
2439
- if !relevant_lib ( sess, lib) {
2440
- continue ;
2441
- }
2428
+ let mut last = ( None , NativeLibKind :: Unspecified , None ) ;
2429
+ for lib in & codegen_results. crate_info . native_libraries [ & cnum] {
2430
+ let Some ( name) = lib. name else {
2431
+ continue ;
2432
+ } ;
2433
+ let name = name. as_str ( ) ;
2434
+ if !relevant_lib ( sess, lib) {
2435
+ continue ;
2436
+ }
2442
2437
2443
- // Skip if this library is the same as the last.
2444
- last = if ( lib. name , lib. kind , lib. verbatim ) == last {
2445
- continue ;
2446
- } else {
2447
- ( lib. name , lib. kind , lib. verbatim )
2448
- } ;
2449
-
2450
- match lib. kind {
2451
- NativeLibKind :: Static {
2452
- bundle : Some ( false ) ,
2453
- whole_archive : Some ( true ) ,
2454
- } => {
2455
- cmd. link_whole_staticlib (
2456
- name,
2457
- lib. verbatim . unwrap_or ( false ) ,
2458
- search_path. get_or_init ( || archive_search_paths ( sess) ) ,
2459
- ) ;
2460
- }
2461
- NativeLibKind :: Static {
2462
- bundle : Some ( false ) ,
2463
- whole_archive : Some ( false ) | None ,
2464
- } => {
2465
- // HACK/FIXME: Fixup a circular dependency between libgcc and libc
2466
- // with glibc. This logic should be moved to the libc crate.
2467
- if sess. target . os == "linux"
2468
- && sess. target . env == "gnu"
2469
- && name == "c"
2470
- {
2471
- cmd. link_staticlib ( "gcc" , false ) ;
2472
- }
2473
- cmd. link_staticlib ( name, lib. verbatim . unwrap_or ( false ) ) ;
2474
- }
2475
- NativeLibKind :: LinkArg => {
2476
- cmd. arg ( name) ;
2438
+ // Skip if this library is the same as the last.
2439
+ last = if ( lib. name , lib. kind , lib. verbatim ) == last {
2440
+ continue ;
2441
+ } else {
2442
+ ( lib. name , lib. kind , lib. verbatim )
2443
+ } ;
2444
+
2445
+ let verbatim = lib. verbatim . unwrap_or ( false ) ;
2446
+ match lib. kind {
2447
+ NativeLibKind :: Static { bundle : Some ( false ) , whole_archive : Some ( true ) } => {
2448
+ if linkage == Linkage :: Static {
2449
+ cmd. link_whole_staticlib (
2450
+ name,
2451
+ verbatim,
2452
+ search_path. get_or_init ( || archive_search_paths ( sess) ) ,
2453
+ ) ;
2454
+ }
2455
+ }
2456
+ NativeLibKind :: Static {
2457
+ bundle : Some ( false ) ,
2458
+ whole_archive : Some ( false ) | None ,
2459
+ } => {
2460
+ if linkage == Linkage :: Static {
2461
+ // HACK/FIXME: Fixup a circular dependency between libgcc and libc
2462
+ // with glibc. This logic should be moved to the libc crate.
2463
+ if sess. target . os == "linux" && sess. target . env == "gnu" && name == "c"
2464
+ {
2465
+ cmd. link_staticlib ( "gcc" , false ) ;
2477
2466
}
2478
- NativeLibKind :: Dylib { .. }
2479
- | NativeLibKind :: Framework { .. }
2480
- | NativeLibKind :: Unspecified
2481
- | NativeLibKind :: RawDylib => { }
2482
- NativeLibKind :: Static { bundle : Some ( true ) | None , whole_archive } => {
2483
- if sess. opts . unstable_opts . packed_bundled_libs {
2484
- // If rlib contains native libs as archives, they are unpacked to tmpdir.
2485
- let path = tmpdir. join ( lib. filename . unwrap ( ) . as_str ( ) ) ;
2486
- if whole_archive == Some ( true ) {
2487
- cmd. link_whole_rlib ( & path) ;
2488
- } else {
2489
- cmd. link_rlib ( & path) ;
2490
- }
2491
- }
2467
+ cmd. link_staticlib ( name, verbatim) ;
2468
+ }
2469
+ }
2470
+ NativeLibKind :: Static { bundle : Some ( true ) | None , whole_archive } => {
2471
+ if linkage == Linkage :: Static && sess. opts . unstable_opts . packed_bundled_libs
2472
+ {
2473
+ // If rlib contains native libs as archives, they are unpacked to tmpdir.
2474
+ let path = tmpdir. join ( lib. filename . unwrap ( ) . as_str ( ) ) ;
2475
+ if whole_archive == Some ( true ) {
2476
+ cmd. link_whole_rlib ( & path) ;
2477
+ } else {
2478
+ cmd. link_rlib ( & path) ;
2492
2479
}
2493
2480
}
2494
2481
}
2482
+ NativeLibKind :: Dylib { as_needed } => {
2483
+ cmd. link_dylib ( name, verbatim, as_needed. unwrap_or ( true ) )
2484
+ }
2485
+ NativeLibKind :: RawDylib => { }
2486
+ NativeLibKind :: Framework { as_needed } => {
2487
+ cmd. link_framework ( name, as_needed. unwrap_or ( true ) )
2488
+ }
2489
+ NativeLibKind :: LinkArg => {
2490
+ if linkage == Linkage :: Static {
2491
+ cmd. arg ( name) ;
2492
+ }
2493
+ }
2494
+ NativeLibKind :: Unspecified => cmd. link_dylib ( name, verbatim, true ) ,
2495
2495
}
2496
2496
}
2497
- Linkage :: Dynamic => add_dynamic_crate ( cmd, sess, & src. dylib . as_ref ( ) . unwrap ( ) . 0 ) ,
2498
2497
}
2499
2498
}
2500
2499
@@ -2648,63 +2647,6 @@ fn add_upstream_rust_crates<'a>(
2648
2647
}
2649
2648
}
2650
2649
2651
- /// Link in all of our upstream crates' native dependencies. Remember that all of these upstream
2652
- /// native dependencies are all non-static dependencies. We've got two cases then:
2653
- ///
2654
- /// 1. The upstream crate is an rlib. In this case we *must* link in the native dependency because
2655
- /// the rlib is just an archive.
2656
- ///
2657
- /// 2. The upstream crate is a dylib. In order to use the dylib, we have to have the dependency
2658
- /// present on the system somewhere. Thus, we don't gain a whole lot from not linking in the
2659
- /// dynamic dependency to this crate as well.
2660
- ///
2661
- /// The use case for this is a little subtle. In theory the native dependencies of a crate are
2662
- /// purely an implementation detail of the crate itself, but the problem arises with generic and
2663
- /// inlined functions. If a generic function calls a native function, then the generic function
2664
- /// must be instantiated in the target crate, meaning that the native symbol must also be resolved
2665
- /// in the target crate.
2666
- fn add_upstream_native_libraries (
2667
- cmd : & mut dyn Linker ,
2668
- sess : & Session ,
2669
- codegen_results : & CodegenResults ,
2670
- ) {
2671
- let mut last = ( None , NativeLibKind :: Unspecified , None ) ;
2672
- for & cnum in & codegen_results. crate_info . used_crates {
2673
- for lib in codegen_results. crate_info . native_libraries [ & cnum] . iter ( ) {
2674
- let Some ( name) = lib. name else {
2675
- continue ;
2676
- } ;
2677
- let name = name. as_str ( ) ;
2678
- if !relevant_lib ( sess, & lib) {
2679
- continue ;
2680
- }
2681
-
2682
- // Skip if this library is the same as the last.
2683
- last = if ( lib. name , lib. kind , lib. verbatim ) == last {
2684
- continue ;
2685
- } else {
2686
- ( lib. name , lib. kind , lib. verbatim )
2687
- } ;
2688
-
2689
- let verbatim = lib. verbatim . unwrap_or ( false ) ;
2690
- match lib. kind {
2691
- NativeLibKind :: Dylib { as_needed } => {
2692
- cmd. link_dylib ( name, verbatim, as_needed. unwrap_or ( true ) )
2693
- }
2694
- NativeLibKind :: Unspecified => cmd. link_dylib ( name, verbatim, true ) ,
2695
- NativeLibKind :: Framework { as_needed } => {
2696
- cmd. link_framework ( name, as_needed. unwrap_or ( true ) )
2697
- }
2698
- // ignore static native libraries here as we've
2699
- // already included them in add_local_native_libraries and
2700
- // add_upstream_rust_crates
2701
- NativeLibKind :: Static { .. } => { }
2702
- NativeLibKind :: RawDylib | NativeLibKind :: LinkArg => { }
2703
- }
2704
- }
2705
- }
2706
- }
2707
-
2708
2650
fn relevant_lib ( sess : & Session , lib : & NativeLib ) -> bool {
2709
2651
match lib. cfg {
2710
2652
Some ( ref cfg) => rustc_attr:: cfg_matches ( cfg, & sess. parse_sess , CRATE_NODE_ID , None ) ,
0 commit comments