33//! `./x.py test` (aka [`Kind::Test`]) is currently allowed to reach build steps in other modules.
44//! However, this contains ~all test parts we expect people to be able to build and run locally.
55
6+ use std:: collections:: HashSet ;
67use std:: ffi:: { OsStr , OsString } ;
78use std:: path:: { Path , PathBuf } ;
89use std:: { env, fs, iter} ;
910
1011use clap_complete:: shells;
1112
13+ use crate :: core:: build_steps:: compile:: run_cargo;
1214use crate :: core:: build_steps:: doc:: DocumentationFormat ;
1315use crate :: core:: build_steps:: synthetic_targets:: MirOptPanicAbortSyntheticTarget ;
1416use crate :: core:: build_steps:: tool:: { self , SourceType , Tool } ;
@@ -2185,6 +2187,7 @@ struct BookTest {
21852187 path : PathBuf ,
21862188 name : & ' static str ,
21872189 is_ext_doc : bool ,
2190+ dependencies : Vec < & ' static str > ,
21882191}
21892192
21902193impl Step for BookTest {
@@ -2237,6 +2240,57 @@ impl BookTest {
22372240 // Books often have feature-gated example text.
22382241 rustbook_cmd. env ( "RUSTC_BOOTSTRAP" , "1" ) ;
22392242 rustbook_cmd. env ( "PATH" , new_path) . arg ( "test" ) . arg ( path) ;
2243+
2244+ // Books may also need to build dependencies. For example, `TheBook` has
2245+ // code samples which use the `trpl` crate. For the `rustdoc` invocation
2246+ // to find them them successfully, they need to be built first and their
2247+ // paths used to generate the
2248+ let libs = if !self . dependencies . is_empty ( ) {
2249+ let mut lib_paths = vec ! [ ] ;
2250+ for dep in self . dependencies {
2251+ let mode = Mode :: ToolRustc ;
2252+ let target = builder. config . build ;
2253+ let cargo = tool:: prepare_tool_cargo (
2254+ builder,
2255+ compiler,
2256+ mode,
2257+ target,
2258+ Kind :: Build ,
2259+ dep,
2260+ SourceType :: Submodule ,
2261+ & [ ] ,
2262+ ) ;
2263+
2264+ let stamp = builder
2265+ . cargo_out ( compiler, mode, target)
2266+ . join ( PathBuf :: from ( dep) . file_name ( ) . unwrap ( ) )
2267+ . with_extension ( "stamp" ) ;
2268+
2269+ let output_paths = run_cargo ( builder, cargo, vec ! [ ] , & stamp, vec ! [ ] , false , false ) ;
2270+ let directories = output_paths
2271+ . into_iter ( )
2272+ . filter_map ( |p| p. parent ( ) . map ( ToOwned :: to_owned) )
2273+ . fold ( HashSet :: new ( ) , |mut set, dir| {
2274+ set. insert ( dir) ;
2275+ set
2276+ } ) ;
2277+
2278+ lib_paths. extend ( directories) ;
2279+ }
2280+ lib_paths
2281+ } else {
2282+ vec ! [ ]
2283+ } ;
2284+
2285+ if !libs. is_empty ( ) {
2286+ let paths = libs
2287+ . into_iter ( )
2288+ . map ( |path| path. into_os_string ( ) )
2289+ . collect :: < Vec < OsString > > ( )
2290+ . join ( OsStr :: new ( "," ) ) ;
2291+ rustbook_cmd. args ( [ OsString :: from ( "--library-path" ) , paths] ) ;
2292+ }
2293+
22402294 builder. add_rust_test_threads ( & mut rustbook_cmd) ;
22412295 let _guard = builder. msg (
22422296 Kind :: Test ,
@@ -2295,6 +2349,7 @@ macro_rules! test_book {
22952349 $name: ident, $path: expr, $book_name: expr,
22962350 default =$default: expr
22972351 $( , submodules = $submodules: expr) ?
2352+ $( , dependencies=$dependencies: expr) ?
22982353 ;
22992354 ) +) => {
23002355 $(
@@ -2324,11 +2379,21 @@ macro_rules! test_book {
23242379 builder. require_submodule( submodule, None ) ;
23252380 }
23262381 ) *
2382+
2383+ let dependencies = vec![ ] ;
2384+ $(
2385+ let mut dependencies = dependencies;
2386+ for dep in $dependencies {
2387+ dependencies. push( dep) ;
2388+ }
2389+ ) ?
2390+
23272391 builder. ensure( BookTest {
23282392 compiler: self . compiler,
23292393 path: PathBuf :: from( $path) ,
23302394 name: $book_name,
23312395 is_ext_doc: !$default,
2396+ dependencies,
23322397 } ) ;
23332398 }
23342399 }
@@ -2343,7 +2408,7 @@ test_book!(
23432408 RustcBook , "src/doc/rustc" , "rustc" , default =true ;
23442409 RustByExample , "src/doc/rust-by-example" , "rust-by-example" , default =false , submodules=[ "src/doc/rust-by-example" ] ;
23452410 EmbeddedBook , "src/doc/embedded-book" , "embedded-book" , default =false , submodules=[ "src/doc/embedded-book" ] ;
2346- TheBook , "src/doc/book" , "book" , default =false , submodules=[ "src/doc/book" ] ;
2411+ TheBook , "src/doc/book" , "book" , default =false , submodules=[ "src/doc/book" ] , dependencies= [ "src/doc/book/packages/trpl" ] ;
23472412 UnstableBook , "src/doc/unstable-book" , "unstable-book" , default =true ;
23482413 EditionGuide , "src/doc/edition-guide" , "edition-guide" , default =false , submodules=[ "src/doc/edition-guide" ] ;
23492414) ;
0 commit comments