@@ -1131,48 +1131,7 @@ impl Build {
11311131 } ;
11321132 let dst = self . get_out_dir ( ) ?;
11331133
1134- let mut objects = Vec :: new ( ) ;
1135- for file in self . files . iter ( ) {
1136- let obj = if file. has_root ( ) || file. components ( ) . any ( |x| x == Component :: ParentDir ) {
1137- // If `file` is an absolute path or might not be usable directly as a suffix due to
1138- // using "..", use the `basename` prefixed with the `dirname`'s hash to ensure name
1139- // uniqueness.
1140- let basename = file
1141- . file_name ( )
1142- . ok_or_else ( || Error :: new ( ErrorKind :: InvalidArgument , "file_name() failure" ) ) ?
1143- . to_string_lossy ( ) ;
1144- let dirname = file
1145- . parent ( )
1146- . ok_or_else ( || Error :: new ( ErrorKind :: InvalidArgument , "parent() failure" ) ) ?
1147- . to_string_lossy ( ) ;
1148- let mut hasher = hash_map:: DefaultHasher :: new ( ) ;
1149- hasher. write ( dirname. to_string ( ) . as_bytes ( ) ) ;
1150- dst. join ( format ! ( "{:016x}-{}" , hasher. finish( ) , basename) )
1151- . with_extension ( "o" )
1152- } else {
1153- dst. join ( file) . with_extension ( "o" )
1154- } ;
1155- let obj = if !obj. starts_with ( & dst) {
1156- dst. join ( obj. file_name ( ) . ok_or_else ( || {
1157- Error :: new ( ErrorKind :: IOError , "Getting object file details failed." )
1158- } ) ?)
1159- } else {
1160- obj
1161- } ;
1162-
1163- match obj. parent ( ) {
1164- Some ( s) => fs:: create_dir_all ( s) ?,
1165- None => {
1166- return Err ( Error :: new (
1167- ErrorKind :: IOError ,
1168- "Getting object file details failed." ,
1169- ) ) ;
1170- }
1171- } ;
1172-
1173- objects. push ( Object :: new ( file. to_path_buf ( ) , obj) ) ;
1174- }
1175-
1134+ let objects = objects_from_files ( self . files . iter ( ) . map ( |v| & * * v) , & dst) ?;
11761135 let print = PrintThread :: new ( ) ?;
11771136
11781137 self . compile_objects ( & objects, & print) ?;
@@ -1316,6 +1275,33 @@ impl Build {
13161275 }
13171276 }
13181277
1278+
1279+ /// Run the compiler, generating intermediate files, but without linking
1280+ /// them into an archive file.
1281+ ///
1282+ /// This will return a list of compiled object files, in the same order
1283+ /// as they were passed in as `file`/`files` methods.
1284+ pub fn compile_intermediates ( & self ) -> Vec < PathBuf > {
1285+ match self . try_compile_intermediates ( ) {
1286+ Ok ( v) => v,
1287+ Err ( e) => fail ( & e. message ) ,
1288+ }
1289+ }
1290+
1291+ /// Run the compiler, generating intermediate files, but without linking
1292+ /// them into an archive file.
1293+ ///
1294+ /// This will return a result instead of panicing; see `compile_intermediates()` for the complete description.
1295+ pub fn try_compile_intermediates ( & self ) -> Result < Vec < PathBuf > , Error > {
1296+ let dst = self . get_out_dir ( ) ?;
1297+ let objects = objects_from_files ( self . files . iter ( ) . map ( |v| & * * v) , & dst) ?;
1298+ let print = PrintThread :: new ( ) ?;
1299+
1300+ self . compile_objects ( & objects, & print) ?;
1301+
1302+ Ok ( objects. into_iter ( ) . map ( |v| v. dst ) . collect ( ) )
1303+ }
1304+
13191305 #[ cfg( feature = "parallel" ) ]
13201306 fn compile_objects ( & self , objs : & [ Object ] , print : & PrintThread ) -> Result < ( ) , Error > {
13211307 use std:: cell:: Cell ;
@@ -3830,6 +3816,54 @@ fn wait_on_child(cmd: &Command, program: &str, child: &mut Child) -> Result<(),
38303816 }
38313817}
38323818
3819+ /// Find the destination object path for each file in the input source files,
3820+ /// and store them in the output Object.
3821+ fn objects_from_files < ' a , I : IntoIterator < Item = & ' a Path > > ( files : I , dst : & Path ) -> Result < Vec < Object > , Error > {
3822+ let mut objects = Vec :: new ( ) ;
3823+ for file in files. into_iter ( ) {
3824+ let obj = if file. has_root ( ) || file. components ( ) . any ( |x| x == Component :: ParentDir ) {
3825+ // If `file` is an absolute path or might not be usable directly as a suffix due to
3826+ // using "..", use the `basename` prefixed with the `dirname`'s hash to ensure name
3827+ // uniqueness.
3828+ let basename = file
3829+ . file_name ( )
3830+ . ok_or_else ( || Error :: new ( ErrorKind :: InvalidArgument , "file_name() failure" ) ) ?
3831+ . to_string_lossy ( ) ;
3832+ let dirname = file
3833+ . parent ( )
3834+ . ok_or_else ( || Error :: new ( ErrorKind :: InvalidArgument , "parent() failure" ) ) ?
3835+ . to_string_lossy ( ) ;
3836+ let mut hasher = hash_map:: DefaultHasher :: new ( ) ;
3837+ hasher. write ( dirname. to_string ( ) . as_bytes ( ) ) ;
3838+ dst. join ( format ! ( "{:016x}-{}" , hasher. finish( ) , basename) )
3839+ . with_extension ( "o" )
3840+ } else {
3841+ dst. join ( file) . with_extension ( "o" )
3842+ } ;
3843+ let obj = if !obj. starts_with ( & dst) {
3844+ dst. join ( obj. file_name ( ) . ok_or_else ( || {
3845+ Error :: new ( ErrorKind :: IOError , "Getting object file details failed." )
3846+ } ) ?)
3847+ } else {
3848+ obj
3849+ } ;
3850+
3851+ match obj. parent ( ) {
3852+ Some ( s) => fs:: create_dir_all ( s) ?,
3853+ None => {
3854+ return Err ( Error :: new (
3855+ ErrorKind :: IOError ,
3856+ "Getting object file details failed." ,
3857+ ) ) ;
3858+ }
3859+ } ;
3860+
3861+ objects. push ( Object :: new ( file. to_path_buf ( ) , obj) ) ;
3862+ }
3863+
3864+ Ok ( objects)
3865+ }
3866+
38333867#[ cfg( feature = "parallel" ) ]
38343868fn try_wait_on_child (
38353869 cmd : & Command ,
0 commit comments