@@ -270,10 +270,9 @@ pub fn each_linked_rlib(
270
270
271
271
/// Create an 'rlib'.
272
272
///
273
- /// An rlib in its current incarnation is essentially a renamed .a file. The rlib primarily contains
274
- /// the object file of the crate, but it also contains all of the object files from native
275
- /// libraries. This is done by unzipping native libraries and inserting all of the contents into
276
- /// this archive.
273
+ /// An rlib in its current incarnation is essentially a renamed .a file (with "dummy" object files).
274
+ /// The rlib primarily contains the object file of the crate, but it also some of the object files
275
+ /// from native libraries.
277
276
fn link_rlib < ' a > (
278
277
sess : & ' a Session ,
279
278
archive_builder_builder : & dyn ArchiveBuilderBuilder ,
@@ -347,44 +346,23 @@ fn link_rlib<'a>(
347
346
// loaded from the libraries found here and then encode that into the
348
347
// metadata of the rlib we're generating somehow.
349
348
for lib in codegen_results. crate_info . used_libraries . iter ( ) {
350
- match lib. kind {
351
- NativeLibKind :: Static { bundle : None | Some ( true ) , whole_archive : Some ( true ) }
352
- if flavor == RlibFlavor :: Normal && sess. opts . unstable_opts . packed_bundled_libs => { }
353
- NativeLibKind :: Static { bundle : None | Some ( true ) , whole_archive : Some ( true ) }
354
- if flavor == RlibFlavor :: Normal =>
355
- {
356
- // Don't allow mixing +bundle with +whole_archive since an rlib may contain
357
- // multiple native libs, some of which are +whole-archive and some of which are
358
- // -whole-archive and it isn't clear how we can currently handle such a
359
- // situation correctly.
360
- // See https://github.com/rust-lang/rust/issues/88085#issuecomment-901050897
361
- sess. emit_err ( errors:: IncompatibleLinkingModifiers ) ;
362
- }
363
- NativeLibKind :: Static { bundle : None | Some ( true ) , .. } => { }
364
- NativeLibKind :: Static { bundle : Some ( false ) , .. }
365
- | NativeLibKind :: Dylib { .. }
366
- | NativeLibKind :: Framework { .. }
367
- | NativeLibKind :: RawDylib
368
- | NativeLibKind :: LinkArg
369
- | NativeLibKind :: Unspecified => continue ,
370
- }
371
- if let Some ( name) = lib. name {
372
- let location =
349
+ let NativeLibKind :: Static { bundle : None | Some ( true ) , whole_archive } = lib. kind else {
350
+ continue ;
351
+ } ;
352
+ if whole_archive == Some ( true ) && !codegen_results. crate_info . feature_packed_bundled_libs {
353
+ sess. emit_err ( errors:: IncompatibleLinkingModifiers ) ;
354
+ }
355
+ if flavor == RlibFlavor :: Normal && let Some ( filename) = lib. filename {
356
+ let path = find_native_static_library ( filename. as_str ( ) , true , & lib_search_paths, sess) ;
357
+ let src = read ( path) . map_err ( |e| sess. emit_fatal ( errors:: ReadFileError { message : e } ) ) ?;
358
+ let ( data, _) = create_wrapper_file ( sess, b".bundled_lib" . to_vec ( ) , & src) ;
359
+ let wrapper_file = emit_wrapper_file ( sess, & data, tmpdir, filename. as_str ( ) ) ;
360
+ packed_bundled_libs. push ( wrapper_file) ;
361
+ } else if let Some ( name) = lib. name {
362
+ let path =
373
363
find_native_static_library ( name. as_str ( ) , lib. verbatim , & lib_search_paths, sess) ;
374
- if sess. opts . unstable_opts . packed_bundled_libs && flavor == RlibFlavor :: Normal {
375
- let filename = lib. filename . unwrap ( ) ;
376
- let lib_path =
377
- find_native_static_library ( filename. as_str ( ) , true , & lib_search_paths, sess) ;
378
- let src = read ( lib_path)
379
- . map_err ( |e| sess. emit_fatal ( errors:: ReadFileError { message : e } ) ) ?;
380
- let ( data, _) = create_wrapper_file ( sess, b".bundled_lib" . to_vec ( ) , & src) ;
381
- let wrapper_file = emit_wrapper_file ( sess, & data, tmpdir, filename. as_str ( ) ) ;
382
- packed_bundled_libs. push ( wrapper_file) ;
383
- continue ;
384
- }
385
- ab. add_archive ( & location, Box :: new ( |_| false ) ) . unwrap_or_else ( |error| {
386
- sess. emit_fatal ( errors:: AddNativeLibrary { library_path : location, error } ) ;
387
- } ) ;
364
+ ab. add_archive ( & path, Box :: new ( |_| false ) ) . unwrap_or_else ( |error| {
365
+ sess. emit_fatal ( errors:: AddNativeLibrary { library_path : path, error } ) } ) ;
388
366
}
389
367
}
390
368
@@ -516,36 +494,14 @@ fn link_staticlib<'a>(
516
494
& codegen_results. crate_info ,
517
495
Some ( CrateType :: Staticlib ) ,
518
496
& mut |cnum, path| {
519
- let name = codegen_results. crate_info . crate_name [ & cnum] ;
520
- let native_libs = & codegen_results. crate_info . native_libraries [ & cnum] ;
521
-
522
- // Here when we include the rlib into our staticlib we need to make a
523
- // decision whether to include the extra object files along the way.
524
- // These extra object files come from statically included native
525
- // libraries, but they may be cfg'd away with #[link(cfg(..))].
526
- //
527
- // This unstable feature, though, only needs liblibc to work. The only
528
- // use case there is where musl is statically included in liblibc.rlib,
529
- // so if we don't want the included version we just need to skip it. As
530
- // a result the logic here is that if *any* linked library is cfg'd away
531
- // we just skip all object files.
532
- //
533
- // Clearly this is not sufficient for a general purpose feature, and
534
- // we'd want to read from the library's metadata to determine which
535
- // object files come from where and selectively skip them.
536
- let skip_object_files = native_libs. iter ( ) . any ( |lib| {
537
- matches ! ( lib. kind, NativeLibKind :: Static { bundle: None | Some ( true ) , .. } )
538
- && !relevant_lib ( sess, lib)
539
- } ) ;
540
-
541
497
let lto = are_upstream_rust_objects_already_included ( sess)
542
498
&& !ignored_for_lto ( sess, & codegen_results. crate_info , cnum) ;
543
499
544
- // Ignoring obj file starting with the crate name
545
- // as simple comparison is not enough - there
546
- // might be also an extra name suffix
547
- let obj_start = name. as_str ( ) . to_owned ( ) ;
500
+ let native_libs = codegen_results. crate_info . native_libraries [ & cnum] . iter ( ) ;
501
+ let relevant = native_libs. clone ( ) . filter ( |lib| relevant_lib ( sess, & lib) ) ;
502
+ let relevant_libs: FxHashSet < _ > = relevant. filter_map ( |lib| lib. filename ) . collect ( ) ;
548
503
504
+ let bundled_libs: FxHashSet < _ > = native_libs. filter_map ( |lib| lib. filename ) . collect ( ) ;
549
505
ab. add_archive (
550
506
path,
551
507
Box :: new ( move |fname : & str | {
@@ -559,20 +515,25 @@ fn link_staticlib<'a>(
559
515
return true ;
560
516
}
561
517
562
- // Otherwise if this is *not* a rust object and we're skipping
563
- // objects then skip this file
564
- if skip_object_files
565
- && ( !fname. starts_with ( & obj_start) || !fname. ends_with ( ".o" ) )
566
- {
518
+ // Skip objects for bundled libs.
519
+ if bundled_libs. contains ( & Symbol :: intern ( fname) ) {
567
520
return true ;
568
521
}
569
522
570
- // ok, don't skip this
571
523
false
572
524
} ) ,
573
525
)
574
526
. unwrap ( ) ;
575
527
528
+ archive_builder_builder
529
+ . extract_bundled_libs ( path, tempdir. as_ref ( ) , & relevant_libs)
530
+ . unwrap_or_else ( |e| sess. emit_fatal ( e) ) ;
531
+ for filename in relevant_libs {
532
+ let joined = tempdir. as_ref ( ) . join ( filename. as_str ( ) ) ;
533
+ let path = joined. as_path ( ) ;
534
+ ab. add_archive ( path, Box :: new ( |_| false ) ) . unwrap ( ) ;
535
+ }
536
+
576
537
all_native_libs
577
538
. extend ( codegen_results. crate_info . native_libraries [ & cnum] . iter ( ) . cloned ( ) ) ;
578
539
} ,
@@ -2590,18 +2551,8 @@ fn add_static_crate<'a>(
2590
2551
cmd. link_rlib ( & fix_windows_verbatim_for_gcc ( path) ) ;
2591
2552
} ;
2592
2553
2593
- // See the comment above in `link_staticlib` and `link_rlib` for why if
2594
- // there's a static library that's not relevant we skip all object
2595
- // files.
2596
- let native_libs = & codegen_results. crate_info . native_libraries [ & cnum] ;
2597
- let skip_native = native_libs. iter ( ) . any ( |lib| {
2598
- matches ! ( lib. kind, NativeLibKind :: Static { bundle: None | Some ( true ) , .. } )
2599
- && !relevant_lib ( sess, lib)
2600
- } ) ;
2601
-
2602
- if ( !are_upstream_rust_objects_already_included ( sess)
2603
- || ignored_for_lto ( sess, & codegen_results. crate_info , cnum) )
2604
- && !skip_native
2554
+ if !are_upstream_rust_objects_already_included ( sess)
2555
+ || ignored_for_lto ( sess, & codegen_results. crate_info , cnum)
2605
2556
{
2606
2557
link_upstream ( cratepath) ;
2607
2558
return ;
@@ -2632,17 +2583,13 @@ fn add_static_crate<'a>(
2632
2583
let is_rust_object =
2633
2584
canonical. starts_with ( & canonical_name) && looks_like_rust_object_file ( & f) ;
2634
2585
2635
- // If we've been requested to skip all native object files
2636
- // (those not generated by the rust compiler) then we can skip
2637
- // this file. See above for why we may want to do this.
2638
- let skip_because_cfg_say_so = skip_native && !is_rust_object;
2639
-
2640
2586
// If we're performing LTO and this is a rust-generated object
2641
2587
// file, then we don't need the object file as it's part of the
2642
2588
// LTO module. Note that `#![no_builtins]` is excluded from LTO,
2643
2589
// though, so we let that object file slide.
2644
- let skip_because_lto =
2645
- upstream_rust_objects_already_included && is_rust_object && is_builtins;
2590
+ if upstream_rust_objects_already_included && is_rust_object && is_builtins {
2591
+ return true ;
2592
+ }
2646
2593
2647
2594
// We skip native libraries because:
2648
2595
// 1. This native libraries won't be used from the generated rlib,
@@ -2653,10 +2600,6 @@ fn add_static_crate<'a>(
2653
2600
return true ;
2654
2601
}
2655
2602
2656
- if skip_because_cfg_say_so || skip_because_lto {
2657
- return true ;
2658
- }
2659
-
2660
2603
false
2661
2604
} ) ,
2662
2605
) {
0 commit comments