1+ #![ allow( deprecated) ] // for SipHasher
2+
13use std:: collections:: { BTreeMap , HashMap } ;
24use std:: fmt;
3- use std:: hash:: { Hash , Hasher } ;
5+ use std:: hash:: { Hash , Hasher , SipHasher } ;
46use std:: path:: { Path , PathBuf } ;
57use std:: rc:: Rc ;
68
@@ -15,7 +17,7 @@ use core::{Dependency, PackageId, PackageIdSpec, SourceId, Summary};
1517use core:: { Edition , Feature , Features , WorkspaceConfig } ;
1618use util:: errors:: * ;
1719use util:: toml:: TomlManifest ;
18- use util:: Config ;
20+ use util:: { Config , Filesystem } ;
1921
2022pub enum EitherManifest {
2123 Real ( Manifest ) ,
@@ -44,6 +46,7 @@ pub struct Manifest {
4446 edition : Edition ,
4547 im_a_teapot : Option < bool > ,
4648 default_run : Option < String > ,
49+ metabuild : Option < Vec < String > > ,
4750}
4851
4952/// When parsing `Cargo.toml`, some warnings should silenced
@@ -190,7 +193,7 @@ pub struct Target {
190193 // as it's absolute currently and is otherwise a little too brittle for
191194 // causing rebuilds. Instead the hash for the path that we send to the
192195 // compiler is handled elsewhere.
193- src_path : NonHashedPathBuf ,
196+ src_path : TargetSourcePath ,
194197 required_features : Option < Vec < String > > ,
195198 tested : bool ,
196199 benched : bool ,
@@ -202,19 +205,50 @@ pub struct Target {
202205}
203206
204207#[ derive( Clone , PartialEq , Eq ) ]
205- struct NonHashedPathBuf {
206- path : PathBuf ,
208+ pub enum TargetSourcePath {
209+ Path ( PathBuf ) ,
210+ Metabuild ,
207211}
208212
209- impl Hash for NonHashedPathBuf {
213+ impl TargetSourcePath {
214+ pub fn path ( & self ) -> & Path {
215+ match self {
216+ TargetSourcePath :: Path ( path) => path. as_ref ( ) ,
217+ TargetSourcePath :: Metabuild => panic ! ( "metabuild not expected" ) ,
218+ }
219+ }
220+
221+ pub fn is_path ( & self ) -> bool {
222+ match self {
223+ TargetSourcePath :: Path ( _) => true ,
224+ _ => false ,
225+ }
226+ }
227+ }
228+
229+ impl Hash for TargetSourcePath {
210230 fn hash < H : Hasher > ( & self , _: & mut H ) {
211231 // ...
212232 }
213233}
214234
215- impl fmt:: Debug for NonHashedPathBuf {
235+ impl fmt:: Debug for TargetSourcePath {
216236 fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
217- self . path . fmt ( f)
237+ match self {
238+ TargetSourcePath :: Path ( path) => path. fmt ( f) ,
239+ TargetSourcePath :: Metabuild => "metabuild" . fmt ( f) ,
240+ }
241+ }
242+ }
243+
244+ impl From < PathBuf > for TargetSourcePath {
245+ fn from ( path : PathBuf ) -> Self {
246+ assert ! (
247+ path. is_absolute( ) ,
248+ "`{}` is not absolute" ,
249+ path. display( )
250+ ) ;
251+ TargetSourcePath :: Path ( path)
218252 }
219253}
220254
@@ -239,7 +273,7 @@ impl ser::Serialize for Target {
239273 kind : & self . kind ,
240274 crate_types : self . rustc_crate_types ( ) ,
241275 name : & self . name ,
242- src_path : & self . src_path . path ,
276+ src_path : & self . src_path . path ( ) . to_path_buf ( ) ,
243277 edition : & self . edition . to_string ( ) ,
244278 required_features : self
245279 . required_features
@@ -253,34 +287,43 @@ compact_debug! {
253287 impl fmt:: Debug for Target {
254288 fn fmt( & self , f: & mut fmt:: Formatter ) -> fmt:: Result {
255289 let ( default , default_name) = {
256- let src = self . src_path( ) . to_path_buf( ) ;
257290 match & self . kind {
258291 TargetKind :: Lib ( kinds) => {
259292 (
260293 Target :: lib_target(
261294 & self . name,
262295 kinds. clone( ) ,
263- src . clone ( ) ,
264- Edition :: Edition2015 ,
296+ self . src_path ( ) . path ( ) . to_path_buf ( ) ,
297+ self . edition ,
265298 ) ,
266- format!( "lib_target({:?}, {:?}, {:?})" ,
267- self . name, kinds, src ) ,
299+ format!( "lib_target({:?}, {:?}, {:?}, {:?} )" ,
300+ self . name, kinds, self . src_path , self . edition ) ,
268301 )
269302 }
270303 TargetKind :: CustomBuild => {
271- (
272- Target :: custom_build_target(
273- & self . name,
274- src. clone( ) ,
275- Edition :: Edition2015 ,
276- ) ,
277- format!( "custom_build_target({:?}, {:?})" ,
278- self . name, src) ,
279- )
304+ match self . src_path {
305+ TargetSourcePath :: Path ( ref path) => {
306+ (
307+ Target :: custom_build_target(
308+ & self . name,
309+ path. to_path_buf( ) ,
310+ self . edition,
311+ ) ,
312+ format!( "custom_build_target({:?}, {:?}, {:?})" ,
313+ self . name, path, self . edition) ,
314+ )
315+ }
316+ TargetSourcePath :: Metabuild => {
317+ (
318+ Target :: metabuild_target( & self . name) ,
319+ format!( "metabuild_target({:?})" , self . name) ,
320+ )
321+ }
322+ }
280323 }
281324 _ => (
282- Target :: with_path ( src . clone( ) , Edition :: Edition2015 ) ,
283- format!( "with_path({:?})" , src ) ,
325+ Target :: new ( self . src_path . clone( ) , self . edition ) ,
326+ format!( "with_path({:?}, {:?} )" , self . src_path , self . edition ) ,
284327 ) ,
285328 }
286329 } ;
@@ -321,6 +364,7 @@ impl Manifest {
321364 im_a_teapot : Option < bool > ,
322365 default_run : Option < String > ,
323366 original : Rc < TomlManifest > ,
367+ metabuild : Option < Vec < String > > ,
324368 ) -> Manifest {
325369 Manifest {
326370 summary,
@@ -342,6 +386,7 @@ impl Manifest {
342386 im_a_teapot,
343387 default_run,
344388 publish_lockfile,
389+ metabuild,
345390 }
346391 }
347392
@@ -464,6 +509,20 @@ impl Manifest {
464509 pub fn default_run ( & self ) -> Option < & str > {
465510 self . default_run . as_ref ( ) . map ( |s| & s[ ..] )
466511 }
512+
513+ pub fn metabuild ( & self ) -> Option < & Vec < String > > {
514+ self . metabuild . as_ref ( )
515+ }
516+
517+ pub fn metabuild_path ( & self , target_dir : Filesystem ) -> PathBuf {
518+ let mut hasher = SipHasher :: new_with_keys ( 0 , 0 ) ;
519+ self . package_id ( ) . hash ( & mut hasher) ;
520+ let hash = hasher. finish ( ) ;
521+ target_dir
522+ . into_path_unlocked ( )
523+ . join ( ".metabuild" )
524+ . join ( format ! ( "metabuild-{}-{:016x}.rs" , self . name( ) , hash) )
525+ }
467526}
468527
469528impl VirtualManifest {
@@ -508,16 +567,11 @@ impl VirtualManifest {
508567}
509568
510569impl Target {
511- fn with_path ( src_path : PathBuf , edition : Edition ) -> Target {
512- assert ! (
513- src_path. is_absolute( ) ,
514- "`{}` is not absolute" ,
515- src_path. display( )
516- ) ;
570+ fn new ( src_path : TargetSourcePath , edition : Edition ) -> Target {
517571 Target {
518572 kind : TargetKind :: Bin ,
519573 name : String :: new ( ) ,
520- src_path : NonHashedPathBuf { path : src_path } ,
574+ src_path,
521575 required_features : None ,
522576 doc : false ,
523577 doctest : false ,
@@ -529,6 +583,10 @@ impl Target {
529583 }
530584 }
531585
586+ fn with_path ( src_path : PathBuf , edition : Edition ) -> Target {
587+ Target :: new ( TargetSourcePath :: from ( src_path) , edition)
588+ }
589+
532590 pub fn lib_target (
533591 name : & str ,
534592 crate_targets : Vec < LibKind > ,
@@ -575,6 +633,17 @@ impl Target {
575633 }
576634 }
577635
636+ pub fn metabuild_target ( name : & str ) -> Target {
637+ Target {
638+ kind : TargetKind :: CustomBuild ,
639+ name : name. to_string ( ) ,
640+ for_host : true ,
641+ benched : false ,
642+ tested : false ,
643+ ..Target :: new ( TargetSourcePath :: Metabuild , Edition :: Edition2015 )
644+ }
645+ }
646+
578647 pub fn example_target (
579648 name : & str ,
580649 crate_targets : Vec < LibKind > ,
@@ -634,8 +703,11 @@ impl Target {
634703 pub fn crate_name ( & self ) -> String {
635704 self . name . replace ( "-" , "_" )
636705 }
637- pub fn src_path ( & self ) -> & Path {
638- & self . src_path . path
706+ pub fn src_path ( & self ) -> & TargetSourcePath {
707+ & self . src_path
708+ }
709+ pub fn set_src_path ( & mut self , src_path : TargetSourcePath ) {
710+ self . src_path = src_path;
639711 }
640712 pub fn required_features ( & self ) -> Option < & Vec < String > > {
641713 self . required_features . as_ref ( )
0 commit comments