Skip to content

Revert "Copy all the sources to OUT_DIR before building them" #226

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
175 changes: 57 additions & 118 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,61 +9,33 @@ extern crate walkdir;
use std::env;
use std::path::{Path, PathBuf};
use std::ffi::{OsStr, OsString};
use std::fs;
use std::process::Command;
use std::process::{Command, Stdio};
use std::str;
use walkdir::WalkDir;

const ENV_VARS: &'static [&'static str] = &[
"AR",
"AS",
"CC",
"CFLAGS",
"CLANGFLAGS",
"CPP",
"CPPFLAGS",
"CXX",
"CXXFLAGS",
"MAKE",
"MOZ_TOOLS",
"MOZTOOLS_PATH",
"PYTHON",
"STLPORT_LIBS",
];

const EXTRA_FILES: &'static [&'static str] = &[
"makefile.cargo",
"rustfmt.toml",
"src/jsglue.hpp",
"src/jsglue.cpp",
];

fn main() {
// https://github.com/servo/mozjs/issues/113
env::set_var("MOZCONFIG", "");

for var in ENV_VARS {
println!("cargo:rerun-if-env-changed={}", var);
}

for file in EXTRA_FILES {
println!("cargo:rerun-if-changed={}", file);
}

let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap());
let src_dir = out_dir.join("mozjs");
let build_dir = out_dir.join("build");

// Used by rust-mozjs downstream, don't remove.
println!("cargo:outdir={}", build_dir.display());

copy_sources("mozjs".as_ref(), &src_dir);

fs::create_dir_all(&build_dir).expect("could not create build dir");
build_jsapi();
build_jsglue();
build_jsapi_bindings();
}

build_jsapi(&src_dir, &build_dir);
build_jsglue(&build_dir);
build_jsapi_bindings(&build_dir);
/// Rerun this build script if files under mozjs/ changed, unless this returns true.
/// Keep this in sync with .gitignore
fn ignore(path: &Path) -> bool {
let ignored_extensions = ["pyc", "so", "dll", "dylib"];
let ignored_trailing_paths = [["psutil", "build"], ["psutil", "tmp"]];

path.extension().map_or(false, |extension| {
ignored_extensions.iter().any(|&ignored| extension == ignored)
}) ||
ignored_trailing_paths.iter().any(|trailing| {
let mut components = path.components().rev();
trailing.iter().rev().all(|&ignored| {
components.next().map_or(false, |component| component.as_os_str() == ignored)
})
})
}

fn find_make() -> OsString {
Expand Down Expand Up @@ -121,10 +93,10 @@ fn cc_flags() -> Vec<&'static str> {
result
}

