1
- use rustc_data_structures:: fx:: FxHashSet ;
1
+ use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
2
2
use rustc_data_structures:: temp_dir:: MaybeTempDir ;
3
3
use rustc_errors:: Handler ;
4
4
use rustc_fs_util:: fix_windows_verbatim_for_gcc;
5
5
use rustc_hir:: def_id:: CrateNum ;
6
- use rustc_middle:: middle:: cstore:: { EncodedMetadata , LibSource } ;
6
+ use rustc_middle:: middle:: cstore:: { DllImport , EncodedMetadata , LibSource } ;
7
7
use rustc_middle:: middle:: dependency_format:: Linkage ;
8
8
use rustc_session:: config:: { self , CFGuard , CrateType , DebugInfo } ;
9
9
use rustc_session:: config:: { OutputFilenames , OutputType , PrintRequest } ;
@@ -30,6 +30,7 @@ use crate::{
30
30
use cc:: windows_registry;
31
31
use tempfile:: Builder as TempFileBuilder ;
32
32
33
+ use std:: cmp:: Ordering ;
33
34
use std:: ffi:: OsString ;
34
35
use std:: path:: { Path , PathBuf } ;
35
36
use std:: process:: { ExitStatus , Output , Stdio } ;
@@ -339,6 +340,12 @@ fn link_rlib<'a, B: ArchiveBuilder<'a>>(
339
340
}
340
341
}
341
342
343
+ for ( raw_dylib_name, raw_dylib_imports) in
344
+ collate_raw_dylibs ( & codegen_results. crate_info . used_libraries )
345
+ {
346
+ ab. inject_dll_import_lib ( & raw_dylib_name, & raw_dylib_imports, tmpdir) ;
347
+ }
348
+
342
349
// After adding all files to the archive, we need to update the
343
350
// symbol table of the archive.
344
351
ab. update_symbols ( ) ;
@@ -389,6 +396,57 @@ fn link_rlib<'a, B: ArchiveBuilder<'a>>(
389
396
ab
390
397
}
391
398
399
+ /// Extract all symbols defined in raw-dylib libraries, collated by library name.
400
+ ///
401
+ /// If we have multiple extern blocks that specify symbols defined in the same raw-dylib library,
402
+ /// then the CodegenResults value contains one NativeLib instance for each block. However, the
403
+ /// linker appears to expect only a single import library for each library used, so we need to
404
+ /// collate the symbols together by library name before generating the import libraries.
405
+ fn collate_raw_dylibs ( used_libraries : & [ NativeLib ] ) -> Vec < ( String , Vec < DllImport > ) > {
406
+ let mut dylib_table: FxHashMap < String , FxHashSet < Symbol > > = FxHashMap :: default ( ) ;
407
+
408
+ for lib in used_libraries {
409
+ if lib. kind == NativeLibKind :: RawDylib {
410
+ let name = lib. name . unwrap_or_else ( ||
411
+ bug ! ( "`link` attribute with kind = \" raw-dylib\" and no name should have caused error earlier" )
412
+ ) ;
413
+ let name = if matches ! ( lib. verbatim, Some ( true ) ) {
414
+ name. to_string ( )
415
+ } else {
416
+ format ! ( "{}.dll" , name)
417
+ } ;
418
+ dylib_table
419
+ . entry ( name)
420
+ . or_default ( )
421
+ . extend ( lib. dll_imports . iter ( ) . map ( |import| import. name ) ) ;
422
+ }
423
+ }
424
+
425
+ // FIXME: when we add support for ordinals, fix this to propagate ordinals. Also figure out
426
+ // what we should do if we have two DllImport values with the same name but different
427
+ // ordinals.
428
+ let mut result = dylib_table
429
+ . into_iter ( )
430
+ . map ( |( lib_name, imported_names) | {
431
+ let mut names = imported_names
432
+ . iter ( )
433
+ . map ( |name| DllImport { name : * name, ordinal : None } )
434
+ . collect :: < Vec < _ > > ( ) ;
435
+ names. sort_unstable_by ( |a : & DllImport , b : & DllImport | {
436
+ match a. name . as_str ( ) . cmp ( & b. name . as_str ( ) ) {
437
+ Ordering :: Equal => a. ordinal . cmp ( & b. ordinal ) ,
438
+ x => x,
439
+ }
440
+ } ) ;
441
+ ( lib_name, names)
442
+ } )
443
+ . collect :: < Vec < _ > > ( ) ;
444
+ result. sort_unstable_by ( |a : & ( String , Vec < DllImport > ) , b : & ( String , Vec < DllImport > ) | {
445
+ a. 0 . cmp ( & b. 0 )
446
+ } ) ;
447
+ result
448
+ }
449
+
392
450
/// Create a static archive.
393
451
///
394
452
/// This is essentially the same thing as an rlib, but it also involves adding all of the upstream
@@ -2176,10 +2234,7 @@ fn add_upstream_native_libraries(
2176
2234
// already included them when we included the rust library
2177
2235
// previously
2178
2236
NativeLibKind :: Static { bundle : None | Some ( true ) , .. } => { }
2179
- NativeLibKind :: RawDylib => {
2180
- // FIXME(#58713): Proper handling for raw dylibs.
2181
- bug ! ( "raw_dylib feature not yet implemented" ) ;
2182
- }
2237
+ NativeLibKind :: RawDylib => { }
2183
2238
}
2184
2239
}
2185
2240
}
0 commit comments