1313extern crate filetime;
1414
1515use std:: { fs, env} ;
16+ use std:: fs:: File ;
1617use std:: process:: { Command , Stdio } ;
1718use std:: path:: { Path , PathBuf } ;
1819
@@ -148,19 +149,29 @@ pub fn up_to_date(src: &Path, dst: &Path) -> bool {
148149 }
149150}
150151
152+ #[ must_use]
151153pub struct NativeLibBoilerplate {
152- pub skip_build : bool ,
153154 pub src_dir : PathBuf ,
154155 pub out_dir : PathBuf ,
155- pub timestamp : PathBuf ,
156156}
157157
158+ impl Drop for NativeLibBoilerplate {
159+ fn drop ( & mut self ) {
160+ t ! ( File :: create( self . out_dir. join( "rustbuild.timestamp" ) ) ) ;
161+ }
162+ }
163+
164+ // Perform standard preparations for native libraries that are build only once for all stages.
165+ // Emit rerun-if-changed and linking attributes for Cargo, check if any source files are
166+ // updated, calculate paths used later in actual build with CMake/make or C/C++ compiler.
167+ // If Err is returned, then everything is up-to-date and further build actions can be skipped.
168+ // Timestamps are created automatically when the result of `native_lib_boilerplate` goes out
169+ // of scope, so all the build actions should be completed until then.
158170pub fn native_lib_boilerplate ( src_name : & str ,
159171 out_name : & str ,
160172 link_name : & str ,
161- timestamp_name : & str ,
162173 search_subdir : & str )
163- -> NativeLibBoilerplate {
174+ -> Result < NativeLibBoilerplate , ( ) > {
164175 let current_dir = PathBuf :: from ( env:: var ( "CARGO_MANIFEST_DIR" ) . unwrap ( ) ) ;
165176 let src_dir = current_dir. join ( ".." ) . join ( src_name) ;
166177 rerun_if_changed_anything_in_dir ( & src_dir) ;
@@ -171,15 +182,11 @@ pub fn native_lib_boilerplate(src_name: &str,
171182 println ! ( "cargo:rustc-link-lib=static={}" , link_name) ;
172183 println ! ( "cargo:rustc-link-search=native={}" , out_dir. join( search_subdir) . display( ) ) ;
173184
174- let timestamp = out_dir. join ( timestamp_name) ;
175- let skip_build = up_to_date ( Path :: new ( "build.rs" ) , & timestamp) &&
176- up_to_date ( & src_dir, & timestamp) ;
177-
178- NativeLibBoilerplate {
179- skip_build : skip_build,
180- src_dir : src_dir,
181- out_dir : out_dir,
182- timestamp : timestamp,
185+ let timestamp = out_dir. join ( "rustbuild.timestamp" ) ;
186+ if !up_to_date ( Path :: new ( "build.rs" ) , & timestamp) || !up_to_date ( & src_dir, & timestamp) {
187+ Ok ( NativeLibBoilerplate { src_dir : src_dir, out_dir : out_dir } )
188+ } else {
189+ Err ( ( ) )
183190 }
184191}
185192
0 commit comments