]> git.lizzy.rs Git - rust.git/blob - src/bootstrap/install.rs
7b2d644c7696d44f56ff254e00c9aab98703fbdb
[rust.git] / src / bootstrap / install.rs
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
16 use std::env;
17 use std::fs;
18 use std::path::{Path, PathBuf, Component};
19 use std::process::Command;
20
21 use dist::{self, pkgname, sanitize_sh, tmpdir};
22
23 use builder::{Builder, ShouldRun, Step};
24 use cache::Interned;
25
26 pub fn install_docs(builder: &Builder, stage: u32, host: Interned<String>) {
27     install_sh(builder, "docs", "rust-docs", stage, Some(host));
28 }
29
30 pub fn install_std(builder: &Builder, stage: u32) {
31     for target in builder.build.config.target.iter() {
32         install_sh(builder, "std", "rust-std", stage, Some(*target));
33     }
34 }
35
36 pub fn install_cargo(builder: &Builder, stage: u32, host: Interned<String>) {
37     install_sh(builder, "cargo", "cargo", stage, Some(host));
38 }
39
40 pub fn install_rls(builder: &Builder, stage: u32, host: Interned<String>) {
41     install_sh(builder, "rls", "rls", stage, Some(host));
42 }
43
44 pub fn install_analysis(builder: &Builder, stage: u32, host: Interned<String>) {
45     install_sh(builder, "analysis", "rust-analysis", stage, Some(host));
46 }
47
48 pub fn install_src(builder: &Builder, stage: u32) {
49     install_sh(builder, "src", "rust-src", stage, None);
50 }
51 pub fn install_rustc(builder: &Builder, stage: u32, host: Interned<String>) {
52     install_sh(builder, "rustc", "rustc", stage, Some(host));
53 }
54
55 fn install_sh(
56     builder: &Builder,
57     package: &str,
58     name: &str,
59     stage: u32,
60     host: Option<Interned<String>>
61 ) {
62     let build = builder.build;
63     println!("Install {} stage{} ({:?})", package, stage, host);
64
65     let prefix_default = PathBuf::from("/usr/local");
66     let sysconfdir_default = PathBuf::from("/etc");
67     let docdir_default = PathBuf::from("share/doc/rust");
68     let bindir_default = PathBuf::from("bin");
69     let libdir_default = PathBuf::from("lib");
70     let mandir_default = PathBuf::from("share/man");
71     let prefix = build.config.prefix.as_ref().unwrap_or(&prefix_default);
72     let sysconfdir = build.config.sysconfdir.as_ref().unwrap_or(&sysconfdir_default);
73     let docdir = build.config.docdir.as_ref().unwrap_or(&docdir_default);
74     let bindir = build.config.bindir.as_ref().unwrap_or(&bindir_default);
75     let libdir = build.config.libdir.as_ref().unwrap_or(&libdir_default);
76     let mandir = build.config.mandir.as_ref().unwrap_or(&mandir_default);
77
78     let sysconfdir = prefix.join(sysconfdir);
79     let docdir = prefix.join(docdir);
80     let bindir = prefix.join(bindir);
81     let libdir = prefix.join(libdir);
82     let mandir = prefix.join(mandir);
83
84     let destdir = env::var_os("DESTDIR").map(PathBuf::from);
85
86     let prefix = add_destdir(&prefix, &destdir);
87     let sysconfdir = add_destdir(&sysconfdir, &destdir);
88     let docdir = add_destdir(&docdir, &destdir);
89     let bindir = add_destdir(&bindir, &destdir);
90     let libdir = add_destdir(&libdir, &destdir);
91     let mandir = add_destdir(&mandir, &destdir);
92
93     let empty_dir = build.out.join("tmp/empty_dir");
94
95     t!(fs::create_dir_all(&empty_dir));
96     let package_name = if let Some(host) = host {
97         format!("{}-{}", pkgname(build, name), host)
98     } else {
99         pkgname(build, name)
100     };
101
102     let mut cmd = Command::new("sh");
103     cmd.current_dir(&empty_dir)
104         .arg(sanitize_sh(&tmpdir(build).join(&package_name).join("install.sh")))
105         .arg(format!("--prefix={}", sanitize_sh(&prefix)))
106         .arg(format!("--sysconfdir={}", sanitize_sh(&sysconfdir)))
107         .arg(format!("--docdir={}", sanitize_sh(&docdir)))
108         .arg(format!("--bindir={}", sanitize_sh(&bindir)))
109         .arg(format!("--libdir={}", sanitize_sh(&libdir)))
110         .arg(format!("--mandir={}", sanitize_sh(&mandir)))
111         .arg("--disable-ldconfig");
112     build.run(&mut cmd);
113     t!(fs::remove_dir_all(&empty_dir));
114 }
115
116 fn add_destdir(path: &Path, destdir: &Option<PathBuf>) -> PathBuf {
117     let mut ret = match *destdir {
118         Some(ref dest) => dest.clone(),
119         None => return path.to_path_buf(),
120     };
121     for part in path.components() {
122         match part {
123             Component::Normal(s) => ret.push(s),
124             _ => {}
125         }
126     }
127     ret
128 }
129
130 macro_rules! install {
131     (($sel:ident, $builder:ident),
132        $($name:ident,
133        $path:expr,
134        $default_cond:expr,
135        only_hosts: $only_hosts:expr,
136        $run_item:block $(, $c:ident)*;)+) => {
137         $(
138             #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
139         pub struct $name {
140             pub stage: u32,
141             pub target: Interned<String>,
142             pub host: Interned<String>,
143         }
144
145         impl Step for $name {
146             type Output = ();
147             const DEFAULT: bool = true;
148             const ONLY_BUILD_TARGETS: bool = true;
149             const ONLY_HOSTS: bool = $only_hosts;
150             $(const $c: bool = true;)*
151
152             fn should_run(run: ShouldRun) -> ShouldRun {
153                 run.path($path)
154             }
155
156             fn make_run(
157                 $builder: &Builder,
158                 path: Option<&Path>,
159                 host: Interned<String>,
160                 target: Interned<String>,
161             ) {
162                 if path.is_none() && !($default_cond) {
163                     return;
164                 }
165                 $builder.ensure($name {
166                     stage: $builder.top_stage,
167                     target,
168                     host,
169                 });
170             }
171
172             fn run($sel, $builder: &Builder) {
173                 $run_item
174             }
175         })+
176     }
177 }
178
179 install!((self, builder),
180     Docs, "src/doc", builder.build.config.docs, only_hosts: false, {
181         builder.ensure(dist::Docs { stage: self.stage, target: self.target });
182         install_docs(builder, self.stage, self.target);
183     };
184     Std, "src/libstd", true, only_hosts: true, {
185         builder.ensure(dist::Std {
186             compiler: builder.compiler(self.stage, self.host),
187             target: self.target
188         });
189         install_std(builder, self.stage);
190     };
191     Cargo, "cargo", builder.build.config.extended, only_hosts: true, {
192         builder.ensure(dist::Cargo { stage: self.stage, target: self.target });
193         install_cargo(builder, self.stage, self.target);
194     };
195     Rls, "rls", builder.build.config.extended, only_hosts: true, {
196         builder.ensure(dist::Rls { stage: self.stage, target: self.target });
197         install_rls(builder, self.stage, self.target);
198     };
199     Analysis, "analysis", builder.build.config.extended, only_hosts: false, {
200         builder.ensure(dist::Analysis {
201             compiler: builder.compiler(self.stage, self.host),
202             target: self.target
203         });
204         install_analysis(builder, self.stage, self.target);
205     };
206     Src, "src", builder.build.config.extended, only_hosts: true, {
207         builder.ensure(dist::Src);
208         install_src(builder, self.stage);
209     }, ONLY_BUILD;
210     Rustc, "src/librustc", builder.build.config.extended, only_hosts: true, {
211         builder.ensure(dist::Rustc { stage: self.stage, target: self.target });
212         install_rustc(builder, self.stage, self.target);
213     };
214 );