1use std::env::consts::EXE_SUFFIX;
2use std::path::PathBuf;
3use std::process::Command;
4use std::{env, process};
5
6use anyhow::Result;
7
8use crate::rustc::rustlib;
9
10#[derive(Clone, Copy, PartialEq, Eq)]
11pub enum Tool {
12 Ar,
13 As,
14 Cov,
15 Lld,
16 Nm,
17 Objcopy,
18 Objdump,
19 Profdata,
20 Readobj,
21 Size,
22 Strip,
23}
24
25impl Tool {
26 pub fn name(self) -> &'static str {
27 match self {
28 Tool::Ar => "ar",
29 Tool::As => "as",
30 Tool::Cov => "cov",
31 Tool::Lld => "lld",
32 Tool::Nm => "nm",
33 Tool::Objcopy => "objcopy",
34 Tool::Objdump => "objdump",
35 Tool::Profdata => "profdata",
36 Tool::Readobj => "readobj",
37 Tool::Size => "size",
38 Tool::Strip => "strip",
39 }
40 }
41
42 pub fn exe(self) -> String {
43 match self {
44 Tool::Lld => format!("rust-lld{EXE_SUFFIX}"),
45 _ => format!("llvm-{}{}", self.name(), EXE_SUFFIX),
46 }
47 }
48
49 pub fn path(self) -> Result<PathBuf> {
50 let mut path = rustlib()?;
51 path.push(self.exe());
52 Ok(path)
53 }
54
55 pub fn rust_exec(self) -> ! {
59 let path = match self.path() {
60 Err(e) => {
61 eprintln!("Failed to find tool: {}\n{}", self.name(), e);
62 process::exit(101)
63 }
64 Ok(p) => p,
65 };
66
67 if !path.exists() {
68 eprintln!(
69 "Could not find tool: {}\nat: {}\nConsider `rustup component add llvm-tools`",
70 self.name(),
71 path.to_string_lossy()
72 );
73 process::exit(102)
74 };
75
76 let args = env::args().skip(1);
78
79 let status = match Command::new(path).args(args).status() {
81 Err(e) => {
82 eprintln!("Failed to execute tool: {}\n{}", self.name(), e);
83 process::exit(101)
84 }
85 Ok(s) => s,
86 };
87
88 process::exit(status.code().unwrap_or(101));
90 }
91
92 pub fn cargo_exec(self, examples: Option<&str>) -> ! {
97 let matches = crate::args(self, examples);
98
99 match crate::run(self, matches) {
100 Err(e) => {
101 eprintln!("error: {e}");
102 process::exit(101)
103 }
104 Ok(ec) => process::exit(ec),
105 }
106 }
107
108 pub fn needs_build(self) -> bool {
110 match self {
111 Tool::Ar | Tool::As | Tool::Cov | Tool::Lld | Tool::Profdata => false,
112 Tool::Nm | Tool::Objcopy | Tool::Objdump | Tool::Readobj | Tool::Size | Tool::Strip => {
113 true
114 }
115 }
116 }
117}