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.
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.
11 //! Implementation of the install aspects of the compiler.
13 //! This module is responsible for installing the standard library,
14 //! compiler, and documentation.
18 use std
::path
::{Path, PathBuf, Component}
;
19 use std
::process
::Command
;
21 use dist
::{self, pkgname, sanitize_sh, tmpdir}
;
23 use builder
::{Builder, RunConfig, ShouldRun, Step}
;
27 pub fn install_docs(builder
: &Builder
, stage
: u32, host
: Interned
<String
>) {
28 install_sh(builder
, "docs", "rust-docs", stage
, Some(host
));
31 pub fn install_std(builder
: &Builder
, stage
: u32, target
: Interned
<String
>) {
32 install_sh(builder
, "std", "rust-std", stage
, Some(target
));
35 pub fn install_cargo(builder
: &Builder
, stage
: u32, host
: Interned
<String
>) {
36 install_sh(builder
, "cargo", "cargo", stage
, Some(host
));
39 pub fn install_rls(builder
: &Builder
, stage
: u32, host
: Interned
<String
>) {
40 install_sh(builder
, "rls", "rls", stage
, Some(host
));
42 pub fn install_clippy(builder
: &Builder
, stage
: u32, host
: Interned
<String
>) {
43 install_sh(builder
, "clippy", "clippy", stage
, Some(host
));
46 pub fn install_rustfmt(builder
: &Builder
, stage
: u32, host
: Interned
<String
>) {
47 install_sh(builder
, "rustfmt", "rustfmt", stage
, Some(host
));
50 pub fn install_analysis(builder
: &Builder
, stage
: u32, host
: Interned
<String
>) {
51 install_sh(builder
, "analysis", "rust-analysis", stage
, Some(host
));
54 pub fn install_src(builder
: &Builder
, stage
: u32) {
55 install_sh(builder
, "src", "rust-src", stage
, None
);
57 pub fn install_rustc(builder
: &Builder
, stage
: u32, host
: Interned
<String
>) {
58 install_sh(builder
, "rustc", "rustc", stage
, Some(host
));
66 host
: Option
<Interned
<String
>>
68 builder
.info(&format
!("Install {} stage{} ({:?})", package
, stage
, host
));
70 let prefix_default
= PathBuf
::from("/usr/local");
71 let sysconfdir_default
= PathBuf
::from("/etc");
72 let datadir_default
= PathBuf
::from("share");
73 let docdir_default
= datadir_default
.join("doc/rust");
74 let bindir_default
= PathBuf
::from("bin");
75 let libdir_default
= PathBuf
::from("lib");
76 let mandir_default
= datadir_default
.join("man");
77 let prefix
= builder
.config
.prefix
.as_ref().map_or(prefix_default
, |p
| {
78 fs
::canonicalize(p
).unwrap_or_else(|_
| panic
!("could not canonicalize {}", p
.display()))
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
);
87 let sysconfdir
= prefix
.join(sysconfdir
);
88 let datadir
= prefix
.join(datadir
);
89 let docdir
= prefix
.join(docdir
);
90 let bindir
= prefix
.join(bindir
);
91 let libdir
= prefix
.join(libdir
);
92 let mandir
= prefix
.join(mandir
);
94 let destdir
= env
::var_os("DESTDIR").map(PathBuf
::from
);
96 let prefix
= add_destdir(&prefix
, &destdir
);
97 let sysconfdir
= add_destdir(&sysconfdir
, &destdir
);
98 let datadir
= add_destdir(&datadir
, &destdir
);
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
);
104 let empty_dir
= builder
.out
.join("tmp/empty_dir");
106 t
!(fs
::create_dir_all(&empty_dir
));
107 let package_name
= if let Some(host
) = host
{
108 format
!("{}-{}", pkgname(builder
, name
), host
)
110 pkgname(builder
, name
)
113 let mut cmd
= Command
::new("sh");
114 cmd
.current_dir(&empty_dir
)
115 .arg(sanitize_sh(&tmpdir(builder
).join(&package_name
).join("install.sh")))
116 .arg(format
!("--prefix={}", sanitize_sh(&prefix
)))
117 .arg(format
!("--sysconfdir={}", sanitize_sh(&sysconfdir
)))
118 .arg(format
!("--datadir={}", sanitize_sh(&datadir
)))
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");
124 builder
.run(&mut cmd
);
125 t
!(fs
::remove_dir_all(&empty_dir
));
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(),
133 for part
in path
.components() {
135 Component
::Normal(s
) => ret
.push(s
),
142 macro_rules
! install
{
143 (($sel
:ident
, $builder
:ident
, $_config
:ident
),
147 only_hosts
: $only_hosts
:expr
,
148 $run_item
:block $
(, $c
:ident
)*;)+) => {
150 #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
153 pub target
: Interned
<String
>,
154 pub host
: Interned
<String
>,
159 fn should_build(config
: &Config
) -> bool
{
160 config
.extended
&& config
.tools
.as_ref()
161 .map_or(true, |t
| t
.contains($path
))
165 fn should_install(builder
: &Builder
) -> bool
{
166 builder
.config
.tools
.as_ref().map_or(false, |t
| t
.contains($path
))
170 impl Step
for $name
{
172 const DEFAULT
: bool
= true;
173 const ONLY_HOSTS
: bool
= $only_hosts
;
174 $
(const $c
: bool
= true;)*
176 fn should_run(run
: ShouldRun
) -> ShouldRun
{
177 let $_config
= &run
.builder
.config
;
178 run
.path($path
).default_condition($default_cond
)
181 fn make_run(run
: RunConfig
) {
182 run
.builder
.ensure($name
{
183 stage
: run
.builder
.top_stage
,
185 host
: run
.builder
.config
.build
,
189 fn run($sel
, $builder
: &Builder
) {
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
);
201 Std
, "src/libstd", true, only_hosts
: true, {
202 for target
in &builder
.targets
{
203 builder
.ensure(dist
::Std
{
204 compiler
: builder
.compiler(self.stage
, self.host
),
207 install_std(builder
, self.stage
, *target
);
210 Cargo
, "cargo", Self::should_build(_config
), only_hosts
: true, {
211 builder
.ensure(dist
::Cargo { stage: self.stage, target: self.target }
);
212 install_cargo(builder
, self.stage
, self.target
);
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
) {
217 install_rls(builder
, self.stage
, self.target
);
219 builder
.info(&format
!("skipping Install RLS stage{} ({})", self.stage
, self.target
));
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
);
227 builder
.info(&format
!("skipping Install clippy stage{} ({})", self.stage
, self.target
));
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
) {
233 install_rustfmt(builder
, self.stage
, self.target
);
236 &format
!("skipping Install Rustfmt stage{} ({})", self.stage
, self.target
));
239 Analysis
, "analysis", Self::should_build(_config
), only_hosts
: false, {
240 builder
.ensure(dist
::Analysis
{
241 compiler
: builder
.compiler(self.stage
, self.host
),
244 install_analysis(builder
, self.stage
, self.target
);
246 Rustc
, "src/librustc", true, only_hosts
: true, {
247 builder
.ensure(dist
::Rustc
{
248 compiler
: builder
.compiler(self.stage
, self.target
),
250 install_rustc(builder
, self.stage
, self.target
);
254 #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
261 const DEFAULT
: bool
= true;
262 const ONLY_HOSTS
: bool
= true;
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
)
271 fn make_run(run
: RunConfig
) {
272 run
.builder
.ensure(Src
{
273 stage
: run
.builder
.top_stage
,
277 fn run(self, builder
: &Builder
) {
278 builder
.ensure(dist
::Src
);
279 install_src(builder
, self.stage
);