]> git.lizzy.rs Git - rust.git/commitdiff
bootstrap: Add build scripts for crates
authorAlex Crichton <alex@alexcrichton.com>
Thu, 21 Jan 2016 23:21:13 +0000 (15:21 -0800)
committerAlex Crichton <alex@alexcrichton.com>
Thu, 11 Feb 2016 19:12:32 +0000 (11:12 -0800)
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

src/liballoc_jemalloc/build.rs [new file with mode: 0644]
src/libflate/build.rs [new file with mode: 0644]
src/librustc_llvm/build.rs [new file with mode: 0644]
src/librustdoc/build.rs [new file with mode: 0644]
src/libstd/build.rs [new file with mode: 0644]

diff --git a/src/liballoc_jemalloc/build.rs b/src/liballoc_jemalloc/build.rs
new file mode 100644 (file)
index 0000000..18f0527
--- /dev/null
@@ -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");
+    }
+}
diff --git a/src/libflate/build.rs b/src/libflate/build.rs
new file mode 100644 (file)
index 0000000..1201698
--- /dev/null
@@ -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");
+}
diff --git a/src/librustc_llvm/build.rs b/src/librustc_llvm/build.rs
new file mode 100644 (file)
index 0000000..4f2fee6
--- /dev/null
@@ -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++");
+        }
+    }
+}
diff --git a/src/librustdoc/build.rs b/src/librustdoc/build.rs
new file mode 100644 (file)
index 0000000..fcb7af1
--- /dev/null
@@ -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");
+}
diff --git a/src/libstd/build.rs b/src/libstd/build.rs
new file mode 100644 (file)
index 0000000..8561d53
--- /dev/null
@@ -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()));
+}