Skip to content

Commit

Permalink
Polish docs for cargo_compile, unit_dependencies, and profile
Browse files Browse the repository at this point in the history
  • Loading branch information
weihanglo committed Oct 10, 2022
1 parent e691e18 commit c8ef066
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 22 deletions.
21 changes: 15 additions & 6 deletions src/cargo/core/compiler/unit_dependencies.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
//! Constructs the dependency graph for compilation.
//! # Constructs the dependency graph for compilation
//!
//! Rust code is typically organized as a set of Cargo packages. The
//! dependencies between the packages themselves are stored in the
//! `Resolve` struct. However, we can't use that information as is for
//! [`Resolve`] struct. However, we can't use that information as is for
//! compilation! A package typically contains several targets, or crates,
//! and these targets has inter-dependencies. For example, you need to
//! compile the `lib` target before the `bin` one, and you need to compile
Expand All @@ -13,7 +13,7 @@
//! is exactly what this module is doing! Well, almost exactly: another
//! complication is that we might want to compile the same target several times
//! (for example, with and without tests), so we actually build a dependency
//! graph of `Unit`s, which capture these properties.
//! graph of [`Unit`]s, which capture these properties.

use std::collections::{HashMap, HashSet};

Expand All @@ -35,23 +35,27 @@ use crate::CargoResult;

const IS_NO_ARTIFACT_DEP: Option<&'static Artifact> = None;

/// Collection of stuff used while creating the `UnitGraph`.
/// Collection of stuff used while creating the [`UnitGraph`].
struct State<'a, 'cfg> {
ws: &'a Workspace<'cfg>,
config: &'cfg Config,
/// Stores the result of building the [`UnitGraph`].
unit_dependencies: UnitGraph,
package_set: &'a PackageSet<'cfg>,
usr_resolve: &'a Resolve,
usr_features: &'a ResolvedFeatures,
/// Like `usr_resolve` but for building standard library (`-Zbuild-std`).
std_resolve: Option<&'a Resolve>,
/// Like `usr_features` but for building standard library (`-Zbuild-std`).
std_features: Option<&'a ResolvedFeatures>,
/// This flag is `true` while generating the dependencies for the standard
/// library.
/// `true` while generating the dependencies for the standard library.
is_std: bool,
/// The mode we are compiling in. Used for preventing from building lib thrice.
global_mode: CompileMode,
target_data: &'a RustcTargetData<'cfg>,
profiles: &'a Profiles,
interner: &'a UnitInterner,
// Units for `-Zrustdoc-scrape-examples`.
scrape_units: &'a [Unit],

/// A set of edges in `unit_dependencies` where (a, b) means that the
Expand All @@ -73,6 +77,9 @@ impl IsArtifact {
}
}