fn build_jsapi(src_dir: &Path, build_dir: &Path) {
fn build_jsapi() {
let out_dir = env::var("OUT_DIR").unwrap();
let target = env::var("TARGET").unwrap();
let mut make = find_make();

// Put MOZTOOLS_PATH at the beginning of PATH if specified
if let Some(moztools) = env::var_os("MOZTOOLS_PATH") {
let path = env::var_os("PATH").unwrap();
Expand All @@ -150,21 +122,17 @@ fn build_jsapi(src_dir: &Path, build_dir: &Path) {
cmd.env("CXXFLAGS", "-stdlib=libc++");
}

let cargo_manifest_dir = PathBuf::from(env::var_os("CARGO_MANIFEST_DIR").unwrap());

let result = cmd
.args(&["-R", "-f"])
.arg(cargo_manifest_dir.join("makefile.cargo"))
.current_dir(&build_dir)
.env("SRC_DIR", &src_dir)
let result = cmd.args(&["-R", "-f", "makefile.cargo"])
.stdout(Stdio::inherit())
.stderr(Stdio::inherit())
.status()
.expect("Failed to run `make`");
assert!(result.success());

println!("cargo:rustc-link-search=native={}/js/src/build", build_dir.display());
assert!(result.success());
println!("cargo:rustc-link-search=native={}/js/src/build", out_dir);
println!("cargo:rustc-link-lib=static=js_static"); // Must come before c++
if target.contains("windows") {
println!("cargo:rustc-link-search=native={}/dist/bin", build_dir.display());
println!("cargo:rustc-link-search=native={}/dist/bin", out_dir);
println!("cargo:rustc-link-lib=winmm");
println!("cargo:rustc-link-lib=psapi");
println!("cargo:rustc-link-lib=user32");
Expand All @@ -180,10 +148,20 @@ fn build_jsapi(src_dir: &Path, build_dir: &Path) {
} else {
println!("cargo:rustc-link-lib=stdc++");
}
println!("cargo:outdir={}", out_dir);
println!("cargo:rerun-if-changed=makefile.cargo");
for entry in walkdir::WalkDir::new("mozjs").into_iter().filter_entry(|e| !ignore(e.path())) {
let entry = entry.unwrap();
if !entry.file_type().is_dir() {
println!("{}", format!("cargo:rerun-if-changed={}", entry.path().display()));
}
}
}


fn build_jsglue(build_dir: &Path) {
fn build_jsglue() {
let out = PathBuf::from(env::var("OUT_DIR").unwrap());

let mut build = cc::Build::new();
build.cpp(true);

Expand All @@ -192,27 +170,28 @@ fn build_jsglue(build_dir: &Path) {
}

let target = env::var("TARGET").unwrap();
let config = format!("{}/js/src/js-confdefs.h", build_dir.display());
let config = format!("{}/js/src/js-confdefs.h", out.display());
if target.contains("windows") {
build.flag("-FI");
} else {
build.flag("-include");
}
build
.flag(&config)
.file("src/jsglue.cpp")
.include(build_dir.join("dist/include"))
.include(build_dir.join("js/src"))
.out_dir(build_dir.join("glue"))
.compile("jsglue");
build.flag(&config);

build.file("src/jsglue.cpp");
build.include(out.join("dist/include"));
build.include(out.join("js/src"));

build.compile("jsglue");
}

/// Invoke bindgen on the JSAPI headers to produce raw FFI bindings for use from
/// Rust.
///
/// To add or remove which functions, types, and variables get bindings
/// generated, see the `const` configuration variables below.
fn build_jsapi_bindings(build_dir: &Path) {
fn build_jsapi_bindings() {
let out = PathBuf::from(env::var("OUT_DIR").unwrap());
let rustfmt_config = Some(PathBuf::from("rustfmt.toml"));

// By default, constructors, destructors and methods declared in .h files are inlined,
Expand All @@ -234,8 +213,8 @@ fn build_jsapi_bindings(build_dir: &Path) {
.with_codegen_config(config)
.rustfmt_bindings(true)
.rustfmt_configuration_file(rustfmt_config)
.clang_arg("-I").clang_arg(build_dir.join("dist/include").to_str().expect("UTF-8"))
.clang_arg("-I").clang_arg(build_dir.join("js/src").to_str().expect("UTF-8"))
.clang_arg("-I").clang_arg(out.join("dist/include").to_str().expect("UTF-8"))
.clang_arg("-I").clang_arg(out.join("js/src").to_str().expect("UTF-8"))
.clang_arg("-x").clang_arg("c++");

let target = env::var("TARGET").unwrap();
Expand All @@ -260,7 +239,7 @@ fn build_jsapi_bindings(build_dir: &Path) {
}

builder = builder.clang_arg("-include");
builder = builder.clang_arg(build_dir.join("js/src/js-confdefs.h").to_str().expect("UTF-8"));
builder = builder.clang_arg(out.join("js/src/js-confdefs.h").to_str().expect("UTF-8"));

println!("Generting bindings {:?} {}.", builder.command_line_flags(), bindgen::clang_version().full);

Expand Down Expand Up @@ -295,8 +274,12 @@ fn build_jsapi_bindings(build_dir: &Path) {
let bindings = builder.generate()
.expect("Should generate JSAPI bindings OK");

bindings.write_to_file(build_dir.join("jsapi.rs"))
bindings.write_to_file(out.join("jsapi.rs"))
.expect("Should write bindings to file OK");

println!("cargo:rerun-if-changed=rustfmt.toml");
println!("cargo:rerun-if-changed=src/jsglue.hpp");
println!("cargo:rerun-if-changed=src/jsglue.cpp");
}

/// JSAPI types for which we should implement `Sync`.
Expand Down Expand Up @@ -384,47 +367,3 @@ const MODULE_RAW_LINES: &'static [(&'static str, &'static str)] = &[
("root::JS", "pub type Heap<T> = ::jsgc::Heap<T>;"),
("root::JS", "pub type Rooted<T> = ::jsgc::Rooted<T>;"),
];

fn copy_sources(source: &Path, target: &Path) {
for entry in WalkDir::new(source) {
let entry = entry.expect("could not walk source tree");
println!("cargo:rerun-if-changed={}", entry.path().display());
let relative_path = entry.path().strip_prefix(&source).unwrap();
let target_path = target.join(relative_path);

if entry.path().is_dir() {
if !target_path.exists() {
fs::create_dir(target_path).expect("could not create directory");
}
} else {
copy_file(entry.path(), &target_path)
}
}
}

fn copy_file(source: &Path, target: &Path) {
if !target_is_up_to_date(&source, &target) {
fs::copy(&source, &target).expect("could not copy file");
}
}

fn target_is_up_to_date(source: &Path, target: &Path) -> bool {
if !target.exists() {
return false;
}

let source_metadata = source.metadata().expect("could not read source metadata");
let target_metadata = target.metadata().expect("could not read target metadata");

let source_modified = match source_metadata.modified() {
Ok(modified) => modified,
Err(_) => return false,
};

let target_modified = match target_metadata.modified() {
Ok(modified) => modified,
Err(_) => return false,
};

source_modified < target_modified
}
9 changes: 6 additions & 3 deletions makefile.cargo
Original file line number Diff line number Diff line change
Expand Up @@ -178,21 +178,24 @@ ifeq ($(NEED_WIN_PYTHON),1)
endif
endif

SRC_DIR = $(shell pwd)

.PHONY : all maybe-configure

all: maybe-configure
$(MAKE) -f Makefile
cd $(OUT_DIR) && $(MAKE) -f Makefile

# Only touch and run configure if we need to, to avoid unnecessary rebuilds.
# The second two time checks handle the case of configure.in and configure having
# the same timestamp (e.g. after a git checkout)
JSSRC := '$(SRC_DIR)'/js/src
JSSRC := $(SRC_DIR)/mozjs/js/src
maybe-configure:
[[ $(JSSRC)/configure -ot $(JSSRC)/configure.in ]] && touch $(JSSRC)/configure || true
[[ $(JSSRC)/old-configure -ot $(JSSRC)/old-configure.in ]] && touch $(JSSRC)/old-configure || true
! [[ $(JSSRC)/configure.in -ot $(JSSRC)/configure ]] && touch $(JSSRC)/configure || true
! [[ $(JSSRC)/old-configure.in -ot $(JSSRC)/old-configure ]] && touch $(JSSRC)/old-configure || true
if [[ $(JSSRC)/configure -nt config.status ]] ; then \
if [[ $(JSSRC)/configure -nt $(OUT_DIR)/config.status ]] ; then \
cd $(OUT_DIR) && \
PYTHON="$(PYTHON)" MOZ_TOOLS="$(MOZ_TOOLS)" \
CC="$(CC)" CFLAGS="$(CFLAGS)" \
CPP="$(CPP)" CPPFLAGS="$(CPPFLAGS)" \
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@ pub mod jsval;
pub use generated::root as jsapi;

// The bindings generated by bindgen
mod generated { include!(concat!(env!("OUT_DIR"), "/build/jsapi.rs")); }
mod generated { include!(concat!(env!("OUT_DIR"), "/jsapi.rs")); }