]> git.lizzy.rs Git - rust.git/blob - src/bootstrap/tool.rs
52ec273c3e8cd2239f51aec83aba2bba494ec256
[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, 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 = Compiler::new(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 // rules.build("tool-rustbook", "src/tools/rustbook")
80 //      .dep(|s| s.name("maybe-clean-tools"))
81 //      .dep(|s| s.name("librustc-tool"))
82 //      .run(move |s| compile::tool(build, s.stage, s.target, "rustbook"));
83 // rules.build("tool-error-index", "src/tools/error_index_generator")
84 //      .dep(|s| s.name("maybe-clean-tools"))
85 //      .dep(|s| s.name("librustc-tool"))
86 //      .run(move |s| compile::tool(build, s.stage, s.target, "error_index_generator"));
87 // rules.build("tool-unstable-book-gen", "src/tools/unstable-book-gen")
88 //      .dep(|s| s.name("maybe-clean-tools"))
89 //      .dep(|s| s.name("libstd-tool"))
90 //      .run(move |s| compile::tool(build, s.stage, s.target, "unstable-book-gen"));
91 // rules.build("tool-tidy", "src/tools/tidy")
92 //      .dep(|s| s.name("maybe-clean-tools"))
93 //      .dep(|s| s.name("libstd-tool"))
94 //      .run(move |s| compile::tool(build, s.stage, s.target, "tidy"));
95 // rules.build("tool-linkchecker", "src/tools/linkchecker")
96 //      .dep(|s| s.name("maybe-clean-tools"))
97 //      .dep(|s| s.name("libstd-tool"))
98 //      .run(move |s| compile::tool(build, s.stage, s.target, "linkchecker"));
99 // rules.build("tool-cargotest", "src/tools/cargotest")
100 //      .dep(|s| s.name("maybe-clean-tools"))
101 //      .dep(|s| s.name("libstd-tool"))
102 //      .run(move |s| compile::tool(build, s.stage, s.target, "cargotest"));
103 // rules.build("tool-compiletest", "src/tools/compiletest")
104 //      .dep(|s| s.name("maybe-clean-tools"))
105 //      .dep(|s| s.name("libtest-tool"))
106 //      .run(move |s| compile::tool(build, s.stage, s.target, "compiletest"));
107 // rules.build("tool-build-manifest", "src/tools/build-manifest")
108 //      .dep(|s| s.name("maybe-clean-tools"))
109 //      .dep(|s| s.name("libstd-tool"))
110 //      .run(move |s| compile::tool(build, s.stage, s.target, "build-manifest"));
111 // rules.build("tool-remote-test-server", "src/tools/remote-test-server")
112 //      .dep(|s| s.name("maybe-clean-tools"))
113 //      .dep(|s| s.name("libstd-tool"))
114 //      .run(move |s| compile::tool(build, s.stage, s.target, "remote-test-server"));
115 // rules.build("tool-remote-test-client", "src/tools/remote-test-client")
116 //      .dep(|s| s.name("maybe-clean-tools"))
117 //      .dep(|s| s.name("libstd-tool"))
118 //      .run(move |s| compile::tool(build, s.stage, s.target, "remote-test-client"));
119 // rules.build("tool-rust-installer", "src/tools/rust-installer")
120 //      .dep(|s| s.name("maybe-clean-tools"))
121 //      .dep(|s| s.name("libstd-tool"))
122 //      .run(move |s| compile::tool(build, s.stage, s.target, "rust-installer"));
123 // rules.build("tool-cargo", "src/tools/cargo")
124 //      .host(true)
125 //      .default(build.config.extended)
126 //      .dep(|s| s.name("maybe-clean-tools"))
127 //      .dep(|s| s.name("libstd-tool"))
128 //      .dep(|s| s.stage(0).host(s.target).name("openssl"))
129 //      .dep(move |s| {
130 //          // Cargo depends on procedural macros, which requires a full host
131 //          // compiler to be available, so we need to depend on that.
132 //          s.name("librustc-link")
133 //           .target(&build.build)
134 //           .host(&build.build)
135 //      })
136 //      .run(move |s| compile::tool(build, s.stage, s.target, "cargo"));
137 // rules.build("tool-rls", "src/tools/rls")
138 //      .host(true)
139 //      .default(build.config.extended)
140 //      .dep(|s| s.name("librustc-tool"))
141 //      .dep(|s| s.stage(0).host(s.target).name("openssl"))
142 //      .dep(move |s| {
143 //          // rls, like cargo, uses procedural macros
144 //          s.name("librustc-link")
145 //           .target(&build.build)
146 //           .host(&build.build)
147 //      })
148 //      .run(move |s| compile::tool(build, s.stage, s.target, "rls"));
149 //
150
151 #[derive(Serialize)]
152 pub struct Tool<'a> {
153     pub stage: u32,
154     pub target: &'a str,
155     pub tool: &'a str,
156 }
157
158 impl<'a> Step<'a> for Tool<'a> {
159     type Output = ();
160
161     /// Build a tool in `src/tools`
162     ///
163     /// This will build the specified tool with the specified `host` compiler in
164     /// `stage` into the normal cargo output directory.
165     fn run(self, builder: &Builder) {
166         let build = builder.build;
167         let stage = self.stage;
168         let target = self.target;
169         let tool = self.tool;
170
171         let _folder = build.fold_output(|| format!("stage{}-{}", stage, tool));
172         println!("Building stage{} tool {} ({})", stage, tool, target);
173
174         let compiler = Compiler::new(stage, &build.build);
175
176         let mut cargo = build.cargo(&compiler, Mode::Tool, target, "build");
177         let dir = build.src.join("src/tools").join(tool);
178         cargo.arg("--manifest-path").arg(dir.join("Cargo.toml"));
179
180         // We don't want to build tools dynamically as they'll be running across
181         // stages and such and it's just easier if they're not dynamically linked.
182         cargo.env("RUSTC_NO_PREFER_DYNAMIC", "1");
183
184         if let Some(dir) = build.openssl_install_dir(target) {
185             cargo.env("OPENSSL_STATIC", "1");
186             cargo.env("OPENSSL_DIR", dir);
187             cargo.env("LIBZ_SYS_STATIC", "1");
188         }
189
190         cargo.env("CFG_RELEASE_CHANNEL", &build.config.channel);
191
192         let info = GitInfo::new(&dir);
193         if let Some(sha) = info.sha() {
194             cargo.env("CFG_COMMIT_HASH", sha);
195         }
196         if let Some(sha_short) = info.sha_short() {
197             cargo.env("CFG_SHORT_COMMIT_HASH", sha_short);
198         }
199         if let Some(date) = info.commit_date() {
200             cargo.env("CFG_COMMIT_DATE", date);
201         }
202
203         build.run(&mut cargo);
204     }
205 }