/// Then entry point for building a dependency graph of compilation units.
///
/// You can find some information for arguments from doc of [`State`].
pub fn build_unit_dependencies<'a, 'cfg>(
ws: &'a Workspace<'cfg>,
package_set: &'a PackageSet<'cfg>,
Expand Down Expand Up @@ -1015,6 +1022,7 @@ fn connect_run_custom_build_deps(state: &mut State<'_, '_>) {
}

impl<'a, 'cfg> State<'a, 'cfg> {
/// Gets `std_resolve` during building std, otherwise `usr_resolve`.
fn resolve(&self) -> &'a Resolve {
if self.is_std {
self.std_resolve.unwrap()
Expand All @@ -1023,6 +1031,7 @@ impl<'a, 'cfg> State<'a, 'cfg> {
}
}

/// Gets `std_features` during building std, otherwise `usr_features`.
fn features(&self) -> &'a ResolvedFeatures {
if self.is_std {
self.std_features.unwrap()
Expand Down
76 changes: 60 additions & 16 deletions src/cargo/ops/cargo_compile.rs
Original file line number Diff line number Diff line change
@@ -1,26 +1,33 @@
//! The Cargo "compile" operation.
//! # The Cargo "compile" operation
//!
//! This module contains the entry point for starting the compilation process
//! for commands like `build`, `test`, `doc`, `rustc`, etc.
//!
//! The `compile` function will do all the work to compile a workspace. A
//! The [`compile`] function will do all the work to compile a workspace. A
//! rough outline is:
//!
//! - Resolve the dependency graph (see `ops::resolve`).
//! - Download any packages needed (see `PackageSet`).
//! - Resolve the dependency graph (see [`ops::resolve`]).
//! - Download any packages needed (see [`PackageSet`]).
//! - Generate a list of top-level "units" of work for the targets the user
//! requested on the command-line. Each `Unit` corresponds to a compiler
//! invocation. This is done in this module (`generate_targets`).
//! - Build the graph of `Unit` dependencies (see
//! `core::compiler::context::unit_dependencies`).
//! - Create a `Context` which will perform the following steps:
//! - Prepare the `target` directory (see `Layout`).
//! requested on the command-line. Each [`Unit`] corresponds to a compiler
//! invocation. This is done in this module ([`generate_targets`]).
//! - Build the graph of `Unit` dependencies (see [`unit_dependencies`]).
//! - Create a [`Context`] which will perform the following steps:
//! - Prepare the `target` directory (see [`Layout`]).
//! - Create a job queue (see `JobQueue`). The queue checks the
//! fingerprint of each `Unit` to determine if it should run or be
//! skipped.
//! - Execute the queue. Each leaf in the queue's dependency graph is
//! executed, and then removed from the graph when finished. This
//! repeats until the queue is empty.
//!
//! **Note**: "target" inside this module generally refers to ["Cargo Target"],
//! which corresponds to artifact that will be built in a package. Not to be
//! confused with target-triple or target architecture.
//!
//! [`unit_dependencies`]: crate::core::compiler::unit_dependencies
//! [`Layout`]: crate::core::compiler::Layout
//! ["Cargo Target"]: https://doc.rust-lang.org/nightly/cargo/reference/cargo-targets.html

use std::collections::{BTreeSet, HashMap, HashSet};
use std::fmt::Write;
Expand Down Expand Up @@ -50,9 +57,9 @@ use anyhow::{bail, Context as _};

/// Contains information about how a package should be compiled.
///
/// Note on distinction between `CompileOptions` and `BuildConfig`:
/// Note on distinction between `CompileOptions` and [`BuildConfig`]:
/// `BuildConfig` contains values that need to be retained after
/// `BuildContext` is created. The other fields are no longer necessary. Think
/// [`BuildContext`] is created. The other fields are no longer necessary. Think
/// of it as `CompileOptions` are high-level settings requested on the
/// command-line, and `BuildConfig` are low-level settings for actually
/// driving `rustc`.
Expand Down Expand Up @@ -105,15 +112,28 @@ impl CompileOptions {
}
}

/// Represents the selected pacakges that will be built.
///
/// Generally, it represents the combination of all `-p` flag. When working within
/// a workspace, `--exclude` and `--workspace` flags also contribute to it.
#[derive(PartialEq, Eq, Debug)]
pub enum Packages {
/// Pacakges selected by default. Ususally means no flag provided.
Default,
/// Opt in all packages.
///
/// As of the time of this writing, it only works on opting in all workspace mebeer
All,
/// Opt out of packages passed in.
///
/// As of the time of this writing, it only works on opting out workspace members.
OptOut(Vec<String>),
/// A sequence of hand-picked packages that will be built. Normally done by `-p` flag.
Packages(Vec<String>),
}

impl Packages {
/// Creates a `Packages` from flags which are generally equivalent to command line flags.
pub fn from_flags(all: bool, exclude: Vec<String>, package: Vec<String>) -> CargoResult<Self> {
Ok(match (all, exclude.len(), package.len()) {
(false, 0, 0) => Packages::Default,
Expand All @@ -124,7 +144,7 @@ impl Packages {
})
}

/// Converts selected packages from a workspace to `PackageIdSpec`s.
/// Converts selected packages to [`PackageIdSpec`]s.
pub fn to_package_id_specs(&self, ws: &Workspace<'_>) -> CargoResult<Vec<PackageIdSpec>> {
let specs = match self {
Packages::All => ws
Expand Down Expand Up @@ -186,7 +206,7 @@ impl Packages {
Ok(specs)
}

/// Gets a list of selected packages from a workspace.
/// Gets a list of selected Packages.
pub fn get_packages<'ws>(&self, ws: &'ws Workspace<'_>) -> CargoResult<Vec<&'ws Package>> {
let packages: Vec<_> = match self {
Packages::Default => ws.default_members().collect(),
Expand Down Expand Up @@ -232,6 +252,7 @@ impl Packages {
}

#[derive(Debug, PartialEq, Eq)]
/// Indicates whether or not the library target gets included.
pub enum LibRule {
/// Include the library, fail if not present
True,
Expand All @@ -242,18 +263,28 @@ pub enum LibRule {
}

#[derive(Debug)]
/// Indicates which Cargo targets will be selected to be built.
pub enum FilterRule {
/// All included.
All,
/// Just a subset of Cargo targets based on names given.
Just(Vec<String>),
}

/// Filter to apply to the root package to select which Cargo targets will be built.
/// (examples, bins, benches, tests, ...)
///
/// The actual filter process happens inside [`generate_targets`].
#[derive(Debug)]
pub enum CompileFilter {
/// The default set of Cargo targets.
Default {
/// Flag whether targets can be safely skipped when required-features are not satisfied.
required_features_filterable: bool,
},
/// Only includes a subset of all Cargo targets.
Only {
/// Include all Cargo targets.
all_targets: bool,
lib: LibRule,
bins: FilterRule,
Expand All @@ -263,13 +294,18 @@ pub enum CompileFilter {
},
}

/// Compiles!
///
/// This uses the [`DefaultExecutor`]. To use a custom [`Executor`], see [`compile_with_exec`].
pub fn compile<'a>(ws: &Workspace<'a>, options: &CompileOptions) -> CargoResult<Compilation<'a>> {
let exec: Arc<dyn Executor> = Arc::new(DefaultExecutor);
compile_with_exec(ws, options, &exec)
}

/// Like `compile` but allows specifying a custom `Executor` that will be able to intercept build
/// calls and add custom logic. `compile` uses `DefaultExecutor` which just passes calls through.
/// Like [`compile`] but allows specifying a custom [`Executor`]
/// that will be able to intercept build calls and add custom logic.
///
/// [`compile`] uses [`DefaultExecutor`] which just passes calls through.
pub fn compile_with_exec<'a>(
ws: &Workspace<'a>,
options: &CompileOptions,
Expand All @@ -279,6 +315,7 @@ pub fn compile_with_exec<'a>(
compile_ws(ws, options, exec)
}

/// Like [`compile_with_exec`] but without warnings from manifest parsing.
pub fn compile_ws<'a>(
ws: &Workspace<'a>,
options: &CompileOptions,
Expand All @@ -295,6 +332,9 @@ pub fn compile_ws<'a>(
cx.compile(exec)
}

/// Executes `rustc --print <VALUE>`.
///
/// * `print_opt_value` is the VALUE passed through.
pub fn print<'a>(
ws: &Workspace<'a>,
options: &CompileOptions,
Expand Down Expand Up @@ -326,6 +366,10 @@ pub fn print<'a>(
Ok(())
}

/// Prepares all required information for the actual compilation.
///
/// For how it works and what data it collects,
/// please see the [module-level documentation](self).
pub fn create_bcx<'a, 'cfg>(
ws: &'a Workspace<'cfg>,
options: &'a CompileOptions,
Expand Down
6 changes: 6 additions & 0 deletions src/cargo/util/profile.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
//! # An internal profiler for Cargo itself
//!
//! > **Note**: This might not be the module you are looking for.
//! > For information about how Cargo handles compiler flags with profiles,
//! > please see the module [`cargo::core::profiles`](crate::core::profiles).

use std::cell::RefCell;
use std::env;
use std::fmt;
Expand Down

0 comments on commit c8ef066

Please sign in to comment.