summaryrefslogtreecommitdiffstats
path: root/js/src/build.rs
blob: 9152f3f1a78a3a1d56dcaa4454d27a742f22caf2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

extern crate glob;
extern crate num_cpus;

use std::env;
use std::path;
use std::process::{Command, Stdio};

fn main() {
    let out_dir = env::var("OUT_DIR").expect("Should have env var OUT_DIR");
    let target = env::var("TARGET").expect("Should have env var TARGET");

    let js_src = env::var("CARGO_MANIFEST_DIR").expect("Should have env var CARGO_MANIFEST_DIR");

    env::set_var("MAKEFLAGS", format!("-j{}", num_cpus::get()));

    // The Rust package used in Spidermonkey inherits the default profile from the toplevel
    // Cargo directory. In particular, both profiles (dev or release) set panic=abort,
    // which defines an exception handling personality that will trigger calls to abort().
    // The Rust bindings package wants to be able to unwind at runtime, so override the
    // profile's value here.
    env::set_var("RUSTFLAGS", "-C panic=unwind");

    env::set_current_dir(&js_src).unwrap();

    let variant = if cfg!(feature = "debugmozjs") {
        "plaindebug"
    } else {
        "plain"
    };

    let python = env::var("PYTHON3").unwrap_or("python3".into());
    let mut cmd = Command::new(&python);
    cmd.args(&[
        "./devtools/automation/autospider.py",
        // Only build SpiderMonkey, don't run all the tests.
        "--build-only",
        // Disable Mozilla's jemalloc; Rust has its own jemalloc that we
        // can swap in instead and everything using a single malloc is
        // good.
        "--no-jemalloc",
        // Don't try to clobber the output directory. Without
        // this option, the build will fail because the directory
        // already exists but wasn't created by autospider.
        "--dep",
        "--objdir",
        &out_dir,
        &variant,
    ])
    .env("NO_RUST_PANIC_HOOK", "1")
    .env("SOURCE", &js_src)
    .env("PWD", &js_src)
    .stdout(Stdio::inherit())
    .stderr(Stdio::inherit());
    println!("Running command: {:?}", cmd);
    let result = cmd.status().expect("Should spawn autospider OK");
    assert!(result.success(), "autospider should exit OK");

    println!("cargo:rustc-link-search=native={}/js/src/build", out_dir);
    println!("cargo:rustc-link-search=native={}/js/src", out_dir);
    println!("cargo:rustc-link-lib=static=js_static");

    maybe_add_spidermonkey_rust_lib();

    println!("cargo:rustc-link-search=native={}/dist/bin", out_dir);
    println!("cargo:rustc-link-lib=nspr4");

    if target.contains("windows") {
        println!("cargo:rustc-link-lib=winmm");
        if target.contains("gnu") {
            println!("cargo:rustc-link-lib=stdc++");
        }
    } else {
        println!("cargo:rustc-link-lib=stdc++");
    }

    println!("cargo:outdir={}", out_dir);
}

/// Find if Spidermonkey built the Spidermonkey Rust library, and add it to the
/// link if it was the case.
fn maybe_add_spidermonkey_rust_lib() {
    let out_dir = env::var("OUT_DIR").expect("cargo should invoke us with the OUT_DIR env var set");

    let mut target_build_dir = path::PathBuf::from(out_dir);
    target_build_dir.push("../../");

    let mut build_dir = target_build_dir.display().to_string();
    build_dir.push_str("mozjs_sys-*/out/*/debug");

    let entries = match glob::glob(&build_dir) {
        Err(_) => {
            return;
        }
        Ok(entries) => entries,
    };

    for entry in entries {
        if let Ok(path) = entry {
            let path = path
                .canonicalize()
                .expect("Should canonicalize debug build path");
            let path = path.to_str().expect("Should be utf8");
            println!("cargo:rustc-link-search=native={}", path);
            println!("cargo:rustc-link-lib=static=jsrust");
            return;
        }
    }
}