Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor BuildContext #8068

Merged
merged 8 commits into from
Apr 19, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
bcx reorg
  • Loading branch information
ehuss committed Apr 19, 2020
commit e0bd9e231ded16bd4899386cd9a05cd5bf3d0ff7
6 changes: 3 additions & 3 deletions src/bin/cargo/commands/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,12 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
)?;

if let Some(out_dir) = args.value_of_path("out-dir", config) {
compile_opts.export_dir = Some(out_dir);
compile_opts.build_config.export_dir = Some(out_dir);
} else if let Some(out_dir) = config.build_config()?.out_dir.as_ref() {
let out_dir = out_dir.resolve_path(config);
compile_opts.export_dir = Some(out_dir);
compile_opts.build_config.export_dir = Some(out_dir);
}
if compile_opts.export_dir.is_some() {
if compile_opts.build_config.export_dir.is_some() {
config
.cli_unstable()
.fail_if_stable_opt("--out-dir", 6790)?;
Expand Down
10 changes: 10 additions & 0 deletions src/cargo/core/compiler/build_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::util::ProcessBuilder;
use crate::util::{CargoResult, Config, RustfixDiagnosticServer};
use serde::ser;
use std::cell::RefCell;
use std::path::PathBuf;

/// Configuration information for a rustc build.
#[derive(Debug)]
Expand All @@ -26,7 +27,15 @@ pub struct BuildConfig {
pub unit_graph: bool,
/// An optional override of the rustc process for primary units
pub primary_unit_rustc: Option<ProcessBuilder>,
/// A thread used by `cargo fix` to receive messages on a socket regarding
/// the success/failure of applying fixes.
pub rustfix_diagnostic_server: RefCell<Option<RustfixDiagnosticServer>>,
/// The directory to copy final artifacts to. Note that even if `out_dir` is
/// set, a copy of artifacts still could be found a `target/(debug\release)`
/// as usual.
// Note that, although the cmd-line flag name is `out-dir`, in code we use
// `export_dir`, to avoid confusion with out dir at `target/debug/deps`.
pub export_dir: Option<PathBuf>,
}

impl BuildConfig {
Expand Down Expand Up @@ -70,6 +79,7 @@ impl BuildConfig {
unit_graph: false,
primary_unit_rustc: None,
rustfix_diagnostic_server: RefCell::new(None),
export_dir: None,
})
}

Expand Down
39 changes: 15 additions & 24 deletions src/cargo/core/compiler/build_context/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::core::compiler::unit::UnitInterner;
use crate::core::compiler::{BuildConfig, BuildOutput, CompileKind, Unit};
use crate::core::compiler::unit_graph::UnitGraph;
use crate::core::compiler::{BuildConfig, CompileKind, Unit};
use crate::core::profiles::Profiles;
use crate::core::{InternedString, Workspace};
use crate::core::{PackageId, PackageSet};
Expand All @@ -8,7 +8,6 @@ use crate::util::errors::CargoResult;
use crate::util::Rustc;
use std::collections::HashMap;
use std::path::PathBuf;
use std::str;

mod target_info;
pub use self::target_info::{FileFlavor, RustcTargetData, TargetInfo};
Expand All @@ -29,35 +28,38 @@ pub struct BuildContext<'a, 'cfg> {
/// Extra compiler args for either `rustc` or `rustdoc`.
pub extra_compiler_args: HashMap<Unit<'a>, Vec<String>>,
/// Package downloader.
pub packages: &'a PackageSet<'cfg>,

/// Source of interning new units as they're created.
pub units: &'a UnitInterner,

///
/// This holds ownership of the `Package` objects.
pub packages: PackageSet<'cfg>,
/// Information about rustc and the target platform.
pub target_data: RustcTargetData,
/// The root units of `unit_graph` (units requested on the command-line).
pub roots: Vec<Unit<'a>>,
/// The dependency graph of units to compile.
pub unit_graph: UnitGraph<'a>,
}

impl<'a, 'cfg> BuildContext<'a, 'cfg> {
pub fn new(
ws: &'a Workspace<'cfg>,
packages: &'a PackageSet<'cfg>,
config: &'cfg Config,
packages: PackageSet<'cfg>,
build_config: &'a BuildConfig,
profiles: Profiles,
units: &'a UnitInterner,
extra_compiler_args: HashMap<Unit<'a>, Vec<String>>,
target_data: RustcTargetData,
roots: Vec<Unit<'a>>,
unit_graph: UnitGraph<'a>,
) -> CargoResult<BuildContext<'a, 'cfg>> {
Ok(BuildContext {
ws,
config: ws.config(),
packages,
config,
build_config,
profiles,
extra_compiler_args,
units,
target_data,
roots,
unit_graph,
})
}

Expand Down Expand Up @@ -104,15 +106,4 @@ impl<'a, 'cfg> BuildContext<'a, 'cfg> {
pub fn extra_args_for(&self, unit: &Unit<'a>) -> Option<&Vec<String>> {
self.extra_compiler_args.get(unit)
}

/// If a build script is overridden, this returns the `BuildOutput` to use.
///
/// `lib_name` is the `links` library name and `kind` is whether it is for
/// Host or Target.
pub fn script_override(&self, lib_name: &str, kind: CompileKind) -> Option<&BuildOutput> {
self.target_data
.target_config(kind)
.links_overrides
.get(lib_name)
}
}
11 changes: 9 additions & 2 deletions src/cargo/core/compiler/build_context/target_info.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use crate::core::compiler::CompileKind;
use crate::core::compiler::CompileTarget;
use crate::core::compiler::{BuildOutput, CompileKind, CompileTarget};
use crate::core::{Dependency, TargetKind, Workspace};
use crate::util::config::{Config, StringList, TargetConfig};
use crate::util::{CargoResult, CargoResultExt, ProcessBuilder, Rustc};
Expand Down Expand Up @@ -583,4 +582,12 @@ impl RustcTargetData {
CompileKind::Target(s) => &self.target_config[&s],
}
}

/// If a build script is overridden, this returns the `BuildOutput` to use.
///
/// `lib_name` is the `links` library name and `kind` is whether it is for
/// Host or Target.
pub fn script_override(&self, lib_name: &str, kind: CompileKind) -> Option<&BuildOutput> {
self.target_config(kind).links_overrides.get(lib_name)
}
}
6 changes: 2 additions & 4 deletions src/cargo/core/compiler/compilation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,7 @@ pub struct Compilation<'cfg> {
}

