]> git.proxmox.com Git - rustc.git/blame - src/bootstrap/install.rs
New upstream version 1.52.1+dfsg1
[rustc.git] / src / bootstrap / install.rs
CommitLineData
c30ab7b3
SL
1//! Implementation of the install aspects of the compiler.
2//!
3//! This module is responsible for installing the standard library,
4//! compiler, and documentation.
5
32a655c1 6use std::env;
c30ab7b3 7use std::fs;
fc512014 8use std::path::{Component, PathBuf};
c30ab7b3
SL
9use std::process::Command;
10
48663c56
XL
11use build_helper::t;
12
fc512014
XL
13use crate::dist::{self, sanitize_sh};
14use crate::tarball::GeneratedTarball;
dc9dc135 15use crate::Compiler;
7cac9316 16
0731742a 17use crate::builder::{Builder, RunConfig, ShouldRun, Step};
3dfed10e 18use crate::config::{Config, TargetSelection};
7cac9316 19
3b2f2976 20fn install_sh(
9fa01778 21 builder: &Builder<'_>,
3b2f2976 22 package: &str,
3b2f2976 23 stage: u32,
3dfed10e 24 host: Option<TargetSelection>,
fc512014 25 tarball: &GeneratedTarball,
3b2f2976 26) {
83c7162d 27 builder.info(&format!("Install {} stage{} ({:?})", package, stage, host));
3b2f2976 28
fc512014
XL
29 let prefix = default_path(&builder.config.prefix, "/usr/local");
30 let sysconfdir = prefix.join(default_path(&builder.config.sysconfdir, "/etc"));
31 let datadir = prefix.join(default_path(&builder.config.datadir, "share"));
32 let docdir = prefix.join(default_path(&builder.config.docdir, "share/doc/rust"));
33 let mandir = prefix.join(default_path(&builder.config.mandir, "share/man"));
34 let libdir = prefix.join(default_path(&builder.config.libdir, "lib"));
35 let bindir = prefix.join(&builder.config.bindir); // Default in config.rs
3b2f2976 36
83c7162d 37 let empty_dir = builder.out.join("tmp/empty_dir");
3b2f2976 38 t!(fs::create_dir_all(&empty_dir));
7cac9316 39
3b2f2976
XL
40 let mut cmd = Command::new("sh");
41 cmd.current_dir(&empty_dir)
fc512014
XL
42 .arg(sanitize_sh(&tarball.decompressed_output().join("install.sh")))
43 .arg(format!("--prefix={}", prepare_dir(prefix)))
44 .arg(format!("--sysconfdir={}", prepare_dir(sysconfdir)))
45 .arg(format!("--datadir={}", prepare_dir(datadir)))
46 .arg(format!("--docdir={}", prepare_dir(docdir)))
47 .arg(format!("--bindir={}", prepare_dir(bindir)))
48 .arg(format!("--libdir={}", prepare_dir(libdir)))
49 .arg(format!("--mandir={}", prepare_dir(mandir)))
3b2f2976 50 .arg("--disable-ldconfig");
83c7162d 51 builder.run(&mut cmd);
3b2f2976 52 t!(fs::remove_dir_all(&empty_dir));
c30ab7b3 53}
32a655c1 54
fc512014 55fn default_path(config: &Option<PathBuf>, default: &str) -> PathBuf {
6a06907d 56 config.as_ref().cloned().unwrap_or_else(|| PathBuf::from(default))
fc512014
XL
57}
58
59fn prepare_dir(mut path: PathBuf) -> String {
60 // The DESTDIR environment variable is a standard way to install software in a subdirectory
61 // while keeping the original directory structure, even if the prefix or other directories
62 // contain absolute paths.
63 //
64 // More information on the environment variable is available here:
65 // https://www.gnu.org/prep/standards/html_node/DESTDIR.html
66 if let Some(destdir) = env::var_os("DESTDIR").map(PathBuf::from) {
67 let without_destdir = path.clone();
68 path = destdir;
69 // Custom .join() which ignores disk roots.
70 for part in without_destdir.components() {
71 if let Component::Normal(s) = part {
72 path.push(s)
73 }
32a655c1
SL
74 }
75 }
fc512014
XL
76
77 // The installation command is not executed from the current directory, but from a temporary
78 // directory. To prevent relative paths from breaking this converts relative paths to absolute
79 // paths. std::fs::canonicalize is not used as that requires the path to actually be present.
80 if path.is_relative() {
81 path = std::env::current_dir().expect("failed to get the current directory").join(path);
82 assert!(path.is_absolute(), "could not make the path relative");
83 }
84
85 sanitize_sh(&path)
32a655c1 86}
3b2f2976
XL
87
88macro_rules! install {
89 (($sel:ident, $builder:ident, $_config:ident),
90 $($name:ident,
91 $path:expr,
92 $default_cond:expr,
93 only_hosts: $only_hosts:expr,
94 $run_item:block $(, $c:ident)*;)+) => {
95 $(
96 #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
97 pub struct $name {
dc9dc135 98 pub compiler: Compiler,
3dfed10e 99 pub target: TargetSelection,
3b2f2976
XL
100 }
101
2c00a5a8
XL
102 impl $name {
103 #[allow(dead_code)]
104 fn should_build(config: &Config) -> bool {
105 config.extended && config.tools.as_ref()
106 .map_or(true, |t| t.contains($path))
107 }
2c00a5a8
XL
108 }
109
3b2f2976
XL
110 impl Step for $name {
111 type Output = ();
112 const DEFAULT: bool = true;
3b2f2976
XL
113 const ONLY_HOSTS: bool = $only_hosts;
114 $(const $c: bool = true;)*
115
9fa01778 116 fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
3b2f2976
XL
117 let $_config = &run.builder.config;
118 run.path($path).default_condition($default_cond)
119 }
120
9fa01778 121 fn make_run(run: RunConfig<'_>) {
3b2f2976 122 run.builder.ensure($name {
dc9dc135 123 compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.build),
3b2f2976 124 target: run.target,
3b2f2976
XL
125 });
126 }
127
9fa01778 128 fn run($sel, $builder: &Builder<'_>) {
3b2f2976
XL
129 $run_item
130 }
131 })+
132 }
133}
134
135install!((self, builder, _config),
136 Docs, "src/doc", _config.docs, only_hosts: false, {
fc512014
XL
137 let tarball = builder.ensure(dist::Docs { host: self.target }).expect("missing docs");
138 install_sh(builder, "docs", self.compiler.stage, Some(self.target), &tarball);
3b2f2976 139 };
1b1a35ee 140 Std, "library/std", true, only_hosts: false, {
83c7162d 141 for target in &builder.targets {
fc512014 142 let tarball = builder.ensure(dist::Std {
dc9dc135 143 compiler: self.compiler,
abe05a73 144 target: *target
fc512014
XL
145 }).expect("missing std");
146 install_sh(builder, "std", self.compiler.stage, Some(*target), &tarball);
abe05a73 147 }
3b2f2976 148 };
2c00a5a8 149 Cargo, "cargo", Self::should_build(_config), only_hosts: true, {
fc512014
XL
150 let tarball = builder.ensure(dist::Cargo { compiler: self.compiler, target: self.target });
151 install_sh(builder, "cargo", self.compiler.stage, Some(self.target), &tarball);
3b2f2976 152 };
2c00a5a8 153 Rls, "rls", Self::should_build(_config), only_hosts: true, {
fc512014
XL
154 if let Some(tarball) = builder.ensure(dist::Rls { compiler: self.compiler, target: self.target }) {
155 install_sh(builder, "rls", self.compiler.stage, Some(self.target), &tarball);
abe05a73 156 } else {
dc9dc135
XL
157 builder.info(
158 &format!("skipping Install RLS stage{} ({})", self.compiler.stage, self.target),
159 );
abe05a73
XL
160 }
161 };
f035d41b 162 RustAnalyzer, "rust-analyzer", Self::should_build(_config), only_hosts: true, {
fc512014
XL
163 let tarball = builder
164 .ensure(dist::RustAnalyzer { compiler: self.compiler, target: self.target })
165 .expect("missing rust-analyzer");
166 install_sh(builder, "rust-analyzer", self.compiler.stage, Some(self.target), &tarball);
f035d41b 167 };
8faf50e0 168 Clippy, "clippy", Self::should_build(_config), only_hosts: true, {
fc512014
XL
169 let tarball = builder.ensure(dist::Clippy { compiler: self.compiler, target: self.target });
170 install_sh(builder, "clippy", self.compiler.stage, Some(self.target), &tarball);
8faf50e0 171 };
0731742a 172 Miri, "miri", Self::should_build(_config), only_hosts: true, {
fc512014
XL
173 if let Some(tarball) = builder.ensure(dist::Miri { compiler: self.compiler, target: self.target }) {
174 install_sh(builder, "miri", self.compiler.stage, Some(self.target), &tarball);
0731742a 175 } else {
dc9dc135
XL
176 builder.info(
177 &format!("skipping Install miri stage{} ({})", self.compiler.stage, self.target),
178 );
0731742a
XL
179 }
180 };
2c00a5a8 181 Rustfmt, "rustfmt", Self::should_build(_config), only_hosts: true, {
fc512014 182 if let Some(tarball) = builder.ensure(dist::Rustfmt {
dc9dc135
XL
183 compiler: self.compiler,
184 target: self.target
fc512014
XL
185 }) {
186 install_sh(builder, "rustfmt", self.compiler.stage, Some(self.target), &tarball);
abe05a73 187 } else {
83c7162d 188 builder.info(
dc9dc135
XL
189 &format!("skipping Install Rustfmt stage{} ({})", self.compiler.stage, self.target),
190 );
abe05a73 191 }
3b2f2976 192 };
2c00a5a8 193 Analysis, "analysis", Self::should_build(_config), only_hosts: false, {
fc512014 194 let tarball = builder.ensure(dist::Analysis {
dc9dc135
XL
195 // Find the actual compiler (handling the full bootstrap option) which
196 // produced the save-analysis data because that data isn't copied
197 // through the sysroot uplifting.
198 compiler: builder.compiler_for(builder.top_stage, builder.config.build, self.target),
3b2f2976 199 target: self.target
fc512014
XL
200 }).expect("missing analysis");
201 install_sh(builder, "analysis", self.compiler.stage, Some(self.target), &tarball);
3b2f2976 202 };
3b2f2976 203 Rustc, "src/librustc", true, only_hosts: true, {
fc512014 204 let tarball = builder.ensure(dist::Rustc {
60c5eb7d 205 compiler: builder.compiler(builder.top_stage, self.target),
3b2f2976 206 });
fc512014 207 install_sh(builder, "rustc", self.compiler.stage, Some(self.target), &tarball);
3b2f2976
XL
208 };
209);
0531ce1d
XL
210
211#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
212pub struct Src {
213 pub stage: u32,
214}
215
216impl Step for Src {
217 type Output = ();
218 const DEFAULT: bool = true;
219 const ONLY_HOSTS: bool = true;
220
9fa01778 221 fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
0531ce1d 222 let config = &run.builder.config;
dc9dc135 223 let cond = config.extended && config.tools.as_ref().map_or(true, |t| t.contains("src"));
0531ce1d
XL
224 run.path("src").default_condition(cond)
225 }
226
9fa01778 227 fn make_run(run: RunConfig<'_>) {
dc9dc135 228 run.builder.ensure(Src { stage: run.builder.top_stage });
0531ce1d
XL
229 }
230
9fa01778 231 fn run(self, builder: &Builder<'_>) {
fc512014
XL
232 let tarball = builder.ensure(dist::Src);
233 install_sh(builder, "src", self.stage, None, &tarball);
0531ce1d
XL
234 }
235}