]> git.lizzy.rs Git - rust.git/blob - src/bootstrap/tool.rs
Fixes warnings and errors introduced while moving code around
[rust.git] / src / bootstrap / tool.rs
1 // Copyright 2017 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 use std::env;
12 use std::path::{Path, PathBuf};
13 use std::process::Command;
14
15 use Mode;
16 use builder::{Step, Builder};
17 use util::{exe, add_lib_path};
18 use compile::{self, libtest_stamp, libstd_stamp, librustc_stamp, Rustc};
19 use native;
20 use channel::GitInfo;
21
22 //// ========================================================================
23 //// Build tools
24 ////
25 //// Tools used during the build system but not shipped
26 //// "pseudo rule" which represents completely cleaning out the tools dir in
27 //// one stage. This needs to happen whenever a dependency changes (e.g.
28 //// libstd, libtest, librustc) and all of the tool compilations above will
29 //// be sequenced after this rule.
30 //rules.build("maybe-clean-tools", "path/to/nowhere")
31 //     .after("librustc-tool")
32 //     .after("libtest-tool")
33 //     .after("libstd-tool");
34 //
35 //rules.build("librustc-tool", "path/to/nowhere")
36 //     .dep(|s| s.name("librustc"))
37 //     .run(move |s| compile::maybe_clean_tools(build, s.stage, s.target, Mode::Librustc));
38 //rules.build("libtest-tool", "path/to/nowhere")
39 //     .dep(|s| s.name("libtest"))
40 //     .run(move |s| compile::maybe_clean_tools(build, s.stage, s.target, Mode::Libtest));
41 //rules.build("libstd-tool", "path/to/nowhere")
42 //     .dep(|s| s.name("libstd"))
43 //     .run(move |s| compile::maybe_clean_tools(build, s.stage, s.target, Mode::Libstd));
44 //
45
46 #[derive(Serialize)]
47 pub struct CleanTools<'a> {
48     pub stage: u32,
49     pub target: &'a str,
50     pub mode: Mode,
51 }
52
53 impl<'a> Step<'a> for CleanTools<'a> {
54     type Output = ();
55
56     /// Build a tool in `src/tools`
57     ///
58     /// This will build the specified tool with the specified `host` compiler in
59     /// `stage` into the normal cargo output directory.
60     fn run(self, builder: &Builder) {
61         let build = builder.build;
62         let stage = self.stage;
63         let target = self.target;
64         let mode = self.mode;
65
66         let compiler = builder.compiler(stage, &build.build);
67
68         let stamp = match mode {
69             Mode::Libstd => libstd_stamp(build, compiler, target),
70             Mode::Libtest => libtest_stamp(build, compiler, target),
71             Mode::Librustc => librustc_stamp(build, compiler, target),
72             _ => panic!(),
73         };
74         let out_dir = build.cargo_out(compiler, Mode::Tool, target);
75         build.clear_if_dirty(&out_dir, &stamp);
76     }
77 }
78
79 #[derive(Serialize)]
80 pub struct ToolBuild<'a> {
81     pub stage: u32,
82     pub target: &'a str,
83     pub tool: &'a str,
84     pub mode: Mode,
85 }
86
87 impl<'a> Step<'a> for ToolBuild<'a> {
88     type Output = PathBuf;
89
90     /// Build a tool in `src/tools`
91     ///
92     /// This will build the specified tool with the specified `host` compiler in
93     /// `stage` into the normal cargo output directory.
94     fn run(self, builder: &Builder) -> PathBuf {
95         let build = builder.build;
96         let stage = self.stage;
97         let target = self.target;
98         let tool = self.tool;
99
100         let compiler = builder.compiler(stage, &build.build);
101         builder.ensure(CleanTools { stage, target, mode: self.mode });
102         match self.mode {
103             Mode::Libstd => builder.ensure(compile::Std { compiler, target }),
104             Mode::Libtest => builder.ensure(compile::Test { compiler, target }),
105             Mode::Librustc => builder.ensure(compile::Rustc { compiler, target }),
106             Mode::Tool => panic!("unexpected Mode::Tool for tool build")
107         }
108
109         let _folder = build.fold_output(|| format!("stage{}-{}", stage, tool));
110         println!("Building stage{} tool {} ({})", stage, tool, target);
111
112         let mut cargo = build.cargo(compiler, Mode::Tool, target, "build");
113         let dir = build.src.join("src/tools").join(tool);
114         cargo.arg("--manifest-path").arg(dir.join("Cargo.toml"));
115
116         // We don't want to build tools dynamically as they'll be running across
117         // stages and such and it's just easier if they're not dynamically linked.
118         cargo.env("RUSTC_NO_PREFER_DYNAMIC", "1");
119
120         if let Some(dir) = build.openssl_install_dir(target) {
121             cargo.env("OPENSSL_STATIC", "1");
122             cargo.env("OPENSSL_DIR", dir);
123             cargo.env("LIBZ_SYS_STATIC", "1");
124         }
125
126         cargo.env("CFG_RELEASE_CHANNEL", &build.config.channel);
127
128         let info = GitInfo::new(&dir);
129         if let Some(sha) = info.sha() {
130             cargo.env("CFG_COMMIT_HASH", sha);
131         }
132         if let Some(sha_short) = info.sha_short() {
133             cargo.env("CFG_SHORT_COMMIT_HASH", sha_short);
134         }
135         if let Some(date) = info.commit_date() {
136             cargo.env("CFG_COMMIT_DATE", date);
137         }
138
139         build.run(&mut cargo);
140         build.cargo_out(compiler, Mode::Tool, target).join(exe(tool, compiler.host))
141     }
142 }
143
144 macro_rules! tool {
145     ($($name:ident, $path:expr, $tool_name:expr, $mode:expr;)+) => {
146         #[derive(Copy, Clone)]
147         pub enum Tool {
148             $(
149                 $name,
150             )+
151         }
152
153         impl<'a> Builder<'a> {
154             pub fn tool_exe(&self, tool: Tool) -> PathBuf {
155                 match tool {
156                     $(Tool::$name =>
157                         self.ensure($name {
158                             stage: 0,
159                             target: &self.build.build,
160                         }),
161                     )+
162                 }
163             }
164         }
165
166         $(
167         #[derive(Serialize)]
168         pub struct $name<'a> {
169             pub stage: u32,
170             pub target: &'a str,
171         }
172
173         impl<'a> Step<'a> for $name<'a> {
174             type Output = PathBuf;
175
176             fn should_run(_builder: &Builder, path: &Path) -> bool {
177                 path.ends_with($path)
178             }
179
180             fn make_run(builder: &Builder, _path: Option<&Path>, _host: &str, target: &str) {
181                 builder.ensure($name {
182                     stage: builder.top_stage,
183                     target,
184                 });
185             }
186
187             fn run(self, builder: &Builder) -> PathBuf {
188                 builder.ensure(ToolBuild {
189                     stage: self.stage,
190                     target: self.target,
191                     tool: $tool_name,
192                     mode: $mode,
193                 })
194             }
195         }
196         )+
197     }
198 }
199
200 tool!(
201     // rules.build("tool-rustbook", "src/tools/rustbook")
202     //      .dep(|s| s.name("maybe-clean-tools"))
203     //      .dep(|s| s.name("librustc-tool"))
204     //      .run(move |s| compile::tool(build, s.stage, s.target, "rustbook"));
205     Rustbook, "src/tools/rustbook", "rustbook", Mode::Librustc;
206     // rules.build("tool-error-index", "src/tools/error_index_generator")
207     //      .dep(|s| s.name("maybe-clean-tools"))
208     //      .dep(|s| s.name("librustc-tool"))
209     //      .run(move |s| compile::tool(build, s.stage, s.target, "error_index_generator"));
210     ErrorIndex, "src/tools/error_index_generator", "error_index_generator", Mode::Librustc;
211     // rules.build("tool-unstable-book-gen", "src/tools/unstable-book-gen")
212     //      .dep(|s| s.name("maybe-clean-tools"))
213     //      .dep(|s| s.name("libstd-tool"))
214     //      .run(move |s| compile::tool(build, s.stage, s.target, "unstable-book-gen"));
215     UnstableBookGen, "src/tools/unstable-book-gen", "unstable-book-gen", Mode::Libstd;
216     // rules.build("tool-tidy", "src/tools/tidy")
217     //      .dep(|s| s.name("maybe-clean-tools"))
218     //      .dep(|s| s.name("libstd-tool"))
219     //      .run(move |s| compile::tool(build, s.stage, s.target, "tidy"));
220     Tidy, "src/tools/tidy", "tidy", Mode::Libstd;
221     // rules.build("tool-linkchecker", "src/tools/linkchecker")
222     //      .dep(|s| s.name("maybe-clean-tools"))
223     //      .dep(|s| s.name("libstd-tool"))
224     //      .run(move |s| compile::tool(build, s.stage, s.target, "linkchecker"));
225     Linkchecker, "src/tools/linkchecker", "linkchecker", Mode::Libstd;
226     // rules.build("tool-cargotest", "src/tools/cargotest")
227     //      .dep(|s| s.name("maybe-clean-tools"))
228     //      .dep(|s| s.name("libstd-tool"))
229     //      .run(move |s| compile::tool(build, s.stage, s.target, "cargotest"));
230     CargoTest, "src/tools/cargotest", "cargotest", Mode::Libstd;
231     // rules.build("tool-compiletest", "src/tools/compiletest")
232     //      .dep(|s| s.name("maybe-clean-tools"))
233     //      .dep(|s| s.name("libtest-tool"))
234     //      .run(move |s| compile::tool(build, s.stage, s.target, "compiletest"));
235     Compiletest, "src/tools/compiletest", "compiletest", Mode::Libtest;
236     // rules.build("tool-build-manifest", "src/tools/build-manifest")
237     //      .dep(|s| s.name("maybe-clean-tools"))
238     //      .dep(|s| s.name("libstd-tool"))
239     //      .run(move |s| compile::tool(build, s.stage, s.target, "build-manifest"));
240     BuildManifest, "src/tools/build-manifest", "build-manifest", Mode::Libstd;
241     // rules.build("tool-remote-test-server", "src/tools/remote-test-server")
242     //      .dep(|s| s.name("maybe-clean-tools"))
243     //      .dep(|s| s.name("libstd-tool"))
244     //      .run(move |s| compile::tool(build, s.stage, s.target, "remote-test-server"));
245     RemoteTestServer, "src/tools/remote-test-server", "remote-test-server", Mode::Libstd;
246     // rules.build("tool-remote-test-client", "src/tools/remote-test-client")
247     //      .dep(|s| s.name("maybe-clean-tools"))
248     //      .dep(|s| s.name("libstd-tool"))
249     //      .run(move |s| compile::tool(build, s.stage, s.target, "remote-test-client"));
250     RemoteTestClient, "src/tools/remote-test-client", "remote-test-client", Mode::Libstd;
251     // rules.build("tool-rust-installer", "src/tools/rust-installer")
252     //      .dep(|s| s.name("maybe-clean-tools"))
253     //      .dep(|s| s.name("libstd-tool"))
254     //      .run(move |s| compile::tool(build, s.stage, s.target, "rust-installer"));
255     RustInstaller, "src/tools/rust-installer", "rust-installer", Mode::Libstd;
256 );
257
258 // rules.build("tool-cargo", "src/tools/cargo")
259 //      .host(true)
260 //      .default(build.config.extended)
261 //      .dep(|s| s.name("maybe-clean-tools"))
262 //      .dep(|s| s.name("libstd-tool"))
263 //      .dep(|s| s.stage(0).host(s.target).name("openssl"))
264 //      .dep(move |s| {
265 //          // Cargo depends on procedural macros, which requires a full host
266 //          // compiler to be available, so we need to depend on that.
267 //          s.name("librustc-link")
268 //           .target(&build.build)
269 //           .host(&build.build)
270 //      })
271 //      .run(move |s| compile::tool(build, s.stage, s.target, "cargo"));
272 #[derive(Serialize)]
273 pub struct Cargo<'a> {
274     pub stage: u32,
275     pub target: &'a str,
276 }
277
278 impl<'a> Step<'a> for Cargo<'a> {
279     type Output = PathBuf;
280     const DEFAULT: bool = true;
281     const ONLY_HOSTS: bool = true;
282
283     fn should_run(_builder: &Builder, path: &Path) -> bool {
284         path.ends_with("src/tools/cargo")
285     }
286
287     fn make_run(builder: &Builder, path: Option<&Path>, _host: &str, target: &str) {
288         if path.is_none() && !builder.build.config.extended {
289             return;
290         }
291         builder.ensure(Cargo {
292             stage: builder.top_stage,
293             target,
294         });
295     }
296
297     fn run(self, builder: &Builder) -> PathBuf {
298         builder.ensure(native::Openssl {
299             target: self.target,
300         });
301         // Cargo depends on procedural macros, which requires a full host
302         // compiler to be available, so we need to depend on that.
303         builder.ensure(Rustc {
304             compiler: builder.compiler(builder.top_stage, &builder.build.build),
305             target: &builder.build.build,
306         });
307         builder.ensure(ToolBuild {
308             stage: self.stage,
309             target: self.target,
310             tool: "cargo",
311             mode: Mode::Libstd,
312         })
313     }
314 }
315
316 // rules.build("tool-rls", "src/tools/rls")
317 //      .host(true)
318 //      .default(build.config.extended)
319 //      .dep(|s| s.name("librustc-tool"))
320 //      .dep(|s| s.stage(0).host(s.target).name("openssl"))
321 //      .dep(move |s| {
322 //          // rls, like cargo, uses procedural macros
323 //          s.name("librustc-link")
324 //           .target(&build.build)
325 //           .host(&build.build)
326 //      })
327 //      .run(move |s| compile::tool(build, s.stage, s.target, "rls"));
328 //
329 #[derive(Serialize)]
330 pub struct Rls<'a> {
331     pub stage: u32,
332     pub target: &'a str,
333 }
334
335 impl<'a> Step<'a> for Rls<'a> {
336     type Output = PathBuf;
337     const DEFAULT: bool = true;
338     const ONLY_HOSTS: bool = true;
339
340     fn should_run(_builder: &Builder, path: &Path) -> bool {
341         path.ends_with("src/tools/rls")
342     }
343
344     fn make_run(builder: &Builder, path: Option<&Path>, _host: &str, target: &str) {
345         if path.is_none() && !builder.build.config.extended {
346             return;
347         }
348         builder.ensure(Cargo {
349             stage: builder.top_stage,
350             target,
351         });
352     }
353
354     fn run(self, builder: &Builder) -> PathBuf {
355         builder.ensure(native::Openssl {
356             target: self.target,
357         });
358         // RLS depends on procedural macros, which requires a full host
359         // compiler to be available, so we need to depend on that.
360         builder.ensure(Rustc {
361             compiler: builder.compiler(builder.top_stage, &builder.build.build),
362             target: &builder.build.build,
363         });
364         builder.ensure(ToolBuild {
365             stage: self.stage,
366             target: self.target,
367             tool: "rls",
368             mode: Mode::Librustc,
369         })
370     }
371 }