@@ -785,6 +785,70 @@ fn link_natively(
785
785
should_archive. then ( || tmpdir. join ( out_filename. file_name ( ) . unwrap ( ) ) . with_extension ( "so" ) ) ;
786
786
let temp_filename = archive_member. as_deref ( ) . unwrap_or ( out_filename) ;
787
787
788
+ // Gather library search paths (-L)
789
+ let mut library_search_dirs = vec ! [ ] ;
790
+ walk_native_lib_search_dirs ( sess, self_contained_components, None , |dir, is_framework| {
791
+ if !is_framework {
792
+ library_search_dirs. push ( dir. to_path_buf ( ) ) ;
793
+ }
794
+ ControlFlow :: < ( ) > :: Continue ( ( ) )
795
+ } ) ;
796
+
797
+ // Find candidate objects to link
798
+ let mut obj_candidates = vec ! [ ] ;
799
+
800
+ // Rust objects
801
+ for module in & codegen_results. modules {
802
+ if let Some ( ref path) = module. object {
803
+ obj_candidates. push ( path. clone ( ) ) ;
804
+ }
805
+ }
806
+
807
+ // eprintln!("Library dirs: {:?}", library_search_dirs);
808
+ // Native libraries
809
+ for native_lib in codegen_results. crate_info . native_libraries . values ( ) . flatten ( ) {
810
+ // eprintln!("native lib {}", native_lib.name);
811
+ if let Some ( ref path) = native_lib. filename {
812
+ // eprintln!(" located at {path:?}");
813
+ obj_candidates. push ( PathBuf :: from ( path. to_string ( ) ) ) ;
814
+ } else {
815
+ // Try to find the library
816
+ let name = native_lib. name . to_string ( ) ;
817
+ let candidates = & [ format ! ( "lib{name}.a" ) , format ! ( "lib{name}.so" ) ] ;
818
+ for candidate in candidates {
819
+ // eprintln!("Finding candidate {candidate}");
820
+ for lib_dir in & library_search_dirs {
821
+ let candidate_path = lib_dir. join ( candidate) ;
822
+ if candidate_path. is_file ( ) {
823
+ eprintln ! ( "Found native library at {candidate_path:?}" ) ;
824
+ obj_candidates. push ( candidate_path) ;
825
+ }
826
+ }
827
+ }
828
+ }
829
+ }
830
+
831
+ use object:: read:: Object ;
832
+
833
+ // Scan native libraries, sources of .ctors/.dtors
834
+ let mut problematic_objects = vec ! [ ] ;
835
+ let sections = & [ ".ctors" , ".dtors" ] ;
836
+ for path in obj_candidates {
837
+ match std:: process:: Command :: new ( "readelf" ) . arg ( "-S" ) . arg ( & path) . output ( ) {
838
+ Ok ( output) => {
839
+ let stdout = String :: from_utf8_lossy ( & output. stdout ) ;
840
+ for section in sections {
841
+ if stdout. lines ( ) . any ( |line| line. contains ( section) ) {
842
+ problematic_objects. push ( ( path. clone ( ) , section. to_string ( ) ) ) ;
843
+ }
844
+ }
845
+ }
846
+ Err ( error) => {
847
+ eprintln ! ( "Cannot run readelf -S: {error:?}" )
848
+ }
849
+ }
850
+ }
851
+
788
852
let mut cmd = linker_with_args (
789
853
& linker_path,
790
854
flavor,
@@ -990,6 +1054,22 @@ fn link_natively(
990
1054
}
991
1055
}
992
1056
1057
+ // Scan the built artifact, lld might keep .ctors/.dtors in it
1058
+ if let Ok ( data) = std:: fs:: read ( & temp_filename) {
1059
+ if let Ok ( file) = object:: read:: File :: parse ( data. as_slice ( ) ) {
1060
+ for section_name in sections {
1061
+ if let Some ( _section) = file. section_by_name ( section_name) {
1062
+ problematic_objects
1063
+ . push ( ( temp_filename. to_path_buf ( ) , section_name. to_string ( ) ) ) ;
1064
+ }
1065
+ }
1066
+ }
1067
+ }
1068
+ if !problematic_objects. is_empty ( ) {
1069
+ eprintln ! ( "PROBLEMATIC OBJECtS\n {problematic_objects:?}" ) ;
1070
+ panic ! ( "{problematic_objects:?}" ) ;
1071
+ }
1072
+
993
1073
match prog {
994
1074
Ok ( prog) => {
995
1075
let is_msvc_link_exe = sess. target . is_like_msvc
0 commit comments