Skip to content

Commit

Permalink
Add rustc/rustdoc config keys to Cargo config
Browse files Browse the repository at this point in the history
In addition to global RUSTC/RUSTDOC env vars, this commit recognizes
`build.rustc` and `build.rustdoc` as configuration keys for Cargo to instruct
what tools should be used instead of the default.

Closes #967
  • Loading branch information
alexcrichton committed May 18, 2015
1 parent 2fe0bf8 commit 9afa4c1
Show file tree
Hide file tree
Showing 16 changed files with 132 additions and 102 deletions.
24 changes: 14 additions & 10 deletions src/cargo/ops/cargo_compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,9 @@ pub enum CompileFilter<'a> {
}
}

pub fn compile(manifest_path: &Path,
options: &CompileOptions)
-> CargoResult<ops::Compilation> {
pub fn compile<'a>(manifest_path: &Path,
options: &CompileOptions<'a>)
-> CargoResult<ops::Compilation<'a>> {
debug!("compile; manifest-path={}", manifest_path.display());

let mut source = try!(PathSource::for_path(manifest_path.parent().unwrap(),
Expand All @@ -101,8 +101,9 @@ pub fn compile(manifest_path: &Path,
compile_pkg(&package, options)
}

pub fn compile_pkg(package: &Package, options: &CompileOptions)
-> CargoResult<ops::Compilation> {
pub fn compile_pkg<'a>(package: &Package,
options: &CompileOptions<'a>)
-> CargoResult<ops::Compilation<'a>> {
let CompileOptions { config, jobs, target, spec, features,
no_default_features, release, mode,
ref filter, ref exec_engine,
Expand Down Expand Up @@ -174,10 +175,12 @@ pub fn compile_pkg(package: &Package, options: &CompileOptions)
profile.rustc_args = Some(args.to_vec());
Some((target, profile))
}
Some(_) =>
return Err(human("extra arguments to `rustc` can only be passed to one target, \
consider filtering\nthe package by passing e.g. `--lib` or \
`--bin NAME` to specify a single target")),
Some(_) => {
return Err(human("extra arguments to `rustc` can only be passed to \
one target, consider filtering\nthe package by \
passing e.g. `--lib` or `--bin NAME` to specify \
a single target"))
}
None => None,
};

Expand All @@ -195,7 +198,8 @@ pub fn compile_pkg(package: &Package, options: &CompileOptions)

try!(ops::compile_targets(&targets, to_build,
&PackageSet::new(&packages),
&resolve_with_overrides, &sources,
&resolve_with_overrides,
&sources,
config,
build_config,
to_build.manifest().profiles()))
Expand Down
13 changes: 8 additions & 5 deletions src/cargo/ops/cargo_rustc/compilation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ use std::path::PathBuf;
use semver::Version;

use core::{PackageId, Package, Target};
use util::{self, CargoResult};
use util::{self, CargoResult, Config};

use super::{CommandType, CommandPrototype};

/// A structure returning the result of a compilation.
pub struct Compilation {
pub struct Compilation<'cfg> {
/// All libraries which were built for a package.
///
/// This is currently used for passing --extern flags to rustdoc tests later
Expand Down Expand Up @@ -44,10 +44,12 @@ pub struct Compilation {

/// Features enabled during this compilation.
pub features: HashSet<String>,

config: &'cfg Config,
}

impl Compilation {
pub fn new(pkg: &Package) -> Compilation {
impl<'cfg> Compilation<'cfg> {
pub fn new(pkg: &Package, config: &'cfg Config) -> Compilation<'cfg> {
Compilation {
libraries: HashMap::new(),
native_dirs: HashMap::new(), // TODO: deprecated, remove
Expand All @@ -58,6 +60,7 @@ impl Compilation {
extra_env: HashMap::new(),
package: pkg.clone(),
features: HashSet::new(),
config: config,
}
}

Expand Down Expand Up @@ -98,7 +101,7 @@ impl Compilation {
search_path.push(self.deps_output.clone());
let search_path = try!(util::join_paths(&search_path,
util::dylib_path_envvar()));
let mut cmd = try!(CommandPrototype::new(cmd));
let mut cmd = try!(CommandPrototype::new(cmd, self.config));
cmd.env(util::dylib_path_envvar(), &search_path);
for (k, v) in self.extra_env.iter() {
cmd.env(k, v);
Expand Down
27 changes: 14 additions & 13 deletions src/cargo/ops/cargo_rustc/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ pub enum Platform {
PluginAndTarget,
}

pub struct Context<'a> {
pub config: &'a Config,
pub struct Context<'a, 'cfg: 'a> {
pub config: &'cfg Config,
pub resolve: &'a Resolve,
pub sources: &'a SourceMap<'a>,
pub compilation: Compilation,
pub sources: &'a SourceMap<'cfg>,
pub compilation: Compilation<'cfg>,
pub build_state: Arc<BuildState>,
pub exec_engine: Arc<Box<ExecEngine>>,
pub fingerprints: HashMap<(&'a PackageId, &'a Target, &'a Profile, Kind),
Expand All @@ -49,23 +49,24 @@ pub struct Context<'a> {
profiles: &'a Profiles,
}

impl<'a> Context<'a> {
impl<'a, 'cfg> Context<'a, 'cfg> {
pub fn new(resolve: &'a Resolve,
sources: &'a SourceMap<'a>,
sources: &'a SourceMap<'cfg>,
deps: &'a PackageSet,
config: &'a Config,
config: &'cfg Config,
host: Layout,
target_layout: Option<Layout>,
root_pkg: &Package,
build_config: BuildConfig,
profiles: &'a Profiles) -> CargoResult<Context<'a>> {
profiles: &'a Profiles) -> CargoResult<Context<'a, 'cfg>> {
let target = build_config.requested_target.clone();
let target = target.as_ref().map(|s| &s[..]);
let (target_dylib, target_exe) = try!(Context::filename_parts(target));
let (target_dylib, target_exe) = try!(Context::filename_parts(target,
config));
let (host_dylib, host_exe) = if build_config.requested_target.is_none() {
(target_dylib.clone(), target_exe.clone())
} else {
try!(Context::filename_parts(None))
try!(Context::filename_parts(None, config))
};
let target_triple = target.unwrap_or(config.rustc_host()).to_string();
let engine = build_config.exec_engine.as_ref().cloned().unwrap_or({
Expand All @@ -84,7 +85,7 @@ impl<'a> Context<'a> {
host_dylib: host_dylib,
host_exe: host_exe,
requirements: HashMap::new(),
compilation: Compilation::new(root_pkg),
compilation: Compilation::new(root_pkg, config),
build_state: Arc::new(BuildState::new(&build_config, deps)),
build_config: build_config,
exec_engine: engine,
Expand All @@ -96,9 +97,9 @@ impl<'a> Context<'a> {

/// Run `rustc` to discover the dylib prefix/suffix for the target
/// specified as well as the exe suffix
fn filename_parts(target: Option<&str>)
fn filename_parts(target: Option<&str>, cfg: &Config)
-> CargoResult<(Option<(String, String)>, String)> {
let mut process = try!(util::process(util::rustc()));
let mut process = try!(util::process(cfg.rustc()));
process.arg("-")
.arg("--crate-name").arg("_")
.arg("--crate-type").arg("dylib")
Expand Down
10 changes: 6 additions & 4 deletions src/cargo/ops/cargo_rustc/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ use std::fmt;
use std::path::Path;
use std::process::Output;

use util::{self, CargoResult, ProcessError, ProcessBuilder, process};
use util::{CargoResult, ProcessError, ProcessBuilder, process};
use util::Config;

/// Trait for objects that can execute commands.
pub trait ExecEngine: Send + Sync {
Expand Down Expand Up @@ -35,11 +36,12 @@ pub struct CommandPrototype {
}

impl CommandPrototype {
pub fn new(ty: CommandType) -> CargoResult<CommandPrototype> {
pub fn new(ty: CommandType, config: &Config)
-> CargoResult<CommandPrototype> {
Ok(CommandPrototype {
builder: try!(match ty {
CommandType::Rustc => process(util::rustc()),
CommandType::Rustdoc => process(util::rustdoc()),
CommandType::Rustc => process(config.rustc()),
CommandType::Rustdoc => process(config.rustdoc()),
CommandType::Target(ref s) |
CommandType::Host(ref s) => process(s),
}),
Expand Down
22 changes: 11 additions & 11 deletions src/cargo/ops/cargo_rustc/fingerprint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,11 @@ pub type Preparation = (Freshness, Work, Work);
/// This function will calculate the fingerprint for a target and prepare the
/// work necessary to either write the fingerprint or copy over all fresh files
/// from the old directories to their new locations.
pub fn prepare_target<'a>(cx: &mut Context<'a>,
pkg: &'a Package,
target: &'a Target,
profile: &'a Profile,
kind: Kind) -> CargoResult<Preparation> {
pub fn prepare_target<'a, 'cfg>(cx: &mut Context<'a, 'cfg>,
pkg: &'a Package,
target: &'a Target,
profile: &'a Profile,
kind: Kind) -> CargoResult<Preparation> {
let _p = profile::start(format!("fingerprint: {} / {}",
pkg.package_id(), target.name()));
let new = dir(cx, pkg, kind);
Expand Down Expand Up @@ -131,12 +131,12 @@ impl Fingerprint {
///
/// Information like file modification time is only calculated for path
/// dependencies and is calculated in `calculate_target_fresh`.
fn calculate<'a>(cx: &mut Context<'a>,
pkg: &'a Package,
target: &'a Target,
profile: &'a Profile,
kind: Kind)
-> CargoResult<Fingerprint> {
fn calculate<'a, 'cfg>(cx: &mut Context<'a, 'cfg>,
pkg: &'a Package,
target: &'a Target,
profile: &'a Profile,
kind: Kind)
-> CargoResult<Fingerprint> {
let key = (pkg.package_id(), target, profile, kind);
match cx.fingerprints.get(&key) {
Some(s) => return Ok(s.clone()),
Expand Down
42 changes: 21 additions & 21 deletions src/cargo/ops/cargo_rustc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::env;
use std::ffi::OsString;
use std::fs;
use std::io::prelude::*;
use std::path::{self, PathBuf};
use std::path::{self, Path, PathBuf};
use std::sync::Arc;

use core::{SourceMap, Package, PackageId, PackageSet, Target, Resolve};
Expand Down Expand Up @@ -56,8 +56,8 @@ pub struct TargetConfig {
///
/// The second element of the tuple returned is the target triple that rustc
/// is a host for.
pub fn rustc_version() -> CargoResult<(String, String)> {
let output = try!(try!(util::process(util::rustc()))
pub fn rustc_version<P: AsRef<Path>>(rustc: P) -> CargoResult<(String, String)> {
let output = try!(try!(util::process(rustc.as_ref()))
.arg("-vV")
.exec_with_output());
let output = try!(String::from_utf8(output.stdout).map_err(|_| {
Expand All @@ -77,17 +77,17 @@ pub fn rustc_version() -> CargoResult<(String, String)> {

// Returns a mapping of the root package plus its immediate dependencies to
// where the compiled libraries are all located.
pub fn compile_targets<'a>(targets: &[(&'a Target, &'a Profile)],
pkg: &'a Package,
deps: &PackageSet,
resolve: &'a Resolve,
sources: &'a SourceMap<'a>,
config: &'a Config,
build_config: BuildConfig,
profiles: &'a Profiles)
-> CargoResult<Compilation> {
pub fn compile_targets<'a, 'cfg: 'a>(targets: &[(&'a Target, &'a Profile)],
pkg: &'a Package,
deps: &'a PackageSet,
resolve: &'a Resolve,
sources: &'a SourceMap<'cfg>,
config: &'cfg Config,
build_config: BuildConfig,
profiles: &'a Profiles)
-> CargoResult<Compilation<'cfg>> {
if targets.is_empty() {
return Ok(Compilation::new(pkg))
return Ok(Compilation::new(pkg, config))
}

debug!("compile_targets: {}", pkg);
Expand Down Expand Up @@ -181,10 +181,10 @@ pub fn compile_targets<'a>(targets: &[(&'a Target, &'a Profile)],
Ok(cx.compilation)
}

fn compile<'a>(targets: &[(&'a Target, &'a Profile)],
pkg: &'a Package,
cx: &mut Context<'a>,
jobs: &mut JobQueue<'a>) -> CargoResult<()> {
fn compile<'a, 'cfg>(targets: &[(&'a Target, &'a Profile)],
pkg: &'a Package,
cx: &mut Context<'a, 'cfg>,
jobs: &mut JobQueue<'a>) -> CargoResult<()> {
debug!("compile_pkg; pkg={}", pkg);
let profiling_marker = profile::start(format!("preparing: {}", pkg));

Expand Down Expand Up @@ -292,10 +292,10 @@ fn compile<'a>(targets: &[(&'a Target, &'a Profile)],
Ok(())
}

fn prepare_init<'a>(cx: &mut Context<'a>,
pkg: &'a Package,
jobs: &mut JobQueue<'a>,
visited: &mut HashSet<&'a PackageId>) {
fn prepare_init<'a, 'cfg>(cx: &mut Context<'a, 'cfg>,
pkg: &'a Package,
jobs: &mut JobQueue<'a>,
visited: &mut HashSet<&'a PackageId>) {
if !visited.insert(pkg.package_id()) { return }

// Set up all dependencies
Expand Down
8 changes: 4 additions & 4 deletions src/cargo/ops/cargo_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,10 +101,10 @@ pub fn run_benches(manifest_path: &Path,
Ok(try!(build_and_run(manifest_path, options, &args)).err())
}

fn build_and_run(manifest_path: &Path,
options: &TestOptions,
test_args: &[String])
-> CargoResult<Result<Compilation, ProcessError>> {
fn build_and_run<'a>(manifest_path: &Path,
options: &TestOptions<'a>,
test_args: &[String])
-> CargoResult<Result<Compilation<'a>, ProcessError>> {
let config = options.compile_opts.config;
let mut source = try!(PathSource::for_path(&manifest_path.parent().unwrap(),
config));
Expand Down
Loading

0 comments on commit 9afa4c1

Please sign in to comment.