1+ //! How to execute a build script and parse its output.
2+ //!
3+ //! ## Preparing a build script run
4+ //!
5+ //! A [build script] is an optional Rust script Cargo will run before building
6+ //! your package. As of this writing, two kinds of special [`Unit`]s will be
7+ //! constructed when there is a build script in a package.
8+ //!
9+ //! * Build script compilation --- This unit is generally the same as units
10+ //! that would compile other Cargo targets. It will recursively creates units
11+ //! of its dependencies. One biggest difference is that the [`Unit`] of
12+ //! compiling a build script is flagged as [`TargetKind::CustomBuild`].
13+ //! * Build script executaion --- During the construction of the [`UnitGraph`],
14+ //! Cargo inserts a [`Unit`] with [`CompileMode::RunCustomBuild`]. This unit
15+ //! depends on the unit of compiling the associated build script, to ensure
16+ //! the executable is available before running. The [`Work`] of running the
17+ //! build script is prepared in the function [`prepare`].
18+ //!
19+ //! ## Running a build script
20+ //!
21+ //! When running a build script, Cargo is aware of the progress and the result
22+ //! of a build script. Standard output is the chosen interprocess communication
23+ //! between Cargo and build script processes. A set of strings is defined for
24+ //! that purpose. These strings, a.k.a. instructions, are interpreted by
25+ //! [`BuildOutput::parse`] and stored in [`Context::build_script_outputs`].
26+ //! The entire execution work is constructed by [`build_work`].
27+ //!
28+ //! [build script]: https://doc.rust-lang.org/nightly/cargo/reference/build-scripts.html
29+ //! [`TargetKind::CustomBuild`]: crate::core::manifest::TargetKind::CustomBuild
30+ //! [`UnitGraph`]: super::unit_graph::UnitGraph
31+ //! [`CompileMode::RunCustomBuild`]: super::CompileMode
32+ //! [instructions]: https://doc.rust-lang.org/cargo/reference/build-scripts.html#outputs-of-the-build-script
33+
134use super :: { fingerprint, Context , Job , LinkType , Unit , Work } ;
235use crate :: core:: compiler:: artifact;
336use crate :: core:: compiler:: context:: Metadata ;
@@ -15,6 +48,10 @@ use std::path::{Path, PathBuf};
1548use std:: str;
1649use std:: sync:: { Arc , Mutex } ;
1750
51+ /// A build script instruction that tells Cargo to display a warning after the
52+ /// build script has finished running. Read [the doc] for more.
53+ ///
54+ /// [the doc]: https://doc.rust-lang.org/nightly/cargo/reference/build-scripts.html#cargo-warning
1855const CARGO_WARNING : & str = "cargo:warning=" ;
1956
2057/// Contains the parsed output of a custom build script.
@@ -63,7 +100,7 @@ pub struct BuildScriptOutputs {
63100
64101/// Linking information for a `Unit`.
65102///
66- /// See `build_map` for more details.
103+ /// See [ `build_map`] for more details.
67104#[ derive( Default ) ]
68105pub struct BuildScripts {
69106 /// List of build script outputs this Unit needs to include for linking. Each
@@ -96,7 +133,8 @@ pub struct BuildScripts {
96133 pub plugins : BTreeSet < ( PackageId , Metadata ) > ,
97134}
98135
99- /// Dependency information as declared by a build script.
136+ /// Dependency information as declared by a build script that might trigger
137+ /// a recompile of itself.
100138#[ derive( Debug ) ]
101139pub struct BuildDeps {
102140 /// Absolute path to the file in the target directory that stores the
@@ -130,6 +168,8 @@ pub fn prepare(cx: &mut Context<'_, '_>, unit: &Unit) -> CargoResult<Job> {
130168 }
131169}
132170
171+ /// Emits the output of a build script as a [`machine_message::BuildScript`]
172+ /// JSON string to standard output.
133173fn emit_build_output (
134174 state : & JobState < ' _ , ' _ > ,
135175 output : & BuildOutput ,
@@ -155,6 +195,14 @@ fn emit_build_output(
155195 Ok ( ( ) )
156196}
157197
198+ /// Constructs the unit of work of running a build script.
199+ ///
200+ /// The construction includes:
201+ ///
202+ /// * Set environment varibles for the build script run.
203+ /// * Create the output dir (`OUT_DIR`) for the build script output.
204+ /// * Determine if the build script needs a re-run.
205+ /// * Run the build script and store its output.
158206fn build_work ( cx : & mut Context < ' _ , ' _ > , unit : & Unit ) -> CargoResult < Job > {
159207 assert ! ( unit. mode. is_run_custom_build( ) ) ;
160208 let bcx = & cx. bcx ;
@@ -517,6 +565,8 @@ fn build_work(cx: &mut Context<'_, '_>, unit: &Unit) -> CargoResult<Job> {
517565 Ok ( job)
518566}
519567
568+ /// When a build script run fails, store only warnings and nuke other outputs,
569+ /// as they are likely broken.
520570fn insert_warnings_in_build_outputs (
521571 build_script_outputs : Arc < Mutex < BuildScriptOutputs > > ,
522572 id : PackageId ,
@@ -534,6 +584,7 @@ fn insert_warnings_in_build_outputs(
534584}
535585
536586impl BuildOutput {
587+ /// Like [`BuildOutput::parse`] but from a file path.
537588 pub fn parse_file (
538589 path : & Path ,
539590 library_name : Option < String > ,
@@ -557,9 +608,13 @@ impl BuildOutput {
557608 )
558609 }
559610
560- // Parses the output of a script.
561- // The `pkg_descr` is used for error messages.
562- // The `library_name` is used for determining if RUSTC_BOOTSTRAP should be allowed.
611+ /// Parses the output instructions of a build script.
612+ ///
613+ /// * `pkg_descr` --- for error messages
614+ /// * `library_name` --- for determining if `RUSTC_BOOTSTRAP` should be allowed
615+ /// * `extra_check_cfg` --- for unstable feature [`-Zcheck-cfg`]
616+ ///
617+ /// [`-Zcheck-cfg`]: https://doc.rust-lang.org/cargo/reference/unstable.html#check-cfg
563618 pub fn parse (
564619 input : & [ u8 ] ,
565620 // Takes String instead of InternedString so passing `unit.pkg.name()` will give a compile error.
@@ -781,6 +836,9 @@ impl BuildOutput {
781836 } )
782837 }
783838
839+ /// Parses [`cargo:rustc-flags`] instruction.
840+ ///
841+ /// [`cargo:rustc-flags`]: https://doc.rust-lang.org/nightly/cargo/reference/build-scripts.html#cargorustc-flagsflags
784842 pub fn parse_rustc_flags (
785843 value : & str ,
786844 whence : & str ,
@@ -826,6 +884,9 @@ impl BuildOutput {
826884 Ok ( ( library_paths, library_links) )
827885 }
828886
887+ /// Parses [`cargo:rustc-env`] instruction.
888+ ///
889+ /// [`cargo:rustc-env`]: https://doc.rust-lang.org/nightly/cargo/reference/build-scripts.html#rustc-env
829890 pub fn parse_rustc_env ( value : & str , whence : & str ) -> CargoResult < ( String , String ) > {
830891 let mut iter = value. splitn ( 2 , '=' ) ;
831892 let name = iter. next ( ) ;
@@ -837,6 +898,9 @@ impl BuildOutput {
837898 }
838899}
839900
901+ /// Prepares the Rust script for the unstable feature [metabuild].
902+ ///
903+ /// [metabuild]: https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#metabuild
840904fn prepare_metabuild ( cx : & Context < ' _ , ' _ > , unit : & Unit , deps : & [ String ] ) -> CargoResult < ( ) > {
841905 let mut output = Vec :: new ( ) ;
842906 let available_deps = cx. unit_deps ( unit) ;
@@ -866,6 +930,8 @@ fn prepare_metabuild(cx: &Context<'_, '_>, unit: &Unit, deps: &[String]) -> Carg
866930}
867931
868932impl BuildDeps {
933+ /// Creates a build script dependency information from a previous
934+ /// build script output path and the content.
869935 pub fn new ( output_file : & Path , output : Option < & BuildOutput > ) -> BuildDeps {
870936 BuildDeps {
871937 build_script_output : output_file. to_path_buf ( ) ,
@@ -881,22 +947,27 @@ impl BuildDeps {
881947 }
882948}
883949
884- /// Computes several maps in `Context`:
885- /// - `build_scripts`: A map that tracks which build scripts each package
950+ /// Computes several maps in [`Context`].
951+ ///
952+ /// - [`build_scripts`]: A map that tracks which build scripts each package
886953/// depends on.
887- /// - `build_explicit_deps`: Dependency statements emitted by build scripts
954+ /// - [ `build_explicit_deps`] : Dependency statements emitted by build scripts
888955/// from a previous run.
889- /// - `build_script_outputs`: Pre-populates this with any overridden build
956+ /// - [ `build_script_outputs`] : Pre-populates this with any overridden build
890957/// scripts.
891958///
892- /// The important one here is `build_scripts`, which for each `(package,
893- /// metadata)` stores a `BuildScripts` object which contains a list of
894- /// dependencies with build scripts that the unit should consider when
895- /// linking. For example this lists all dependencies' `-L` flags which need to
896- /// be propagated transitively.
959+ /// The important one here is [ `build_scripts`] , which for each `(package,
960+ /// metadata)` stores a [ `BuildScripts`] object which contains a list of
961+ /// dependencies with build scripts that the unit should consider when linking.
962+ /// For example this lists all dependencies' `-L` flags which need to be
963+ /// propagated transitively.
897964///
898965/// The given set of units to this function is the initial set of
899966/// targets/profiles which are being built.
967+ ///
968+ /// [`build_scripts`]: Context::build_scripts
969+ /// [`build_explicit_deps`]: Context::build_explicit_deps
970+ /// [`build_script_outputs`]: Context::build_script_outputs
900971pub fn build_map ( cx : & mut Context < ' _ , ' _ > ) -> CargoResult < ( ) > {
901972 let mut ret = HashMap :: new ( ) ;
902973 for unit in & cx. bcx . roots {
@@ -943,7 +1014,6 @@ pub fn build_map(cx: &mut Context<'_, '_>) -> CargoResult<()> {
9431014 add_to_link ( & mut ret, unit. pkg . package_id ( ) , script_meta) ;
9441015 }
9451016
946- // Load any dependency declarations from a previous run.
9471017 if unit. mode . is_run_custom_build ( ) {
9481018 parse_previous_explicit_deps ( cx, unit) ;
9491019 }
@@ -982,6 +1052,7 @@ pub fn build_map(cx: &mut Context<'_, '_>) -> CargoResult<()> {
9821052 }
9831053 }
9841054
1055+ /// Load any dependency declarations from a previous build script run.
9851056 fn parse_previous_explicit_deps ( cx : & mut Context < ' _ , ' _ > , unit : & Unit ) {
9861057 let script_run_dir = cx. files ( ) . build_script_run_dir ( unit) ;
9871058 let output_file = script_run_dir. join ( "output" ) ;
0 commit comments