]>
git.proxmox.com Git - rustc.git/blob - src/bootstrap/config.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 //! Serialized configuration of a build.
13 //! This module implements parsing `config.mk` and `config.toml` configuration
14 //! files to tweak how the build runs.
16 use std
::collections
::HashMap
;
19 use std
::io
::prelude
::*;
20 use std
::path
::PathBuf
;
24 use rustc_serialize
::Decodable
;
25 use toml
::{Parser, Decoder, Value}
;
27 /// Global configuration for the entire build and/or bootstrap.
29 /// This structure is derived from a combination of both `config.toml` and
30 /// `config.mk`. As of the time of this writing it's unlikely that `config.toml`
31 /// is used all that much, so this is primarily filled out by `config.mk` which
32 /// is generated from `./configure`.
34 /// Note that this structure is not decoded directly into, but rather it is
35 /// filled out from the decoded forms of the structs below. For documentation
36 /// each field, see the corresponding fields in
37 /// `src/bootstrap/config.toml.example`.
44 pub compiler_docs
: bool
,
46 pub target_config
: HashMap
<String
, Target
>,
48 // llvm codegen options
49 pub llvm_assertions
: bool
,
50 pub llvm_optimize
: bool
,
51 pub llvm_version_check
: bool
,
52 pub llvm_static_stdcpp
: bool
,
54 // rust codegen options
55 pub rust_optimize
: bool
,
56 pub rust_codegen_units
: u32,
57 pub rust_debug_assertions
: bool
,
58 pub rust_debuginfo
: bool
,
60 pub rustc_default_linker
: Option
<String
>,
61 pub rustc_default_ar
: Option
<String
>,
62 pub rust_optimize_tests
: bool
,
63 pub rust_debuginfo_tests
: bool
,
66 pub host
: Vec
<String
>,
67 pub target
: Vec
<String
>,
68 pub rustc
: Option
<PathBuf
>,
69 pub cargo
: Option
<PathBuf
>,
70 pub local_rebuild
: bool
,
73 pub debug_jemalloc
: bool
,
74 pub use_jemalloc
: bool
,
75 pub backtrace
: bool
, // support for RUST_BACKTRACE
79 pub musl_root
: Option
<PathBuf
>,
80 pub prefix
: Option
<String
>,
83 /// Per-target configuration stored in the global configuration structure.
86 pub llvm_config
: Option
<PathBuf
>,
87 pub jemalloc
: Option
<PathBuf
>,
88 pub cc
: Option
<PathBuf
>,
89 pub cxx
: Option
<PathBuf
>,
90 pub ndk
: Option
<PathBuf
>,
93 /// Structure of the `config.toml` file that configuration is read from.
95 /// This structure uses `Decodable` to automatically decode a TOML configuration
96 /// file into this format, and then this is traversed and written into the above
97 /// `Config` structure.
98 #[derive(RustcDecodable, Default)]
100 build
: Option
<Build
>,
103 target
: Option
<HashMap
<String
, TomlTarget
>>,
106 /// TOML representation of various global build decisions.
107 #[derive(RustcDecodable, Default, Clone)]
109 build
: Option
<String
>,
112 cargo
: Option
<String
>,
113 rustc
: Option
<String
>,
114 compiler_docs
: Option
<bool
>,
118 /// TOML representation of how the LLVM build is configured.
119 #[derive(RustcDecodable, Default)]
121 ccache
: Option
<bool
>,
123 assertions
: Option
<bool
>,
124 optimize
: Option
<bool
>,
125 version_check
: Option
<bool
>,
126 static_libstdcpp
: Option
<bool
>,
129 /// TOML representation of how the Rust build is configured.
130 #[derive(RustcDecodable, Default)]
132 optimize
: Option
<bool
>,
133 codegen_units
: Option
<u32>,
134 debug_assertions
: Option
<bool
>,
135 debuginfo
: Option
<bool
>,
136 debug_jemalloc
: Option
<bool
>,
137 use_jemalloc
: Option
<bool
>,
138 backtrace
: Option
<bool
>,
139 default_linker
: Option
<String
>,
140 default_ar
: Option
<String
>,
141 channel
: Option
<String
>,
142 musl_root
: Option
<String
>,
144 optimize_tests
: Option
<bool
>,
145 debuginfo_tests
: Option
<bool
>,
148 /// TOML representation of how each build target is configured.
149 #[derive(RustcDecodable, Default)]
151 llvm_config
: Option
<String
>,
152 jemalloc
: Option
<String
>,
155 android_ndk
: Option
<String
>,
159 pub fn parse(build
: &str, file
: Option
<PathBuf
>) -> Config
{
160 let mut config
= Config
::default();
161 config
.llvm_optimize
= true;
162 config
.use_jemalloc
= true;
163 config
.backtrace
= true;
164 config
.rust_optimize
= true;
165 config
.rust_optimize_tests
= true;
166 config
.submodules
= true;
168 config
.rust_rpath
= true;
169 config
.rust_codegen_units
= 1;
170 config
.build
= build
.to_string();
171 config
.channel
= "dev".to_string();
173 let toml
= file
.map(|file
| {
174 let mut f
= t
!(File
::open(&file
));
175 let mut toml
= String
::new();
176 t
!(f
.read_to_string(&mut toml
));
177 let mut p
= Parser
::new(&toml
);
178 let table
= match p
.parse() {
179 Some(table
) => table
,
181 println
!("failed to parse TOML configuration:");
182 for err
in p
.errors
.iter() {
183 let (loline
, locol
) = p
.to_linecol(err
.lo
);
184 let (hiline
, hicol
) = p
.to_linecol(err
.hi
);
185 println
!("{}:{}-{}:{}: {}", loline
, locol
, hiline
,
191 let mut d
= Decoder
::new(Value
::Table(table
));
192 match Decodable
::decode(&mut d
) {
195 println
!("failed to decode TOML: {}", e
);
199 }).unwrap_or_else(|| TomlConfig
::default());
201 let build
= toml
.build
.clone().unwrap_or(Build
::default());
202 set(&mut config
.build
, build
.build
.clone());
203 config
.host
.push(config
.build
.clone());
204 for host
in build
.host
.iter() {
205 if !config
.host
.contains(host
) {
206 config
.host
.push(host
.clone());
209 for target
in config
.host
.iter().chain(&build
.target
) {
210 if !config
.target
.contains(target
) {
211 config
.target
.push(target
.clone());
214 config
.rustc
= build
.rustc
.map(PathBuf
::from
);
215 config
.cargo
= build
.cargo
.map(PathBuf
::from
);
216 set(&mut config
.compiler_docs
, build
.compiler_docs
);
217 set(&mut config
.docs
, build
.docs
);
219 if let Some(ref llvm
) = toml
.llvm
{
220 set(&mut config
.ccache
, llvm
.ccache
);
221 set(&mut config
.ninja
, llvm
.ninja
);
222 set(&mut config
.llvm_assertions
, llvm
.assertions
);
223 set(&mut config
.llvm_optimize
, llvm
.optimize
);
224 set(&mut config
.llvm_version_check
, llvm
.version_check
);
225 set(&mut config
.llvm_static_stdcpp
, llvm
.static_libstdcpp
);
227 if let Some(ref rust
) = toml
.rust
{
228 set(&mut config
.rust_debug_assertions
, rust
.debug_assertions
);
229 set(&mut config
.rust_debuginfo
, rust
.debuginfo
);
230 set(&mut config
.rust_optimize
, rust
.optimize
);
231 set(&mut config
.rust_optimize_tests
, rust
.optimize_tests
);
232 set(&mut config
.rust_debuginfo_tests
, rust
.debuginfo_tests
);
233 set(&mut config
.rust_rpath
, rust
.rpath
);
234 set(&mut config
.debug_jemalloc
, rust
.debug_jemalloc
);
235 set(&mut config
.use_jemalloc
, rust
.use_jemalloc
);
236 set(&mut config
.backtrace
, rust
.backtrace
);
237 set(&mut config
.channel
, rust
.channel
.clone());
238 config
.rustc_default_linker
= rust
.default_linker
.clone();
239 config
.rustc_default_ar
= rust
.default_ar
.clone();
240 config
.musl_root
= rust
.musl_root
.clone().map(PathBuf
::from
);
242 match rust
.codegen_units
{
243 Some(0) => config
.rust_codegen_units
= num_cpus
::get() as u32,
244 Some(n
) => config
.rust_codegen_units
= n
,
249 if let Some(ref t
) = toml
.target
{
250 for (triple
, cfg
) in t
{
251 let mut target
= Target
::default();
253 if let Some(ref s
) = cfg
.llvm_config
{
254 target
.llvm_config
= Some(env
::current_dir().unwrap().join(s
));
256 if let Some(ref s
) = cfg
.jemalloc
{
257 target
.jemalloc
= Some(env
::current_dir().unwrap().join(s
));
259 if let Some(ref s
) = cfg
.android_ndk
{
260 target
.ndk
= Some(env
::current_dir().unwrap().join(s
));
262 target
.cxx
= cfg
.cxx
.clone().map(PathBuf
::from
);
263 target
.cc
= cfg
.cc
.clone().map(PathBuf
::from
);
265 config
.target_config
.insert(triple
.clone(), target
);
272 /// "Temporary" routine to parse `config.mk` into this configuration.
274 /// While we still have `./configure` this implements the ability to decode
275 /// that configuration into this. This isn't exactly a full-blown makefile
276 /// parser, but hey it gets the job done!
277 pub fn update_with_config_mk(&mut self) {
278 let mut config
= String
::new();
279 File
::open("config.mk").unwrap().read_to_string(&mut config
).unwrap();
280 for line
in config
.lines() {
281 let mut parts
= line
.splitn(2, ":=").map(|s
| s
.trim());
282 let key
= parts
.next().unwrap();
283 let value
= match parts
.next() {
284 Some(n
) if n
.starts_with('
\"'
) => &n
[1..n
.len() - 1],
290 ($
(($name
:expr
, $val
:expr
),)*) => {
293 if key
== concat
!("CFG_ENABLE_", $name
) {
297 if key
== concat
!("CFG_DISABLE_", $name
) {
307 ("CCACHE", self.ccache
),
308 ("MANAGE_SUBMODULES", self.submodules
),
309 ("COMPILER_DOCS", self.compiler_docs
),
311 ("LLVM_ASSERTIONS", self.llvm_assertions
),
312 ("OPTIMIZE_LLVM", self.llvm_optimize
),
313 ("LLVM_VERSION_CHECK", self.llvm_version_check
),
314 ("LLVM_STATIC_STDCPP", self.llvm_static_stdcpp
),
315 ("OPTIMIZE", self.rust_optimize
),
316 ("DEBUG_ASSERTIONS", self.rust_debug_assertions
),
317 ("DEBUGINFO", self.rust_debuginfo
),
318 ("JEMALLOC", self.use_jemalloc
),
319 ("DEBUG_JEMALLOC", self.debug_jemalloc
),
320 ("RPATH", self.rust_rpath
),
321 ("OPTIMIZE_TESTS", self.rust_optimize_tests
),
322 ("DEBUGINFO_TESTS", self.rust_debuginfo_tests
),
323 ("LOCAL_REBUILD", self.local_rebuild
),
324 ("NINJA", self.ninja
),
328 "CFG_BUILD" => self.build
= value
.to_string(),
330 self.host
= value
.split(" ").map(|s
| s
.to_string())
334 self.target
= value
.split(" ").map(|s
| s
.to_string())
337 "CFG_MUSL_ROOT" if value
.len() > 0 => {
338 self.musl_root
= Some(PathBuf
::from(value
));
340 "CFG_DEFAULT_AR" if value
.len() > 0 => {
341 self.rustc_default_ar
= Some(value
.to_string());
343 "CFG_DEFAULT_LINKER" if value
.len() > 0 => {
344 self.rustc_default_linker
= Some(value
.to_string());
346 "CFG_RELEASE_CHANNEL" => {
347 self.channel
= value
.to_string();
350 self.prefix
= Some(value
.to_string());
352 "CFG_LLVM_ROOT" if value
.len() > 0 => {
353 let target
= self.target_config
.entry(self.build
.clone())
354 .or_insert(Target
::default());
355 let root
= PathBuf
::from(value
);
356 target
.llvm_config
= Some(root
.join("bin/llvm-config"));
358 "CFG_JEMALLOC_ROOT" if value
.len() > 0 => {
359 let target
= self.target_config
.entry(self.build
.clone())
360 .or_insert(Target
::default());
361 target
.jemalloc
= Some(PathBuf
::from(value
));
363 "CFG_ARM_LINUX_ANDROIDEABI_NDK" if value
.len() > 0 => {
364 let target
= "arm-linux-androideabi".to_string();
365 let target
= self.target_config
.entry(target
)
366 .or_insert(Target
::default());
367 target
.ndk
= Some(PathBuf
::from(value
));
369 "CFG_ARMV7_LINUX_ANDROIDEABI_NDK" if value
.len() > 0 => {
370 let target
= "armv7-linux-androideabi".to_string();
371 let target
= self.target_config
.entry(target
)
372 .or_insert(Target
::default());
373 target
.ndk
= Some(PathBuf
::from(value
));
375 "CFG_I686_LINUX_ANDROID_NDK" if value
.len() > 0 => {
376 let target
= "i686-linux-android".to_string();
377 let target
= self.target_config
.entry(target
)
378 .or_insert(Target
::default());
379 target
.ndk
= Some(PathBuf
::from(value
));
381 "CFG_AARCH64_LINUX_ANDROID_NDK" if value
.len() > 0 => {
382 let target
= "aarch64-linux-android".to_string();
383 let target
= self.target_config
.entry(target
)
384 .or_insert(Target
::default());
385 target
.ndk
= Some(PathBuf
::from(value
));
387 "CFG_LOCAL_RUST_ROOT" if value
.len() > 0 => {
388 self.rustc
= Some(PathBuf
::from(value
).join("bin/rustc"));
389 self.cargo
= Some(PathBuf
::from(value
).join("bin/cargo"));
397 fn set
<T
>(field
: &mut T
, val
: Option
<T
>) {
398 if let Some(v
) = val
{