]>
Commit | Line | Data |
---|---|---|
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 | 6 | use std::env; |
c30ab7b3 | 7 | use std::fs; |
dc9dc135 | 8 | use std::path::{Component, Path, PathBuf}; |
c30ab7b3 SL |
9 | use std::process::Command; |
10 | ||
48663c56 XL |
11 | use build_helper::t; |
12 | ||
0731742a | 13 | use crate::dist::{self, pkgname, sanitize_sh, tmpdir}; |
dc9dc135 | 14 | use crate::Compiler; |
7cac9316 | 15 | |
0731742a | 16 | use crate::builder::{Builder, RunConfig, ShouldRun, Step}; |
3dfed10e | 17 | use crate::config::{Config, TargetSelection}; |
7cac9316 | 18 | |
3dfed10e | 19 | pub fn install_docs(builder: &Builder<'_>, stage: u32, host: TargetSelection) { |
3b2f2976 XL |
20 | install_sh(builder, "docs", "rust-docs", stage, Some(host)); |
21 | } | |
cc61c64b | 22 | |
3dfed10e | 23 | pub fn install_std(builder: &Builder<'_>, stage: u32, target: TargetSelection) { |
abe05a73 | 24 | install_sh(builder, "std", "rust-std", stage, Some(target)); |
3b2f2976 | 25 | } |
c30ab7b3 | 26 | |
3dfed10e | 27 | pub fn install_cargo(builder: &Builder<'_>, stage: u32, host: TargetSelection) { |
3b2f2976 XL |
28 | install_sh(builder, "cargo", "cargo", stage, Some(host)); |
29 | } | |
7cac9316 | 30 | |
3dfed10e | 31 | pub fn install_rls(builder: &Builder<'_>, stage: u32, host: TargetSelection) { |
3b2f2976 XL |
32 | install_sh(builder, "rls", "rls", stage, Some(host)); |
33 | } | |
3dfed10e XL |
34 | |
35 | pub fn install_rust_analyzer(builder: &Builder<'_>, stage: u32, host: TargetSelection) { | |
f035d41b XL |
36 | install_sh(builder, "rust-analyzer", "rust-analyzer", stage, Some(host)); |
37 | } | |
3dfed10e XL |
38 | |
39 | pub fn install_clippy(builder: &Builder<'_>, stage: u32, host: TargetSelection) { | |
8faf50e0 XL |
40 | install_sh(builder, "clippy", "clippy", stage, Some(host)); |
41 | } | |
3dfed10e | 42 | pub fn install_miri(builder: &Builder<'_>, stage: u32, host: TargetSelection) { |
0731742a XL |
43 | install_sh(builder, "miri", "miri", stage, Some(host)); |
44 | } | |
7cac9316 | 45 | |
3dfed10e | 46 | pub fn install_rustfmt(builder: &Builder<'_>, stage: u32, host: TargetSelection) { |
abe05a73 XL |
47 | install_sh(builder, "rustfmt", "rustfmt", stage, Some(host)); |
48 | } | |
49 | ||
3dfed10e | 50 | pub fn install_analysis(builder: &Builder<'_>, stage: u32, host: TargetSelection) { |
3b2f2976 XL |
51 | install_sh(builder, "analysis", "rust-analysis", stage, Some(host)); |
52 | } | |
7cac9316 | 53 | |
9fa01778 | 54 | pub fn install_src(builder: &Builder<'_>, stage: u32) { |
3b2f2976 XL |
55 | install_sh(builder, "src", "rust-src", stage, None); |
56 | } | |
3dfed10e | 57 | pub fn install_rustc(builder: &Builder<'_>, stage: u32, host: TargetSelection) { |
3b2f2976 XL |
58 | install_sh(builder, "rustc", "rustc", stage, Some(host)); |
59 | } | |
7cac9316 | 60 | |
3b2f2976 | 61 | fn install_sh( |
9fa01778 | 62 | builder: &Builder<'_>, |
3b2f2976 XL |
63 | package: &str, |
64 | name: &str, | |
65 | stage: u32, | |
3dfed10e | 66 | host: Option<TargetSelection>, |
3b2f2976 | 67 | ) { |
83c7162d | 68 | builder.info(&format!("Install {} stage{} ({:?})", package, stage, host)); |
3b2f2976 XL |
69 | |
70 | let prefix_default = PathBuf::from("/usr/local"); | |
71 | let sysconfdir_default = PathBuf::from("/etc"); | |
2c00a5a8 XL |
72 | let datadir_default = PathBuf::from("share"); |
73 | let docdir_default = datadir_default.join("doc/rust"); | |
3b2f2976 | 74 | let libdir_default = PathBuf::from("lib"); |
2c00a5a8 | 75 | let mandir_default = datadir_default.join("man"); |
83c7162d | 76 | let prefix = builder.config.prefix.as_ref().map_or(prefix_default, |p| { |
f035d41b XL |
77 | fs::create_dir_all(p) |
78 | .unwrap_or_else(|err| panic!("could not create {}: {}", p.display(), err)); | |
79 | fs::canonicalize(p) | |
80 | .unwrap_or_else(|err| panic!("could not canonicalize {}: {}", p.display(), err)) | |
83c7162d XL |
81 | }); |
82 | let sysconfdir = builder.config.sysconfdir.as_ref().unwrap_or(&sysconfdir_default); | |
83 | let datadir = builder.config.datadir.as_ref().unwrap_or(&datadir_default); | |
84 | let docdir = builder.config.docdir.as_ref().unwrap_or(&docdir_default); | |
e1599b0c | 85 | let bindir = &builder.config.bindir; |
83c7162d XL |
86 | let libdir = builder.config.libdir.as_ref().unwrap_or(&libdir_default); |
87 | let mandir = builder.config.mandir.as_ref().unwrap_or(&mandir_default); | |
3b2f2976 XL |
88 | |
89 | let sysconfdir = prefix.join(sysconfdir); | |
2c00a5a8 | 90 | let datadir = prefix.join(datadir); |
3b2f2976 XL |
91 | let docdir = prefix.join(docdir); |
92 | let bindir = prefix.join(bindir); | |
93 | let libdir = prefix.join(libdir); | |
94 | let mandir = prefix.join(mandir); | |
95 | ||
96 | let destdir = env::var_os("DESTDIR").map(PathBuf::from); | |
97 | ||
98 | let prefix = add_destdir(&prefix, &destdir); | |
99 | let sysconfdir = add_destdir(&sysconfdir, &destdir); | |
2c00a5a8 | 100 | let datadir = add_destdir(&datadir, &destdir); |
3b2f2976 XL |
101 | let docdir = add_destdir(&docdir, &destdir); |
102 | let bindir = add_destdir(&bindir, &destdir); | |
103 | let libdir = add_destdir(&libdir, &destdir); | |
104 | let mandir = add_destdir(&mandir, &destdir); | |
105 | ||
83c7162d | 106 | let empty_dir = builder.out.join("tmp/empty_dir"); |
3b2f2976 XL |
107 | |
108 | t!(fs::create_dir_all(&empty_dir)); | |
109 | let package_name = if let Some(host) = host { | |
3dfed10e | 110 | format!("{}-{}", pkgname(builder, name), host.triple) |
3b2f2976 | 111 | } else { |
83c7162d | 112 | pkgname(builder, name) |
3b2f2976 | 113 | }; |
7cac9316 | 114 | |
3b2f2976 XL |
115 | let mut cmd = Command::new("sh"); |
116 | cmd.current_dir(&empty_dir) | |
83c7162d | 117 | .arg(sanitize_sh(&tmpdir(builder).join(&package_name).join("install.sh"))) |
3b2f2976 XL |
118 | .arg(format!("--prefix={}", sanitize_sh(&prefix))) |
119 | .arg(format!("--sysconfdir={}", sanitize_sh(&sysconfdir))) | |
2c00a5a8 | 120 | .arg(format!("--datadir={}", sanitize_sh(&datadir))) |
3b2f2976 XL |
121 | .arg(format!("--docdir={}", sanitize_sh(&docdir))) |
122 | .arg(format!("--bindir={}", sanitize_sh(&bindir))) | |
123 | .arg(format!("--libdir={}", sanitize_sh(&libdir))) | |
124 | .arg(format!("--mandir={}", sanitize_sh(&mandir))) | |
125 | .arg("--disable-ldconfig"); | |
83c7162d | 126 | builder.run(&mut cmd); |
3b2f2976 | 127 | t!(fs::remove_dir_all(&empty_dir)); |
c30ab7b3 | 128 | } |
32a655c1 SL |
129 | |
130 | fn add_destdir(path: &Path, destdir: &Option<PathBuf>) -> PathBuf { | |
131 | let mut ret = match *destdir { | |
132 | Some(ref dest) => dest.clone(), | |
133 | None => return path.to_path_buf(), | |
134 | }; | |
135 | for part in path.components() { | |
74b04a01 XL |
136 | if let Component::Normal(s) = part { |
137 | ret.push(s) | |
32a655c1 SL |
138 | } |
139 | } | |
041b39d2 | 140 | ret |
32a655c1 | 141 | } |
3b2f2976 XL |
142 | |
143 | macro_rules! install { | |
144 | (($sel:ident, $builder:ident, $_config:ident), | |
145 | $($name:ident, | |
146 | $path:expr, | |
147 | $default_cond:expr, | |
148 | only_hosts: $only_hosts:expr, | |
149 | $run_item:block $(, $c:ident)*;)+) => { | |
150 | $( | |
151 | #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] | |
152 | pub struct $name { | |
dc9dc135 | 153 | pub compiler: Compiler, |
3dfed10e | 154 | pub target: TargetSelection, |
3b2f2976 XL |
155 | } |
156 | ||
2c00a5a8 XL |
157 | impl $name { |
158 | #[allow(dead_code)] | |
159 | fn should_build(config: &Config) -> bool { | |
160 | config.extended && config.tools.as_ref() | |
161 | .map_or(true, |t| t.contains($path)) | |
162 | } | |
2c00a5a8 XL |
163 | } |
164 | ||
3b2f2976 XL |
165 | impl Step for $name { |
166 | type Output = (); | |
167 | const DEFAULT: bool = true; | |
3b2f2976 XL |
168 | const ONLY_HOSTS: bool = $only_hosts; |
169 | $(const $c: bool = true;)* | |
170 | ||
9fa01778 | 171 | fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { |
3b2f2976 XL |
172 | let $_config = &run.builder.config; |
173 | run.path($path).default_condition($default_cond) | |
174 | } | |
175 | ||
9fa01778 | 176 | fn make_run(run: RunConfig<'_>) { |
3b2f2976 | 177 | run.builder.ensure($name { |
dc9dc135 | 178 | compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.build), |
3b2f2976 | 179 | target: run.target, |
3b2f2976 XL |
180 | }); |
181 | } | |
182 | ||
9fa01778 | 183 | fn run($sel, $builder: &Builder<'_>) { |
3b2f2976 XL |
184 | $run_item |
185 | } | |
186 | })+ | |
187 | } | |
188 | } | |
189 | ||
190 | install!((self, builder, _config), | |
191 | Docs, "src/doc", _config.docs, only_hosts: false, { | |
dc9dc135 XL |
192 | builder.ensure(dist::Docs { host: self.target }); |
193 | install_docs(builder, self.compiler.stage, self.target); | |
3b2f2976 | 194 | }; |
1b1a35ee | 195 | Std, "library/std", true, only_hosts: false, { |
83c7162d | 196 | for target in &builder.targets { |
abe05a73 | 197 | builder.ensure(dist::Std { |
dc9dc135 | 198 | compiler: self.compiler, |
abe05a73 XL |
199 | target: *target |
200 | }); | |
dc9dc135 | 201 | install_std(builder, self.compiler.stage, *target); |
abe05a73 | 202 | } |
3b2f2976 | 203 | }; |
2c00a5a8 | 204 | Cargo, "cargo", Self::should_build(_config), only_hosts: true, { |
dc9dc135 XL |
205 | builder.ensure(dist::Cargo { compiler: self.compiler, target: self.target }); |
206 | install_cargo(builder, self.compiler.stage, self.target); | |
3b2f2976 | 207 | }; |
2c00a5a8 | 208 | Rls, "rls", Self::should_build(_config), only_hosts: true, { |
f9652781 | 209 | if builder.ensure(dist::Rls { compiler: self.compiler, target: self.target }).is_some() { |
dc9dc135 | 210 | install_rls(builder, self.compiler.stage, self.target); |
abe05a73 | 211 | } else { |
dc9dc135 XL |
212 | builder.info( |
213 | &format!("skipping Install RLS stage{} ({})", self.compiler.stage, self.target), | |
214 | ); | |
abe05a73 XL |
215 | } |
216 | }; | |
f035d41b XL |
217 | RustAnalyzer, "rust-analyzer", Self::should_build(_config), only_hosts: true, { |
218 | builder.ensure(dist::RustAnalyzer { compiler: self.compiler, target: self.target }); | |
f9652781 | 219 | install_rust_analyzer(builder, self.compiler.stage, self.target); |
f035d41b | 220 | }; |
8faf50e0 | 221 | Clippy, "clippy", Self::should_build(_config), only_hosts: true, { |
f9f354fc | 222 | builder.ensure(dist::Clippy { compiler: self.compiler, target: self.target }); |
f9652781 | 223 | install_clippy(builder, self.compiler.stage, self.target); |
8faf50e0 | 224 | }; |
0731742a | 225 | Miri, "miri", Self::should_build(_config), only_hosts: true, { |
f9652781 | 226 | if builder.ensure(dist::Miri { compiler: self.compiler, target: self.target }).is_some() { |
dc9dc135 | 227 | install_miri(builder, self.compiler.stage, self.target); |
0731742a | 228 | } else { |
dc9dc135 XL |
229 | builder.info( |
230 | &format!("skipping Install miri stage{} ({})", self.compiler.stage, self.target), | |
231 | ); | |
0731742a XL |
232 | } |
233 | }; | |
2c00a5a8 | 234 | Rustfmt, "rustfmt", Self::should_build(_config), only_hosts: true, { |
dc9dc135 XL |
235 | if builder.ensure(dist::Rustfmt { |
236 | compiler: self.compiler, | |
237 | target: self.target | |
f9652781 | 238 | }).is_some() { |
dc9dc135 | 239 | install_rustfmt(builder, self.compiler.stage, self.target); |
abe05a73 | 240 | } else { |
83c7162d | 241 | builder.info( |
dc9dc135 XL |
242 | &format!("skipping Install Rustfmt stage{} ({})", self.compiler.stage, self.target), |
243 | ); | |
abe05a73 | 244 | } |
3b2f2976 | 245 | }; |
2c00a5a8 | 246 | Analysis, "analysis", Self::should_build(_config), only_hosts: false, { |
3b2f2976 | 247 | builder.ensure(dist::Analysis { |
dc9dc135 XL |
248 | // Find the actual compiler (handling the full bootstrap option) which |
249 | // produced the save-analysis data because that data isn't copied | |
250 | // through the sysroot uplifting. | |
251 | compiler: builder.compiler_for(builder.top_stage, builder.config.build, self.target), | |
3b2f2976 XL |
252 | target: self.target |
253 | }); | |
dc9dc135 | 254 | install_analysis(builder, self.compiler.stage, self.target); |
3b2f2976 | 255 | }; |
3b2f2976 XL |
256 | Rustc, "src/librustc", true, only_hosts: true, { |
257 | builder.ensure(dist::Rustc { | |
60c5eb7d | 258 | compiler: builder.compiler(builder.top_stage, self.target), |
3b2f2976 | 259 | }); |
dc9dc135 | 260 | install_rustc(builder, self.compiler.stage, self.target); |
3b2f2976 XL |
261 | }; |
262 | ); | |
0531ce1d XL |
263 | |
264 | #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] | |
265 | pub struct Src { | |
266 | pub stage: u32, | |
267 | } | |
268 | ||
269 | impl Step for Src { | |
270 | type Output = (); | |
271 | const DEFAULT: bool = true; | |
272 | const ONLY_HOSTS: bool = true; | |
273 | ||
9fa01778 | 274 | fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { |
0531ce1d | 275 | let config = &run.builder.config; |
dc9dc135 | 276 | let cond = config.extended && config.tools.as_ref().map_or(true, |t| t.contains("src")); |
0531ce1d XL |
277 | run.path("src").default_condition(cond) |
278 | } | |
279 | ||
9fa01778 | 280 | fn make_run(run: RunConfig<'_>) { |
dc9dc135 | 281 | run.builder.ensure(Src { stage: run.builder.top_stage }); |
0531ce1d XL |
282 | } |
283 | ||
9fa01778 | 284 | fn run(self, builder: &Builder<'_>) { |
0531ce1d XL |
285 | builder.ensure(dist::Src); |
286 | install_src(builder, self.stage); | |
287 | } | |
288 | } |