mod links;
mod output_depinfo;
+/// Whether an object is for the host arch, or the target arch.
+///
+/// These will be the same unless cross-compiling.
#[derive(PartialEq, Eq, Hash, Debug, Clone, Copy, PartialOrd, Ord)]
pub enum Kind { Host, Target }
+/// Configuration information for a rustc build.
#[derive(Default, Clone)]
pub struct BuildConfig {
+ /// The host arch triple
+ ///
+ /// e.g. x86_64-unknown-linux-gnu, would be
+ /// - machine: x86_64
+ /// - hardware-platform: unknown
+ /// - operating system: linux-gnu
pub host_triple: String,
+ /// Build information for the host arch
pub host: TargetConfig,
+ /// The target arch triple, defaults to host arch
pub requested_target: Option<String>,
+ /// Build information for the target
pub target: TargetConfig,
+ /// How many rustc jobs to run in parallel
pub jobs: u32,
+ /// Whether we are building for release
pub release: bool,
+ /// Whether we are running tests
pub test: bool,
+ /// Whether we are building documentation
pub doc_all: bool,
+ /// Whether to print std output in json format (for machine reading)
pub json_messages: bool,
}
+/// Information required to build for a target
#[derive(Clone, Default)]
pub struct TargetConfig {
+ /// The path of archiver (lib builder) for this target.
pub ar: Option<PathBuf>,
+ /// The path of the linker for this target.
pub linker: Option<PathBuf>,
+ /// Special build options for any necessary input files (filename -> options)
pub overrides: HashMap<String, BuildOutput>,
}
use util::{CargoResult, CargoResultExt, CargoError, process_error, read2};
use util::errors::CargoErrorKind;
+/// A builder object for an external process, similar to `std::process::Command`.
#[derive(Clone, Debug)]
pub struct ProcessBuilder {
+ /// The program to execute.
program: OsString,
+ /// A list of arguments to pass to the program.
args: Vec<OsString>,
+ /// Any environment variables that should be set for the program.
env: HashMap<String, Option<OsString>>,
+ /// Which directory to run the program from.
cwd: Option<OsString>,
+ /// The `make` jobserver. See the [jobserver crate][jobserver_docs] for
+ /// more information.
+ ///
+ /// [jobserver_docs]: https://docs.rs/jobserver/0.1.6/jobserver/
jobserver: Option<Client>,
}
}
impl ProcessBuilder {
+ /// (chainable) Set the executable for the process.
pub fn program<T: AsRef<OsStr>>(&mut self, program: T) -> &mut ProcessBuilder {
self.program = program.as_ref().to_os_string();
self
}
+ /// (chainable) Add an arg to the args list.
pub fn arg<T: AsRef<OsStr>>(&mut self, arg: T) -> &mut ProcessBuilder {
self.args.push(arg.as_ref().to_os_string());
self
}
+ /// (chainable) Add many args to the args list.
pub fn args<T: AsRef<OsStr>>(&mut self, arguments: &[T]) -> &mut ProcessBuilder {
self.args.extend(arguments.iter().map(|t| {
t.as_ref().to_os_string()
self
}
+ /// (chainable) Replace args with new args list
pub fn args_replace<T: AsRef<OsStr>>(&mut self, arguments: &[T]) -> &mut ProcessBuilder {
self.args = arguments.iter().map(|t| {
t.as_ref().to_os_string()
self
}
+ /// (chainable) Set the current working directory of the process
pub fn cwd<T: AsRef<OsStr>>(&mut self, path: T) -> &mut ProcessBuilder {
self.cwd = Some(path.as_ref().to_os_string());
self
}
+ /// (chainable) Set an environment variable for the process.
pub fn env<T: AsRef<OsStr>>(&mut self, key: &str,
val: T) -> &mut ProcessBuilder {
self.env.insert(key.to_string(), Some(val.as_ref().to_os_string()));
self
}
+ /// (chainable) Unset an environment variable for the process.
pub fn env_remove(&mut self, key: &str) -> &mut ProcessBuilder {
self.env.insert(key.to_string(), None);
self
}
+ /// Get the executable name.
pub fn get_program(&self) -> &OsString {
&self.program
}
+ /// Get the program arguments
pub fn get_args(&self) -> &[OsString] {
&self.args
}
+ /// Get the current working directory for the process
pub fn get_cwd(&self) -> Option<&Path> {
self.cwd.as_ref().map(Path::new)
}
+ /// Get an environment variable as the process will see it (will inherit from environment
+ /// unless explicitally unset).
pub fn get_env(&self, var: &str) -> Option<OsString> {
self.env.get(var).cloned().or_else(|| Some(env::var_os(var)))
.and_then(|s| s)
}
+ /// Get all environment variables explicitally set or unset for the process (not inherited
+ /// vars).
pub fn get_envs(&self) -> &HashMap<String, Option<OsString>> { &self.env }
+ /// Set the `make` jobserver. See the [jobserver crate][jobserver_docs] for
+ /// more information.
+ ///
+ /// [jobserver_docs]: https://docs.rs/jobserver/0.1.6/jobserver/
pub fn inherit_jobserver(&mut self, jobserver: &Client) -> &mut Self {
self.jobserver = Some(jobserver.clone());
self
}
+ /// Run the process, waiting for completion, and mapping non-success exit codes to an error.
pub fn exec(&self) -> CargoResult<()> {
let mut command = self.build_command();
let exit = command.status().chain_err(|| {
}
}
+ /// On unix, executes the process using the unix syscall `execvp`, which will block this
+ /// process, and will only return if there is an error. On windows this is a synonym for
+ /// `exec`.
#[cfg(unix)]
pub fn exec_replace(&self) -> CargoResult<()> {
use std::os::unix::process::CommandExt;
&format!("could not execute process `{}`", self.debug_string()), None, None))))
}
+ /// On unix, executes the process using the unix syscall `execvp`, which will block this
+ /// process, and will only return if there is an error. On windows this is a synonym for
+ /// `exec`.
#[cfg(windows)]
pub fn exec_replace(&self) -> CargoResult<()> {
self.exec()
}
+ /// Execute the process, returning the stdio output, or an error if non-zero exit status.
pub fn exec_with_output(&self) -> CargoResult<Output> {
let mut command = self.build_command();
}
}
+ /// Execute a command, passing each line of stdout and stderr to the supplied callbacks, which
+ /// can mutate the string data.
+ ///
+ /// If any invocations of these function return an error, it will be propagated.
+ ///
+ /// Optionally, output can be passed to errors using `print_output`
pub fn exec_with_streaming(&self,
on_stdout_line: &mut FnMut(&str) -> CargoResult<()>,
on_stderr_line: &mut FnMut(&str) -> CargoResult<()>,
Ok(output)
}
+ /// Converts ProcessBuilder into a `std::process::Command`, and handles the jobserver if
+ /// present.
pub fn build_command(&self) -> Command {
let mut command = Command::new(&self.program);
if let Some(cwd) = self.get_cwd() {
command
}
+ /// Get the command line for the process as a string.
fn debug_string(&self) -> String {
let mut program = format!("{}", self.program.to_string_lossy());
for arg in &self.args {
}
}
+/// A helper function to create a ProcessBuilder.
pub fn process<T: AsRef<OsStr>>(cmd: T) -> ProcessBuilder {
ProcessBuilder {
program: cmd.as_ref().to_os_string(),