Skip to content

Commit bd31c08

Browse files
committed
Clean up build script stuff and documentation.
1 parent 742ccbd commit bd31c08

File tree

9 files changed

+180
-141
lines changed

9 files changed

+180
-141
lines changed

src/cargo/core/compiler/build_context/mod.rs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@ mod target_info;
1616
pub use self::target_info::{FileFlavor, TargetInfo};
1717

1818
/// The build context, containing all information about a build task.
19+
///
20+
/// It is intended that this is mostly static information. Stuff that mutates
21+
/// during the build can be found in the parent `Context`. (I say mostly,
22+
/// because this has internal caching, but nothing that should be observable
23+
/// or require &mut.)
1924
pub struct BuildContext<'a, 'cfg> {
2025
/// The workspace the build is for.
2126
pub ws: &'a Workspace<'cfg>,
@@ -183,6 +188,17 @@ impl<'a, 'cfg> BuildContext<'a, 'cfg> {
183188
pub fn extra_args_for(&self, unit: &Unit<'a>) -> Option<&Vec<String>> {
184189
self.extra_compiler_args.get(unit)
185190
}
191+
192+
/// If a build script is overridden, this returns the `BuildOutput` to use.
193+
///
194+
/// `lib_name` is the `links` library name and `kind` is whether it is for
195+
/// Host or Target.
196+
pub fn script_override(&self, lib_name: &str, kind: Kind) -> Option<&BuildOutput> {
197+
match kind {
198+
Kind::Host => self.host_config.overrides.get(lib_name),
199+
Kind::Target => self.target_config.overrides.get(lib_name),
200+
}
201+
}
186202
}
187203

188204
/// Information required to build for a target.
@@ -192,7 +208,11 @@ pub struct TargetConfig {
192208
pub ar: Option<PathBuf>,
193209
/// The path of the linker for this target.
194210
pub linker: Option<PathBuf>,
195-
/// Special build options for any necessary input files (filename -> options).
211+
/// Build script override for the given library name.
212+
///
213+
/// Any package with a `links` value for the given library name will skip
214+
/// running its build script and instead use the given output from the
215+
/// config file.
196216
pub overrides: HashMap<String, BuildOutput>,
197217
}
198218

src/cargo/core/compiler/context/mod.rs

Lines changed: 30 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::collections::{HashMap, HashSet};
33
use std::ffi::OsStr;
44
use std::fmt::Write;
55
use std::path::PathBuf;
6-
use std::sync::Arc;
6+
use std::sync::{Arc, Mutex};
77

88
use filetime::FileTime;
99
use jobserver::Client;
@@ -15,7 +15,7 @@ use crate::util::errors::{CargoResult, CargoResultExt};
1515
use crate::util::{internal, profile, Config};
1616

1717
use super::build_plan::BuildPlan;
18-
use super::custom_build::{self, BuildDeps, BuildScripts, BuildState};
18+
use super::custom_build::{self, BuildDeps, BuildScriptOutputs, BuildScripts};
1919
use super::fingerprint::Fingerprint;
2020
use super::job_queue::JobQueue;
2121
use super::layout::Layout;
@@ -28,21 +28,45 @@ mod compilation_files;
2828
use self::compilation_files::CompilationFiles;
2929
pub use self::compilation_files::{Metadata, OutputFile};
3030

31+
/// Collection of all the stuff that is needed to perform a build.
3132
pub struct Context<'a, 'cfg> {
33+
/// Mostly static information about the build task.
3234
pub bcx: &'a BuildContext<'a, 'cfg>,
35+
/// A large collection of information about the result of the entire compilation.
3336
pub compilation: Compilation<'cfg>,
34-
pub build_state: Arc<BuildState>,
35-
pub build_script_overridden: HashSet<(PackageId, Kind)>,
37+
/// Output from build scripts, updated after each build script runs.
38+
pub build_script_outputs: Arc<Mutex<BuildScriptOutputs>>,
39+
/// Dependencies (like rerun-if-changed) declared by a build script.
40+
/// This is *only* populated from the output from previous runs.
41+
/// If the build script hasn't ever been run, then it must be run.
3642
pub build_explicit_deps: HashMap<Unit<'a>, BuildDeps>,
43+
/// Fingerprints used to detect if a unit is out-of-date.
3744
pub fingerprints: HashMap<Unit<'a>, Arc<Fingerprint>>,
45+
/// Cache of file mtimes to reduce filesystem hits.
3846
pub mtime_cache: HashMap<PathBuf, FileTime>,
47+
/// A set used to track which units have been compiled.
48+
/// A unit may appear in the job graph multiple times as a dependency of
49+
/// multiple packages, but it only needs to run once.
3950
pub compiled: HashSet<Unit<'a>>,
51+
/// Linking information for each `Unit`.
52+
/// See `build_map` for details.
4053
pub build_scripts: HashMap<Unit<'a>, Arc<BuildScripts>>,
54+
/// Used to check the `links` field in the manifest is not duplicated and
55+
/// is used correctly.
4156
pub links: Links,
57+
/// Job server client to manage concurrency with other processes.
4258
pub jobserver: Client,
59+
/// "Primary" packages are the ones the user selected on the command-line
60+
/// with `-p` flags. If no flags are specified, then it is the defaults
61+
/// based on the current directory and the default workspace members.
4362
primary_packages: HashSet<PackageId>,
63+
/// The dependency graph of units to compile.
4464
unit_dependencies: HashMap<Unit<'a>, Vec<Unit<'a>>>,
65+
/// An abstraction of the files and directories that will be generated by
66+
/// the compilation. This is `None` until after `unit_dependencies` has
67+
/// been computed.
4568
files: Option<CompilationFiles<'a, 'cfg>>,
69+
/// Cache of packages, populated when they are downloaded.
4670
package_cache: HashMap<PackageId, &'a Package>,
4771

4872
/// A flag indicating whether pipelining is enabled for this compilation
@@ -82,16 +106,14 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
82106
Ok(Self {
83107
bcx,
84108
compilation: Compilation::new(bcx)?,
85-
build_state: Arc::new(BuildState::new(&bcx.host_config, &bcx.target_config)),
109+
build_script_outputs: Arc::new(Mutex::new(BuildScriptOutputs::default())),
86110
fingerprints: HashMap::new(),
87111
mtime_cache: HashMap::new(),
88112
compiled: HashSet::new(),
89113
build_scripts: HashMap::new(),
90114
build_explicit_deps: HashMap::new(),
91115
links: Links::new(),
92116
jobserver,
93-
build_script_overridden: HashSet::new(),
94-
95117
primary_packages: HashSet::new(),
96118
unit_dependencies: HashMap::new(),
97119
files: None,
@@ -228,7 +250,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
228250
super::output_depinfo(&mut self, unit)?;
229251
}
230252

231-
for (&(ref pkg, _), output) in self.build_state.outputs.lock().unwrap().iter() {
253+
for (&(ref pkg, _), output) in self.build_script_outputs.lock().unwrap().iter() {
232254
self.compilation
233255
.cfgs
234256
.entry(pkg.clone())
@@ -338,22 +360,6 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
338360
//
339361
// TODO: this ideally should be `-> &[Unit<'a>]`.
340362
pub fn dep_targets(&self, unit: &Unit<'a>) -> Vec<Unit<'a>> {
341-
// If this build script's execution has been overridden then we don't
342-
// actually depend on anything, we've reached the end of the dependency
343-
// chain as we've got all the info we're gonna get.
344-
//
345-
// Note there's a subtlety about this piece of code! The
346-
// `build_script_overridden` map here is populated in
347-
// `custom_build::build_map` which you need to call before inspecting
348-
// dependencies. However, that code itself calls this method and
349-
// gets a full pre-filtered set of dependencies. This is not super
350-
// obvious, and clear, but it does work at the moment.
351-
if unit.target.is_custom_build() {
352-
let key = (unit.pkg.package_id(), unit.kind);
353-
if self.build_script_overridden.contains(&key) {
354-
return Vec::new();
355-
}
356-
}
357363
self.unit_dependencies[unit].clone()
358364
}
359365

src/cargo/core/compiler/context/unit_dependencies.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,13 @@ fn compute_deps_custom_build<'a, 'cfg>(
258258
unit: &Unit<'a>,
259259
bcx: &BuildContext<'a, 'cfg>,
260260
) -> CargoResult<Vec<(Unit<'a>, UnitFor)>> {
261+
if let Some(links) = unit.pkg.manifest().links() {
262+
if bcx.script_override(links, unit.kind).is_some() {
263+
// Overridden build scripts don't have any dependencies.
264+
return Ok(Vec::new());
265+
}
266+
}
267+
261268
// When not overridden, then the dependencies to run a build script are:
262269
//
263270
// 1. Compiling the build script itself.

0 commit comments

Comments
 (0)