]>
Commit | Line | Data |
---|---|---|
c30ab7b3 SL |
1 | // Copyright 2016 The Rust Project Developers. See the COPYRIGHT |
2 | // file at the top-level directory of this distribution and at | |
3 | // http://rust-lang.org/COPYRIGHT. | |
4 | // | |
5 | // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | |
6 | // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | |
7 | // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | |
8 | // option. This file may not be copied, modified, or distributed | |
9 | // except according to those terms. | |
10 | ||
11 | //! Implementation of the install aspects of the compiler. | |
12 | //! | |
13 | //! This module is responsible for installing the standard library, | |
14 | //! compiler, and documentation. | |
15 | ||
32a655c1 | 16 | use std::env; |
c30ab7b3 | 17 | use std::fs; |
32a655c1 | 18 | use std::path::{Path, PathBuf, Component}; |
c30ab7b3 SL |
19 | use std::process::Command; |
20 | ||
3b2f2976 | 21 | use dist::{self, pkgname, sanitize_sh, tmpdir}; |
7cac9316 | 22 | |
3b2f2976 XL |
23 | use builder::{Builder, RunConfig, ShouldRun, Step}; |
24 | use cache::Interned; | |
2c00a5a8 | 25 | use config::Config; |
7cac9316 | 26 | |
3b2f2976 XL |
27 | pub fn install_docs(builder: &Builder, stage: u32, host: Interned<String>) { |
28 | install_sh(builder, "docs", "rust-docs", stage, Some(host)); | |
29 | } | |
cc61c64b | 30 | |
abe05a73 XL |
31 | pub fn install_std(builder: &Builder, stage: u32, target: Interned<String>) { |
32 | install_sh(builder, "std", "rust-std", stage, Some(target)); | |
3b2f2976 | 33 | } |
c30ab7b3 | 34 | |
3b2f2976 XL |
35 | pub fn install_cargo(builder: &Builder, stage: u32, host: Interned<String>) { |
36 | install_sh(builder, "cargo", "cargo", stage, Some(host)); | |
37 | } | |
7cac9316 | 38 | |
3b2f2976 XL |
39 | pub fn install_rls(builder: &Builder, stage: u32, host: Interned<String>) { |
40 | install_sh(builder, "rls", "rls", stage, Some(host)); | |
41 | } | |
8faf50e0 XL |
42 | pub fn install_clippy(builder: &Builder, stage: u32, host: Interned<String>) { |
43 | install_sh(builder, "clippy", "clippy", stage, Some(host)); | |
44 | } | |
7cac9316 | 45 | |
abe05a73 XL |
46 | pub fn install_rustfmt(builder: &Builder, stage: u32, host: Interned<String>) { |
47 | install_sh(builder, "rustfmt", "rustfmt", stage, Some(host)); | |
48 | } | |
49 | ||
3b2f2976 XL |
50 | pub fn install_analysis(builder: &Builder, stage: u32, host: Interned<String>) { |
51 | install_sh(builder, "analysis", "rust-analysis", stage, Some(host)); | |
52 | } | |
7cac9316 | 53 | |
3b2f2976 XL |
54 | pub fn install_src(builder: &Builder, stage: u32) { |
55 | install_sh(builder, "src", "rust-src", stage, None); | |
56 | } | |
57 | pub fn install_rustc(builder: &Builder, stage: u32, host: Interned<String>) { | |
58 | install_sh(builder, "rustc", "rustc", stage, Some(host)); | |
59 | } | |
7cac9316 | 60 | |
3b2f2976 XL |
61 | fn install_sh( |
62 | builder: &Builder, | |
63 | package: &str, | |
64 | name: &str, | |
65 | stage: u32, | |
66 | host: Option<Interned<String>> | |
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 XL |
74 | let bindir_default = PathBuf::from("bin"); |
75 | let libdir_default = PathBuf::from("lib"); | |
2c00a5a8 | 76 | let mandir_default = datadir_default.join("man"); |
83c7162d | 77 | let prefix = builder.config.prefix.as_ref().map_or(prefix_default, |p| { |
8faf50e0 | 78 | fs::canonicalize(p).unwrap_or_else(|_| panic!("could not canonicalize {}", p.display())) |
83c7162d XL |
79 | }); |
80 | let sysconfdir = builder.config.sysconfdir.as_ref().unwrap_or(&sysconfdir_default); | |
81 | let datadir = builder.config.datadir.as_ref().unwrap_or(&datadir_default); | |
82 | let docdir = builder.config.docdir.as_ref().unwrap_or(&docdir_default); | |
83 | let bindir = builder.config.bindir.as_ref().unwrap_or(&bindir_default); | |
84 | let libdir = builder.config.libdir.as_ref().unwrap_or(&libdir_default); | |
85 | let mandir = builder.config.mandir.as_ref().unwrap_or(&mandir_default); | |
3b2f2976 XL |
86 | |
87 | let sysconfdir = prefix.join(sysconfdir); | |
2c00a5a8 | 88 | let datadir = prefix.join(datadir); |
3b2f2976 XL |
89 | let docdir = prefix.join(docdir); |
90 | let bindir = prefix.join(bindir); | |
91 | let libdir = prefix.join(libdir); | |
92 | let mandir = prefix.join(mandir); | |
93 | ||
94 | let destdir = env::var_os("DESTDIR").map(PathBuf::from); | |
95 | ||
96 | let prefix = add_destdir(&prefix, &destdir); | |
97 | let sysconfdir = add_destdir(&sysconfdir, &destdir); | |
2c00a5a8 | 98 | let datadir = add_destdir(&datadir, &destdir); |
3b2f2976 XL |
99 | let docdir = add_destdir(&docdir, &destdir); |
100 | let bindir = add_destdir(&bindir, &destdir); | |
101 | let libdir = add_destdir(&libdir, &destdir); | |
102 | let mandir = add_destdir(&mandir, &destdir); | |
103 | ||
83c7162d | 104 | let empty_dir = builder.out.join("tmp/empty_dir"); |
3b2f2976 XL |
105 | |
106 | t!(fs::create_dir_all(&empty_dir)); | |
107 | let package_name = if let Some(host) = host { | |
83c7162d | 108 | format!("{}-{}", pkgname(builder, name), host) |
3b2f2976 | 109 | } else { |
83c7162d | 110 | pkgname(builder, name) |
3b2f2976 | 111 | }; |
7cac9316 | 112 | |
3b2f2976 XL |
113 | let mut cmd = Command::new("sh"); |
114 | cmd.current_dir(&empty_dir) | |
83c7162d | 115 | .arg(sanitize_sh(&tmpdir(builder).join(&package_name).join("install.sh"))) |
3b2f2976 XL |
116 | .arg(format!("--prefix={}", sanitize_sh(&prefix))) |
117 | .arg(format!("--sysconfdir={}", sanitize_sh(&sysconfdir))) | |
2c00a5a8 | 118 | .arg(format!("--datadir={}", sanitize_sh(&datadir))) |
3b2f2976 XL |
119 | .arg(format!("--docdir={}", sanitize_sh(&docdir))) |
120 | .arg(format!("--bindir={}", sanitize_sh(&bindir))) | |
121 | .arg(format!("--libdir={}", sanitize_sh(&libdir))) | |
122 | .arg(format!("--mandir={}", sanitize_sh(&mandir))) | |
123 | .arg("--disable-ldconfig"); | |
83c7162d | 124 | builder.run(&mut cmd); |
3b2f2976 | 125 | t!(fs::remove_dir_all(&empty_dir)); |
c30ab7b3 | 126 | } |
32a655c1 SL |
127 | |
128 | fn add_destdir(path: &Path, destdir: &Option<PathBuf>) -> PathBuf { | |
129 | let mut ret = match *destdir { | |
130 | Some(ref dest) => dest.clone(), | |
131 | None => return path.to_path_buf(), | |
132 | }; | |
133 | for part in path.components() { | |
134 | match part { | |
135 | Component::Normal(s) => ret.push(s), | |
136 | _ => {} | |
137 | } | |
138 | } | |
041b39d2 | 139 | ret |
32a655c1 | 140 | } |
3b2f2976 XL |
141 | |
142 | macro_rules! install { | |
143 | (($sel:ident, $builder:ident, $_config:ident), | |
144 | $($name:ident, | |
145 | $path:expr, | |
146 | $default_cond:expr, | |
147 | only_hosts: $only_hosts:expr, | |
148 | $run_item:block $(, $c:ident)*;)+) => { | |
149 | $( | |
150 | #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] | |
151 | pub struct $name { | |
152 | pub stage: u32, | |
153 | pub target: Interned<String>, | |
154 | pub host: Interned<String>, | |
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 | } | |
163 | ||
164 | #[allow(dead_code)] | |
165 | fn should_install(builder: &Builder) -> bool { | |
166 | builder.config.tools.as_ref().map_or(false, |t| t.contains($path)) | |
167 | } | |
168 | } | |
169 | ||
3b2f2976 XL |
170 | impl Step for $name { |
171 | type Output = (); | |
172 | const DEFAULT: bool = true; | |
3b2f2976 XL |
173 | const ONLY_HOSTS: bool = $only_hosts; |
174 | $(const $c: bool = true;)* | |
175 | ||
176 | fn should_run(run: ShouldRun) -> ShouldRun { | |
177 | let $_config = &run.builder.config; | |
178 | run.path($path).default_condition($default_cond) | |
179 | } | |
180 | ||
181 | fn make_run(run: RunConfig) { | |
182 | run.builder.ensure($name { | |
183 | stage: run.builder.top_stage, | |
184 | target: run.target, | |
83c7162d | 185 | host: run.builder.config.build, |
3b2f2976 XL |
186 | }); |
187 | } | |
188 | ||
189 | fn run($sel, $builder: &Builder) { | |
190 | $run_item | |
191 | } | |
192 | })+ | |
193 | } | |
194 | } | |
195 | ||
196 | install!((self, builder, _config), | |
197 | Docs, "src/doc", _config.docs, only_hosts: false, { | |
198 | builder.ensure(dist::Docs { stage: self.stage, host: self.target }); | |
199 | install_docs(builder, self.stage, self.target); | |
200 | }; | |
201 | Std, "src/libstd", true, only_hosts: true, { | |
83c7162d | 202 | for target in &builder.targets { |
abe05a73 XL |
203 | builder.ensure(dist::Std { |
204 | compiler: builder.compiler(self.stage, self.host), | |
205 | target: *target | |
206 | }); | |
207 | install_std(builder, self.stage, *target); | |
208 | } | |
3b2f2976 | 209 | }; |
2c00a5a8 | 210 | Cargo, "cargo", Self::should_build(_config), only_hosts: true, { |
3b2f2976 XL |
211 | builder.ensure(dist::Cargo { stage: self.stage, target: self.target }); |
212 | install_cargo(builder, self.stage, self.target); | |
213 | }; | |
2c00a5a8 XL |
214 | Rls, "rls", Self::should_build(_config), only_hosts: true, { |
215 | if builder.ensure(dist::Rls { stage: self.stage, target: self.target }).is_some() || | |
216 | Self::should_install(builder) { | |
abe05a73 XL |
217 | install_rls(builder, self.stage, self.target); |
218 | } else { | |
83c7162d | 219 | builder.info(&format!("skipping Install RLS stage{} ({})", self.stage, self.target)); |
abe05a73 XL |
220 | } |
221 | }; | |
8faf50e0 XL |
222 | Clippy, "clippy", Self::should_build(_config), only_hosts: true, { |
223 | if builder.ensure(dist::Clippy { stage: self.stage, target: self.target }).is_some() || | |
224 | Self::should_install(builder) { | |
225 | install_clippy(builder, self.stage, self.target); | |
226 | } else { | |
227 | builder.info(&format!("skipping Install clippy stage{} ({})", self.stage, self.target)); | |
228 | } | |
229 | }; | |
2c00a5a8 XL |
230 | Rustfmt, "rustfmt", Self::should_build(_config), only_hosts: true, { |
231 | if builder.ensure(dist::Rustfmt { stage: self.stage, target: self.target }).is_some() || | |
232 | Self::should_install(builder) { | |
abe05a73 XL |
233 | install_rustfmt(builder, self.stage, self.target); |
234 | } else { | |
83c7162d XL |
235 | builder.info( |
236 | &format!("skipping Install Rustfmt stage{} ({})", self.stage, self.target)); | |
abe05a73 | 237 | } |
3b2f2976 | 238 | }; |
2c00a5a8 | 239 | Analysis, "analysis", Self::should_build(_config), only_hosts: false, { |
3b2f2976 XL |
240 | builder.ensure(dist::Analysis { |
241 | compiler: builder.compiler(self.stage, self.host), | |
242 | target: self.target | |
243 | }); | |
244 | install_analysis(builder, self.stage, self.target); | |
245 | }; | |
3b2f2976 XL |
246 | Rustc, "src/librustc", true, only_hosts: true, { |
247 | builder.ensure(dist::Rustc { | |
248 | compiler: builder.compiler(self.stage, self.target), | |
249 | }); | |
250 | install_rustc(builder, self.stage, self.target); | |
251 | }; | |
252 | ); | |
0531ce1d XL |
253 | |
254 | #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] | |
255 | pub struct Src { | |
256 | pub stage: u32, | |
257 | } | |
258 | ||
259 | impl Step for Src { | |
260 | type Output = (); | |
261 | const DEFAULT: bool = true; | |
262 | const ONLY_HOSTS: bool = true; | |
263 | ||
264 | fn should_run(run: ShouldRun) -> ShouldRun { | |
265 | let config = &run.builder.config; | |
266 | let cond = config.extended && | |
267 | config.tools.as_ref().map_or(true, |t| t.contains("src")); | |
268 | run.path("src").default_condition(cond) | |
269 | } | |
270 | ||
271 | fn make_run(run: RunConfig) { | |
272 | run.builder.ensure(Src { | |
273 | stage: run.builder.top_stage, | |
274 | }); | |
275 | } | |
276 | ||
277 | fn run(self, builder: &Builder) { | |
278 | builder.ensure(dist::Src); | |
279 | install_src(builder, self.stage); | |
280 | } | |
281 | } |