From: Alex Crichton Date: Thu, 21 Jan 2016 23:21:13 +0000 (-0800) Subject: bootstrap: Add build scripts for crates X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=4da4970767ae8fc2e3b6d0c280312bb0f4efeed6;p=rust.git 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 --- diff --git a/src/liballoc_jemalloc/build.rs b/src/liballoc_jemalloc/build.rs new file mode 100644 index 00000000000..18f0527425a --- /dev/null +++ b/src/liballoc_jemalloc/build.rs @@ -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 or the MIT license +// , 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::>().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"); + } +} diff --git a/src/libflate/build.rs b/src/libflate/build.rs new file mode 100644 index 00000000000..12016980a2c --- /dev/null +++ b/src/libflate/build.rs @@ -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 or the MIT license +// , 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"); +} diff --git a/src/librustc_llvm/build.rs b/src/librustc_llvm/build.rs new file mode 100644 index 00000000000..4f2fee6943f --- /dev/null +++ b/src/librustc_llvm/build.rs @@ -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 or the MIT license +// , 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::>(); + 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++"); + } + } +} diff --git a/src/librustdoc/build.rs b/src/librustdoc/build.rs new file mode 100644 index 00000000000..fcb7af11dce --- /dev/null +++ b/src/librustdoc/build.rs @@ -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 or the MIT license +// , 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"); +} diff --git a/src/libstd/build.rs b/src/libstd/build.rs new file mode 100644 index 00000000000..8561d53a0d3 --- /dev/null +++ b/src/libstd/build.rs @@ -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 or the MIT license +// , 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::>().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())); +}