-
Notifications
You must be signed in to change notification settings - Fork 13.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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
- Loading branch information
1 parent
2581b14
commit 4da4970
Showing
5 changed files
with
387 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT | ||
// file at the top-level directory of this distribution and at | ||
// http://rust-lang.org/COPYRIGHT. | ||
// | ||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | ||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | ||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | ||
// option. This file may not be copied, modified, or distributed | ||
// except according to those terms. | ||
|
||
extern crate build_helper; | ||
extern crate gcc; | ||
|
||
use std::env; | ||
use std::path::PathBuf; | ||
use std::process::Command; | ||
use build_helper::run; | ||
|
||
fn main() { | ||
let target = env::var("TARGET").unwrap(); | ||
let host = env::var("HOST").unwrap(); | ||
let build_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap()); | ||
let src_dir = env::current_dir().unwrap(); | ||
|
||
if let Some(jemalloc) = env::var_os("JEMALLOC_OVERRIDE") { | ||
let jemalloc = PathBuf::from(jemalloc); | ||
println!("cargo:rustc-link-search=native={}", | ||
jemalloc.parent().unwrap().display()); | ||
let stem = jemalloc.file_stem().unwrap().to_str().unwrap(); | ||
let name = jemalloc.file_name().unwrap().to_str().unwrap(); | ||
let kind = if name.ends_with(".a") {"static"} else {"dylib"}; | ||
println!("cargo:rustc-link-lib={}={}", kind, &stem[3..]); | ||
return | ||
} | ||
|
||
let compiler = gcc::Config::new().get_compiler(); | ||
let ar = build_helper::cc2ar(compiler.path(), &target); | ||
let cflags = compiler.args().iter().map(|s| s.to_str().unwrap()) | ||
.collect::<Vec<_>>().join(" "); | ||
|
||
let mut cmd = Command::new("sh"); | ||
cmd.arg(src_dir.join("../jemalloc/configure").to_str().unwrap() | ||
.replace("C:\\", "/c/") | ||
.replace("\\", "/")) | ||
.current_dir(&build_dir) | ||
.env("CC", compiler.path()) | ||
.env("EXTRA_CFLAGS", cflags) | ||
.env("AR", &ar) | ||
.env("RANLIB", format!("{} s", ar.display())); | ||
|
||
if target.contains("windows-gnu") { | ||
// A bit of history here, this used to be --enable-lazy-lock added in | ||
// #14006 which was filed with jemalloc in jemalloc/jemalloc#83 which | ||
// was also reported to MinGW: | ||
// | ||
// http://sourceforge.net/p/mingw-w64/bugs/395/ | ||
// | ||
// When updating jemalloc to 4.0, however, it was found that binaries | ||
// would exit with the status code STATUS_RESOURCE_NOT_OWNED indicating | ||
// that a thread was unlocking a mutex it never locked. Disabling this | ||
// "lazy lock" option seems to fix the issue, but it was enabled by | ||
// default for MinGW targets in 13473c7 for jemalloc. | ||
// | ||
// As a result of all that, force disabling lazy lock on Windows, and | ||
// after reading some code it at least *appears* that the initialization | ||
// of mutexes is otherwise ok in jemalloc, so shouldn't cause problems | ||
// hopefully... | ||
// | ||
// tl;dr: make windows behave like other platforms by disabling lazy | ||
// locking, but requires passing an option due to a historical | ||
// default with jemalloc. | ||
cmd.arg("--disable-lazy-lock"); | ||
} else if target.contains("ios") || target.contains("android") { | ||
cmd.arg("--disable-tls"); | ||
} | ||
|
||
if cfg!(feature = "debug-jemalloc") { | ||
cmd.arg("--enable-debug"); | ||
} | ||
|
||
// Turn off broken quarantine (see jemalloc/jemalloc#161) | ||
cmd.arg("--disable-fill"); | ||
cmd.arg("--with-jemalloc-prefix=je_"); | ||
cmd.arg(format!("--host={}", build_helper::gnu_target(&target))); | ||
cmd.arg(format!("--build={}", build_helper::gnu_target(&host))); | ||
|
||
run(&mut cmd); | ||
run(Command::new("make") | ||
.current_dir(&build_dir) | ||
.arg("build_lib_static") | ||
.arg("-j").arg(env::var("NUM_JOBS").unwrap())); | ||
|
||
if target.contains("windows") { | ||
println!("cargo:rustc-link-lib=static=jemalloc"); | ||
} else { | ||
println!("cargo:rustc-link-lib=static=jemalloc_pic"); | ||
} | ||
println!("cargo:rustc-link-search=native={}/lib", build_dir.display()); | ||
if target.contains("android") { | ||
println!("cargo:rustc-link-lib=gcc"); | ||
} else if !target.contains("windows") { | ||
println!("cargo:rustc-link-lib=pthread"); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT | ||
// file at the top-level directory of this distribution and at | ||
// http://rust-lang.org/COPYRIGHT. | ||
// | ||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | ||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | ||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | ||
// option. This file may not be copied, modified, or distributed | ||
// except according to those terms. | ||
|
||
extern crate gcc; | ||
|
||
fn main() { | ||
gcc::Config::new() | ||
.file("../rt/miniz.c") | ||
.compile("libminiz.a"); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT | ||
// file at the top-level directory of this distribution and at | ||
// http://rust-lang.org/COPYRIGHT. | ||
// | ||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | ||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | ||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | ||
// option. This file may not be copied, modified, or distributed | ||
// except according to those terms. | ||
|
||
extern crate gcc; | ||
extern crate build_helper; | ||
|
||
use std::process::Command; | ||
use std::env; | ||
use std::path::PathBuf; | ||
|
||
use build_helper::output; | ||
|
||
fn main() { | ||
let target = env::var("TARGET").unwrap(); | ||
let llvm_config = env::var_os("LLVM_CONFIG").map(PathBuf::from) | ||
.unwrap_or_else(|| { | ||
match env::var_os("CARGO_TARGET_DIR").map(PathBuf::from) { | ||
Some(dir) => { | ||
let to_test = dir.parent().unwrap().parent().unwrap() | ||
.join(&target).join("llvm/bin/llvm-config"); | ||
if Command::new(&to_test).output().is_ok() { | ||
return to_test | ||
} | ||
} | ||
None => {} | ||
} | ||
PathBuf::from("llvm-config") | ||
}); | ||
|
||
println!("cargo:rerun-if-changed={}", llvm_config.display()); | ||
|
||
let optional_components = ["x86", "arm", "aarch64", "mips", "powerpc", | ||
"pnacl"]; | ||
|
||
// FIXME: surely we don't need all these components, right? Stuff like mcjit | ||
// or interpreter the compiler itself never uses. | ||
let required_components = &["ipo", "bitreader", "bitwriter", "linker", | ||
"asmparser", "mcjit", "interpreter", | ||
"instrumentation"]; | ||
|
||
let components = output(Command::new(&llvm_config).arg("--components")); | ||
let mut components = components.split_whitespace().collect::<Vec<_>>(); | ||
components.retain(|c| { | ||
optional_components.contains(c) || required_components.contains(c) | ||
}); | ||
|
||
for component in required_components { | ||
if !components.contains(component) { | ||
panic!("require llvm component {} but wasn't found", component); | ||
} | ||
} | ||
|
||
for component in components.iter() { | ||
println!("cargo:rustc-cfg=llvm_component=\"{}\"", component); | ||
} | ||
|
||
// Link in our own LLVM shims, compiled with the same flags as LLVM | ||
let mut cmd = Command::new(&llvm_config); | ||
cmd.arg("--cxxflags"); | ||
let cxxflags = output(&mut cmd); | ||
let mut cfg = gcc::Config::new(); | ||
for flag in cxxflags.split_whitespace() { | ||
cfg.flag(flag); | ||
} | ||
cfg.file("../rustllvm/ExecutionEngineWrapper.cpp") | ||
.file("../rustllvm/PassWrapper.cpp") | ||
.file("../rustllvm/RustWrapper.cpp") | ||
.file("../rustllvm/ArchiveWrapper.cpp") | ||
.cpp(true) | ||
.cpp_link_stdlib(None) // we handle this below | ||
.compile("librustllvm.a"); | ||
|
||
// Link in all LLVM libraries | ||
let mut cmd = Command::new(&llvm_config); | ||
cmd.arg("--libs").arg("--system-libs").args(&components[..]); | ||
for lib in output(&mut cmd).split_whitespace() { | ||
let name = if lib.starts_with("-l") { | ||
&lib[2..] | ||
} else if lib.starts_with("-") { | ||
&lib[1..] | ||
} else { | ||
continue | ||
}; | ||
|
||
// Don't need or want this library, but LLVM's CMake build system | ||
// doesn't provide a way to disable it, so filter it here even though we | ||
// may or may not have built it. We don't reference anything from this | ||
// library and it otherwise may just pull in extra dependencies on | ||
// libedit which we don't want | ||
if name == "LLVMLineEditor" { | ||
continue | ||
} | ||
|
||
let kind = if name.starts_with("LLVM") {"static"} else {"dylib"}; | ||
println!("cargo:rustc-link-lib={}={}", kind, name); | ||
} | ||
|
||
// LLVM ldflags | ||
let mut cmd = Command::new(&llvm_config); | ||
cmd.arg("--ldflags"); | ||
for lib in output(&mut cmd).split_whitespace() { | ||
if lib.starts_with("-l") { | ||
println!("cargo:rustc-link-lib={}", &lib[2..]); | ||
} else if lib.starts_with("-L") { | ||
println!("cargo:rustc-link-search=native={}", &lib[2..]); | ||
} | ||
} | ||
|
||
// C++ runtime library | ||
if !target.contains("msvc") { | ||
if let Some(s) = env::var_os("LLVM_STATIC_STDCPP") { | ||
assert!(!cxxflags.contains("stdlib=libc++")); | ||
let path = PathBuf::from(s); | ||
println!("cargo:rustc-link-search=native={}", | ||
path.parent().unwrap().display()); | ||
println!("cargo:rustc-link-lib=static=stdc++"); | ||
} else if cxxflags.contains("stdlib=libc++") { | ||
println!("cargo:rustc-link-lib=c++"); | ||
} else { | ||
println!("cargo:rustc-link-lib=stdc++"); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT | ||
// file at the top-level directory of this distribution and at | ||
// http://rust-lang.org/COPYRIGHT. | ||
// | ||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | ||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | ||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | ||
// option. This file may not be copied, modified, or distributed | ||
// except according to those terms. | ||
|
||
extern crate gcc; | ||
|
||
fn main() { | ||
let mut cfg = gcc::Config::new(); | ||
cfg.file("../rt/hoedown/src/autolink.c") | ||
.file("../rt/hoedown/src/buffer.c") | ||
.file("../rt/hoedown/src/document.c") | ||
.file("../rt/hoedown/src/escape.c") | ||
.file("../rt/hoedown/src/html.c") | ||
.file("../rt/hoedown/src/html_blocks.c") | ||
.file("../rt/hoedown/src/html_smartypants.c") | ||
.file("../rt/hoedown/src/stack.c") | ||
.file("../rt/hoedown/src/version.c") | ||
.include("../rt/hoedown/src") | ||
.compile("libhoedown.a"); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT | ||
// file at the top-level directory of this distribution and at | ||
// http://rust-lang.org/COPYRIGHT. | ||
// | ||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | ||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | ||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | ||
// option. This file may not be copied, modified, or distributed | ||
// except according to those terms. | ||
|
||
extern crate gcc; | ||
extern crate build_helper; | ||
|
||
use std::env; | ||
use std::fs; | ||
use std::path::PathBuf; | ||
use std::process::Command; | ||
|
||
use build_helper::run; | ||
|
||
fn main() { | ||
let target = env::var("TARGET").unwrap(); | ||
let host = env::var("HOST").unwrap(); | ||
if !target.contains("apple") && !target.contains("msvc") { | ||
build_libbacktrace(&host, &target); | ||
} | ||
|
||
if target.contains("unknown-linux") { | ||
if target.contains("musl") { | ||
println!("cargo:rustc-link-lib=static=unwind"); | ||
} else { | ||
println!("cargo:rustc-link-lib=dl"); | ||
println!("cargo:rustc-link-lib=rt"); | ||
println!("cargo:rustc-link-lib=pthread"); | ||
println!("cargo:rustc-link-lib=gcc_s"); | ||
} | ||
} else if target.contains("android") { | ||
println!("cargo:rustc-link-lib=dl"); | ||
println!("cargo:rustc-link-lib=log"); | ||
println!("cargo:rustc-link-lib=gcc"); | ||
} else if target.contains("freebsd") { | ||
println!("cargo:rustc-link-lib=execinfo"); | ||
println!("cargo:rustc-link-lib=pthread"); | ||
println!("cargo:rustc-link-lib=gcc_s"); | ||
} else if target.contains("dragonfly") || target.contains("bitrig") || | ||
target.contains("netbsd") || target.contains("openbsd") { | ||
println!("cargo:rustc-link-lib=pthread"); | ||
|
||
if target.contains("rumprun") { | ||
println!("cargo:rustc-link-lib=unwind"); | ||
} else if target.contains("netbsd") || target.contains("openbsd") { | ||
println!("cargo:rustc-link-lib=gcc"); | ||
} else if target.contains("bitrig") { | ||
println!("cargo:rustc-link-lib=c++abi"); | ||
} else if target.contains("dragonfly") { | ||
println!("cargo:rustc-link-lib=gcc_pic"); | ||
} | ||
} else if target.contains("apple-darwin") { | ||
println!("cargo:rustc-link-lib=System"); | ||
} else if target.contains("apple-ios") { | ||
println!("cargo:rustc-link-lib=System"); | ||
println!("cargo:rustc-link-lib=objc"); | ||
println!("cargo:rustc-link-lib=framework=Security"); | ||
println!("cargo:rustc-link-lib=framework=Foundation"); | ||
} else if target.contains("windows") { | ||
if target.contains("windows-gnu") { | ||
println!("cargo:rustc-link-lib=gcc_eh"); | ||
} | ||
println!("cargo:rustc-link-lib=advapi32"); | ||
println!("cargo:rustc-link-lib=ws2_32"); | ||
println!("cargo:rustc-link-lib=userenv"); | ||
println!("cargo:rustc-link-lib=shell32"); | ||
} | ||
} | ||
|
||
fn build_libbacktrace(host: &str, target: &str) { | ||
let src_dir = env::current_dir().unwrap().join("../libbacktrace"); | ||
let build_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap()); | ||
|
||
println!("cargo:rustc-link-lib=static=backtrace"); | ||
println!("cargo:rustc-link-search=native={}/.libs", build_dir.display()); | ||
|
||
if fs::metadata(&build_dir.join(".libs/libbacktrace.a")).is_ok() { | ||
return | ||
} | ||
|
||
let compiler = gcc::Config::new().get_compiler(); | ||
let ar = build_helper::cc2ar(compiler.path(), target); | ||
let cflags = compiler.args().iter().map(|s| s.to_str().unwrap()) | ||
.collect::<Vec<_>>().join(" "); | ||
run(Command::new("sh") | ||
.current_dir(&build_dir) | ||
.arg(src_dir.join("configure").to_str().unwrap() | ||
.replace("C:\\", "/c/") | ||
.replace("\\", "/")) | ||
.arg("--with-pic") | ||
.arg("--disable-multilib") | ||
.arg("--disable-shared") | ||
.arg("--disable-host-shared") | ||
.arg(format!("--host={}", build_helper::gnu_target(target))) | ||
.arg(format!("--build={}", build_helper::gnu_target(host))) | ||
.env("CC", compiler.path()) | ||
.env("AR", &ar) | ||
.env("RANLIB", format!("{} s", ar.display())) | ||
.env("CFLAGS", cflags)); | ||
run(Command::new("make") | ||
.current_dir(&build_dir) | ||
.arg(format!("INCDIR={}", src_dir.display())) | ||
.arg("-j").arg(env::var("NUM_JOBS").unwrap())); | ||
} |