|
5 | 5 | use std::env;
|
6 | 6 | use std::path::PathBuf;
|
7 | 7 |
|
8 |
| -fn main() { |
9 |
| - let mut build = cc::Build::new(); |
10 |
| - let outdir = env::var("DEP_MOZJS_OUTDIR").unwrap(); |
11 |
| - let include_path: PathBuf = [&outdir, "dist", "include"].iter().collect(); |
| 8 | +fn cc_flags(bindgen: bool) -> Vec<&'static str> { |
| 9 | + let mut result = vec!["-DSTATIC_JS_API"]; |
12 | 10 |
|
13 |
| - build |
14 |
| - .cpp(true) |
15 |
| - .file("src/jsglue.cpp") |
16 |
| - .flag("-DSTATIC_JS_API") |
17 |
| - .include(include_path); |
18 | 11 | if env::var("CARGO_FEATURE_DEBUGMOZJS").is_ok() {
|
19 |
| - build.define("DEBUG", ""); |
| 12 | + result.push("-DDEBUG"); |
20 | 13 |
|
21 |
| - if cfg!(target_os = "windows") { |
22 |
| - build.flag("-Od"); |
23 |
| - } else { |
24 |
| - build.flag("-g"); |
25 |
| - build.flag("-O0"); |
| 14 | + // bindgen doesn't like this |
| 15 | + if !bindgen { |
| 16 | + if cfg!(target_os = "windows") { |
| 17 | + result.push("-Od"); |
| 18 | + } else { |
| 19 | + result.push("-g"); |
| 20 | + result.push("-O0"); |
| 21 | + } |
26 | 22 | }
|
27 | 23 | }
|
28 | 24 |
|
29 | 25 | if env::var("CARGO_FEATURE_PROFILEMOZJS").is_ok() {
|
30 |
| - build.flag_if_supported("-fno-omit-frame-pointer"); |
| 26 | + result.push("-fno-omit-frame-pointer"); |
31 | 27 | }
|
32 | 28 |
|
33 |
| - build.flag_if_supported("-Wno-c++0x-extensions"); |
34 |
| - build.flag_if_supported("-Wno-return-type-c-linkage"); |
35 |
| - build.flag_if_supported("-Wno-invalid-offsetof"); |
36 |
| - build.flag_if_supported("-Wno-unused-parameter"); |
| 29 | + result.push("-Wno-c++0x-extensions"); |
| 30 | + result.push("-Wno-return-type-c-linkage"); |
| 31 | + result.push("-Wno-invalid-offsetof"); |
| 32 | + result.push("-Wno-unused-parameter"); |
| 33 | + |
| 34 | + result |
| 35 | +} |
| 36 | + |
| 37 | +fn main() { |
| 38 | + //let mut build = cxx_build::bridge("src/jsglue.rs"); // returns a cc::Build; |
| 39 | + let mut build = cc::Build::new(); |
| 40 | + let outdir = env::var("DEP_MOZJS_OUTDIR").unwrap(); |
| 41 | + let include_path: PathBuf = [&outdir, "dist", "include"].iter().collect(); |
| 42 | + |
| 43 | + build |
| 44 | + .cpp(true) |
| 45 | + .file("src/jsglue.cpp") |
| 46 | + .include(&include_path); |
| 47 | + for flag in cc_flags(false) { |
| 48 | + build.flag_if_supported(flag); |
| 49 | + } |
37 | 50 |
|
38 | 51 | let confdefs_path: PathBuf = [&outdir, "js", "src", "js-confdefs.h"].iter().collect();
|
39 |
| - if build.get_compiler().is_like_msvc() { |
| 52 | + let msvc = if build.get_compiler().is_like_msvc() { |
40 | 53 | build.flag(&format!("-FI{}", confdefs_path.to_string_lossy()));
|
41 | 54 | build.define("WIN32", "");
|
42 | 55 | build.flag("-Zi");
|
43 | 56 | build.flag("-GR-");
|
44 | 57 | build.flag("-std:c++17");
|
| 58 | + true |
45 | 59 | } else {
|
46 | 60 | build.flag("-fPIC");
|
47 | 61 | build.flag("-fno-rtti");
|
48 | 62 | build.flag("-std=c++17");
|
49 |
| - build.define("JS_NO_JSVAL_JSID_STRUCT_TYPES", ""); |
50 | 63 | build.flag("-include");
|
51 | 64 | build.flag(&confdefs_path.to_string_lossy());
|
52 |
| - } |
| 65 | + false |
| 66 | + }; |
53 | 67 |
|
54 | 68 | build.compile("jsglue");
|
55 | 69 | println!("cargo:rerun-if-changed=src/jsglue.cpp");
|
| 70 | + let mut builder = bindgen::Builder::default() |
| 71 | + .header("./src/jsglue.cpp") |
| 72 | + .parse_callbacks(Box::new(bindgen::CargoCallbacks)) |
| 73 | + .size_t_is_usize(true) |
| 74 | + .formatter(bindgen::Formatter::Rustfmt) |
| 75 | + .clang_arg("-x") |
| 76 | + .clang_arg("c++") |
| 77 | + .clang_args(cc_flags(true)) |
| 78 | + .clang_args(["-I", &include_path.to_string_lossy()]) |
| 79 | + .enable_cxx_namespaces() |
| 80 | + .allowlist_file("./src/jsglue.cpp") |
| 81 | + .allowlist_recursively(false); |
| 82 | + |
| 83 | + if msvc { |
| 84 | + builder = builder.clang_args([ |
| 85 | + &format!("-FI{}", confdefs_path.to_string_lossy()), |
| 86 | + "-DWIN32", |
| 87 | + "-GR-", |
| 88 | + "-std=c++17", |
| 89 | + ]) |
| 90 | + } else { |
| 91 | + builder = builder |
| 92 | + .clang_args(["-fPIC", "-fno-rtti", "-std=c++17"]) |
| 93 | + .clang_args(["-include", &confdefs_path.to_str().expect("UTF-8")]) |
| 94 | + } |
| 95 | + |
| 96 | + for ty in BLACKLIST_TYPES { |
| 97 | + builder = builder.blocklist_type(ty); |
| 98 | + } |
| 99 | + |
| 100 | + for ty in OPAQUE_TYPES { |
| 101 | + builder = builder.opaque_type(ty); |
| 102 | + } |
| 103 | + |
| 104 | + for &(module, raw_line) in MODULE_RAW_LINES { |
| 105 | + builder = builder.module_raw_line(module, raw_line); |
| 106 | + } |
| 107 | + let bindings = builder |
| 108 | + .generate() |
| 109 | + .expect("Unable to generate bindings to jsglue"); |
| 110 | + |
| 111 | + // Write the bindings to the $OUT_DIR/bindings.rs file. |
| 112 | + let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()).join("gluebindings.rs"); |
| 113 | + bindings |
| 114 | + .write_to_file(out_path) |
| 115 | + .expect("Couldn't write bindings!"); |
56 | 116 | }
|
| 117 | + |
| 118 | +/// Types that have generic arguments must be here or else bindgen does not generate <T> |
| 119 | +/// as it treats them as opaque types |
| 120 | +const BLACKLIST_TYPES: &'static [&'static str] = &[ |
| 121 | + "JS::.*", |
| 122 | + "already_AddRefed", |
| 123 | + // we don't want it null |
| 124 | + "EncodedStringCallback", |
| 125 | +]; |
| 126 | + |
| 127 | +/// Types that should be treated as an opaque blob of bytes whenever they show |
| 128 | +/// up within a whitelisted type. |
| 129 | +/// |
| 130 | +/// These are types which are too tricky for bindgen to handle, and/or use C++ |
| 131 | +/// features that don't have an equivalent in rust, such as partial template |
| 132 | +/// specialization. |
| 133 | +const OPAQUE_TYPES: &'static [&'static str] = &[ |
| 134 | + "JS::Auto.*Impl", |
| 135 | + "JS::StackGCVector.*", |
| 136 | + "JS::PersistentRooted.*", |
| 137 | + "JS::detail::CallArgsBase.*", |
| 138 | + "js::detail::UniqueSelector.*", |
| 139 | + "mozilla::BufferList", |
| 140 | + "mozilla::Maybe.*", |
| 141 | + "mozilla::UniquePtr.*", |
| 142 | + "mozilla::Variant", |
| 143 | + "mozilla::Hash.*", |
| 144 | + "mozilla::detail::Hash.*", |
| 145 | + "RefPtr_Proxy.*", |
| 146 | +]; |
| 147 | + |
| 148 | +/// Map mozjs_sys mod namespaces to bindgen mod namespaces |
| 149 | +const MODULE_RAW_LINES: &'static [(&'static str, &'static str)] = &[ |
| 150 | + ("root", "pub(crate) use mozjs_sys::jsapi::*;"), |
| 151 | + ("root", "pub use crate::glue::EncodedStringCallback;"), |
| 152 | + ("root::js", "pub(crate) use mozjs_sys::jsapi::js::*;"), |
| 153 | + ( |
| 154 | + "root::mozilla", |
| 155 | + "pub(crate) use mozjs_sys::jsapi::mozilla::*;", |
| 156 | + ), |
| 157 | + ("root::JS", "pub(crate) use mozjs_sys::jsapi::JS::*;"), |
| 158 | +]; |
0 commit comments