13
13
extern crate filetime;
14
14
15
15
use std:: { fs, env} ;
16
+ use std:: fs:: File ;
16
17
use std:: process:: { Command , Stdio } ;
17
18
use std:: path:: { Path , PathBuf } ;
18
19
@@ -166,19 +167,29 @@ pub fn up_to_date(src: &Path, dst: &Path) -> bool {
166
167
}
167
168
}
168
169
170
+ #[ must_use]
169
171
pub struct NativeLibBoilerplate {
170
- pub skip_build : bool ,
171
172
pub src_dir : PathBuf ,
172
173
pub out_dir : PathBuf ,
173
- pub timestamp : PathBuf ,
174
174
}
175
175
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.
176
188
pub fn native_lib_boilerplate ( src_name : & str ,
177
189
out_name : & str ,
178
190
link_name : & str ,
179
- timestamp_name : & str ,
180
191
search_subdir : & str )
181
- -> NativeLibBoilerplate {
192
+ -> Result < NativeLibBoilerplate , ( ) > {
182
193
let current_dir = PathBuf :: from ( env:: var ( "CARGO_MANIFEST_DIR" ) . unwrap ( ) ) ;
183
194
let src_dir = current_dir. join ( ".." ) . join ( src_name) ;
184
195
rerun_if_changed_anything_in_dir ( & src_dir) ;
@@ -189,15 +200,11 @@ pub fn native_lib_boilerplate(src_name: &str,
189
200
println ! ( "cargo:rustc-link-lib=static={}" , link_name) ;
190
201
println ! ( "cargo:rustc-link-search=native={}" , out_dir. join( search_subdir) . display( ) ) ;
191
202
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 ( ( ) )
201
208
}
202
209
}
203
210
0 commit comments