@@ -149,6 +149,50 @@ pub fn bin_name(name: &str) -> String {
149149 if is_windows ( ) { format ! ( "{name}.exe" ) } else { name. to_string ( ) }
150150}
151151
152+ fn ar < P : AsRef < str > , P2 : AsRef < str > > ( obj_path : P , lib_path : P2 , caller_line_number : u32 ) {
153+ let mut ar = Command :: new ( env:: var ( "AR" ) . unwrap ( ) ) ;
154+ ar. current_dir ( tmp_dir ( ) ) . arg ( "crus" ) . arg ( lib_path. as_ref ( ) ) . arg ( obj_path. as_ref ( ) ) ;
155+ let output = ar. output ( ) . unwrap ( ) ;
156+ if !output. status . success ( ) {
157+ handle_failed_output ( & ar, output, caller_line_number) ;
158+ }
159+ }
160+
161+ /// Builds a static lib (`.lib` on Windows MSVC and `.a` for the rest) with the given name.
162+ #[ track_caller]
163+ pub fn build_native_static_lib ( lib_name : & str ) -> PathBuf {
164+ let caller_location = std:: panic:: Location :: caller ( ) ;
165+ let caller_line_number = caller_location. line ( ) ;
166+
167+ let obj_file = format ! ( "{lib_name}.o" ) ;
168+ let src = format ! ( "{lib_name}.c" ) ;
169+ let lib_name = if is_msvc ( ) {
170+ let lib_path = format ! ( "lib{lib_name}.lib" ) ;
171+ // First compiling `.c` to `.o`.
172+ cc ( ) . arg ( "-c" ) . out_exe ( lib_name) . input ( src) . run ( ) ;
173+ // Generating `.lib` from `.o`.
174+ let mut msvc_lib = Command :: new ( env:: var ( "MSVC_LIB_PATH" ) . unwrap ( ) ) ;
175+ msvc_lib
176+ . current_dir ( tmp_dir ( ) )
177+ . arg ( "-nologo" )
178+ . arg ( & format ! ( "-out:{}" , cygpath_windows( & lib_path) ) )
179+ . arg ( & obj_file) ;
180+ let output = msvc_lib. output ( ) . unwrap ( ) ;
181+ if !output. status . success ( ) {
182+ handle_failed_output ( & msvc_lib, output, caller_line_number) ;
183+ }
184+ lib_path
185+ } else {
186+ let lib_path = format ! ( "lib{lib_name}.a" ) ;
187+ // First compiling `.c` to `.o`.
188+ cc ( ) . arg ( "-v" ) . arg ( "-c" ) . out_exe ( & obj_file) . input ( src) . run ( ) ;
189+ // Generating `.a` from `.o`.
190+ ar ( obj_file, & lib_path, caller_line_number) ;
191+ lib_path
192+ } ;
193+ tmp_dir ( ) . join ( lib_name)
194+ }
195+
152196/// Use `cygpath -w` on a path to get a Windows path string back. This assumes that `cygpath` is
153197/// available on the platform!
154198#[ track_caller]
0 commit comments