1
+ #![ allow( deprecated) ] // for SipHasher
2
+
1
3
use std:: collections:: { BTreeMap , HashMap } ;
2
4
use std:: fmt;
3
- use std:: hash:: { Hash , Hasher } ;
5
+ use std:: hash:: { Hash , Hasher , SipHasher } ;
4
6
use std:: path:: { Path , PathBuf } ;
5
7
use std:: rc:: Rc ;
6
8
@@ -15,7 +17,7 @@ use core::{Dependency, PackageId, PackageIdSpec, SourceId, Summary};
15
17
use core:: { Edition , Feature , Features , WorkspaceConfig } ;
16
18
use util:: errors:: * ;
17
19
use util:: toml:: TomlManifest ;
18
- use util:: Config ;
20
+ use util:: { Config , Filesystem } ;
19
21
20
22
pub enum EitherManifest {
21
23
Real ( Manifest ) ,
@@ -44,6 +46,7 @@ pub struct Manifest {
44
46
edition : Edition ,
45
47
im_a_teapot : Option < bool > ,
46
48
default_run : Option < String > ,
49
+ metabuild : Option < Vec < String > > ,
47
50
}
48
51
49
52
/// When parsing `Cargo.toml`, some warnings should silenced
@@ -190,7 +193,7 @@ pub struct Target {
190
193
// as it's absolute currently and is otherwise a little too brittle for
191
194
// causing rebuilds. Instead the hash for the path that we send to the
192
195
// compiler is handled elsewhere.
193
- src_path : NonHashedPathBuf ,
196
+ src_path : TargetSourcePath ,
194
197
required_features : Option < Vec < String > > ,
195
198
tested : bool ,
196
199
benched : bool ,
@@ -202,19 +205,50 @@ pub struct Target {
202
205
}
203
206
204
207
#[ derive( Clone , PartialEq , Eq ) ]
205
- struct NonHashedPathBuf {
206
- path : PathBuf ,
208
+ pub enum TargetSourcePath {
209
+ Path ( PathBuf ) ,
210
+ Metabuild ,
207
211
}
208
212
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 {
210
230
fn hash < H : Hasher > ( & self , _: & mut H ) {
211
231
// ...
212
232
}
213
233
}
214
234
215
- impl fmt:: Debug for NonHashedPathBuf {
235
+ impl fmt:: Debug for TargetSourcePath {
216
236
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)
218
252
}
219
253
}
220
254
@@ -239,7 +273,7 @@ impl ser::Serialize for Target {
239
273
kind : & self . kind ,
240
274
crate_types : self . rustc_crate_types ( ) ,
241
275
name : & self . name ,
242
- src_path : & self . src_path . path ,
276
+ src_path : & self . src_path . path ( ) . to_path_buf ( ) ,
243
277
edition : & self . edition . to_string ( ) ,
244
278
required_features : self
245
279
. required_features
@@ -253,34 +287,43 @@ compact_debug! {
253
287
impl fmt:: Debug for Target {
254
288
fn fmt( & self , f: & mut fmt:: Formatter ) -> fmt:: Result {
255
289
let ( default , default_name) = {
256
- let src = self . src_path( ) . to_path_buf( ) ;
257
290
match & self . kind {
258
291
TargetKind :: Lib ( kinds) => {
259
292
(
260
293
Target :: lib_target(
261
294
& self . name,
262
295
kinds. clone( ) ,
263
- src . clone ( ) ,
264
- Edition :: Edition2015 ,
296
+ self . src_path ( ) . path ( ) . to_path_buf ( ) ,
297
+ self . edition ,
265
298
) ,
266
- format!( "lib_target({:?}, {:?}, {:?})" ,
267
- self . name, kinds, src ) ,
299
+ format!( "lib_target({:?}, {:?}, {:?}, {:?} )" ,
300
+ self . name, kinds, self . src_path , self . edition ) ,
268
301
)
269
302
}
270
303
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
+ }
280
323
}
281
324
_ => (
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 ) ,
284
327
) ,
285
328
}
286
329
} ;
@@ -321,6 +364,7 @@ impl Manifest {
321
364
im_a_teapot : Option < bool > ,
322
365
default_run : Option < String > ,
323
366
original : Rc < TomlManifest > ,
367
+ metabuild : Option < Vec < String > > ,
324
368
) -> Manifest {
325
369
Manifest {
326
370
summary,
@@ -342,6 +386,7 @@ impl Manifest {
342
386
im_a_teapot,
343
387
default_run,
344
388
publish_lockfile,
389
+ metabuild,
345
390
}
346
391
}
347
392
@@ -464,6 +509,20 @@ impl Manifest {
464
509
pub fn default_run ( & self ) -> Option < & str > {
465
510
self . default_run . as_ref ( ) . map ( |s| & s[ ..] )
466
511
}
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
+ }
467
526
}
468
527
469
528
impl VirtualManifest {
@@ -508,16 +567,11 @@ impl VirtualManifest {
508
567
}
509
568
510
569
impl 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 {
517
571
Target {
518
572
kind : TargetKind :: Bin ,
519
573
name : String :: new ( ) ,
520
- src_path : NonHashedPathBuf { path : src_path } ,
574
+ src_path,
521
575
required_features : None ,
522
576
doc : false ,
523
577
doctest : false ,
@@ -529,6 +583,10 @@ impl Target {
529
583
}
530
584
}
531
585
586
+ fn with_path ( src_path : PathBuf , edition : Edition ) -> Target {
587
+ Target :: new ( TargetSourcePath :: from ( src_path) , edition)
588
+ }
589
+
532
590
pub fn lib_target (
533
591
name : & str ,
534
592
crate_targets : Vec < LibKind > ,
@@ -575,6 +633,17 @@ impl Target {
575
633
}
576
634
}
577
635
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
+
578
647
pub fn example_target (
579
648
name : & str ,
580
649
crate_targets : Vec < LibKind > ,
@@ -634,8 +703,11 @@ impl Target {
634
703
pub fn crate_name ( & self ) -> String {
635
704
self . name . replace ( "-" , "_" )
636
705
}
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;
639
711
}
640
712
pub fn required_features ( & self ) -> Option < & Vec < String > > {
641
713
self . required_features . as_ref ( )
0 commit comments