7
7
//! Everything here is basically just a shim around calling either `rustbook` or
8
8
//! `rustdoc`.
9
9
10
- use std:: ffi:: OsStr ;
11
10
use std:: fs;
12
11
use std:: io;
13
12
use std:: path:: { Path , PathBuf } ;
@@ -16,6 +15,7 @@ use crate::builder::crate_description;
16
15
use crate :: builder:: { Builder , Compiler , Kind , RunConfig , ShouldRun , Step } ;
17
16
use crate :: cache:: { Interned , INTERNER } ;
18
17
use crate :: compile;
18
+ use crate :: compile:: make_run_crates;
19
19
use crate :: config:: { Config , TargetSelection } ;
20
20
use crate :: tool:: { self , prepare_tool_cargo, SourceType , Tool } ;
21
21
use crate :: util:: { symlink_dir, t, up_to_date} ;
@@ -87,15 +87,6 @@ book!(
87
87
StyleGuide , "src/doc/style-guide" , "style-guide" ;
88
88
) ;
89
89
90
- // "library/std" -> ["library", "std"]
91
- //
92
- // Used for deciding whether a particular step is one requested by the user on
93
- // the `x.py doc` command line, which determines whether `--open` will open that
94
- // page.
95
- pub ( crate ) fn components_simplified ( path : & PathBuf ) -> Vec < & str > {
96
- path. iter ( ) . map ( |component| component. to_str ( ) . unwrap_or ( "???" ) ) . collect ( )
97
- }
98
-
99
90
#[ derive( Debug , Copy , Clone , Hash , PartialEq , Eq ) ]
100
91
pub struct UnstableBook {
101
92
target : TargetSelection ,
@@ -425,11 +416,18 @@ impl Step for SharedAssets {
425
416
}
426
417
}
427
418
428
- #[ derive( Debug , Copy , Clone , Hash , PartialEq , Eq ) ]
419
+ #[ derive( Debug , Copy , Clone , Hash , PartialEq , Eq , PartialOrd , Ord ) ]
429
420
pub struct Std {
430
421
pub stage : u32 ,
431
422
pub target : TargetSelection ,
432
423
pub format : DocumentationFormat ,
424
+ crates : Interned < Vec < String > > ,
425
+ }
426
+
427
+ impl Std {
428
+ pub ( crate ) fn new ( stage : u32 , target : TargetSelection , format : DocumentationFormat ) -> Self {
429
+ Std { stage, target, format, crates : INTERNER . intern_list ( vec ! [ ] ) }
430
+ }
433
431
}
434
432
435
433
impl Step for Std {
@@ -438,7 +436,7 @@ impl Step for Std {
438
436
439
437
fn should_run ( run : ShouldRun < ' _ > ) -> ShouldRun < ' _ > {
440
438
let builder = run. builder ;
441
- run. all_krates ( "sysroot" ) . path ( "library" ) . default_condition ( builder. config . docs )
439
+ run. crate_or_deps ( "sysroot" ) . path ( "library" ) . default_condition ( builder. config . docs )
442
440
}
443
441
444
442
fn make_run ( run : RunConfig < ' _ > ) {
@@ -450,14 +448,15 @@ impl Step for Std {
450
448
} else {
451
449
DocumentationFormat :: HTML
452
450
} ,
451
+ crates : make_run_crates ( & run, "library" ) ,
453
452
} ) ;
454
453
}
455
454
456
455
/// Compile all standard library documentation.
457
456
///
458
457
/// This will generate all documentation for the standard library and its
459
458
/// dependencies. This is largely just a wrapper around `cargo doc`.
460
- fn run ( self , builder : & Builder < ' _ > ) {
459
+ fn run ( mut self , builder : & Builder < ' _ > ) {
461
460
let stage = self . stage ;
462
461
let target = self . target ;
463
462
let out = match self . format {
@@ -471,41 +470,24 @@ impl Step for Std {
471
470
builder. ensure ( SharedAssets { target : self . target } ) ;
472
471
}
473
472
474
- let index_page = builder. src . join ( "src/doc/index.md" ) . into_os_string ( ) ;
473
+ let index_page = builder
474
+ . src
475
+ . join ( "src/doc/index.md" )
476
+ . into_os_string ( )
477
+ . into_string ( )
478
+ . expect ( "non-utf8 paths are unsupported" ) ;
475
479
let mut extra_args = match self . format {
476
- DocumentationFormat :: HTML => vec ! [
477
- OsStr :: new( "--markdown-css" ) ,
478
- OsStr :: new( "rust.css" ) ,
479
- OsStr :: new( "--markdown-no-toc" ) ,
480
- OsStr :: new( "--index-page" ) ,
481
- & index_page,
482
- ] ,
483
- DocumentationFormat :: JSON => vec ! [ OsStr :: new( "--output-format" ) , OsStr :: new( "json" ) ] ,
480
+ DocumentationFormat :: HTML => {
481
+ vec ! [ "--markdown-css" , "rust.css" , "--markdown-no-toc" , "--index-page" , & index_page]
482
+ }
483
+ DocumentationFormat :: JSON => vec ! [ "--output-format" , "json" ] ,
484
484
} ;
485
485
486
486
if !builder. config . docs_minification {
487
- extra_args. push ( OsStr :: new ( "--disable-minification" ) ) ;
487
+ extra_args. push ( "--disable-minification" ) ;
488
488
}
489
489
490
- let requested_crates = builder
491
- . paths
492
- . iter ( )
493
- . map ( components_simplified)
494
- . filter_map ( |path| {
495
- if path. len ( ) >= 2 && path. get ( 0 ) == Some ( & "library" ) {
496
- // single crate
497
- Some ( path[ 1 ] . to_owned ( ) )
498
- } else if !path. is_empty ( ) {
499
- // ??
500
- Some ( path[ 0 ] . to_owned ( ) )
501
- } else {
502
- // all library crates
503
- None
504
- }
505
- } )
506
- . collect :: < Vec < _ > > ( ) ;
507
-
508
- doc_std ( builder, self . format , stage, target, & out, & extra_args, & requested_crates) ;
490
+ doc_std ( builder, self . format , stage, target, & out, & extra_args, & self . crates ) ;
509
491
510
492
// Don't open if the format is json
511
493
if let DocumentationFormat :: JSON = self . format {
@@ -514,7 +496,11 @@ impl Step for Std {
514
496
515
497
// Look for library/std, library/core etc in the `x.py doc` arguments and
516
498
// open the corresponding rendered docs.
517
- for requested_crate in requested_crates {
499
+ if self . crates . is_empty ( ) {
500
+ self . crates = INTERNER . intern_list ( vec ! [ "library" . to_owned( ) ] ) ;
501
+ } ;
502
+
503
+ for requested_crate in & * self . crates {
518
504
if requested_crate == "library" {
519
505
// For `x.py doc library --open`, open `std` by default.
520
506
let index = out. join ( "std" ) . join ( "index.html" ) ;
@@ -538,7 +524,7 @@ impl Step for Std {
538
524
/// or remote link.
539
525
const STD_PUBLIC_CRATES : [ & str ; 5 ] = [ "core" , "alloc" , "std" , "proc_macro" , "test" ] ;
540
526
541
- #[ derive( Debug , Copy , Clone , Hash , PartialEq , Eq ) ]
527
+ #[ derive( Debug , Copy , Clone , Hash , PartialEq , Eq , PartialOrd , Ord ) ]
542
528
pub enum DocumentationFormat {
543
529
HTML ,
544
530
JSON ,
@@ -563,24 +549,22 @@ fn doc_std(
563
549
stage : u32 ,
564
550
target : TargetSelection ,
565
551
out : & Path ,
566
- extra_args : & [ & OsStr ] ,
552
+ extra_args : & [ & str ] ,
567
553
requested_crates : & [ String ] ,
568
554
) {
569
- builder. info ( & format ! (
570
- "Documenting{} stage{} library ({}) in {} format" ,
571
- crate_description( requested_crates) ,
572
- stage,
573
- target,
574
- format. as_str( )
575
- ) ) ;
576
555
if builder. no_std ( target) == Some ( true ) {
577
556
panic ! (
578
557
"building std documentation for no_std target {target} is not supported\n \
579
- Set `docs = false` in the config to disable documentation."
558
+ Set `docs = false` in the config to disable documentation, or pass `--exclude doc::library` ."
580
559
) ;
581
560
}
561
+
582
562
let compiler = builder. compiler ( stage, builder. config . build ) ;
583
563
564
+ let description =
565
+ format ! ( "library{} in {} format" , crate_description( & requested_crates) , format. as_str( ) ) ;
566
+ let _guard = builder. msg ( Kind :: Doc , stage, & description, compiler. host , target) ;
567
+
584
568
let target_doc_dir_name = if format == DocumentationFormat :: JSON { "json-doc" } else { "doc" } ;
585
569
let target_dir =
586
570
builder. stage_out ( compiler, Mode :: Std ) . join ( target. triple ) . join ( target_doc_dir_name) ;
@@ -590,42 +574,71 @@ fn doc_std(
590
574
// as a function parameter.
591
575
let out_dir = target_dir. join ( target. triple ) . join ( "doc" ) ;
592
576
593
- let run_cargo_rustdoc_for = |package : & str | {
594
- let mut cargo = builder. cargo ( compiler, Mode :: Std , SourceType :: InTree , target, "rustdoc" ) ;
595
- compile:: std_cargo ( builder, target, compiler. stage , & mut cargo) ;
596
- cargo
597
- . arg ( "--target-dir" )
598
- . arg ( & * target_dir. to_string_lossy ( ) )
599
- . arg ( "-p" )
600
- . arg ( package)
601
- . arg ( "-Zskip-rustdoc-fingerprint" )
602
- . arg ( "--" )
603
- . arg ( "-Z" )
604
- . arg ( "unstable-options" )
605
- . arg ( "--resource-suffix" )
606
- . arg ( & builder. version )
607
- . args ( extra_args) ;
608
- if builder. config . library_docs_private_items {
609
- cargo. arg ( "--document-private-items" ) . arg ( "--document-hidden-items" ) ;
610
- }
611
- builder. run ( & mut cargo. into ( ) ) ;
577
+ let mut cargo = builder. cargo ( compiler, Mode :: Std , SourceType :: InTree , target, "doc" ) ;
578
+ compile:: std_cargo ( builder, target, compiler. stage , & mut cargo) ;
579
+ cargo
580
+ . arg ( "--no-deps" )
581
+ . arg ( "--target-dir" )
582
+ . arg ( & * target_dir. to_string_lossy ( ) )
583
+ . arg ( "-Zskip-rustdoc-fingerprint" )
584
+ . rustdocflag ( "-Z" )
585
+ . rustdocflag ( "unstable-options" )
586
+ . rustdocflag ( "--resource-suffix" )
587
+ . rustdocflag ( & builder. version ) ;
588
+ for arg in extra_args {
589
+ cargo. rustdocflag ( arg) ;
590
+ }
591
+
592
+ if builder. config . library_docs_private_items {
593
+ cargo. rustdocflag ( "--document-private-items" ) . rustdocflag ( "--document-hidden-items" ) ;
594
+ }
595
+
596
+ // HACK: because we use `--manifest-path library/sysroot/Cargo.toml`, cargo thinks we only want to document that specific crate, not its dependencies.
597
+ // Override its default.
598
+ let built_crates = if requested_crates. is_empty ( ) {
599
+ builder
600
+ . in_tree_crates ( "sysroot" , None )
601
+ . into_iter ( )
602
+ . map ( |krate| krate. name . to_string ( ) )
603
+ . collect ( )
604
+ } else {
605
+ requested_crates. to_vec ( )
612
606
} ;
613
607
614
- for krate in STD_PUBLIC_CRATES {
615
- run_cargo_rustdoc_for ( krate) ;
616
- if requested_crates. iter ( ) . any ( |p| p == krate) {
617
- // No need to document more of the libraries if we have the one we want.
618
- break ;
619
- }
608
+ for krate in built_crates {
609
+ cargo. arg ( "-p" ) . arg ( krate) ;
620
610
}
621
611
612
+ builder. run ( & mut cargo. into ( ) ) ;
622
613
builder. cp_r ( & out_dir, & out) ;
623
614
}
624
615
625
616
#[ derive( Debug , Copy , Clone , Hash , PartialEq , Eq ) ]
626
617
pub struct Rustc {
627
618
pub stage : u32 ,
628
619
pub target : TargetSelection ,
620
+ crates : Interned < Vec < String > > ,
621
+ }
622
+
623
+ impl Rustc {
624
+ pub ( crate ) fn new ( stage : u32 , target : TargetSelection , builder : & Builder < ' _ > ) -> Self {
625
+ // Find dependencies for top level crates.
626
+ let root_crates = vec ! [
627
+ INTERNER . intern_str( "rustc_driver" ) ,
628
+ INTERNER . intern_str( "rustc_codegen_llvm" ) ,
629
+ INTERNER . intern_str( "rustc_codegen_ssa" ) ,
630
+ ] ;
631
+ let crates: Vec < _ > = root_crates
632
+ . iter ( )
633
+ . flat_map ( |krate| {
634
+ builder
635
+ . in_tree_crates ( krate, Some ( target) )
636
+ . into_iter ( )
637
+ . map ( |krate| krate. name . to_string ( ) )
638
+ } )
639
+ . collect ( ) ;
640
+ Self { stage, target, crates : INTERNER . intern_list ( crates) }
641
+ }
629
642
}
630
643
631
644
impl Step for Rustc {
@@ -641,7 +654,11 @@ impl Step for Rustc {
641
654
}
642
655
643
656
fn make_run ( run : RunConfig < ' _ > ) {
644
- run. builder . ensure ( Rustc { stage : run. builder . top_stage , target : run. target } ) ;
657
+ run. builder . ensure ( Rustc {
658
+ stage : run. builder . top_stage ,
659
+ target : run. target ,
660
+ crates : make_run_crates ( & run, "compiler" ) ,
661
+ } ) ;
645
662
}
646
663
647
664
/// Generates compiler documentation.
@@ -654,15 +671,6 @@ impl Step for Rustc {
654
671
let stage = self . stage ;
655
672
let target = self . target ;
656
673
657
- let paths = builder
658
- . paths
659
- . iter ( )
660
- . filter ( |path| {
661
- let components = components_simplified ( path) ;
662
- components. len ( ) >= 2 && components[ 0 ] == "compiler"
663
- } )
664
- . collect :: < Vec < _ > > ( ) ;
665
-
666
674
// This is the intended out directory for compiler documentation.
667
675
let out = builder. compiler_doc_out ( target) ;
668
676
t ! ( fs:: create_dir_all( & out) ) ;
@@ -672,7 +680,13 @@ impl Step for Rustc {
672
680
let compiler = builder. compiler ( stage, builder. config . build ) ;
673
681
builder. ensure ( compile:: Std :: new ( compiler, builder. config . build ) ) ;
674
682
675
- builder. info ( & format ! ( "Documenting stage{} compiler ({})" , stage, target) ) ;
683
+ let _guard = builder. msg (
684
+ Kind :: Doc ,
685
+ stage,
686
+ & format ! ( "compiler{}" , crate_description( & self . crates) ) ,
687
+ compiler. host ,
688
+ target,
689
+ ) ;
676
690
677
691
// This uses a shared directory so that librustdoc documentation gets
678
692
// correctly built and merged with the rustc documentation. This is
@@ -710,22 +724,8 @@ impl Step for Rustc {
710
724
cargo. rustdocflag ( "--extern-html-root-url" ) ;
711
725
cargo. rustdocflag ( "ena=https://docs.rs/ena/latest/" ) ;
712
726
713
- let root_crates = if paths. is_empty ( ) {
714
- vec ! [
715
- INTERNER . intern_str( "rustc_driver" ) ,
716
- INTERNER . intern_str( "rustc_codegen_llvm" ) ,
717
- INTERNER . intern_str( "rustc_codegen_ssa" ) ,
718
- ]
719
- } else {
720
- paths. into_iter ( ) . map ( |p| builder. crate_paths [ p] ) . collect ( )
721
- } ;
722
- // Find dependencies for top level crates.
723
- let compiler_crates = root_crates. iter ( ) . flat_map ( |krate| {
724
- builder. in_tree_crates ( krate, Some ( target) ) . into_iter ( ) . map ( |krate| krate. name )
725
- } ) ;
726
-
727
727
let mut to_open = None ;
728
- for krate in compiler_crates {
728
+ for krate in & * self . crates {
729
729
// Create all crate output directories first to make sure rustdoc uses
730
730
// relative links.
731
731
// FIXME: Cargo should probably do this itself.
@@ -785,7 +785,7 @@ macro_rules! tool_doc {
785
785
786
786
if true $( && $rustc_tool) ? {
787
787
// Build rustc docs so that we generate relative links.
788
- builder. ensure( Rustc { stage, target } ) ;
788
+ builder. ensure( Rustc :: new ( stage, target, builder ) ) ;
789
789
790
790
// Rustdoc needs the rustc sysroot available to build.
791
791
// FIXME: is there a way to only ensure `check::Rustc` here? Last time I tried it failed
0 commit comments