+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::env;
+use std::path::{Path, PathBuf};
+use std::process::Command;
+
+use Mode;
+use builder::{Step, Builder};
+use util::{exe, add_lib_path};
+use compile::{self, stamp, Rustc};
+use native;
+use channel::GitInfo;
+
+//// ========================================================================
+//// Build tools
+////
+//// Tools used during the build system but not shipped
+//// "pseudo rule" which represents completely cleaning out the tools dir in
+//// one stage. This needs to happen whenever a dependency changes (e.g.
+//// libstd, libtest, librustc) and all of the tool compilations above will
+//// be sequenced after this rule.
+//rules.build("maybe-clean-tools", "path/to/nowhere")
+// .after("librustc-tool")
+// .after("libtest-tool")
+// .after("libstd-tool");
+//
+//rules.build("librustc-tool", "path/to/nowhere")
+// .dep(|s| s.name("librustc"))
+// .run(move |s| compile::maybe_clean_tools(build, s.stage, s.target, Mode::Librustc));
+//rules.build("libtest-tool", "path/to/nowhere")
+// .dep(|s| s.name("libtest"))
+// .run(move |s| compile::maybe_clean_tools(build, s.stage, s.target, Mode::Libtest));
+//rules.build("libstd-tool", "path/to/nowhere")
+// .dep(|s| s.name("libstd"))
+// .run(move |s| compile::maybe_clean_tools(build, s.stage, s.target, Mode::Libstd));
+//
+
+#[derive(Serialize)]
+pub struct CleanTools<'a> {
+ pub stage: u32,
+ pub target: &'a str,
+ pub mode: Mode,
+}
+
+impl<'a> Step<'a> for CleanTools<'a> {
+ type Output = ();
+
+ /// Build a tool in `src/tools`
+ ///
+ /// This will build the specified tool with the specified `host` compiler in
+ /// `stage` into the normal cargo output directory.
+ fn run(self, builder: &Builder) {
+ let build = builder.build;
+ let stage = self.stage;
+ let target = self.target;
+ let mode = self.mode;
+
+ let compiler = Compiler::new(stage, &build.build);
+
+ let stamp = match mode {
+ Mode::Libstd => libstd_stamp(build, &compiler, target),
+ Mode::Libtest => libtest_stamp(build, &compiler, target),
+ Mode::Librustc => librustc_stamp(build, &compiler, target),
+ _ => panic!(),
+ };
+ let out_dir = build.cargo_out(&compiler, Mode::Tool, target);
+ build.clear_if_dirty(&out_dir, &stamp);
+ }
+}
+
+// rules.build("tool-rustbook", "src/tools/rustbook")
+// .dep(|s| s.name("maybe-clean-tools"))
+// .dep(|s| s.name("librustc-tool"))
+// .run(move |s| compile::tool(build, s.stage, s.target, "rustbook"));
+// rules.build("tool-error-index", "src/tools/error_index_generator")
+// .dep(|s| s.name("maybe-clean-tools"))
+// .dep(|s| s.name("librustc-tool"))
+// .run(move |s| compile::tool(build, s.stage, s.target, "error_index_generator"));
+// rules.build("tool-unstable-book-gen", "src/tools/unstable-book-gen")
+// .dep(|s| s.name("maybe-clean-tools"))
+// .dep(|s| s.name("libstd-tool"))
+// .run(move |s| compile::tool(build, s.stage, s.target, "unstable-book-gen"));
+// rules.build("tool-tidy", "src/tools/tidy")
+// .dep(|s| s.name("maybe-clean-tools"))
+// .dep(|s| s.name("libstd-tool"))
+// .run(move |s| compile::tool(build, s.stage, s.target, "tidy"));
+// rules.build("tool-linkchecker", "src/tools/linkchecker")
+// .dep(|s| s.name("maybe-clean-tools"))
+// .dep(|s| s.name("libstd-tool"))
+// .run(move |s| compile::tool(build, s.stage, s.target, "linkchecker"));
+// rules.build("tool-cargotest", "src/tools/cargotest")
+// .dep(|s| s.name("maybe-clean-tools"))
+// .dep(|s| s.name("libstd-tool"))
+// .run(move |s| compile::tool(build, s.stage, s.target, "cargotest"));
+// rules.build("tool-compiletest", "src/tools/compiletest")
+// .dep(|s| s.name("maybe-clean-tools"))
+// .dep(|s| s.name("libtest-tool"))
+// .run(move |s| compile::tool(build, s.stage, s.target, "compiletest"));
+// rules.build("tool-build-manifest", "src/tools/build-manifest")
+// .dep(|s| s.name("maybe-clean-tools"))
+// .dep(|s| s.name("libstd-tool"))
+// .run(move |s| compile::tool(build, s.stage, s.target, "build-manifest"));
+// rules.build("tool-remote-test-server", "src/tools/remote-test-server")
+// .dep(|s| s.name("maybe-clean-tools"))
+// .dep(|s| s.name("libstd-tool"))
+// .run(move |s| compile::tool(build, s.stage, s.target, "remote-test-server"));
+// rules.build("tool-remote-test-client", "src/tools/remote-test-client")
+// .dep(|s| s.name("maybe-clean-tools"))
+// .dep(|s| s.name("libstd-tool"))
+// .run(move |s| compile::tool(build, s.stage, s.target, "remote-test-client"));
+// rules.build("tool-rust-installer", "src/tools/rust-installer")
+// .dep(|s| s.name("maybe-clean-tools"))
+// .dep(|s| s.name("libstd-tool"))
+// .run(move |s| compile::tool(build, s.stage, s.target, "rust-installer"));
+// rules.build("tool-cargo", "src/tools/cargo")
+// .host(true)
+// .default(build.config.extended)
+// .dep(|s| s.name("maybe-clean-tools"))
+// .dep(|s| s.name("libstd-tool"))
+// .dep(|s| s.stage(0).host(s.target).name("openssl"))
+// .dep(move |s| {
+// // Cargo depends on procedural macros, which requires a full host
+// // compiler to be available, so we need to depend on that.
+// s.name("librustc-link")
+// .target(&build.build)
+// .host(&build.build)
+// })
+// .run(move |s| compile::tool(build, s.stage, s.target, "cargo"));
+// rules.build("tool-rls", "src/tools/rls")
+// .host(true)
+// .default(build.config.extended)
+// .dep(|s| s.name("librustc-tool"))
+// .dep(|s| s.stage(0).host(s.target).name("openssl"))
+// .dep(move |s| {
+// // rls, like cargo, uses procedural macros
+// s.name("librustc-link")
+// .target(&build.build)
+// .host(&build.build)
+// })
+// .run(move |s| compile::tool(build, s.stage, s.target, "rls"));
+//
+
+#[derive(Serialize)]
+pub struct Tool<'a> {
+ pub stage: u32,
+ pub target: &'a str,
+ pub tool: &'a str,
+}
+
+impl<'a> Step<'a> for Tool<'a> {
+ type Output = ();
+
+ /// Build a tool in `src/tools`
+ ///
+ /// This will build the specified tool with the specified `host` compiler in
+ /// `stage` into the normal cargo output directory.
+ fn run(self, builder: &Builder) {
+ let build = builder.build;
+ let stage = self.stage;
+ let target = self.target;
+ let tool = self.tool;
+
+ let _folder = build.fold_output(|| format!("stage{}-{}", stage, tool));
+ println!("Building stage{} tool {} ({})", stage, tool, target);
+
+ let compiler = Compiler::new(stage, &build.build);
+
+ let mut cargo = build.cargo(&compiler, Mode::Tool, target, "build");
+ let dir = build.src.join("src/tools").join(tool);
+ cargo.arg("--manifest-path").arg(dir.join("Cargo.toml"));
+
+ // We don't want to build tools dynamically as they'll be running across
+ // stages and such and it's just easier if they're not dynamically linked.
+ cargo.env("RUSTC_NO_PREFER_DYNAMIC", "1");
+
+ if let Some(dir) = build.openssl_install_dir(target) {
+ cargo.env("OPENSSL_STATIC", "1");
+ cargo.env("OPENSSL_DIR", dir);
+ cargo.env("LIBZ_SYS_STATIC", "1");
+ }
+
+ cargo.env("CFG_RELEASE_CHANNEL", &build.config.channel);
+
+ let info = GitInfo::new(&dir);
+ if let Some(sha) = info.sha() {
+ cargo.env("CFG_COMMIT_HASH", sha);
+ }
+ if let Some(sha_short) = info.sha_short() {
+ cargo.env("CFG_SHORT_COMMIT_HASH", sha_short);
+ }
+ if let Some(date) = info.commit_date() {
+ cargo.env("CFG_COMMIT_DATE", date);
+ }
+
+ build.run(&mut cargo);
+ }
+}