1313extern crate filetime;
1414
1515use std:: { fs, env} ;
16+ use std:: fs:: File ;
1617use std:: process:: { Command , Stdio } ;
1718use std:: path:: { Path , PathBuf } ;
1819
@@ -166,19 +167,29 @@ pub fn up_to_date(src: &Path, dst: &Path) -> bool {
166167 }
167168}
168169
170+ #[ must_use]
169171pub struct NativeLibBoilerplate {
170- pub skip_build : bool ,
171172 pub src_dir : PathBuf ,
172173 pub out_dir : PathBuf ,
173- pub timestamp : PathBuf ,
174174}
175175
176+ impl Drop for NativeLibBoilerplate {
177+ fn drop ( & mut self ) {
178+ t ! ( File :: create( self . out_dir. join( "rustbuild.timestamp" ) ) ) ;
179+ }
180+ }
181+
182+ // Perform standard preparations for native libraries that are build only once for all stages.
183+ // Emit rerun-if-changed and linking attributes for Cargo, check if any source files are
184+ // updated, calculate paths used later in actual build with CMake/make or C/C++ compiler.
185+ // If Err is returned, then everything is up-to-date and further build actions can be skipped.
186+ // Timestamps are created automatically when the result of `native_lib_boilerplate` goes out
187+ // of scope, so all the build actions should be completed until then.
176188pub fn native_lib_boilerplate ( src_name : & str ,
177189 out_name : & str ,
178190 link_name : & str ,
179- timestamp_name : & str ,
180191 search_subdir : & str )
181- -> NativeLibBoilerplate {
192+ -> Result < NativeLibBoilerplate , ( ) > {
182193 let current_dir = PathBuf :: from ( env:: var ( "CARGO_MANIFEST_DIR" ) . unwrap ( ) ) ;
183194 let src_dir = current_dir. join ( ".." ) . join ( src_name) ;
184195 rerun_if_changed_anything_in_dir ( & src_dir) ;
@@ -189,15 +200,11 @@ pub fn native_lib_boilerplate(src_name: &str,
189200 println ! ( "cargo:rustc-link-lib=static={}" , link_name) ;
190201 println ! ( "cargo:rustc-link-search=native={}" , out_dir. join( search_subdir) . display( ) ) ;
191202
192- let timestamp = out_dir. join ( timestamp_name) ;
193- let skip_build = up_to_date ( Path :: new ( "build.rs" ) , & timestamp) &&
194- up_to_date ( & src_dir, & timestamp) ;
195-
196- NativeLibBoilerplate {
197- skip_build : skip_build,
198- src_dir : src_dir,
199- out_dir : out_dir,
200- timestamp : timestamp,
203+ let timestamp = out_dir. join ( "rustbuild.timestamp" ) ;
204+ if !up_to_date ( Path :: new ( "build.rs" ) , & timestamp) || !up_to_date ( & src_dir, & timestamp) {
205+ Ok ( NativeLibBoilerplate { src_dir : src_dir, out_dir : out_dir } )
206+ } else {
207+ Err ( ( ) )
201208 }
202209}
203210
0 commit comments