impl<'cfg> Compilation<'cfg> {
pub fn new<'a>(
bcx: &BuildContext<'a, 'cfg>,
default_kind: CompileKind,
) -> CargoResult<Compilation<'cfg>> {
pub fn new<'a>(bcx: &BuildContext<'a, 'cfg>) -> CargoResult<Compilation<'cfg>> {
let mut rustc = bcx.rustc().process();
let mut primary_rustc_process = bcx.build_config.primary_unit_rustc.clone();
let mut rustc_workspace_wrapper_process = bcx.rustc().workspace_process();
Expand All @@ -104,6 +101,7 @@ impl<'cfg> Compilation<'cfg> {
}
}

let default_kind = bcx.build_config.requested_kind;
Ok(Compilation {
// TODO: deprecated; remove.
native_dirs: BTreeSet::new(),
Expand Down
13 changes: 5 additions & 8 deletions src/cargo/core/compiler/context/compilation_files.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,15 +119,12 @@ impl OutputFile {

impl<'a, 'cfg: 'a> CompilationFiles<'a, 'cfg> {
pub(super) fn new(
roots: &[Unit<'a>],
cx: &Context<'a, 'cfg>,
host: Layout,
target: HashMap<CompileTarget, Layout>,
export_dir: Option<PathBuf>,
ws: &'a Workspace<'cfg>,
cx: &Context<'a, 'cfg>,
) -> CompilationFiles<'a, 'cfg> {
let mut metas = HashMap::new();
for unit in roots {
for unit in &cx.bcx.roots {
metadata_of(unit, cx, &mut metas);
}
let outputs = metas
Expand All @@ -136,11 +133,11 @@ impl<'a, 'cfg: 'a> CompilationFiles<'a, 'cfg> {
.map(|unit| (unit, LazyCell::new()))
.collect();
CompilationFiles {
ws,
ws: &cx.bcx.ws,
host,
target,
export_dir,
roots: roots.to_vec(),
export_dir: cx.bcx.build_config.export_dir.clone(),
roots: cx.bcx.roots.clone(),
metas,
outputs,
}
Expand Down
59 changes: 21 additions & 38 deletions src/cargo/core/compiler/context/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ use jobserver::Client;
use crate::core::compiler::{self, compilation, Unit};
use crate::core::PackageId;
use crate::util::errors::{CargoResult, CargoResultExt};
use crate::util::{profile, Config};
use crate::util::profile;

use super::build_plan::BuildPlan;
use super::custom_build::{self, BuildDeps, BuildScriptOutputs, BuildScripts};
use super::fingerprint::Fingerprint;
use super::job_queue::JobQueue;
use super::layout::Layout;
use super::unit_graph::{UnitDep, UnitGraph};
use super::unit_graph::UnitDep;
use super::{BuildContext, Compilation, CompileKind, CompileMode, Executor, FileFlavor};

mod compilation_files;
Expand Down Expand Up @@ -53,8 +53,6 @@ pub struct Context<'a, 'cfg> {
/// with `-p` flags. If no flags are specified, then it is the defaults
/// based on the current directory and the default workspace members.
primary_packages: HashSet<PackageId>,
/// The dependency graph of units to compile.
unit_dependencies: UnitGraph<'a>,
/// An abstraction of the files and directories that will be generated by
/// the compilation. This is `None` until after `unit_dependencies` has
/// been computed.
Expand All @@ -78,12 +76,7 @@ pub struct Context<'a, 'cfg> {
}

impl<'a, 'cfg> Context<'a, 'cfg> {
pub fn new(
config: &'cfg Config,
bcx: &'a BuildContext<'a, 'cfg>,
unit_dependencies: UnitGraph<'a>,
default_kind: CompileKind,
) -> CargoResult<Self> {
pub fn new(bcx: &'a BuildContext<'a, 'cfg>) -> CargoResult<Self> {
// Load up the jobserver that we'll use to manage our parallelism. This
// is the same as the GNU make implementation of a jobserver, and
// intentionally so! It's hoped that we can interact with GNU make and
Expand All @@ -92,7 +85,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
// Note that if we don't have a jobserver in our environment then we
// create our own, and we create it with `n` tokens, but immediately
// acquire one, because one token is ourself, a running process.
let jobserver = match config.jobserver_from_env() {
let jobserver = match bcx.config.jobserver_from_env() {
Some(c) => c.clone(),
None => {
let client = Client::new(bcx.build_config.jobs as usize)
Expand All @@ -106,7 +99,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> {

Ok(Self {
bcx,
compilation: Compilation::new(bcx, default_kind)?,
compilation: Compilation::new(bcx)?,
build_script_outputs: Arc::new(Mutex::new(BuildScriptOutputs::default())),
fingerprints: HashMap::new(),
mtime_cache: HashMap::new(),
Expand All @@ -115,7 +108,6 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
build_explicit_deps: HashMap::new(),
jobserver,
primary_packages: HashSet::new(),
unit_dependencies,
files: None,
rmeta_required: HashSet::new(),
rustc_clients: HashMap::new(),
Expand All @@ -125,21 +117,16 @@ impl<'a, 'cfg> Context<'a, 'cfg> {

/// Starts compilation, waits for it to finish, and returns information
/// about the result of compilation.
pub fn compile(
mut self,
units: &[Unit<'a>],
export_dir: Option<PathBuf>,
exec: &Arc<dyn Executor>,
) -> CargoResult<Compilation<'cfg>> {
let mut queue = JobQueue::new(self.bcx, units);
pub fn compile(mut self, exec: &Arc<dyn Executor>) -> CargoResult<Compilation<'cfg>> {
let mut queue = JobQueue::new(self.bcx);
let mut plan = BuildPlan::new();
let build_plan = self.bcx.build_config.build_plan;
self.prepare_units(export_dir, units)?;
self.prepare_units()?;
self.prepare()?;
custom_build::build_map(&mut self, units)?;
custom_build::build_map(&mut self)?;
self.check_collistions()?;

for unit in units.iter() {
for unit in &self.bcx.roots {
// Build up a list of pending jobs, each of which represent
// compiling a particular package. No actual work is executed as
// part of this, that's all done next as part of the `execute`
Expand Down Expand Up @@ -168,7 +155,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
}

// Collect the result of the build into `self.compilation`.
for unit in units.iter() {
for unit in &self.bcx.roots {
// Collect tests and executables.
for output in self.outputs(unit)?.iter() {
if output.flavor == FileFlavor::DebugInfo || output.flavor == FileFlavor::Auxiliary
Expand All @@ -192,7 +179,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
// If the unit has a build script, add `OUT_DIR` to the
// environment variables.
if unit.target.is_lib() {
for dep in &self.unit_dependencies[unit] {
for dep in &self.bcx.unit_graph[unit] {
if dep.unit.mode.is_run_custom_build() {
let out_dir = self
.files()
Expand Down Expand Up @@ -283,11 +270,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
Ok(None)
}

pub fn prepare_units(
&mut self,
export_dir: Option<PathBuf>,
units: &[Unit<'a>],
) -> CargoResult<()> {
pub fn prepare_units(&mut self) -> CargoResult<()> {
let dest = self.bcx.profiles.get_dir_name();
let host_layout = Layout::new(self.bcx.ws, None, &dest)?;
let mut targets = HashMap::new();
Expand All @@ -296,12 +279,11 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
targets.insert(target, layout);
}
self.primary_packages
.extend(units.iter().map(|u| u.pkg.package_id()));
.extend(self.bcx.roots.iter().map(|u| u.pkg.package_id()));

self.record_units_requiring_metadata();

let files =
CompilationFiles::new(units, host_layout, targets, export_dir, self.bcx.ws, self);
let files = CompilationFiles::new(self, host_layout, targets);
self.files = Some(files);
Ok(())
}
Expand Down Expand Up @@ -345,7 +327,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> {

/// Direct dependencies for the given unit.
pub fn unit_deps(&self, unit: &Unit<'a>) -> &[UnitDep<'a>] {
&self.unit_dependencies[unit]
&self.bcx.unit_graph[unit]
}

/// Returns the RunCustomBuild Unit associated with the given Unit.
Expand All @@ -355,7 +337,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
if unit.mode.is_run_custom_build() {
return Some(unit);
}
self.unit_dependencies[&unit]
self.bcx.unit_graph[&unit]
.iter()
.find(|unit_dep| {
unit_dep.unit.mode.is_run_custom_build()
Expand Down Expand Up @@ -391,7 +373,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
// Keep sorted for consistency.
let mut inputs = BTreeSet::new();
// Note: dev-deps are skipped if they are not present in the unit graph.
for unit in self.unit_dependencies.keys() {
for unit in self.bcx.unit_graph.keys() {
inputs.insert(unit.pkg.manifest_path().to_path_buf());
}
Ok(inputs.into_iter().collect())
Expand Down Expand Up @@ -458,7 +440,8 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
};

let mut keys = self
.unit_dependencies
.bcx
.unit_graph
.keys()
.filter(|unit| !unit.mode.is_run_custom_build())
.collect::<Vec<_>>();
Expand Down Expand Up @@ -502,7 +485,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
/// Units which depend only on the metadata of others requires the others to
/// actually produce metadata, so we'll record that here.
fn record_units_requiring_metadata(&mut self) {
for (key, deps) in self.unit_dependencies.iter() {
for (key, deps) in self.bcx.unit_graph.iter() {
for dep in deps {
if self.only_requires_rmeta(key, &dep.unit) {
self.rmeta_required.insert(dep.unit);
Expand Down
Loading