<commit_before>use std::collections::{HashSet, HashMap};
use std::dynamic_lib::DynamicLibrary;
use std::io::{fs, USER_RWX};
use std::io::fs::PathExtensions;

use core::{SourceMap, Package, PackageId, PackageSet, Target, Resolve};
use util::{mod, CargoResult, ProcessBuilder, CargoError, human, caused_human};
use util::{Require, Config, internal, ChainError, Fresh, profile, join_paths};

use self::job::{Job, Work};
use self::job_queue::{JobQueue, Stage};

pub use self::compilation::Compilation;
pub use self::context::Context;
pub use self::context::Platform;
pub use self::layout::{Layout, LayoutProxy};
pub use self::custom_build::BuildOutput;

mod context;
mod compilation;
mod custom_build;
mod fingerprint;
mod job;
mod job_queue;
mod layout;
mod links;

#[deriving(PartialEq, Eq, Hash, Show, Copy)]
pub enum Kind { Host, Target }

#[deriving(Default, Clone)]
pub struct BuildConfig {
    pub host: TargetConfig,
    pub target: TargetConfig,
}

#[deriving(Clone, Default)]
pub struct TargetConfig {
    pub ar: Option<String>,
    pub linker: Option<String>,
    pub overrides: HashMap<String, BuildOutput>,
}

/// Run `rustc` to figure out what its current version string is.
///
/// 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("rustc"))
        .arg("-v")
        .arg("verbose")
        .exec_with_output());
    let output = try!(String::from_utf8(output.output).map_err(|_| {
        internal("rustc -v didn't return utf8 output")
    }));
    let triple = {
        let triple = output.as_slice().lines().filter(|l| {
            l.starts_with("host: ")
        }).map(|l| l.slice_from(6)).next();
        let triple = try!(triple.require(|| {
            internal("rustc -v didn't have a line for `host:`")
        }));
        triple.to_string()
    };
    Ok((output, triple))
}

// This is a temporary assert that ensures the consistency of the arguments
// given the current limitations of Cargo. The long term fix is to have each
// Target know the absolute path to the build location.
fn uniq_target_dest<'a>(targets: &[&'a Target]) -> Option<&'a str> {
    let mut curr: Option<Option<&str>> = None;

    for t in targets.iter().filter(|t| !t.get_profile().is_custom_build()) {<commit_msg>auto merge of #1075 : cmr/cargo/rustc-vverbose, r=alexcrichton<commit_after>use std::collections::{HashSet, HashMap};
use std::dynamic_lib::DynamicLibrary;
use std::io::{fs, USER_RWX};
use std::io::fs::PathExtensions;

use core::{SourceMap, Package, PackageId, PackageSet, Target, Resolve};
use util::{mod, CargoResult, ProcessBuilder, CargoError, human, caused_human};
use util::{Require, Config, internal, ChainError, Fresh, profile, join_paths};

use self::job::{Job, Work};
use self::job_queue::{JobQueue, Stage};

pub use self::compilation::Compilation;
pub use self::context::Context;
pub use self::context::Platform;
pub use self::layout::{Layout, LayoutProxy};
pub use self::custom_build::BuildOutput;

mod context;
mod compilation;
mod custom_build;
mod fingerprint;
mod job;
mod job_queue;
mod layout;
mod links;

#[deriving(PartialEq, Eq, Hash, Show, Copy)]
pub enum Kind { Host, Target }

#[deriving(Default, Clone)]
pub struct BuildConfig {
    pub host: TargetConfig,
    pub target: TargetConfig,
}

#[deriving(Clone, Default)]
pub struct TargetConfig {
    pub ar: Option<String>,
    pub linker: Option<String>,
    pub overrides: HashMap<String, BuildOutput>,
}

/// Run `rustc` to figure out what its current version string is.
///
/// The second element of the tuple returned is the target triple that rustc
/// is a host for.
pub fn rustc_version() -> CargoResult<(String, String)> {
    rustc_new_version().or_else(|_| rustc_old_version())
}

pub fn rustc_old_version() -> CargoResult<(String, String)> {
    let output = try!(try!(util::process("rustc"))
        .arg("-v")
        .arg("verbose")
        .exec_with_output());
    let output = try!(String::from_utf8(output.output).map_err(|_| {
        internal("rustc -v didn't return utf8 output")
    }));
    let triple = {
        let triple = output.as_slice().lines().filter(|l| {
            l.starts_with("host: ")
        }).map(|l| l.slice_from(6)).next();
        let triple = try!(triple.require(|| {
            internal("rustc -v didn't have a line for `host:`")
        }));
        triple.to_string()
    };
    Ok((output, triple))
}

pub fn rustc_new_version() -> CargoResult<(String, String)> {
    let output = try!(try!(util::process("rustc"))
        .arg("-vV")
        .exec_with_output());
    let output = try!(String::from_utf8(output.output).map_err(|_| {
        internal("rustc -v didn't return utf8 output")
    }));
    let triple = {
        let triple = output.as_slice().lines().filter(|l| {
            l.starts_with("host: ")
        }).map(|l| l.slice_from(6)).next();
        let triple = try!(triple.require(|| {
            internal("rustc -v didn't have a line for `host:`")
        }));
        triple.to_string()
    };
    Ok((output, triple))
}

// This is a temporary assert that ensures the consistency of the arguments
// given the current limitations of Cargo. The long term fix is to have each
// Target know the absolute path to the build location.
fn uniq_target_dest<'a>(targets: &[&'a Target]) -> Option<&'a str> {
    let mut curr: Option<Option<&str>> = None;

    for t in targets.iter().filter(|t| !t.get_profile().is_custom_build()) {
{'fraction_non_alphanumeric': 0.1542774461928016, 'fraction_numerical': 0.0023512389220473866, 'mean_word_length': 3.859402460456942, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2954569', 'n_tokens_mistral': 1724, 'n_tokens_neox': 1747, 'n_words': 507}