]>
Commit | Line | Data |
---|---|---|
7453a54e SL |
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. | |
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 | ||
a7813a04 XL |
11 | //! Serialized configuration of a build. |
12 | //! | |
13 | //! This module implements parsing `config.mk` and `config.toml` configuration | |
14 | //! files to tweak how the build runs. | |
15 | ||
7453a54e SL |
16 | use std::collections::HashMap; |
17 | use std::env; | |
18 | use std::fs::File; | |
19 | use std::io::prelude::*; | |
20 | use std::path::PathBuf; | |
21 | use std::process; | |
22 | ||
23 | use num_cpus; | |
24 | use rustc_serialize::Decodable; | |
25 | use toml::{Parser, Decoder, Value}; | |
c30ab7b3 | 26 | use util::push_exe_path; |
7453a54e SL |
27 | |
28 | /// Global configuration for the entire build and/or bootstrap. | |
29 | /// | |
30 | /// This structure is derived from a combination of both `config.toml` and | |
31 | /// `config.mk`. As of the time of this writing it's unlikely that `config.toml` | |
32 | /// is used all that much, so this is primarily filled out by `config.mk` which | |
33 | /// is generated from `./configure`. | |
34 | /// | |
35 | /// Note that this structure is not decoded directly into, but rather it is | |
a7813a04 XL |
36 | /// filled out from the decoded forms of the structs below. For documentation |
37 | /// each field, see the corresponding fields in | |
38 | /// `src/bootstrap/config.toml.example`. | |
7453a54e SL |
39 | #[derive(Default)] |
40 | pub struct Config { | |
476ff2be | 41 | pub ccache: Option<String>, |
a7813a04 | 42 | pub ninja: bool, |
32a655c1 | 43 | pub verbose: usize, |
7453a54e SL |
44 | pub submodules: bool, |
45 | pub compiler_docs: bool, | |
46 | pub docs: bool, | |
8bb4bdeb | 47 | pub locked_deps: bool, |
476ff2be | 48 | pub vendor: bool, |
7453a54e | 49 | pub target_config: HashMap<String, Target>, |
32a655c1 SL |
50 | pub full_bootstrap: bool, |
51 | pub extended: bool, | |
8bb4bdeb | 52 | pub sanitizers: bool, |
7453a54e SL |
53 | |
54 | // llvm codegen options | |
55 | pub llvm_assertions: bool, | |
56 | pub llvm_optimize: bool, | |
476ff2be | 57 | pub llvm_release_debuginfo: bool, |
7453a54e SL |
58 | pub llvm_version_check: bool, |
59 | pub llvm_static_stdcpp: bool, | |
476ff2be | 60 | pub llvm_link_shared: bool, |
32a655c1 | 61 | pub llvm_targets: Option<String>, |
8bb4bdeb XL |
62 | pub llvm_link_jobs: Option<u32>, |
63 | pub llvm_clean_rebuild: bool, | |
7453a54e SL |
64 | |
65 | // rust codegen options | |
66 | pub rust_optimize: bool, | |
67 | pub rust_codegen_units: u32, | |
68 | pub rust_debug_assertions: bool, | |
69 | pub rust_debuginfo: bool, | |
c30ab7b3 | 70 | pub rust_debuginfo_lines: bool, |
476ff2be | 71 | pub rust_debuginfo_only_std: bool, |
7453a54e SL |
72 | pub rust_rpath: bool, |
73 | pub rustc_default_linker: Option<String>, | |
74 | pub rustc_default_ar: Option<String>, | |
a7813a04 XL |
75 | pub rust_optimize_tests: bool, |
76 | pub rust_debuginfo_tests: bool, | |
8bb4bdeb | 77 | pub rust_dist_src: bool, |
7453a54e SL |
78 | |
79 | pub build: String, | |
80 | pub host: Vec<String>, | |
81 | pub target: Vec<String>, | |
3157f602 XL |
82 | pub rustc: Option<PathBuf>, |
83 | pub cargo: Option<PathBuf>, | |
84 | pub local_rebuild: bool, | |
7453a54e | 85 | |
32a655c1 SL |
86 | // dist misc |
87 | pub dist_sign_folder: Option<PathBuf>, | |
88 | pub dist_upload_addr: Option<String>, | |
89 | pub dist_gpg_password_file: Option<PathBuf>, | |
90 | ||
7453a54e SL |
91 | // libstd features |
92 | pub debug_jemalloc: bool, | |
93 | pub use_jemalloc: bool, | |
5bcae85e | 94 | pub backtrace: bool, // support for RUST_BACKTRACE |
7453a54e SL |
95 | |
96 | // misc | |
97 | pub channel: String, | |
c30ab7b3 | 98 | pub quiet_tests: bool, |
9e0c209e | 99 | // Fallback musl-root for all targets |
7453a54e | 100 | pub musl_root: Option<PathBuf>, |
32a655c1 SL |
101 | pub prefix: Option<PathBuf>, |
102 | pub docdir: Option<PathBuf>, | |
103 | pub libdir: Option<PathBuf>, | |
104 | pub libdir_relative: Option<PathBuf>, | |
105 | pub mandir: Option<PathBuf>, | |
9e0c209e SL |
106 | pub codegen_tests: bool, |
107 | pub nodejs: Option<PathBuf>, | |
c30ab7b3 | 108 | pub gdb: Option<PathBuf>, |
476ff2be | 109 | pub python: Option<PathBuf>, |
32a655c1 | 110 | pub configure_args: Vec<String>, |
8bb4bdeb | 111 | pub openssl_static: bool, |
7453a54e SL |
112 | } |
113 | ||
114 | /// Per-target configuration stored in the global configuration structure. | |
115 | #[derive(Default)] | |
116 | pub struct Target { | |
117 | pub llvm_config: Option<PathBuf>, | |
118 | pub jemalloc: Option<PathBuf>, | |
119 | pub cc: Option<PathBuf>, | |
120 | pub cxx: Option<PathBuf>, | |
121 | pub ndk: Option<PathBuf>, | |
9e0c209e | 122 | pub musl_root: Option<PathBuf>, |
8bb4bdeb | 123 | pub qemu_rootfs: Option<PathBuf>, |
7453a54e SL |
124 | } |
125 | ||
126 | /// Structure of the `config.toml` file that configuration is read from. | |
127 | /// | |
128 | /// This structure uses `Decodable` to automatically decode a TOML configuration | |
129 | /// file into this format, and then this is traversed and written into the above | |
130 | /// `Config` structure. | |
131 | #[derive(RustcDecodable, Default)] | |
132 | struct TomlConfig { | |
133 | build: Option<Build>, | |
32a655c1 | 134 | install: Option<Install>, |
7453a54e SL |
135 | llvm: Option<Llvm>, |
136 | rust: Option<Rust>, | |
137 | target: Option<HashMap<String, TomlTarget>>, | |
32a655c1 | 138 | dist: Option<Dist>, |
7453a54e SL |
139 | } |
140 | ||
141 | /// TOML representation of various global build decisions. | |
142 | #[derive(RustcDecodable, Default, Clone)] | |
143 | struct Build { | |
144 | build: Option<String>, | |
145 | host: Vec<String>, | |
146 | target: Vec<String>, | |
147 | cargo: Option<String>, | |
148 | rustc: Option<String>, | |
149 | compiler_docs: Option<bool>, | |
150 | docs: Option<bool>, | |
c30ab7b3 SL |
151 | submodules: Option<bool>, |
152 | gdb: Option<String>, | |
8bb4bdeb | 153 | locked_deps: Option<bool>, |
476ff2be SL |
154 | vendor: Option<bool>, |
155 | nodejs: Option<String>, | |
156 | python: Option<String>, | |
32a655c1 SL |
157 | full_bootstrap: Option<bool>, |
158 | extended: Option<bool>, | |
8bb4bdeb XL |
159 | verbose: Option<usize>, |
160 | sanitizers: Option<bool>, | |
161 | openssl_static: Option<bool>, | |
32a655c1 SL |
162 | } |
163 | ||
164 | /// TOML representation of various global install decisions. | |
165 | #[derive(RustcDecodable, Default, Clone)] | |
166 | struct Install { | |
167 | prefix: Option<String>, | |
168 | mandir: Option<String>, | |
169 | docdir: Option<String>, | |
170 | libdir: Option<String>, | |
7453a54e SL |
171 | } |
172 | ||
173 | /// TOML representation of how the LLVM build is configured. | |
174 | #[derive(RustcDecodable, Default)] | |
175 | struct Llvm { | |
476ff2be | 176 | ccache: Option<StringOrBool>, |
a7813a04 | 177 | ninja: Option<bool>, |
7453a54e SL |
178 | assertions: Option<bool>, |
179 | optimize: Option<bool>, | |
476ff2be | 180 | release_debuginfo: Option<bool>, |
7453a54e SL |
181 | version_check: Option<bool>, |
182 | static_libstdcpp: Option<bool>, | |
32a655c1 | 183 | targets: Option<String>, |
8bb4bdeb XL |
184 | link_jobs: Option<u32>, |
185 | clean_rebuild: Option<bool>, | |
32a655c1 SL |
186 | } |
187 | ||
188 | #[derive(RustcDecodable, Default, Clone)] | |
189 | struct Dist { | |
190 | sign_folder: Option<String>, | |
191 | gpg_password_file: Option<String>, | |
192 | upload_addr: Option<String>, | |
8bb4bdeb | 193 | src_tarball: Option<bool>, |
7453a54e SL |
194 | } |
195 | ||
476ff2be SL |
196 | #[derive(RustcDecodable)] |
197 | enum StringOrBool { | |
198 | String(String), | |
199 | Bool(bool), | |
200 | } | |
201 | ||
202 | impl Default for StringOrBool { | |
203 | fn default() -> StringOrBool { | |
204 | StringOrBool::Bool(false) | |
205 | } | |
206 | } | |
207 | ||
7453a54e SL |
208 | /// TOML representation of how the Rust build is configured. |
209 | #[derive(RustcDecodable, Default)] | |
210 | struct Rust { | |
211 | optimize: Option<bool>, | |
212 | codegen_units: Option<u32>, | |
213 | debug_assertions: Option<bool>, | |
214 | debuginfo: Option<bool>, | |
c30ab7b3 | 215 | debuginfo_lines: Option<bool>, |
476ff2be | 216 | debuginfo_only_std: Option<bool>, |
7453a54e SL |
217 | debug_jemalloc: Option<bool>, |
218 | use_jemalloc: Option<bool>, | |
5bcae85e | 219 | backtrace: Option<bool>, |
7453a54e SL |
220 | default_linker: Option<String>, |
221 | default_ar: Option<String>, | |
222 | channel: Option<String>, | |
223 | musl_root: Option<String>, | |
224 | rpath: Option<bool>, | |
a7813a04 XL |
225 | optimize_tests: Option<bool>, |
226 | debuginfo_tests: Option<bool>, | |
9e0c209e | 227 | codegen_tests: Option<bool>, |
7453a54e SL |
228 | } |
229 | ||
230 | /// TOML representation of how each build target is configured. | |
231 | #[derive(RustcDecodable, Default)] | |
232 | struct TomlTarget { | |
233 | llvm_config: Option<String>, | |
234 | jemalloc: Option<String>, | |
235 | cc: Option<String>, | |
236 | cxx: Option<String>, | |
237 | android_ndk: Option<String>, | |
c30ab7b3 | 238 | musl_root: Option<String>, |
8bb4bdeb | 239 | qemu_rootfs: Option<String>, |
7453a54e SL |
240 | } |
241 | ||
242 | impl Config { | |
243 | pub fn parse(build: &str, file: Option<PathBuf>) -> Config { | |
244 | let mut config = Config::default(); | |
245 | config.llvm_optimize = true; | |
246 | config.use_jemalloc = true; | |
5bcae85e | 247 | config.backtrace = true; |
7453a54e | 248 | config.rust_optimize = true; |
a7813a04 | 249 | config.rust_optimize_tests = true; |
7453a54e SL |
250 | config.submodules = true; |
251 | config.docs = true; | |
252 | config.rust_rpath = true; | |
253 | config.rust_codegen_units = 1; | |
254 | config.build = build.to_string(); | |
255 | config.channel = "dev".to_string(); | |
9e0c209e | 256 | config.codegen_tests = true; |
8bb4bdeb | 257 | config.rust_dist_src = true; |
7453a54e SL |
258 | |
259 | let toml = file.map(|file| { | |
260 | let mut f = t!(File::open(&file)); | |
261 | let mut toml = String::new(); | |
262 | t!(f.read_to_string(&mut toml)); | |
263 | let mut p = Parser::new(&toml); | |
264 | let table = match p.parse() { | |
265 | Some(table) => table, | |
266 | None => { | |
267 | println!("failed to parse TOML configuration:"); | |
268 | for err in p.errors.iter() { | |
269 | let (loline, locol) = p.to_linecol(err.lo); | |
270 | let (hiline, hicol) = p.to_linecol(err.hi); | |
271 | println!("{}:{}-{}:{}: {}", loline, locol, hiline, | |
272 | hicol, err.desc); | |
273 | } | |
274 | process::exit(2); | |
275 | } | |
276 | }; | |
277 | let mut d = Decoder::new(Value::Table(table)); | |
278 | match Decodable::decode(&mut d) { | |
279 | Ok(cfg) => cfg, | |
280 | Err(e) => { | |
281 | println!("failed to decode TOML: {}", e); | |
282 | process::exit(2); | |
283 | } | |
284 | } | |
285 | }).unwrap_or_else(|| TomlConfig::default()); | |
286 | ||
287 | let build = toml.build.clone().unwrap_or(Build::default()); | |
288 | set(&mut config.build, build.build.clone()); | |
289 | config.host.push(config.build.clone()); | |
290 | for host in build.host.iter() { | |
291 | if !config.host.contains(host) { | |
292 | config.host.push(host.clone()); | |
293 | } | |
294 | } | |
295 | for target in config.host.iter().chain(&build.target) { | |
296 | if !config.target.contains(target) { | |
297 | config.target.push(target.clone()); | |
298 | } | |
299 | } | |
3157f602 XL |
300 | config.rustc = build.rustc.map(PathBuf::from); |
301 | config.cargo = build.cargo.map(PathBuf::from); | |
476ff2be | 302 | config.nodejs = build.nodejs.map(PathBuf::from); |
c30ab7b3 | 303 | config.gdb = build.gdb.map(PathBuf::from); |
476ff2be | 304 | config.python = build.python.map(PathBuf::from); |
7453a54e SL |
305 | set(&mut config.compiler_docs, build.compiler_docs); |
306 | set(&mut config.docs, build.docs); | |
c30ab7b3 | 307 | set(&mut config.submodules, build.submodules); |
8bb4bdeb | 308 | set(&mut config.locked_deps, build.locked_deps); |
476ff2be | 309 | set(&mut config.vendor, build.vendor); |
32a655c1 SL |
310 | set(&mut config.full_bootstrap, build.full_bootstrap); |
311 | set(&mut config.extended, build.extended); | |
8bb4bdeb XL |
312 | set(&mut config.verbose, build.verbose); |
313 | set(&mut config.sanitizers, build.sanitizers); | |
314 | set(&mut config.openssl_static, build.openssl_static); | |
32a655c1 SL |
315 | |
316 | if let Some(ref install) = toml.install { | |
317 | config.prefix = install.prefix.clone().map(PathBuf::from); | |
318 | config.mandir = install.mandir.clone().map(PathBuf::from); | |
319 | config.docdir = install.docdir.clone().map(PathBuf::from); | |
320 | config.libdir = install.libdir.clone().map(PathBuf::from); | |
321 | } | |
7453a54e SL |
322 | |
323 | if let Some(ref llvm) = toml.llvm { | |
476ff2be SL |
324 | match llvm.ccache { |
325 | Some(StringOrBool::String(ref s)) => { | |
326 | config.ccache = Some(s.to_string()) | |
327 | } | |
328 | Some(StringOrBool::Bool(true)) => { | |
329 | config.ccache = Some("ccache".to_string()); | |
330 | } | |
331 | Some(StringOrBool::Bool(false)) | None => {} | |
332 | } | |
a7813a04 | 333 | set(&mut config.ninja, llvm.ninja); |
7453a54e SL |
334 | set(&mut config.llvm_assertions, llvm.assertions); |
335 | set(&mut config.llvm_optimize, llvm.optimize); | |
476ff2be | 336 | set(&mut config.llvm_release_debuginfo, llvm.release_debuginfo); |
7453a54e SL |
337 | set(&mut config.llvm_version_check, llvm.version_check); |
338 | set(&mut config.llvm_static_stdcpp, llvm.static_libstdcpp); | |
8bb4bdeb | 339 | set(&mut config.llvm_clean_rebuild, llvm.clean_rebuild); |
32a655c1 | 340 | config.llvm_targets = llvm.targets.clone(); |
8bb4bdeb | 341 | config.llvm_link_jobs = llvm.link_jobs; |
7453a54e | 342 | } |
32a655c1 | 343 | |
7453a54e SL |
344 | if let Some(ref rust) = toml.rust { |
345 | set(&mut config.rust_debug_assertions, rust.debug_assertions); | |
346 | set(&mut config.rust_debuginfo, rust.debuginfo); | |
c30ab7b3 | 347 | set(&mut config.rust_debuginfo_lines, rust.debuginfo_lines); |
476ff2be | 348 | set(&mut config.rust_debuginfo_only_std, rust.debuginfo_only_std); |
7453a54e | 349 | set(&mut config.rust_optimize, rust.optimize); |
a7813a04 XL |
350 | set(&mut config.rust_optimize_tests, rust.optimize_tests); |
351 | set(&mut config.rust_debuginfo_tests, rust.debuginfo_tests); | |
9e0c209e | 352 | set(&mut config.codegen_tests, rust.codegen_tests); |
7453a54e SL |
353 | set(&mut config.rust_rpath, rust.rpath); |
354 | set(&mut config.debug_jemalloc, rust.debug_jemalloc); | |
355 | set(&mut config.use_jemalloc, rust.use_jemalloc); | |
5bcae85e | 356 | set(&mut config.backtrace, rust.backtrace); |
7453a54e SL |
357 | set(&mut config.channel, rust.channel.clone()); |
358 | config.rustc_default_linker = rust.default_linker.clone(); | |
359 | config.rustc_default_ar = rust.default_ar.clone(); | |
360 | config.musl_root = rust.musl_root.clone().map(PathBuf::from); | |
361 | ||
362 | match rust.codegen_units { | |
363 | Some(0) => config.rust_codegen_units = num_cpus::get() as u32, | |
364 | Some(n) => config.rust_codegen_units = n, | |
365 | None => {} | |
366 | } | |
367 | } | |
368 | ||
369 | if let Some(ref t) = toml.target { | |
370 | for (triple, cfg) in t { | |
371 | let mut target = Target::default(); | |
372 | ||
373 | if let Some(ref s) = cfg.llvm_config { | |
374 | target.llvm_config = Some(env::current_dir().unwrap().join(s)); | |
375 | } | |
376 | if let Some(ref s) = cfg.jemalloc { | |
377 | target.jemalloc = Some(env::current_dir().unwrap().join(s)); | |
378 | } | |
379 | if let Some(ref s) = cfg.android_ndk { | |
380 | target.ndk = Some(env::current_dir().unwrap().join(s)); | |
381 | } | |
382 | target.cxx = cfg.cxx.clone().map(PathBuf::from); | |
383 | target.cc = cfg.cc.clone().map(PathBuf::from); | |
c30ab7b3 | 384 | target.musl_root = cfg.musl_root.clone().map(PathBuf::from); |
8bb4bdeb | 385 | target.qemu_rootfs = cfg.qemu_rootfs.clone().map(PathBuf::from); |
7453a54e SL |
386 | |
387 | config.target_config.insert(triple.clone(), target); | |
388 | } | |
389 | } | |
390 | ||
32a655c1 SL |
391 | if let Some(ref t) = toml.dist { |
392 | config.dist_sign_folder = t.sign_folder.clone().map(PathBuf::from); | |
393 | config.dist_gpg_password_file = t.gpg_password_file.clone().map(PathBuf::from); | |
394 | config.dist_upload_addr = t.upload_addr.clone(); | |
8bb4bdeb | 395 | set(&mut config.rust_dist_src, t.src_tarball); |
32a655c1 SL |
396 | } |
397 | ||
7453a54e SL |
398 | return config |
399 | } | |
400 | ||
a7813a04 XL |
401 | /// "Temporary" routine to parse `config.mk` into this configuration. |
402 | /// | |
403 | /// While we still have `./configure` this implements the ability to decode | |
404 | /// that configuration into this. This isn't exactly a full-blown makefile | |
405 | /// parser, but hey it gets the job done! | |
7453a54e SL |
406 | pub fn update_with_config_mk(&mut self) { |
407 | let mut config = String::new(); | |
408 | File::open("config.mk").unwrap().read_to_string(&mut config).unwrap(); | |
409 | for line in config.lines() { | |
410 | let mut parts = line.splitn(2, ":=").map(|s| s.trim()); | |
411 | let key = parts.next().unwrap(); | |
412 | let value = match parts.next() { | |
413 | Some(n) if n.starts_with('\"') => &n[1..n.len() - 1], | |
414 | Some(n) => n, | |
415 | None => continue | |
416 | }; | |
417 | ||
418 | macro_rules! check { | |
419 | ($(($name:expr, $val:expr),)*) => { | |
420 | if value == "1" { | |
421 | $( | |
422 | if key == concat!("CFG_ENABLE_", $name) { | |
423 | $val = true; | |
424 | continue | |
425 | } | |
426 | if key == concat!("CFG_DISABLE_", $name) { | |
427 | $val = false; | |
428 | continue | |
429 | } | |
430 | )* | |
431 | } | |
432 | } | |
433 | } | |
434 | ||
435 | check! { | |
7453a54e SL |
436 | ("MANAGE_SUBMODULES", self.submodules), |
437 | ("COMPILER_DOCS", self.compiler_docs), | |
438 | ("DOCS", self.docs), | |
439 | ("LLVM_ASSERTIONS", self.llvm_assertions), | |
476ff2be | 440 | ("LLVM_RELEASE_DEBUGINFO", self.llvm_release_debuginfo), |
7453a54e SL |
441 | ("OPTIMIZE_LLVM", self.llvm_optimize), |
442 | ("LLVM_VERSION_CHECK", self.llvm_version_check), | |
443 | ("LLVM_STATIC_STDCPP", self.llvm_static_stdcpp), | |
476ff2be | 444 | ("LLVM_LINK_SHARED", self.llvm_link_shared), |
8bb4bdeb | 445 | ("LLVM_CLEAN_REBUILD", self.llvm_clean_rebuild), |
7453a54e SL |
446 | ("OPTIMIZE", self.rust_optimize), |
447 | ("DEBUG_ASSERTIONS", self.rust_debug_assertions), | |
448 | ("DEBUGINFO", self.rust_debuginfo), | |
c30ab7b3 | 449 | ("DEBUGINFO_LINES", self.rust_debuginfo_lines), |
476ff2be | 450 | ("DEBUGINFO_ONLY_STD", self.rust_debuginfo_only_std), |
7453a54e SL |
451 | ("JEMALLOC", self.use_jemalloc), |
452 | ("DEBUG_JEMALLOC", self.debug_jemalloc), | |
453 | ("RPATH", self.rust_rpath), | |
a7813a04 XL |
454 | ("OPTIMIZE_TESTS", self.rust_optimize_tests), |
455 | ("DEBUGINFO_TESTS", self.rust_debuginfo_tests), | |
c30ab7b3 | 456 | ("QUIET_TESTS", self.quiet_tests), |
3157f602 | 457 | ("LOCAL_REBUILD", self.local_rebuild), |
5bcae85e | 458 | ("NINJA", self.ninja), |
9e0c209e | 459 | ("CODEGEN_TESTS", self.codegen_tests), |
8bb4bdeb | 460 | ("LOCKED_DEPS", self.locked_deps), |
476ff2be | 461 | ("VENDOR", self.vendor), |
32a655c1 SL |
462 | ("FULL_BOOTSTRAP", self.full_bootstrap), |
463 | ("EXTENDED", self.extended), | |
8bb4bdeb XL |
464 | ("SANITIZERS", self.sanitizers), |
465 | ("DIST_SRC", self.rust_dist_src), | |
466 | ("CARGO_OPENSSL_STATIC", self.openssl_static), | |
7453a54e SL |
467 | } |
468 | ||
469 | match key { | |
8bb4bdeb XL |
470 | "CFG_BUILD" if value.len() > 0 => self.build = value.to_string(), |
471 | "CFG_HOST" if value.len() > 0 => { | |
472 | self.host.extend(value.split(" ").map(|s| s.to_string())); | |
473 | ||
7453a54e | 474 | } |
8bb4bdeb XL |
475 | "CFG_TARGET" if value.len() > 0 => { |
476 | self.target.extend(value.split(" ").map(|s| s.to_string())); | |
7453a54e SL |
477 | } |
478 | "CFG_MUSL_ROOT" if value.len() > 0 => { | |
c30ab7b3 SL |
479 | self.musl_root = Some(parse_configure_path(value)); |
480 | } | |
481 | "CFG_MUSL_ROOT_X86_64" if value.len() > 0 => { | |
482 | let target = "x86_64-unknown-linux-musl".to_string(); | |
483 | let target = self.target_config.entry(target) | |
484 | .or_insert(Target::default()); | |
485 | target.musl_root = Some(parse_configure_path(value)); | |
486 | } | |
487 | "CFG_MUSL_ROOT_I686" if value.len() > 0 => { | |
488 | let target = "i686-unknown-linux-musl".to_string(); | |
489 | let target = self.target_config.entry(target) | |
490 | .or_insert(Target::default()); | |
491 | target.musl_root = Some(parse_configure_path(value)); | |
492 | } | |
493 | "CFG_MUSL_ROOT_ARM" if value.len() > 0 => { | |
494 | let target = "arm-unknown-linux-musleabi".to_string(); | |
495 | let target = self.target_config.entry(target) | |
496 | .or_insert(Target::default()); | |
497 | target.musl_root = Some(parse_configure_path(value)); | |
498 | } | |
499 | "CFG_MUSL_ROOT_ARMHF" if value.len() > 0 => { | |
500 | let target = "arm-unknown-linux-musleabihf".to_string(); | |
501 | let target = self.target_config.entry(target) | |
502 | .or_insert(Target::default()); | |
503 | target.musl_root = Some(parse_configure_path(value)); | |
504 | } | |
505 | "CFG_MUSL_ROOT_ARMV7" if value.len() > 0 => { | |
506 | let target = "armv7-unknown-linux-musleabihf".to_string(); | |
507 | let target = self.target_config.entry(target) | |
508 | .or_insert(Target::default()); | |
509 | target.musl_root = Some(parse_configure_path(value)); | |
7453a54e SL |
510 | } |
511 | "CFG_DEFAULT_AR" if value.len() > 0 => { | |
512 | self.rustc_default_ar = Some(value.to_string()); | |
513 | } | |
514 | "CFG_DEFAULT_LINKER" if value.len() > 0 => { | |
515 | self.rustc_default_linker = Some(value.to_string()); | |
516 | } | |
c30ab7b3 SL |
517 | "CFG_GDB" if value.len() > 0 => { |
518 | self.gdb = Some(parse_configure_path(value)); | |
519 | } | |
7453a54e SL |
520 | "CFG_RELEASE_CHANNEL" => { |
521 | self.channel = value.to_string(); | |
522 | } | |
523 | "CFG_PREFIX" => { | |
32a655c1 | 524 | self.prefix = Some(PathBuf::from(value)); |
7453a54e | 525 | } |
c30ab7b3 | 526 | "CFG_DOCDIR" => { |
32a655c1 | 527 | self.docdir = Some(PathBuf::from(value)); |
c30ab7b3 SL |
528 | } |
529 | "CFG_LIBDIR" => { | |
32a655c1 SL |
530 | self.libdir = Some(PathBuf::from(value)); |
531 | } | |
532 | "CFG_LIBDIR_RELATIVE" => { | |
533 | self.libdir_relative = Some(PathBuf::from(value)); | |
c30ab7b3 SL |
534 | } |
535 | "CFG_MANDIR" => { | |
32a655c1 | 536 | self.mandir = Some(PathBuf::from(value)); |
c30ab7b3 | 537 | } |
7453a54e SL |
538 | "CFG_LLVM_ROOT" if value.len() > 0 => { |
539 | let target = self.target_config.entry(self.build.clone()) | |
540 | .or_insert(Target::default()); | |
c30ab7b3 SL |
541 | let root = parse_configure_path(value); |
542 | target.llvm_config = Some(push_exe_path(root, &["bin", "llvm-config"])); | |
7453a54e SL |
543 | } |
544 | "CFG_JEMALLOC_ROOT" if value.len() > 0 => { | |
545 | let target = self.target_config.entry(self.build.clone()) | |
546 | .or_insert(Target::default()); | |
32a655c1 | 547 | target.jemalloc = Some(parse_configure_path(value).join("libjemalloc_pic.a")); |
7453a54e SL |
548 | } |
549 | "CFG_ARM_LINUX_ANDROIDEABI_NDK" if value.len() > 0 => { | |
550 | let target = "arm-linux-androideabi".to_string(); | |
551 | let target = self.target_config.entry(target) | |
a7813a04 | 552 | .or_insert(Target::default()); |
c30ab7b3 | 553 | target.ndk = Some(parse_configure_path(value)); |
a7813a04 XL |
554 | } |
555 | "CFG_ARMV7_LINUX_ANDROIDEABI_NDK" if value.len() > 0 => { | |
556 | let target = "armv7-linux-androideabi".to_string(); | |
557 | let target = self.target_config.entry(target) | |
7453a54e | 558 | .or_insert(Target::default()); |
c30ab7b3 | 559 | target.ndk = Some(parse_configure_path(value)); |
7453a54e SL |
560 | } |
561 | "CFG_I686_LINUX_ANDROID_NDK" if value.len() > 0 => { | |
3157f602 | 562 | let target = "i686-linux-android".to_string(); |
7453a54e SL |
563 | let target = self.target_config.entry(target) |
564 | .or_insert(Target::default()); | |
c30ab7b3 | 565 | target.ndk = Some(parse_configure_path(value)); |
7453a54e SL |
566 | } |
567 | "CFG_AARCH64_LINUX_ANDROID_NDK" if value.len() > 0 => { | |
3157f602 | 568 | let target = "aarch64-linux-android".to_string(); |
7453a54e SL |
569 | let target = self.target_config.entry(target) |
570 | .or_insert(Target::default()); | |
c30ab7b3 | 571 | target.ndk = Some(parse_configure_path(value)); |
7453a54e | 572 | } |
3157f602 | 573 | "CFG_LOCAL_RUST_ROOT" if value.len() > 0 => { |
c30ab7b3 SL |
574 | let path = parse_configure_path(value); |
575 | self.rustc = Some(push_exe_path(path.clone(), &["bin", "rustc"])); | |
576 | self.cargo = Some(push_exe_path(path, &["bin", "cargo"])); | |
9e0c209e | 577 | } |
476ff2be SL |
578 | "CFG_PYTHON" if value.len() > 0 => { |
579 | let path = parse_configure_path(value); | |
580 | self.python = Some(path); | |
581 | } | |
582 | "CFG_ENABLE_CCACHE" if value == "1" => { | |
583 | self.ccache = Some("ccache".to_string()); | |
584 | } | |
585 | "CFG_ENABLE_SCCACHE" if value == "1" => { | |
586 | self.ccache = Some("sccache".to_string()); | |
587 | } | |
32a655c1 SL |
588 | "CFG_CONFIGURE_ARGS" if value.len() > 0 => { |
589 | self.configure_args = value.split_whitespace() | |
590 | .map(|s| s.to_string()) | |
591 | .collect(); | |
592 | } | |
8bb4bdeb XL |
593 | "CFG_QEMU_ARMHF_ROOTFS" if value.len() > 0 => { |
594 | let target = "arm-unknown-linux-gnueabihf".to_string(); | |
595 | let target = self.target_config.entry(target) | |
596 | .or_insert(Target::default()); | |
597 | target.qemu_rootfs = Some(parse_configure_path(value)); | |
598 | } | |
7453a54e SL |
599 | _ => {} |
600 | } | |
601 | } | |
602 | } | |
32a655c1 SL |
603 | |
604 | pub fn verbose(&self) -> bool { | |
605 | self.verbose > 0 | |
606 | } | |
607 | ||
608 | pub fn very_verbose(&self) -> bool { | |
609 | self.verbose > 1 | |
610 | } | |
7453a54e SL |
611 | } |
612 | ||
c30ab7b3 SL |
613 | #[cfg(not(windows))] |
614 | fn parse_configure_path(path: &str) -> PathBuf { | |
615 | path.into() | |
616 | } | |
617 | ||
618 | #[cfg(windows)] | |
619 | fn parse_configure_path(path: &str) -> PathBuf { | |
620 | // on windows, configure produces unix style paths e.g. /c/some/path but we | |
621 | // only want real windows paths | |
622 | ||
623 | use std::process::Command; | |
624 | use build_helper; | |
625 | ||
626 | // '/' is invalid in windows paths, so we can detect unix paths by the presence of it | |
627 | if !path.contains('/') { | |
628 | return path.into(); | |
629 | } | |
630 | ||
631 | let win_path = build_helper::output(Command::new("cygpath").arg("-w").arg(path)); | |
632 | let win_path = win_path.trim(); | |
633 | ||
634 | win_path.into() | |
635 | } | |
636 | ||
7453a54e SL |
637 | fn set<T>(field: &mut T, val: Option<T>) { |
638 | if let Some(v) = val { | |
639 | *field = v; | |
640 | } | |
641 | } |