1717//! Everything here is basically just a shim around calling either `rustbook` or
1818//! `rustdoc`.
1919
20+ use std:: collections:: HashSet ;
2021use std:: fs:: { self , File } ;
2122use std:: io:: prelude:: * ;
2223use std:: io;
2324use std:: path:: { PathBuf , Path } ;
2425
25- use Mode ;
26+ use { Build , Mode } ;
2627use build_helper:: up_to_date;
2728
2829use util:: { cp_r, symlink_dir} ;
@@ -483,21 +484,17 @@ impl Step for Std {
483484 let mut cargo = builder. cargo ( compiler, Mode :: Libstd , target, "doc" ) ;
484485 compile:: std_cargo ( builder, & compiler, target, & mut cargo) ;
485486
486- // We don't want to build docs for internal std dependencies unless
487- // in compiler-docs mode. When not in that mode, we whitelist the crates
488- // for which docs must be built.
489- if !build. config . compiler_docs {
490- cargo. arg ( "--no-deps" ) ;
491- for krate in & [ "alloc" , "core" , "std" , "std_unicode" ] {
492- cargo. arg ( "-p" ) . arg ( krate) ;
493- // Create all crate output directories first to make sure rustdoc uses
494- // relative links.
495- // FIXME: Cargo should probably do this itself.
496- t ! ( fs:: create_dir_all( out_dir. join( krate) ) ) ;
497- }
487+ // Keep a whitelist so we do not build internal stdlib crates, these will be
488+ // build by the rustc step later if enabled.
489+ cargo. arg ( "--no-deps" ) ;
490+ for krate in & [ "alloc" , "core" , "std" , "std_unicode" ] {
491+ cargo. arg ( "-p" ) . arg ( krate) ;
492+ // Create all crate output directories first to make sure rustdoc uses
493+ // relative links.
494+ // FIXME: Cargo should probably do this itself.
495+ t ! ( fs:: create_dir_all( out_dir. join( krate) ) ) ;
498496 }
499497
500-
501498 build. run ( & mut cargo) ;
502499 cp_r ( & my_out, & out) ;
503500 }
@@ -564,12 +561,12 @@ impl Step for Test {
564561}
565562
566563#[ derive( Debug , Copy , Clone , Hash , PartialEq , Eq ) ]
567- pub struct Rustc {
564+ pub struct WhitelistedRustc {
568565 stage : u32 ,
569566 target : Interned < String > ,
570567}
571568
572- impl Step for Rustc {
569+ impl Step for WhitelistedRustc {
573570 type Output = ( ) ;
574571 const DEFAULT : bool = true ;
575572 const ONLY_HOSTS : bool = true ;
@@ -580,21 +577,26 @@ impl Step for Rustc {
580577 }
581578
582579 fn make_run ( run : RunConfig ) {
583- run. builder . ensure ( Rustc {
580+ run. builder . ensure ( WhitelistedRustc {
584581 stage : run. builder . top_stage ,
585582 target : run. target ,
586583 } ) ;
587584 }
588585
589- /// Generate all compiler documentation.
586+ /// Generate whitelisted compiler crate documentation.
590587 ///
591- /// This will generate all documentation for the compiler libraries and their
592- /// dependencies. This is largely just a wrapper around `cargo doc`.
588+ /// This will generate all documentation for crates that are whitelisted
589+ /// to be included in the standard documentation. This documentation is
590+ /// included in the standard Rust documentation, so we should always
591+ /// document it and symlink to merge with the rest of the std and test
592+ /// documentation. We don't build other compiler documentation
593+ /// here as we want to be able to keep it separate from the standard
594+ /// documentation. This is largely just a wrapper around `cargo doc`.
593595 fn run ( self , builder : & Builder ) {
594596 let build = builder. build ;
595597 let stage = self . stage ;
596598 let target = self . target ;
597- println ! ( "Documenting stage{} compiler ({})" , stage, target) ;
599+ println ! ( "Documenting stage{} whitelisted compiler ({})" , stage, target) ;
598600 let out = build. doc_out ( target) ;
599601 t ! ( fs:: create_dir_all( & out) ) ;
600602 let compiler = builder. compiler ( stage, build. build ) ;
@@ -620,24 +622,116 @@ impl Step for Rustc {
620622 let mut cargo = builder. cargo ( compiler, Mode :: Librustc , target, "doc" ) ;
621623 compile:: rustc_cargo ( build, & mut cargo) ;
622624
623- if build. config . compiler_docs {
624- // src/rustc/Cargo.toml contains a bin crate called rustc which
625- // would otherwise overwrite the docs for the real rustc lib crate.
626- cargo. arg ( "-p" ) . arg ( "rustc_driver" ) ;
627- } else {
628- // Like with libstd above if compiler docs aren't enabled then we're not
629- // documenting internal dependencies, so we have a whitelist.
630- cargo. arg ( "--no-deps" ) ;
631- for krate in & [ "proc_macro" ] {
632- cargo. arg ( "-p" ) . arg ( krate) ;
633- }
625+ // We don't want to build docs for internal compiler dependencies in this
626+ // step (there is another step for that). Therefore, we whitelist the crates
627+ // for which docs must be built.
628+ cargo. arg ( "--no-deps" ) ;
629+ for krate in & [ "proc_macro" ] {
630+ cargo. arg ( "-p" ) . arg ( krate) ;
634631 }
635632
636633 build. run ( & mut cargo) ;
637634 cp_r ( & my_out, & out) ;
638635 }
639636}
640637
638+ #[ derive( Debug , Copy , Clone , Hash , PartialEq , Eq ) ]
639+ pub struct Rustc {
640+ stage : u32 ,
641+ target : Interned < String > ,
642+ }
643+
644+ impl Step for Rustc {
645+ type Output = ( ) ;
646+ const DEFAULT : bool = true ;
647+ const ONLY_HOSTS : bool = true ;
648+
649+ fn should_run ( run : ShouldRun ) -> ShouldRun {
650+ let builder = run. builder ;
651+ run. krate ( "rustc-main" ) . default_condition ( builder. build . config . docs )
652+ }
653+
654+ fn make_run ( run : RunConfig ) {
655+ run. builder . ensure ( Rustc {
656+ stage : run. builder . top_stage ,
657+ target : run. target ,
658+ } ) ;
659+ }
660+
661+ /// Generate compiler documentation.
662+ ///
663+ /// This will generate all documentation for compiler and dependencies.
664+ /// Compiler documentation is distributed separately, so we make sure
665+ /// we do not merge it with the other documentation from std, test and
666+ /// proc_macros. This is largely just a wrapper around `cargo doc`.
667+ fn run ( self , builder : & Builder ) {
668+ let build = builder. build ;
669+ let stage = self . stage ;
670+ let target = self . target ;
671+ println ! ( "Documenting stage{} compiler ({})" , stage, target) ;
672+ let out = build. compiler_doc_out ( target) ;
673+ t ! ( fs:: create_dir_all( & out) ) ;
674+ let compiler = builder. compiler ( stage, build. build ) ;
675+ let rustdoc = builder. rustdoc ( compiler. host ) ;
676+ let compiler = if build. force_use_stage1 ( compiler, target) {
677+ builder. compiler ( 1 , compiler. host )
678+ } else {
679+ compiler
680+ } ;
681+
682+ if !build. config . compiler_docs {
683+ println ! ( "\t skipping - compiler docs disabled" ) ;
684+ return ;
685+ }
686+
687+ // Build libstd docs so that we generate relative links
688+ builder. ensure ( Std { stage, target } ) ;
689+
690+ builder. ensure ( compile:: Rustc { compiler, target } ) ;
691+ let out_dir = build. stage_out ( compiler, Mode :: Librustc )
692+ . join ( target) . join ( "doc" ) ;
693+ // We do not symlink to the same shared folder that already contains std library
694+ // documentation from previous steps as we do not want to include that.
695+ build. clear_if_dirty ( & out, & rustdoc) ;
696+ t ! ( symlink_dir_force( & out, & out_dir) ) ;
697+
698+ let mut cargo = builder. cargo ( compiler, Mode :: Librustc , target, "doc" ) ;
699+ compile:: rustc_cargo ( build, & mut cargo) ;
700+
701+ // Only include compiler crates, no dependencies of those, such as `libc`.
702+ cargo. arg ( "--no-deps" ) ;
703+
704+ // Find dependencies for top level crates.
705+ let mut compiler_crates = HashSet :: new ( ) ;
706+ for root_crate in & [ "rustc" , "rustc_driver" ] {
707+ let interned_root_crate = INTERNER . intern_str ( root_crate) ;
708+ find_compiler_crates ( & build, & interned_root_crate, & mut compiler_crates) ;
709+ }
710+
711+ for krate in & compiler_crates {
712+ cargo. arg ( "-p" ) . arg ( krate) ;
713+ }
714+
715+ build. run ( & mut cargo) ;
716+ }
717+ }
718+
719+ fn find_compiler_crates (
720+ build : & Build ,
721+ name : & Interned < String > ,
722+ crates : & mut HashSet < Interned < String > >
723+ ) {
724+ // Add current crate.
725+ crates. insert ( * name) ;
726+
727+ // Look for dependencies.
728+ for dep in build. crates . get ( name) . unwrap ( ) . deps . iter ( ) {
729+ if build. crates . get ( dep) . unwrap ( ) . is_local ( build) {
730+ find_compiler_crates ( build, dep, crates) ;
731+ }
732+ }
733+ }
734+
641735#[ derive( Debug , Copy , Clone , Hash , PartialEq , Eq ) ]
642736pub struct ErrorIndex {
643737 target : Interned < String > ,
0 commit comments