Skip to content

Commit 4da4970

Browse files
committed
bootstrap: Add build scripts for crates
This commits adds build scripts to the necessary Rust crates for all the native dependencies. This is currently a duplication of the support found in mk/rt.mk and is my best effort at representing the logic twice, but there may be some unfortunate-and-inevitable divergence. As a summary: * alloc_jemalloc - build script to compile jemallocal * flate - build script to compile miniz.c * rustc_llvm - build script to run llvm-config and learn about how to link it. Note that this crucially (and will not ever) compile LLVM as that would take far too long. * rustdoc - build script to compile hoedown * std - script to determine lots of libraries/linkages as well as compile libbacktrace
1 parent 2581b14 commit 4da4970

File tree

5 files changed

+387
-0
lines changed

5 files changed

+387
-0
lines changed

src/liballoc_jemalloc/build.rs

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
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+
11+
extern crate build_helper;
12+
extern crate gcc;
13+
14+
use std::env;
15+
use std::path::PathBuf;
16+
use std::process::Command;
17+
use build_helper::run;
18+
19+
fn main() {
20+
let target = env::var("TARGET").unwrap();
21+
let host = env::var("HOST").unwrap();
22+
let build_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap());
23+
let src_dir = env::current_dir().unwrap();
24+
25+
if let Some(jemalloc) = env::var_os("JEMALLOC_OVERRIDE") {
26+
let jemalloc = PathBuf::from(jemalloc);
27+
println!("cargo:rustc-link-search=native={}",
28+
jemalloc.parent().unwrap().display());
29+
let stem = jemalloc.file_stem().unwrap().to_str().unwrap();
30+
let name = jemalloc.file_name().unwrap().to_str().unwrap();
31+
let kind = if name.ends_with(".a") {"static"} else {"dylib"};
32+
println!("cargo:rustc-link-lib={}={}", kind, &stem[3..]);
33+
return
34+
}
35+
36+
let compiler = gcc::Config::new().get_compiler();
37+
let ar = build_helper::cc2ar(compiler.path(), &target);
38+
let cflags = compiler.args().iter().map(|s| s.to_str().unwrap())
39+
.collect::<Vec<_>>().join(" ");
40+
41+
let mut cmd = Command::new("sh");
42+
cmd.arg(src_dir.join("../jemalloc/configure").to_str().unwrap()
43+
.replace("C:\\", "/c/")
44+
.replace("\\", "/"))
45+
.current_dir(&build_dir)
46+
.env("CC", compiler.path())
47+
.env("EXTRA_CFLAGS", cflags)
48+
.env("AR", &ar)
49+
.env("RANLIB", format!("{} s", ar.display()));
50+
51+
if target.contains("windows-gnu") {
52+
// A bit of history here, this used to be --enable-lazy-lock added in
53+
// #14006 which was filed with jemalloc in jemalloc/jemalloc#83 which
54+
// was also reported to MinGW:
55+
//
56+
// http://sourceforge.net/p/mingw-w64/bugs/395/
57+
//
58+
// When updating jemalloc to 4.0, however, it was found that binaries
59+
// would exit with the status code STATUS_RESOURCE_NOT_OWNED indicating
60+
// that a thread was unlocking a mutex it never locked. Disabling this
61+
// "lazy lock" option seems to fix the issue, but it was enabled by
62+
// default for MinGW targets in 13473c7 for jemalloc.
63+
//
64+
// As a result of all that, force disabling lazy lock on Windows, and
65+
// after reading some code it at least *appears* that the initialization
66+
// of mutexes is otherwise ok in jemalloc, so shouldn't cause problems
67+
// hopefully...
68+
//
69+
// tl;dr: make windows behave like other platforms by disabling lazy
70+
// locking, but requires passing an option due to a historical
71+
// default with jemalloc.
72+
cmd.arg("--disable-lazy-lock");
73+
} else if target.contains("ios") || target.contains("android") {
74+
cmd.arg("--disable-tls");
75+
}
76+
77+
if cfg!(feature = "debug-jemalloc") {
78+
cmd.arg("--enable-debug");
79+
}
80+
81+
// Turn off broken quarantine (see jemalloc/jemalloc#161)
82+
cmd.arg("--disable-fill");
83+
cmd.arg("--with-jemalloc-prefix=je_");
84+
cmd.arg(format!("--host={}", build_helper::gnu_target(&target)));
85+
cmd.arg(format!("--build={}", build_helper::gnu_target(&host)));
86+
87+
run(&mut cmd);
88+
run(Command::new("make")
89+
.current_dir(&build_dir)
90+
.arg("build_lib_static")
91+
.arg("-j").arg(env::var("NUM_JOBS").unwrap()));
92+
93+
if target.contains("windows") {
94+
println!("cargo:rustc-link-lib=static=jemalloc");
95+
} else {
96+
println!("cargo:rustc-link-lib=static=jemalloc_pic");
97+
}
98+
println!("cargo:rustc-link-search=native={}/lib", build_dir.display());
99+
if target.contains("android") {
100+
println!("cargo:rustc-link-lib=gcc");
101+
} else if !target.contains("windows") {
102+
println!("cargo:rustc-link-lib=pthread");
103+
}
104+
}

