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
+
1
34
use super :: { fingerprint, Context , Job , LinkType , Unit , Work } ;
2
35
use crate :: core:: compiler:: artifact;
3
36
use crate :: core:: compiler:: context:: Metadata ;
@@ -15,6 +48,10 @@ use std::path::{Path, PathBuf};
15
48
use std:: str;
16
49
use std:: sync:: { Arc , Mutex } ;
17
50
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
18
55
const CARGO_WARNING : & str = "cargo:warning=" ;
19
56
20
57
/// Contains the parsed output of a custom build script.
@@ -63,7 +100,7 @@ pub struct BuildScriptOutputs {
63
100
64
101
/// Linking information for a `Unit`.
65
102
///
66
- /// See `build_map` for more details.
103
+ /// See [ `build_map`] for more details.
67
104
#[ derive( Default ) ]
68
105
pub struct BuildScripts {
69
106
/// List of build script outputs this Unit needs to include for linking. Each
@@ -96,7 +133,8 @@ pub struct BuildScripts {
96
133
pub plugins : BTreeSet < ( PackageId , Metadata ) > ,
97
134
}
98
135
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.
100
138
#[ derive( Debug ) ]
101
139
pub struct BuildDeps {
102
140
/// 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> {
130
168
}
131
169
}
132
170
171
+ /// Emits the output of a build script as a [`machine_message::BuildScript`]
172
+ /// JSON string to standard output.
133
173
fn emit_build_output (
134
174
state : & JobState < ' _ , ' _ > ,
135
175
output : & BuildOutput ,
@@ -155,6 +195,14 @@ fn emit_build_output(
155
195
Ok ( ( ) )
156
196
}
157
197
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.
158
206
fn build_work ( cx : & mut Context < ' _ , ' _ > , unit : & Unit ) -> CargoResult < Job > {
159
207
assert ! ( unit. mode. is_run_custom_build( ) ) ;
160
208
let bcx = & cx. bcx ;
@@ -517,6 +565,8 @@ fn build_work(cx: &mut Context<'_, '_>, unit: &Unit) -> CargoResult<Job> {
517
565
Ok ( job)
518
566
}
519
567
568
+ /// When a build script run fails, store only warnings and nuke other outputs,
569
+ /// as they are likely broken.
520
570
fn insert_warnings_in_build_outputs (
521
571
build_script_outputs : Arc < Mutex < BuildScriptOutputs > > ,
522
572
id : PackageId ,
@@ -534,6 +584,7 @@ fn insert_warnings_in_build_outputs(
534
584
}
535
585
536
586
impl BuildOutput {
587
+ /// Like [`BuildOutput::parse`] but from a file path.
537
588
pub fn parse_file (
538
589
path : & Path ,
539
590
library_name : Option < String > ,
@@ -557,9 +608,13 @@ impl BuildOutput {
557
608
)
558
609
}
559
610
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
563
618
pub fn parse (
564
619
input : & [ u8 ] ,
565
620
// Takes String instead of InternedString so passing `unit.pkg.name()` will give a compile error.
@@ -781,6 +836,9 @@ impl BuildOutput {
781
836
} )
782
837
}
783
838
839
+ /// Parses [`cargo:rustc-flags`] instruction.
840
+ ///
841
+ /// [`cargo:rustc-flags`]: https://doc.rust-lang.org/nightly/cargo/reference/build-scripts.html#cargorustc-flagsflags
784
842
pub fn parse_rustc_flags (
785
843
value : & str ,
786
844
whence : & str ,
@@ -826,6 +884,9 @@ impl BuildOutput {
826
884
Ok ( ( library_paths, library_links) )
827
885
}
828
886
887
+ /// Parses [`cargo:rustc-env`] instruction.
888
+ ///
889
+ /// [`cargo:rustc-env`]: https://doc.rust-lang.org/nightly/cargo/reference/build-scripts.html#rustc-env
829
890
pub fn parse_rustc_env ( value : & str , whence : & str ) -> CargoResult < ( String , String ) > {
830
891
let mut iter = value. splitn ( 2 , '=' ) ;
831
892
let name = iter. next ( ) ;
@@ -837,6 +898,9 @@ impl BuildOutput {
837
898
}
838
899
}
839
900
901
+ /// Prepares the Rust script for the unstable feature [metabuild].
902
+ ///
903
+ /// [metabuild]: https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#metabuild
840
904
fn prepare_metabuild ( cx : & Context < ' _ , ' _ > , unit : & Unit , deps : & [ String ] ) -> CargoResult < ( ) > {
841
905
let mut output = Vec :: new ( ) ;
842
906
let available_deps = cx. unit_deps ( unit) ;
@@ -866,6 +930,8 @@ fn prepare_metabuild(cx: &Context<'_, '_>, unit: &Unit, deps: &[String]) -> Carg
866
930
}
867
931
868
932
impl BuildDeps {
933
+ /// Creates a build script dependency information from a previous
934
+ /// build script output path and the content.
869
935
pub fn new ( output_file : & Path , output : Option < & BuildOutput > ) -> BuildDeps {
870
936
BuildDeps {
871
937
build_script_output : output_file. to_path_buf ( ) ,
@@ -881,22 +947,27 @@ impl BuildDeps {
881
947
}
882
948
}
883
949
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
886
953
/// depends on.
887
- /// - `build_explicit_deps`: Dependency statements emitted by build scripts
954
+ /// - [ `build_explicit_deps`] : Dependency statements emitted by build scripts
888
955
/// 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
890
957
/// scripts.
891
958
///
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.
897
964
///
898
965
/// The given set of units to this function is the initial set of
899
966
/// 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
900
971
pub fn build_map ( cx : & mut Context < ' _ , ' _ > ) -> CargoResult < ( ) > {
901
972
let mut ret = HashMap :: new ( ) ;
902
973
for unit in & cx. bcx . roots {
@@ -943,7 +1014,6 @@ pub fn build_map(cx: &mut Context<'_, '_>) -> CargoResult<()> {
943
1014
add_to_link ( & mut ret, unit. pkg . package_id ( ) , script_meta) ;
944
1015
}
945
1016
946
- // Load any dependency declarations from a previous run.
947
1017
if unit. mode . is_run_custom_build ( ) {
948
1018
parse_previous_explicit_deps ( cx, unit) ;
949
1019
}
@@ -982,6 +1052,7 @@ pub fn build_map(cx: &mut Context<'_, '_>) -> CargoResult<()> {
982
1052
}
983
1053
}
984
1054
1055
+ /// Load any dependency declarations from a previous build script run.
985
1056
fn parse_previous_explicit_deps ( cx : & mut Context < ' _ , ' _ > , unit : & Unit ) {
986
1057
let script_run_dir = cx. files ( ) . build_script_run_dir ( unit) ;
987
1058
let output_file = script_run_dir. join ( "output" ) ;
0 commit comments