1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
|
use std::env::consts::EXE_SUFFIX;
use std::path::PathBuf;
use std::process::Command;
use std::{env, process};
use anyhow::Result;
use crate::rustc::rustlib;
#[derive(Clone, Copy, PartialEq, Eq)]
pub enum Tool {
Ar,
As,
Cov,
Lld,
Nm,
Objcopy,
Objdump,
Profdata,
Readobj,
Size,
Strip,
}
impl Tool {
pub fn name(self) -> &'static str {
match self {
Tool::Ar => "ar",
Tool::As => "as",
Tool::Cov => "cov",
Tool::Lld => "lld",
Tool::Nm => "nm",
Tool::Objcopy => "objcopy",
Tool::Objdump => "objdump",
Tool::Profdata => "profdata",
Tool::Readobj => "readobj",
Tool::Size => "size",
Tool::Strip => "strip",
}
}
pub fn exe(self) -> String {
match self {
Tool::Lld => format!("rust-lld{EXE_SUFFIX}"),
_ => format!("llvm-{}{}", self.name(), EXE_SUFFIX),
}
}
pub fn path(self) -> Result<PathBuf> {
let mut path = rustlib()?;
path.push(self.exe());
Ok(path)
}
/// Forwards execution to the specified tool.
/// If the tool fails to start or is not found this process exits with
/// status code 101 the same as if the process has a panic!
pub fn rust_exec(self) -> ! {
let path = match self.path() {
Err(e) => {
eprintln!("Failed to find tool: {}\n{}", self.name(), e);
process::exit(101)
}
Ok(p) => p,
};
if !path.exists() {
eprintln!(
"Could not find tool: {}\nat: {}\nConsider `rustup component add llvm-tools`",
self.name(),
path.to_string_lossy()
);
process::exit(102)
};
// Note: The first argument is the name of the binary (e.g. `rust-nm`)
let args = env::args().skip(1);
// Spawn the process and check if the process did spawn
let status = match Command::new(path).args(args).status() {
Err(e) => {
eprintln!("Failed to execute tool: {}\n{}", self.name(), e);
process::exit(101)
}
Ok(s) => s,
};
// Forward the exit code from the tool
process::exit(status.code().unwrap_or(101));
}
/// Parses arguments for `cargo $tool` and then if needed executes `cargo build`
/// before parsing the required arguments to `rust-$tool`.
/// If the tool fails to start or is not found this process exits with
/// status code 101 the same as if the process has a panic!
pub fn cargo_exec(self, examples: Option<&str>) -> ! {
let matches = crate::args(self, examples);
match crate::run(self, matches) {
Err(e) => {
eprintln!("error: {e}");
process::exit(101)
}
Ok(ec) => process::exit(ec),
}
}
// Whether this tool requires the project to be previously built
pub fn needs_build(self) -> bool {
match self {
Tool::Ar | Tool::As | Tool::Cov | Tool::Lld | Tool::Profdata => false,
Tool::Nm | Tool::Objcopy | Tool::Objdump | Tool::Readobj | Tool::Size | Tool::Strip => {
true
}
}
}
}
|