@@ -89,6 +89,30 @@ fn find_registrar_symbol(file: &Path) -> Option<String> {
89
89
. map ( |s| s. to_string ( ) )
90
90
}
91
91
92
+ /// Loads dynamic library in platform dependent manner.
93
+ ///
94
+ /// For unix, you have to use RTLD_DEEPBIND flag to escape problems described
95
+ /// [here](https://github.com/fedochet/rust-proc-macro-panic-inside-panic-expample)
96
+ /// and [here](https://github.com/rust-lang/rust/issues/60593).
97
+ ///
98
+ /// Usage of RTLD_DEEPBIND is suggested by @edwin0cheng
99
+ /// [here](https://github.com/fedochet/rust-proc-macro-panic-inside-panic-expample/issues/1)
100
+ ///
101
+ /// It seems that on Windows that behaviour is default, so we do nothing in that case.
102
+ fn load_library ( file : & Path ) -> Result < Library , std:: io:: Error > {
103
+ if cfg ! ( target_os = "windows" ) {
104
+ Library :: new ( file)
105
+ } else {
106
+ use std:: os:: raw:: c_int;
107
+ use libloading:: os:: unix:: Library as UnixLibrary ;
108
+
109
+ const RTLD_NOW : c_int = 0x00002 ;
110
+ const RTLD_DEEPBIND : c_int = 0x00008 ;
111
+
112
+ UnixLibrary :: open ( Some ( file) , RTLD_NOW | RTLD_DEEPBIND ) . map ( |lib| lib. into ( ) )
113
+ }
114
+ }
115
+
92
116
struct ProcMacroLibraryLibloading {
93
117
lib : Library ,
94
118
exported_macros : Vec < ProcMacro > ,
@@ -99,7 +123,7 @@ impl ProcMacroLibraryLibloading {
99
123
let symbol_name = find_registrar_symbol ( file)
100
124
. ok_or ( format ! ( "Cannot find registrar symbol in file {:?}" , file) ) ?;
101
125
102
- let lib = Library :: new ( file) . map_err ( |e| e. to_string ( ) ) ?;
126
+ let lib = load_library ( file) . map_err ( |e| e. to_string ( ) ) ?;
103
127
104
128
let exported_macros = {
105
129
let macros: libloading:: Symbol < & & [ ProcMacro ] > = unsafe { lib. get ( symbol_name. as_bytes ( ) ) }
0 commit comments