src/libflate/build.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
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+
11+
extern crate gcc;
12+
13+
fn main() {
14+
gcc::Config::new()
15+
.file("../rt/miniz.c")
16+
.compile("libminiz.a");
17+
}

src/librustc_llvm/build.rs

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
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+
11+
extern crate gcc;
12+
extern crate build_helper;
13+
14+
use std::process::Command;
15+
use std::env;
16+
use std::path::PathBuf;
17+
18+
use build_helper::output;
19+
20+
fn main() {
21+
let target = env::var("TARGET").unwrap();
22+
let llvm_config = env::var_os("LLVM_CONFIG").map(PathBuf::from)
23+
.unwrap_or_else(|| {
24+
match env::var_os("CARGO_TARGET_DIR").map(PathBuf::from) {
25+
Some(dir) => {
26+
let to_test = dir.parent().unwrap().parent().unwrap()
27+
.join(&target).join("llvm/bin/llvm-config");
28+
if Command::new(&to_test).output().is_ok() {
29+
return to_test
30+
}
31+
}
32+
None => {}
33+
}
34+
PathBuf::from("llvm-config")
35+
});
36+
37+
println!("cargo:rerun-if-changed={}", llvm_config.display());
38+
39+
let optional_components = ["x86", "arm", "aarch64", "mips", "powerpc",
40+
"pnacl"];
41+
42+
// FIXME: surely we don't need all these components, right? Stuff like mcjit
43+
// or interpreter the compiler itself never uses.
44+
let required_components = &["ipo", "bitreader", "bitwriter", "linker",
45+
"asmparser", "mcjit", "interpreter",
46+
"instrumentation"];
47+
48+
let components = output(Command::new(&llvm_config).arg("--components"));
49+
let mut components = components.split_whitespace().collect::<Vec<_>>();
50+
components.retain(|c| {
51+
optional_components.contains(c) || required_components.contains(c)
52+
});
53+
54+
for component in required_components {
55+
if !components.contains(component) {
56+
panic!("require llvm component {} but wasn't found", component);
57+
}
58+
}
59+
60+
for component in components.iter() {
61+
println!("cargo:rustc-cfg=llvm_component=\"{}\"", component);
62+
}
63+
64+
// Link in our own LLVM shims, compiled with the same flags as LLVM
65+
let mut cmd = Command::new(&llvm_config);
66+
cmd.arg("--cxxflags");
67+
let cxxflags = output(&mut cmd);
68+
let mut cfg = gcc::Config::new();
69+
for flag in cxxflags.split_whitespace() {
70+
cfg.flag(flag);
71+
}
72+
cfg.file("../rustllvm/ExecutionEngineWrapper.cpp")
73+
.file("../rustllvm/PassWrapper.cpp")
74+
.file("../rustllvm/RustWrapper.cpp")
75+
.file("../rustllvm/ArchiveWrapper.cpp")
76+
.cpp(true)
77+
.cpp_link_stdlib(None) // we handle this below
78+
.compile("librustllvm.a");
79+
80+
// Link in all LLVM libraries
81+
let mut cmd = Command::new(&llvm_config);
82+
cmd.arg("--libs").arg("--system-libs").args(&components[..]);
83+
for lib in output(&mut cmd).split_whitespace() {
84+
let name = if lib.starts_with("-l") {
85+
&lib[2..]
86+
} else if lib.starts_with("-") {
87+
&lib[1..]
88+
} else {
89+
continue
90+
};
91+
92+
// Don't need or want this library, but LLVM's CMake build system
93+
// doesn't provide a way to disable it, so filter it here even though we
94+
// may or may not have built it. We don't reference anything from this
95+
// library and it otherwise may just pull in extra dependencies on
96+
// libedit which we don't want
97+
if name == "LLVMLineEditor" {
98+
continue
99+
}
100+
101+
let kind = if name.starts_with("LLVM") {"static"} else {"dylib"};
102+
println!("cargo:rustc-link-lib={}={}", kind, name);
103+
}
104+
105+
// LLVM ldflags
106+
let mut cmd = Command::new(&llvm_config);
107+
cmd.arg("--ldflags");
108+
for lib in output(&mut cmd).split_whitespace() {
109+
if lib.starts_with("-l") {
110+
println!("cargo:rustc-link-lib={}", &lib[2..]);
111+
} else if lib.starts_with("-L") {
112+
println!("cargo:rustc-link-search=native={}", &lib[2..]);
113+
}
114+
}
115+
116+
// C++ runtime library
117+
if !target.contains("msvc") {
118+
if let Some(s) = env::var_os("LLVM_STATIC_STDCPP") {
119+
assert!(!cxxflags.contains("stdlib=libc++"));
120+
let path = PathBuf::from(s);
121+
println!("cargo:rustc-link-search=native={}",
122+
path.parent().unwrap().display());
123+
println!("cargo:rustc-link-lib=static=stdc++");
124+
} else if cxxflags.contains("stdlib=libc++") {
125+
println!("cargo:rustc-link-lib=c++");
126+
} else {
127+
println!("cargo:rustc-link-lib=stdc++");
128+
}
129+
}
130+
}

