From c08806d8f4aee2fcfc8b87760908cc8e8c399310 Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Sat, 11 Feb 2023 00:49:19 +0000 Subject: [PATCH 1/7] doc: enhancement of `compiler::output_depinfo` --- src/cargo/core/compiler/fingerprint/mod.rs | 49 ++++++++++++++------ src/cargo/core/compiler/output_depinfo.rs | 53 ++++++++++++---------- 2 files changed, 63 insertions(+), 39 deletions(-) diff --git a/src/cargo/core/compiler/fingerprint/mod.rs b/src/cargo/core/compiler/fingerprint/mod.rs index fc3ce5e9b9d..e728263a38c 100644 --- a/src/cargo/core/compiler/fingerprint/mod.rs +++ b/src/cargo/core/compiler/fingerprint/mod.rs @@ -136,26 +136,47 @@ //! //! ### dep-info files //! +//! Cargo has several kinds of "dep info" files: +//! +//! * dep-info files generated by `rustc`. +//! * Fingerprint dep-info files translated from the first one. +//! * dep-info for external build system integration. +//! * Unstable `-Zbinary-dep-depinfo`. +//! +//! #### `rustc` dep-info files +//! //! Cargo passes the `--emit=dep-info` flag to `rustc` so that `rustc` will //! generate a "dep info" file (with the `.d` extension). This is a //! Makefile-like syntax that includes all of the source files used to build //! the crate. This file is used by Cargo to know which files to check to see -//! if the crate will need to be rebuilt. -//! -//! After `rustc` exits successfully, Cargo will read the dep info file and -//! translate it into a binary format that is stored in the fingerprint -//! directory ([`translate_dep_info`]). The mtime of the fingerprint dep-info -//! file itself is used as the reference for comparing the source files to -//! determine if any of the source files have been modified (see below for -//! more detail). Note that Cargo parses the special `# env-var:...` comments in -//! dep-info files to learn about environment variables that the rustc compile -//! depends on. Cargo then later uses this to trigger a recompile if a -//! referenced env var changes (even if the source didn't change). +//! if the crate will need to be rebuilt. Example: +//! +//! ```makefile +//! /path/to/target/debug/deps/cargo-b6219d178925203d: src/bin/main.rs src/bin/cargo/cli.rs # … etc. +//! ``` +//! +//! #### Fingerprint dep-info files +//! +//! After `rustc` exits successfully, Cargo will read the first kind of dep +//! info file and translate it into a binary format that is stored in the +//! fingerprint directory ([`translate_dep_info`]). +//! +//! These are used to quickly scan for any changed files. The mtime of the +//! fingerprint dep-info file itself is used as the reference for comparing the +//! source files to determine if any of the source files have been modified +//! (see [below](#mtime-comparison) for more detail). +//! +//! Note that Cargo parses the special `# env-var:...` comments in dep-info +//! files to learn about environment variables that the rustc compile depends on. +//! Cargo then later uses this to trigger a recompile if a referenced env var +//! changes (even if the source didn't change). +//! +//! #### dep-info files for build system integration. //! //! There is also a third dep-info file. Cargo will extend the file created by //! rustc with some additional information and saves this into the output //! directory. This is intended for build system integration. See the -//! [`output_depinfo`] module for more detail. +//! [`output_depinfo`] function for more detail. //! //! #### -Zbinary-dep-depinfo //! @@ -317,8 +338,8 @@ //! [`CompileMode`]: crate::core::compiler::CompileMode //! [`Lto`]: crate::core::compiler::Lto //! [`CompileKind`]: crate::core::compiler::CompileKind -//! [`JobQueue`]: ../job_queue/struct.JobQueue.html -//! [`output_depinfo`]: ../output_depinfo/index.html +//! [`JobQueue`]: super::job_queue::JobQueue +//! [`output_depinfo`]: super::output_depinfo() //! [`CheckDepInfo`]: LocalFingerprint::CheckDepInfo //! [`RerunIfChanged`]: LocalFingerprint::RerunIfChanged //! [`CompileMode::RunCustomBuild`]: crate::core::compiler::CompileMode::RunCustomBuild diff --git a/src/cargo/core/compiler/output_depinfo.rs b/src/cargo/core/compiler/output_depinfo.rs index 7a0d6277bbe..b8c3b20478e 100644 --- a/src/cargo/core/compiler/output_depinfo.rs +++ b/src/cargo/core/compiler/output_depinfo.rs @@ -1,26 +1,5 @@ -//! Module for generating dep-info files. -//! -//! `rustc` generates a dep-info file with a `.d` extension at the same -//! location of the output artifacts as a result of using `--emit=dep-info`. -//! This dep-info file is a Makefile-like syntax that indicates the -//! dependencies needed to build the artifact. Example: -//! -//! ```makefile -//! /path/to/target/debug/deps/cargo-b6219d178925203d: src/bin/main.rs src/bin/cargo/cli.rs # … etc. -//! ``` -//! -//! The fingerprint module has code to parse these files, and stores them as -//! binary format in the fingerprint directory. These are used to quickly scan -//! for any changed files. -//! -//! On top of all this, Cargo emits its own dep-info files in the output -//! directory. This is done for every "uplifted" artifact. These are intended -//! to be used with external build systems so that they can detect if Cargo -//! needs to be re-executed. It includes all the entries from the `rustc` -//! dep-info file, and extends it with any `rerun-if-changed` entries from -//! build scripts. It also includes sources from any path dependencies. Registry -//! dependencies are not included under the assumption that changes to them can -//! be detected via changes to `Cargo.lock`. +//! dep-info files for external build system integration. +//! See [`output_depinfo`] for more. use cargo_util::paths::normalize_path; use std::collections::{BTreeSet, HashSet}; @@ -32,6 +11,7 @@ use crate::util::{internal, CargoResult}; use cargo_util::paths; use log::debug; +/// Bacially just normalizes a given path and converts it to a string. fn render_filename>(path: P, basedir: Option<&str>) -> CargoResult { let path = path.as_ref(); if let Some(basedir) = basedir { @@ -52,6 +32,15 @@ fn wrap_path(path: &Path) -> CargoResult { .map(|f| f.replace(" ", "\\ ")) } +/// Collects all dependencies of the `unit` for the output dep info file. +/// +/// Dependencies will be stored in `deps`, including: +/// +/// * dependencies from [fingerprint dep-info] +/// * paths from `rerun-if-changed` build script instruction +/// * ...and traverse transitive dependencies recursively +/// +/// [fingerprint dep-info]: super::fingerprint#fingerprint-dep-info-files fn add_deps_for_unit( deps: &mut BTreeSet, cx: &mut Context<'_, '_>, @@ -105,9 +94,23 @@ fn add_deps_for_unit( Ok(()) } -/// Save a `.d` dep-info file for the given unit. +/// Save a `.d` dep-info file for the given unit. This is the third kind of +/// dep-info mentioned in [`fingerprint`] module. +/// +/// Argument `unit` is expected to be the root unit, which will be uplifted. +/// +/// Cargo emits its own dep-info files in the output directory. This is +/// only done for every "uplifted" artifact. These are intended to be used +/// with external build systems so that they can detect if Cargo needs to be +/// re-executed. +/// +/// It includes all the entries from the `rustc` dep-info file, and extends it +/// with any `rerun-if-changed` entries from build scripts. It also includes +/// sources from any path dependencies. Registry dependencies are not included +/// under the assumption that changes to them can be detected via changes to +/// `Cargo.lock`. /// -/// This only saves files for uplifted artifacts. +/// [`fingerprint`]: super::fingerprint#dep-info-files pub fn output_depinfo(cx: &mut Context<'_, '_>, unit: &Unit) -> CargoResult<()> { let bcx = cx.bcx; let mut deps = BTreeSet::new(); From 7b92f0beffe2d9320c129901692dcf49c38c018c Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Sat, 11 Feb 2023 01:53:37 +0000 Subject: [PATCH 2/7] doc: enhancement of `compiler::job` --- src/cargo/core/compiler/job.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/cargo/core/compiler/job.rs b/src/cargo/core/compiler/job.rs index b3e53af65d2..b0f05070737 100644 --- a/src/cargo/core/compiler/job.rs +++ b/src/cargo/core/compiler/job.rs @@ -5,11 +5,15 @@ use super::job_queue::JobState; use crate::core::compiler::fingerprint::DirtyReason; use crate::util::CargoResult; +/// Represents a unit of [`Work`] with a [`Freshness`] for caller +/// to determine whether to re-execute or not. pub struct Job { work: Work, fresh: Freshness, } +/// The basic unit of work. +/// /// Each proc should send its description before starting. /// It should send either once or close immediately. pub struct Work { @@ -17,6 +21,7 @@ pub struct Work { } impl Work { + /// Creates a unit of work. pub fn new(f: F) -> Work where F: FnOnce(&JobState<'_, '_>) -> CargoResult<()> + Send + 'static, @@ -24,14 +29,17 @@ impl Work { Work { inner: Box::new(f) } } + /// Creates a unit of work that does nothing. pub fn noop() -> Work { Work::new(|_| Ok(())) } + /// Consumes this work by running it. pub fn call(self, tx: &JobState<'_, '_>) -> CargoResult<()> { (self.inner)(tx) } + /// Creates a new unit of work that chains `next` after ourself. pub fn then(self, next: Work) -> Work { Work::new(move |state| { self.call(state)?; @@ -70,6 +78,7 @@ impl Job { &self.fresh } + /// Chains the given work by putting it in front of our own unit of work. pub fn before(&mut self, next: Work) { let prev = mem::replace(&mut self.work, Work::noop()); self.work = next.then(prev); From 92f89728b828506ccd5b86571f1725115acb5592 Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Sat, 11 Feb 2023 12:29:54 +0000 Subject: [PATCH 3/7] doc: enhancement of `util::queue` --- src/cargo/util/queue.rs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/cargo/util/queue.rs b/src/cargo/util/queue.rs index 66554ea5921..bbc68f603fe 100644 --- a/src/cargo/util/queue.rs +++ b/src/cargo/util/queue.rs @@ -7,9 +7,12 @@ use std::time::Duration; /// This is a sort of channel where any thread can push to a queue and any /// thread can pop from a queue. /// -/// This supports both bounded and unbounded operations. `push` will never block, -/// and allows the queue to grow without bounds. `push_bounded` will block if the -/// queue is over capacity, and will resume once there is enough capacity. +/// This supports both bounded and unbounded operations. [`push`] will never block, +/// and allows the queue to grow without bounds. [`push_bounded`] will block if +/// the queue is over capacity, and will resume once there is enough capacity. +/// +/// [`push`]: Self::push +/// [`push_bounded`]: Self::push_bounded pub struct Queue { state: Mutex>, popper_cv: Condvar, @@ -22,6 +25,7 @@ struct State { } impl Queue { + /// Creates a queue with a given bound. pub fn new(bound: usize) -> Queue { Queue { state: Mutex::new(State { @@ -33,6 +37,7 @@ impl Queue { } } + /// Pushes an item onto the queue, regardless of the capacity of the queue. pub fn push(&self, item: T) { self.state.lock().unwrap().items.push_back(item); self.popper_cv.notify_one(); @@ -49,6 +54,7 @@ impl Queue { self.popper_cv.notify_one(); } + /// Pops an item from the queue, blocking if the queue is empty. pub fn pop(&self, timeout: Duration) -> Option { let (mut state, result) = self .popper_cv @@ -66,6 +72,7 @@ impl Queue { } } + /// Pops all items from the queue without blocking. pub fn try_pop_all(&self) -> Vec { let mut state = self.state.lock().unwrap(); let result = state.items.drain(..).collect(); From 2fa38a215f2de2706cb182df8d831487ad4c809d Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Sat, 11 Feb 2023 12:40:39 +0000 Subject: [PATCH 4/7] doc: enhancement of `compiler::artifact` --- src/cargo/core/compiler/artifact.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cargo/core/compiler/artifact.rs b/src/cargo/core/compiler/artifact.rs index b1391eccdb0..1f3b12b5c09 100644 --- a/src/cargo/core/compiler/artifact.rs +++ b/src/cargo/core/compiler/artifact.rs @@ -1,4 +1,5 @@ -/// Generate artifact information from unit dependencies for configuring the compiler environment. +//! Generate artifact information from unit dependencies for configuring the compiler environment. + use crate::core::compiler::unit_graph::UnitDep; use crate::core::compiler::{Context, CrateType, FileFlavor, Unit}; use crate::core::dependency::ArtifactKind; From 392db56a08cd555d16f7e027927b7210d23f854e Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Sat, 11 Feb 2023 13:42:41 +0000 Subject: [PATCH 5/7] doc: enhancement of `-Zrustdoc-map` --- src/cargo/core/compiler/rustdoc.rs | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/cargo/core/compiler/rustdoc.rs b/src/cargo/core/compiler/rustdoc.rs index 6443e54bf2f..f6fdd005a3f 100644 --- a/src/cargo/core/compiler/rustdoc.rs +++ b/src/cargo/core/compiler/rustdoc.rs @@ -13,7 +13,9 @@ use url::Url; const DOCS_RS_URL: &'static str = "https://docs.rs/"; -/// Mode used for `std`. +/// Mode used for `std`. This is for unstable feature [`-Zrustdoc-map`][1]. +/// +/// [1]: https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#rustdoc-map #[derive(Debug, Hash)] pub enum RustdocExternMode { /// Use a local `file://` URL. @@ -54,11 +56,17 @@ impl<'de> serde::de::Deserialize<'de> for RustdocExternMode { } } +/// A map of registry names to URLs where documentations are hosted. +/// This is for unstable feature [`-Zrustdoc-map`][1]. +/// +/// [1]: https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#rustdoc-map #[derive(serde::Deserialize, Debug)] #[serde(default)] pub struct RustdocExternMap { #[serde(deserialize_with = "default_crates_io_to_docs_rs")] - pub(crate) registries: HashMap, + /// * Key is the registry name in the configuration `[registries.]`. + /// * Value is the URL where the documentation is hosted. + registries: HashMap, std: Option, } @@ -92,6 +100,11 @@ impl hash::Hash for RustdocExternMap { } } +/// Adds unstable flag [`--extern-html-root-url`][1] to the given `rustdoc` +/// invocation. This is for unstable feature [`-Zrustdoc-map`][2]. +/// +/// [1]: https://doc.rust-lang.org/nightly/rustdoc/unstable-features.html#--extern-html-root-url-control-how-rustdoc-links-to-non-local-crates +/// [2]: https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#rustdoc-map pub fn add_root_urls( cx: &Context<'_, '_>, unit: &Unit, @@ -191,8 +204,11 @@ pub fn add_root_urls( Ok(()) } -/// Indicates whether a target should have examples scraped from it -/// by rustdoc. Configured within Cargo.toml. +/// Indicates whether a target should have examples scraped from it by rustdoc. +/// Configured within Cargo.toml and only for unstable feature +/// [`-Zrustdoc-scrape-examples`][1]. +/// +/// [1]: https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#scrape-examples #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Debug, Copy)] pub enum RustdocScrapeExamples { Enabled, From b59e827dbab780e605619364d198bac8f6dd6974 Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Sat, 11 Feb 2023 00:50:21 +0000 Subject: [PATCH 6/7] refactor: make local function invisible --- src/cargo/core/compiler/output_depinfo.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/cargo/core/compiler/output_depinfo.rs b/src/cargo/core/compiler/output_depinfo.rs index b8c3b20478e..d659d620cbc 100644 --- a/src/cargo/core/compiler/output_depinfo.rs +++ b/src/cargo/core/compiler/output_depinfo.rs @@ -13,6 +13,12 @@ use log::debug; /// Bacially just normalizes a given path and converts it to a string. fn render_filename>(path: P, basedir: Option<&str>) -> CargoResult { + fn wrap_path(path: &Path) -> CargoResult { + path.to_str() + .ok_or_else(|| internal(format!("path `{:?}` not utf-8", path))) + .map(|f| f.replace(" ", "\\ ")) + } + let path = path.as_ref(); if let Some(basedir) = basedir { let norm_path = normalize_path(path); @@ -26,12 +32,6 @@ fn render_filename>(path: P, basedir: Option<&str>) -> CargoResul } } -fn wrap_path(path: &Path) -> CargoResult { - path.to_str() - .ok_or_else(|| internal(format!("path `{:?}` not utf-8", path))) - .map(|f| f.replace(" ", "\\ ")) -} - /// Collects all dependencies of the `unit` for the output dep info file. /// /// Dependencies will be stored in `deps`, including: From 25f5267c6107ee0eb50fa4c86b5e302e00a46ed1 Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Sat, 11 Feb 2023 12:30:58 +0000 Subject: [PATCH 7/7] refactor: remove unnecessary function --- src/cargo/core/compiler/context/mod.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/cargo/core/compiler/context/mod.rs b/src/cargo/core/compiler/context/mod.rs index dff61c2ed3f..520a22b3653 100644 --- a/src/cargo/core/compiler/context/mod.rs +++ b/src/cargo/core/compiler/context/mod.rs @@ -348,7 +348,9 @@ impl<'a, 'cfg> Context<'a, 'cfg> { pub fn prepare(&mut self) -> CargoResult<()> { let _p = profile::start("preparing layout"); - self.files_mut() + self.files + .as_mut() + .unwrap() .host .prepare() .with_context(|| "couldn't prepare build directories")?; @@ -375,10 +377,6 @@ impl<'a, 'cfg> Context<'a, 'cfg> { self.files.as_ref().unwrap() } - fn files_mut(&mut self) -> &mut CompilationFiles<'a, 'cfg> { - self.files.as_mut().unwrap() - } - /// Returns the filenames that the given unit will generate. pub fn outputs(&self, unit: &Unit) -> CargoResult>> { self.files.as_ref().unwrap().outputs(unit, self.bcx)