Skip to content

Commit

Permalink
Automate timestamp creation and build skipping for native libraries
Browse files Browse the repository at this point in the history
Add comments
  • Loading branch information
petrochenkov committed Mar 4, 2017
1 parent c652a4f commit 428f063
Show file tree
Hide file tree
Showing 9 changed files with 56 additions and 80 deletions.
4 changes: 2 additions & 2 deletions src/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

33 changes: 20 additions & 13 deletions src/build_helper/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
extern crate filetime;

use std::{fs, env};
use std::fs::File;
use std::process::{Command, Stdio};
use std::path::{Path, PathBuf};

Expand Down Expand Up @@ -166,19 +167,29 @@ pub fn up_to_date(src: &Path, dst: &Path) -> bool {
}
}

#[must_use]
pub struct NativeLibBoilerplate {
pub skip_build: bool,
pub src_dir: PathBuf,
pub out_dir: PathBuf,
pub timestamp: PathBuf,
}

impl Drop for NativeLibBoilerplate {
fn drop(&mut self) {
t!(File::create(self.out_dir.join("rustbuild.timestamp")));
}
}

// Perform standard preparations for native libraries that are build only once for all stages.
// Emit rerun-if-changed and linking attributes for Cargo, check if any source files are
// updated, calculate paths used later in actual build with CMake/make or C/C++ compiler.
// If Err is returned, then everything is up-to-date and further build actions can be skipped.
// Timestamps are created automatically when the result of `native_lib_boilerplate` goes out
// of scope, so all the build actions should be completed until then.
pub fn native_lib_boilerplate(src_name: &str,
out_name: &str,
link_name: &str,
timestamp_name: &str,
search_subdir: &str)
-> NativeLibBoilerplate {
-> Result<NativeLibBoilerplate, ()> {
let current_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());
let src_dir = current_dir.join("..").join(src_name);
rerun_if_changed_anything_in_dir(&src_dir);
Expand All @@ -189,15 +200,11 @@ pub fn native_lib_boilerplate(src_name: &str,
println!("cargo:rustc-link-lib=static={}", link_name);
println!("cargo:rustc-link-search=native={}", out_dir.join(search_subdir).display());

let timestamp = out_dir.join(timestamp_name);
let skip_build = up_to_date(Path::new("build.rs"), &timestamp) &&
up_to_date(&src_dir, &timestamp);

NativeLibBoilerplate {
skip_build: skip_build,
src_dir: src_dir,
out_dir: out_dir,
timestamp: timestamp,
let timestamp = out_dir.join("rustbuild.timestamp");
if !up_to_date(Path::new("build.rs"), &timestamp) || !up_to_date(&src_dir, &timestamp) {
Ok(NativeLibBoilerplate { src_dir: src_dir, out_dir: out_dir })
} else {
Err(())
}
}

Expand Down
13 changes: 4 additions & 9 deletions src/liballoc_jemalloc/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,10 @@

#![deny(warnings)]

#[macro_use]
extern crate build_helper;
extern crate gcc;

use std::env;
use std::fs::File;
use std::path::PathBuf;
use std::process::Command;
use build_helper::{run, native_lib_boilerplate};
Expand Down Expand Up @@ -60,11 +58,10 @@ fn main() {
}

let link_name = if target.contains("windows") { "jemalloc" } else { "jemalloc_pic" };
let native = native_lib_boilerplate("jemalloc", "jemalloc", link_name,
"rustbuild.timestamp", "lib");
if native.skip_build {
return
}
let native = match native_lib_boilerplate("jemalloc", "jemalloc", link_name, "lib") {
Ok(native) => native,
_ => return,
};

let compiler = gcc::Config::new().get_compiler();
// only msvc returns None for ar so unwrap is okay
Expand Down Expand Up @@ -175,6 +172,4 @@ fn main() {
.file("pthread_atfork_dummy.c")
.compile("libpthread_atfork_dummy.a");
}

t!(File::create(&native.timestamp));
}
15 changes: 6 additions & 9 deletions src/libcompiler_builtins/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,16 +82,13 @@ fn main() {
}

// Can't reuse `sources` list for the freshness check becuse it doesn't contain header files.
// Use the produced library itself as a timestamp.
let out_name = "libcompiler-rt.a";
let native = native_lib_boilerplate("compiler-rt", "compiler-rt", "compiler-rt",
out_name, ".");
if native.skip_build {
return
}
let native = match native_lib_boilerplate("compiler-rt", "compiler-rt", "compiler-rt", ".") {
Ok(native) => native,
_ => return,
};

let cfg = &mut gcc::Config::new();
cfg.out_dir(native.out_dir);
cfg.out_dir(&native.out_dir);

if target.contains("msvc") {
// Don't pull in extra libraries on MSVC
Expand Down Expand Up @@ -416,5 +413,5 @@ fn main() {
cfg.file(Path::new("../compiler-rt/lib/builtins").join(src));
}

cfg.compile(out_name);
cfg.compile("libcompiler-rt.a");
}
14 changes: 5 additions & 9 deletions src/librustc_asan/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,21 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#[macro_use]
extern crate build_helper;
extern crate cmake;

use std::env;
use std::fs::File;
use build_helper::native_lib_boilerplate;

use cmake::Config;

fn main() {
if let Some(llvm_config) = env::var_os("LLVM_CONFIG") {
let native = native_lib_boilerplate("compiler-rt", "asan", "clang_rt.asan-x86_64",
"rustbuild.timestamp", "build/lib/linux");
if native.skip_build {
return
}
let native = match native_lib_boilerplate("compiler-rt", "asan", "clang_rt.asan-x86_64",
"build/lib/linux") {
Ok(native) => native,
_ => return,
};

Config::new(&native.src_dir)
.define("COMPILER_RT_BUILD_SANITIZERS", "ON")
Expand All @@ -34,7 +32,5 @@ fn main() {
.out_dir(&native.out_dir)
.build_target("asan")
.build();

t!(File::create(&native.timestamp));
}
}
14 changes: 5 additions & 9 deletions src/librustc_lsan/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,21 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#[macro_use]
extern crate build_helper;
extern crate cmake;

use std::env;
use std::fs::File;
use build_helper::native_lib_boilerplate;

use cmake::Config;

fn main() {
if let Some(llvm_config) = env::var_os("LLVM_CONFIG") {
let native = native_lib_boilerplate("compiler-rt", "lsan", "clang_rt.lsan-x86_64",
"rustbuild.timestamp", "build/lib/linux");
if native.skip_build {
return
}
let native = match native_lib_boilerplate("compiler-rt", "lsan", "clang_rt.lsan-x86_64",
"build/lib/linux") {
Ok(native) => native,
_ => return,
};

Config::new(&native.src_dir)
.define("COMPILER_RT_BUILD_SANITIZERS", "ON")
Expand All @@ -34,7 +32,5 @@ fn main() {
.out_dir(&native.out_dir)
.build_target("lsan")
.build();

t!(File::create(&native.timestamp));
}
}
14 changes: 5 additions & 9 deletions src/librustc_msan/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,21 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#[macro_use]
extern crate build_helper;
extern crate cmake;

use std::env;
use std::fs::File;
use build_helper::native_lib_boilerplate;

use cmake::Config;

fn main() {
if let Some(llvm_config) = env::var_os("LLVM_CONFIG") {
let native = native_lib_boilerplate("compiler-rt", "msan", "clang_rt.msan-x86_64",
"rustbuild.timestamp", "build/lib/linux");
if native.skip_build {
return
}
let native = match native_lib_boilerplate("compiler-rt", "msan", "clang_rt.msan-x86_64",
"build/lib/linux") {
Ok(native) => native,
_ => return,
};

Config::new(&native.src_dir)
.define("COMPILER_RT_BUILD_SANITIZERS", "ON")
Expand All @@ -34,7 +32,5 @@ fn main() {
.out_dir(&native.out_dir)
.build_target("msan")
.build();

t!(File::create(&native.timestamp));
}
}
14 changes: 5 additions & 9 deletions src/librustc_tsan/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,21 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#[macro_use]
extern crate build_helper;
extern crate cmake;

use std::env;
use std::fs::File;
use build_helper::native_lib_boilerplate;

use cmake::Config;

fn main() {
if let Some(llvm_config) = env::var_os("LLVM_CONFIG") {
let native = native_lib_boilerplate("compiler-rt", "tsan", "clang_rt.tsan-x86_64",
"rustbuild.timestamp", "build/lib/linux");
if native.skip_build {
return
}
let native = match native_lib_boilerplate("compiler-rt", "tsan", "clang_rt.tsan-x86_64",
"build/lib/linux") {
Ok(native) => native,
_ => return,
};

Config::new(&native.src_dir)
.define("COMPILER_RT_BUILD_SANITIZERS", "ON")
Expand All @@ -34,7 +32,5 @@ fn main() {
.out_dir(&native.out_dir)
.build_target("tsan")
.build();

t!(File::create(&native.timestamp));
}
}
15 changes: 4 additions & 11 deletions src/libstd/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,10 @@

#![deny(warnings)]

#[macro_use]
extern crate build_helper;
extern crate gcc;

use std::env;
use std::fs::File;
use std::process::Command;
use build_helper::{run, native_lib_boilerplate};

Expand All @@ -24,7 +22,7 @@ fn main() {
let host = env::var("HOST").expect("HOST was not set");
if cfg!(feature = "backtrace") && !target.contains("apple") && !target.contains("msvc") &&
!target.contains("emscripten") && !target.contains("fuchsia") && !target.contains("redox") {
build_libbacktrace(&host, &target);
let _ = build_libbacktrace(&host, &target);
}

if target.contains("linux") {
Expand Down Expand Up @@ -66,12 +64,8 @@ fn main() {
}
}

fn build_libbacktrace(host: &str, target: &str) {
let native = native_lib_boilerplate("libbacktrace", "libbacktrace", "backtrace",
"rustbuild.timestamp", ".libs");
if native.skip_build {
return
}
fn build_libbacktrace(host: &str, target: &str) -> Result<(), ()> {
let native = native_lib_boilerplate("libbacktrace", "libbacktrace", "backtrace", ".libs")?;

let compiler = gcc::Config::new().get_compiler();
// only msvc returns None for ar so unwrap is okay
Expand Down Expand Up @@ -99,6 +93,5 @@ fn build_libbacktrace(host: &str, target: &str) {
.current_dir(&native.out_dir)
.arg(format!("INCDIR={}", native.src_dir.display()))
.arg("-j").arg(env::var("NUM_JOBS").expect("NUM_JOBS was not set")));

t!(File::create(&native.timestamp));
Ok(())
}

0 comments on commit 428f063

Please sign in to comment.