src/librustdoc/build.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
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+
11+
extern crate gcc;
12+
13+
fn main() {
14+
let mut cfg = gcc::Config::new();
15+
cfg.file("../rt/hoedown/src/autolink.c")
16+
.file("../rt/hoedown/src/buffer.c")
17+
.file("../rt/hoedown/src/document.c")
18+
.file("../rt/hoedown/src/escape.c")
19+
.file("../rt/hoedown/src/html.c")
20+
.file("../rt/hoedown/src/html_blocks.c")
21+
.file("../rt/hoedown/src/html_smartypants.c")
22+
.file("../rt/hoedown/src/stack.c")
23+
.file("../rt/hoedown/src/version.c")
24+
.include("../rt/hoedown/src")
25+
.compile("libhoedown.a");
26+
}

src/libstd/build.rs

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
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+
11+
extern crate gcc;
12+
extern crate build_helper;
13+
14+
use std::env;
15+
use std::fs;
16+
use std::path::PathBuf;
17+
use std::process::Command;
18+
19+
use build_helper::run;
20+
21+
fn main() {
22+
let target = env::var("TARGET").unwrap();
23+
let host = env::var("HOST").unwrap();
24+
if !target.contains("apple") && !target.contains("msvc") {
25+
build_libbacktrace(&host, &target);
26+
}
27+
28+
if target.contains("unknown-linux") {
29+
if target.contains("musl") {
30+
println!("cargo:rustc-link-lib=static=unwind");
31+
} else {
32+
println!("cargo:rustc-link-lib=dl");
33+
println!("cargo:rustc-link-lib=rt");
34+
println!("cargo:rustc-link-lib=pthread");
35+
println!("cargo:rustc-link-lib=gcc_s");
36+
}
37+
} else if target.contains("android") {
38+
println!("cargo:rustc-link-lib=dl");
39+
println!("cargo:rustc-link-lib=log");
40+
println!("cargo:rustc-link-lib=gcc");
41+
} else if target.contains("freebsd") {
42+
println!("cargo:rustc-link-lib=execinfo");
43+
println!("cargo:rustc-link-lib=pthread");
44+
println!("cargo:rustc-link-lib=gcc_s");
45+
} else if target.contains("dragonfly") || target.contains("bitrig") ||
46+
target.contains("netbsd") || target.contains("openbsd") {
47+
println!("cargo:rustc-link-lib=pthread");
48+
49+
if target.contains("rumprun") {
50+
println!("cargo:rustc-link-lib=unwind");
51+
} else if target.contains("netbsd") || target.contains("openbsd") {
52+
println!("cargo:rustc-link-lib=gcc");
53+
} else if target.contains("bitrig") {
54+
println!("cargo:rustc-link-lib=c++abi");
55+
} else if target.contains("dragonfly") {
56+
println!("cargo:rustc-link-lib=gcc_pic");
57+
}
58+
} else if target.contains("apple-darwin") {
59+
println!("cargo:rustc-link-lib=System");
60+
} else if target.contains("apple-ios") {
61+
println!("cargo:rustc-link-lib=System");
62+
println!("cargo:rustc-link-lib=objc");
63+
println!("cargo:rustc-link-lib=framework=Security");
64+
println!("cargo:rustc-link-lib=framework=Foundation");
65+
} else if target.contains("windows") {
66+
if target.contains("windows-gnu") {
67+
println!("cargo:rustc-link-lib=gcc_eh");
68+
}
69+
println!("cargo:rustc-link-lib=advapi32");
70+
println!("cargo:rustc-link-lib=ws2_32");
71+
println!("cargo:rustc-link-lib=userenv");
72+
println!("cargo:rustc-link-lib=shell32");
73+
}
74+
}
75+
76+
fn build_libbacktrace(host: &str, target: &str) {
77+
let src_dir = env::current_dir().unwrap().join("../libbacktrace");
78+
let build_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap());
79+
80+
println!("cargo:rustc-link-lib=static=backtrace");
81+
println!("cargo:rustc-link-search=native={}/.libs", build_dir.display());
82+
83+
if fs::metadata(&build_dir.join(".libs/libbacktrace.a")).is_ok() {
84+
return
85+
}
86+
87+
let compiler = gcc::Config::new().get_compiler();
88+
let ar = build_helper::cc2ar(compiler.path(), target);
89+
let cflags = compiler.args().iter().map(|s| s.to_str().unwrap())
90+
.collect::<Vec<_>>().join(" ");
91+
run(Command::new("sh")
92+
.current_dir(&build_dir)
93+
.arg(src_dir.join("configure").to_str().unwrap()
94+
.replace("C:\\", "/c/")
95+
.replace("\\", "/"))
96+
.arg("--with-pic")
97+
.arg("--disable-multilib")
98+
.arg("--disable-shared")
99+
.arg("--disable-host-shared")
100+
.arg(format!("--host={}", build_helper::gnu_target(target)))
101+
.arg(format!("--build={}", build_helper::gnu_target(host)))
102+
.env("CC", compiler.path())
103+
.env("AR", &ar)
104+
.env("RANLIB", format!("{} s", ar.display()))
105+
.env("CFLAGS", cflags));
106+
run(Command::new("make")
107+
.current_dir(&build_dir)
108+
.arg(format!("INCDIR={}", src_dir.display()))
109+
.arg("-j").arg(env::var("NUM_JOBS").unwrap()));
110+
}

0 commit comments

Comments
 (0)