]>
git.proxmox.com Git - rustc.git/blob - src/bootstrap/sanity.rs
1 // Copyright 2015 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 //! Sanity checking performed by rustbuild before actually executing anything.
13 //! This module contains the implementation of ensuring that the build
14 //! environment looks reasonable before progressing. This will verify that
15 //! various programs like git and python exist, along with ensuring that all C
16 //! compilers for cross-compiling are found.
18 //! In theory if we get past this phase it's a bug if a build fails, but in
19 //! practice that's likely not true!
21 use std
::collections
::HashSet
;
23 use std
::ffi
::{OsStr, OsString}
;
25 use std
::process
::Command
;
27 use build_helper
::output
;
31 pub fn check(build
: &mut Build
) {
32 let mut checked
= HashSet
::new();
33 let path
= env
::var_os("PATH").unwrap_or(OsString
::new());
34 // On Windows, quotes are invalid characters for filename paths, and if
35 // one is present as part of the PATH then that can lead to the system
36 // being unable to identify the files properly. See
37 // https://github.com/rust-lang/rust/issues/34959 for more details.
39 if path
.to_string_lossy().contains("\"") {
40 panic
!("PATH contains invalid character '\"'");
43 let mut need_cmd
= |cmd
: &OsStr
| {
44 if !checked
.insert(cmd
.to_owned()) {
47 for path
in env
::split_paths(&path
).map(|p
| p
.join(cmd
)) {
48 if fs
::metadata(&path
).is_ok() ||
49 fs
::metadata(path
.with_extension("exe")).is_ok() {
53 panic
!("\n\ncouldn't find required command: {:?}\n\n", cmd
);
56 // If we've got a git directory we're gona need git to update
57 // submodules and learn about various other aspects.
58 if fs
::metadata(build
.src
.join(".git")).is_ok() {
59 need_cmd("git".as_ref());
62 // We need cmake, but only if we're actually building LLVM
63 for host
in build
.config
.host
.iter() {
64 if let Some(config
) = build
.config
.target_config
.get(host
) {
65 if config
.llvm_config
.is_some() {
69 need_cmd("cmake".as_ref());
70 if build
.config
.ninja
{
71 need_cmd("ninja".as_ref())
76 need_cmd("python".as_ref());
78 // If a manual nodejs was added to the config,
79 // of if a nodejs install is detected through config, use it.
80 if let Some(ref s
) = build
.config
.nodejs
{
84 // We're gonna build some custom C code here and there, host triples
85 // also build some C++ shims for LLVM so we need a C++ compiler.
86 for target
in build
.config
.target
.iter() {
87 need_cmd(build
.cc(target
).as_ref());
88 if let Some(ar
) = build
.ar(target
) {
89 need_cmd(ar
.as_ref());
92 for host
in build
.config
.host
.iter() {
93 need_cmd(build
.cxx(host
).as_ref());
96 // Externally configured LLVM requires FileCheck to exist
97 let filecheck
= build
.llvm_filecheck(&build
.config
.build
);
98 if !filecheck
.starts_with(&build
.out
) && !filecheck
.exists() && build
.config
.codegen_tests
{
99 panic
!("filecheck executable {:?} does not exist", filecheck
);
102 for target
in build
.config
.target
.iter() {
103 // Either can't build or don't want to run jemalloc on these targets
104 if target
.contains("rumprun") ||
105 target
.contains("bitrig") ||
106 target
.contains("openbsd") ||
107 target
.contains("msvc") ||
108 target
.contains("emscripten") {
109 build
.config
.use_jemalloc
= false;
112 // Can't compile for iOS unless we're on OSX
113 if target
.contains("apple-ios") &&
114 !build
.config
.build
.contains("apple-darwin") {
115 panic
!("the iOS target is only supported on OSX");
118 // Make sure musl-root is valid if specified
119 if target
.contains("musl") && !target
.contains("mips") {
120 match build
.musl_root(target
) {
122 if fs
::metadata(root
.join("lib/libc.a")).is_err() {
123 panic
!("couldn't find libc.a in musl dir: {}",
124 root
.join("lib").display());
126 if fs
::metadata(root
.join("lib/libunwind.a")).is_err() {
127 panic
!("couldn't find libunwind.a in musl dir: {}",
128 root
.join("lib").display());
132 panic
!("when targeting MUSL either the build.musl-root \
133 option or the target.$TARGET.musl-root one must \
134 be specified in config.toml")
139 if target
.contains("msvc") {
140 // There are three builds of cmake on windows: MSVC, MinGW, and
141 // Cygwin. The Cygwin build does not have generators for Visual
142 // Studio, so detect that here and error.
143 let out
= output(Command
::new("cmake").arg("--help"));
144 if !out
.contains("Visual Studio") {
146 cmake does not support Visual Studio generators.
148 This is likely due to it being an msys/cygwin build of cmake,
149 rather than the required windows version, built using MinGW
152 If you are building under msys2 try installing the mingw-w64-x86_64-cmake
153 package instead of cmake:
155 $ pacman -R cmake && pacman -S mingw-w64-x86_64-cmake
160 if target
.contains("arm-linux-android") {
161 need_cmd("adb".as_ref());
165 for host
in build
.flags
.host
.iter() {
166 if !build
.config
.host
.contains(host
) {
167 panic
!("specified host `{}` is not in the ./configure list", host
);
170 for target
in build
.flags
.target
.iter() {
171 if !build
.config
.target
.contains(target
) {
172 panic
!("specified target `{}` is not in the ./configure list",
177 let run
= |cmd
: &mut Command
| {
178 cmd
.output().map(|output
| {
179 String
::from_utf8_lossy(&output
.stdout
)
180 .lines().next().unwrap()
184 build
.gdb_version
= run(Command
::new("gdb").arg("--version")).ok();
185 build
.lldb_version
= run(Command
::new("lldb").arg("--version")).ok();
186 if build
.lldb_version
.is_some() {
187 build
.lldb_python_dir
= run(Command
::new("lldb").arg("-P")).ok();