Bug 1578839 - Implement resizing of the browser with the embedded RDM UI. r=mtigley
[gecko.git] / js / rust / build.rs
blobe0845f0dfff7601e906487d6aad92e0374f0708b
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 extern crate bindgen;
6 extern crate cmake;
7 extern crate env_logger;
8 extern crate glob;
10 use std::env;
11 use std::path;
13 fn main() {
14     env_logger::init();
15     build_jsapi_bindings();
16     build_jsglue_cpp();
19 /// Build the ./src/jsglue.cpp file containing C++ glue methods built on top of
20 /// JSAPI.
21 fn build_jsglue_cpp() {
22     let dst = cmake::Config::new(".").build();
24     println!("cargo:rustc-link-search=native={}/lib", dst.display());
25     println!("cargo:rustc-link-lib=static=jsglue");
26     println!("cargo:rerun-if-changed=src/jsglue.cpp");
29 /// Find the public include directory within our mozjs-sys crate dependency.
30 fn get_mozjs_include_dir() -> path::PathBuf {
31     let out_dir = env::var("OUT_DIR")
32         .expect("cargo should invoke us with the OUT_DIR env var set");
34     let mut target_build_dir = path::PathBuf::from(out_dir);
35     target_build_dir.push("../../");
37     let mut include_dir_glob = target_build_dir.display().to_string();
38     include_dir_glob.push_str("mozjs_sys-*/out/dist/include");
40     let entries = glob::glob(&include_dir_glob)
41         .expect("Should find entries for mozjs-sys include dir");
43     for entry in entries {
44         if let Ok(path) = entry {
45             return path.canonicalize()
46                 .expect("Should canonicalize include path");
47         }
48     }
50     panic!("Should have found either a mozjs_sys in target/debug or in target/release");
53 /// Invoke bindgen on the JSAPI headers to produce raw FFI bindings for use from
54 /// Rust.
55 ///
56 /// To add or remove which functions, types, and variables get bindings
57 /// generated, see the `const` configuration variables below.
58 fn build_jsapi_bindings() {
59     let mut builder = bindgen::builder()
60         .rust_target(bindgen::RustTarget::Stable_1_19)
61         .header("./etc/wrapper.hpp")
62         .raw_line("pub use self::root::*;")
63         // Translate every enum with the "rustified enum" strategy. We should
64         // investigate switching to the "constified module" strategy, which has
65         // similar ergonomics but avoids some potential Rust UB footguns.
66         .rustified_enum(".*")
67         .enable_cxx_namespaces();
69     if cfg!(feature = "debugmozjs") {
70         builder = builder
71             .clang_arg("-DJS_GC_ZEAL")
72             .clang_arg("-DDEBUG")
73             .clang_arg("-DJS_DEBUG");
74     }
76     if cfg!(feature = "bigint") {
77         builder = builder.clang_arg("-DENABLE_BIGINT");
78     }
80     let include_dir = get_mozjs_include_dir();
81     let include_dir = include_dir.to_str()
82         .expect("Path to mozjs include dir should be utf-8");
83     builder = builder.clang_arg("-I");
84     builder = builder.clang_arg(include_dir);
86     for ty in UNSAFE_IMPL_SYNC_TYPES {
87         builder = builder.raw_line(format!("unsafe impl Sync for {} {{}}", ty));
88     }
90     for extra in EXTRA_CLANG_FLAGS {
91         builder = builder.clang_arg(*extra);
92     }
94     for ty in WHITELIST_TYPES {
95         builder = builder.whitelist_type(ty);
96     }
98     for var in WHITELIST_VARS {
99         builder = builder.whitelist_var(var);
100     }
102     for func in WHITELIST_FUNCTIONS {
103         builder = builder.whitelist_function(func);
104     }
106     if cfg!(feature = "bigint") {
107         builder = builder.whitelist_type("JS::BigInt");
108     }
110     for ty in OPAQUE_TYPES {
111         builder = builder.opaque_type(ty);
112     }
114     for ty in BLACKLIST_TYPES {
115         builder = builder.blacklist_type(ty);
116     }
118     let bindings = builder.generate()
119         .expect("Should generate JSAPI bindings OK");
121     let out = path::PathBuf::from(env::var("OUT_DIR").unwrap());
123     if cfg!(feature = "debugmozjs") {
124         bindings.write_to_file(out.join("jsapi_debug.rs"))
125             .expect("Should write bindings to file OK");
126     } else {
127         bindings.write_to_file(out.join("jsapi.rs"))
128             .expect("Should write bindings to file OK");
129     }
131     println!("cargo:rerun-if-changed=etc/wrapper.hpp");
134 /// JSAPI types for which we should implement `Sync`.
135 const UNSAFE_IMPL_SYNC_TYPES: &'static [&'static str] = &[
136     "JSClass",
137     "JSFunctionSpec",
138     "JSNativeWrapper",
139     "JSPropertySpec",
140     "JSTypedMethodJitInfo",
143 /// Flags passed through bindgen directly to Clang.
144 const EXTRA_CLANG_FLAGS: &'static [&'static str] = &[
145     "-x", "c++",
146     "-std=gnu++14",
147     "-fno-sized-deallocation",
148     "-fno-aligned-new",
149     "-DRUST_BINDGEN",
152 /// Types which we want to generate bindings for (and every other type they
153 /// transitively use).
154 const WHITELIST_TYPES: &'static [&'static str] = &[
155     "JS::AutoCheckCannotGC",
156     "JS::CallArgs",
157     "JS::RealmOptions",
158     "JS::ContextOptions",
159     "js::DOMCallbacks",
160     "js::DOMProxyShadowsResult",
161     "js::ESClass",
162     "JS::ForOfIterator",
163     "JS::Handle",
164     "JS::HandleFunction",
165     "JS::HandleId",
166     "JS::HandleObject",
167     "JS::HandleString",
168     "JS::HandleValue",
169     "JS::HandleValueArray",
170     "JS::IsAcceptableThis",
171     "JSAutoRealm",
172     "JSAutoStructuredCloneBuffer",
173     "JSClass",
174     "JSClassOps",
175     "JSContext",
176     "JSErrNum",
177     "JSErrorCallback",
178     "JSErrorFormatString",
179     "JSErrorReport",
180     "JSExnType",
181     "JSFlatString",
182     "JSFunction",
183     "JSFunctionSpec",
184     "JS::GCDescription",
185     "JSGCInvocationKind",
186     "JSGCMode",
187     "JSGCParamKey",
188     "JS::GCProgress",
189     "JSGCStatus",
190     "JSJitCompilerOption",
191     "JSJitGetterCallArgs",
192     "JSJitMethodCallArgs",
193     "JSJitSetterCallArgs",
194     "JSNativeWrapper",
195     "JSPropertySpec",
196     "JSProtoKey",
197     "JSObject",
198     "JSString",
199     "JSStructuredCloneReader",
200     "JSStructuredCloneWriter",
201     "JSScript",
202     "JSType",
203     "JSTypedMethodJitInfo",
204     "JSValueTag",
205     "JSValueType",
206     "JSVersion",
207     "JSWrapObjectCallbacks",
208     "jsid",
209     "JS::Compartment",
210     "JS::Latin1Char",
211     "JS::detail::MaybeWrapped",
212     "JS::MutableHandle",
213     "JS::MutableHandleObject",
214     "JS::MutableHandleValue",
215     "JS::NativeImpl",
216     "js::ObjectOps",
217     "JS::ObjectOpResult",
218     "JS::PersistentRootedIdVector",
219     "JS::PersistentRootedObjectVector",
220     "JS::PromiseState",
221     "JS::PropertyDescriptor",
222     "JS::Rooted",
223     "JS::RootedObject",
224     "JS::RootedValue",
225     "JS::RootingContext",
226     "JS::RootKind",
227     "js::Scalar::Type",
228     "JS::ServoSizes",
229     "js::shadow::Object",
230     "js::shadow::ObjectGroup",
231     "JS::SourceText",
232     "js::StackFormat",
233     "JSStructuredCloneCallbacks",
234     "JS::Symbol",
235     "JS::SymbolCode",
236     "JS::TraceKind",
237     "JS::TransferableOwnership",
238     "JS::Value",
239     "JS::WarningReporter",
240     "JS::shadow::Realm",
241     "JS::shadow::Zone",
242     "JS::Zone",
245 /// Global variables we want to generate bindings to.
246 const WHITELIST_VARS: &'static [&'static str] = &[
247     "JS_STRUCTURED_CLONE_VERSION",
248     "JSCLASS_.*",
249     "JSFUN_.*",
250     "JSID_TYPE_VOID",
251     "JSITER_.*",
252     "JSPROP_.*",
253     "JS::FalseHandleValue",
254     "JS::NullHandleValue",
255     "JS::TrueHandleValue",
256     "JS::UndefinedHandleValue",
259 /// Functions we want to generate bindings to.
260 const WHITELIST_FUNCTIONS: &'static [&'static str] = &[
261     "INTERNED_STRING_TO_JSID",
262     "JS::ExceptionStackOrNull",
263     "JS_AddExtraGCRootsTracer",
264     "JS_AddInterruptCallback",
265     "JS::AddPromiseReactions",
266     "js::AddRawValueRoot",
267     "JS_AlreadyHasOwnPropertyById",
268     "JS_AtomizeAndPinString",
269     "js::AssertSameCompartment",
270     "JS::BuildStackString",
271     "JS::Call",
272     "JS_CallFunctionName",
273     "JS_CallFunctionValue",
274     "JS::CallOriginalPromiseThen",
275     "JS::CallOriginalPromiseResolve",
276     "JS::CallOriginalPromiseReject",
277     "JS::CompileFunctionUtf8",
278     "JS::Construct",
279     "JS::ContextOptionsRef",
280     "JS_CopyPropertiesFrom",
281     "JS::CurrentGlobalOrNull",
282     "JS_DeletePropertyById",
283     "js::detail::IsWindowSlow",
284     "JS::Evaluate",
285     "JS_ForwardGetPropertyTo",
286     "JS_ForwardSetPropertyTo",
287     "JS::GCTraceKindToAscii",
288     "JS::GetArrayBufferLengthAndData",
289     "js::GetArrayBufferViewLengthAndData",
290     "js::GetFunctionNativeReserved",
291     "JS::GetNonCCWObjectGlobal",
292     "js::GetObjectProto",
293     "JS_GetObjectRuntime",
294     "JS_GetOwnPropertyDescriptorById",
295     "JS::GetPromiseResult",
296     "JS::GetPromiseState",
297     "JS_GetPropertyDescriptorById",
298     "js::GetPropertyKeys",
299     "JS_GetPrototype",
300     "JS_GetRuntime",
301     "js::GetStaticPrototype",
302     "JS_HasOwnPropertyById",
303     "JS_HasProperty",
304     "JS_HasPropertyById",
305     "JS::HeapObjectWriteBarriers",
306     "JS::HeapScriptWriteBarriers",
307     "JS::HeapStringWriteBarriers",
308     "JS::HeapValueWriteBarriers",
309     "JS_InitializePropertiesFromCompatibleNativeObject",
310     "JS::InitSelfHostedCode",
311     "JS::IsConstructor",
312     "JS::IsPromiseObject",
313     "JS_ClearPendingException",
314     "JS_DefineElement",
315     "JS_DefineFunction",
316     "JS_DefineFunctions",
317     "JS_DefineProperties",
318     "JS_DefineProperty",
319     "JS_DefinePropertyById",
320     "JS_DefineUCProperty",
321     "JS::detail::InitWithFailureDiagnostic",
322     "JS_DestroyContext",
323     "JS::DisableIncrementalGC",
324     "js::Dump.*",
325     "JS::EnterRealm",
326     "JS_EnumerateStandardClasses",
327     "JS_ErrorFromException",
328     "JS_FireOnNewGlobalObject",
329     "JS_free",
330     "JS_GC",
331     "JS::GetArrayBufferData",
332     "JS_GetArrayBufferViewType",
333     "JS_GetFloat32ArrayData",
334     "JS_GetFloat64ArrayData",
335     "JS_GetFunctionObject",
336     "JS_GetGCParameter",
337     "JS_GetInt16ArrayData",
338     "JS_GetInt32ArrayData",
339     "JS_GetInt8ArrayData",
340     "JS_GetLatin1StringCharsAndLength",
341     "JS_GetParentRuntime",
342     "JS_GetPendingException",
343     "JS_GetProperty",
344     "JS_GetPropertyById",
345     "js::GetPropertyKeys",
346     "JS_GetPrototype",
347     "JS_GetReservedSlot",
348     "JS::GetRealmErrorPrototype",
349     "JS::GetRealmFunctionPrototype",
350     "JS::GetRealmIteratorPrototype",
351     "JS::GetRealmObjectPrototype",
352     "JS::GetScriptedCallerGlobal",
353     "JS_GetTwoByteStringCharsAndLength",
354     "JS_GetUint16ArrayData",
355     "JS_GetUint32ArrayData",
356     "JS_GetUint8ArrayData",
357     "JS_GetUint8ClampedArrayData",
358     "JS::GetWellKnownSymbol",
359     "JS_GlobalObjectTraceHook",
360     "JS::HideScriptedCaller",
361     "JS::InitRealmStandardClasses",
362     "JS_IsArrayObject",
363     "JS_IsExceptionPending",
364     "JS_IsGlobalObject",
365     "JS::IsCallable",
366     "JS::LeaveRealm",
367     "JS_LinkConstructorAndPrototype",
368     "JS_MayResolveStandardClass",
369     "JS::NewArrayBuffer",
370     "JS_NewArrayObject",
371     "JS_NewContext",
372     "JS_NewFloat32Array",
373     "JS_NewFloat64Array",
374     "JS_NewFunction",
375     "js::NewFunctionWithReserved",
376     "JS_NewGlobalObject",
377     "JS_NewInt16Array",
378     "JS_NewInt32Array",
379     "JS_NewInt8Array",
380     "JS_NewObject",
381     "JS_NewObjectWithGivenProto",
382     "JS_NewObjectWithoutMetadata",
383     "JS_NewObjectWithUniqueType",
384     "JS_NewPlainObject",
385     "JS::NewPromiseObject",
386     "JS_NewStringCopyN",
387     "JS_NewUCStringCopyN",
388     "JS_NewUint16Array",
389     "JS_NewUint32Array",
390     "JS_NewUint8Array",
391     "JS_NewUint8ClampedArray",
392     "js::ObjectClassName",
393     "JS::ObjectIsDate",
394     "JS_ParseJSON",
395     "JS_ReadBytes",
396     "JS_ReadStructuredClone",
397     "JS_ReadUint32Pair",
398     "JS_RemoveExtraGCRootsTracer",
399     "js::RemoveRawValueRoot",
400     "JS_ReportErrorASCII",
401     "JS_ReportErrorNumberUTF8",
402     "JS_RequestInterruptCallback",
403     "JS_ResolveStandardClass",
404     "js::RunJobs",
405     "JS::SameValue",
406     "js::SetDOMCallbacks",
407     "js::SetDOMProxyInformation",
408     "JS::SetEnqueuePromiseJobCallback",
409     "js::SetFunctionNativeReserved",
410     "JS_SetGCCallback",
411     "JS::SetGCSliceCallback",
412     "JS_SetGCParameter",
413     "JS_SetGCZeal",
414     "JS::SetGetIncumbentGlobalCallback",
415     "JS_SetGlobalJitCompilerOption",
416     "JS_SetImmutablePrototype",
417     "JS_SetNativeStackQuota",
418     "JS_SetOffthreadIonCompilationEnabled",
419     "JS_SetParallelParsingEnabled",
420     "JS_SetPendingException",
421     "js::SetPreserveWrapperCallback",
422     "JS::SetPromiseRejectionTrackerCallback",
423     "JS_SetPrototype",
424     "js::SetWindowProxy",
425     "js::SetWindowProxyClass",
426     "JS_SetProperty",
427     "JS_SetReservedSlot",
428     "JS_SetWrapObjectCallbacks",
429     "JS_ShutDown",
430     "JS_SplicePrototype",
431     "js::StopDrainingJobQueue",
432     "JS_StrictPropertyStub",
433     "JS_StringEqualsAscii",
434     "JS_StringHasLatin1Chars",
435     "JS_WrapObject",
436     "JS_WrapValue",
437     "JS_WriteBytes",
438     "JS_WriteStructuredClone",
439     "JS_WriteUint32Pair",
440     "JS::ResolvePromise",
441     "JS::RejectPromise",
442     "JS::SetWarningReporter",
443     "js::ToBooleanSlow",
444     "js::ToInt32Slow",
445     "js::ToInt64Slow",
446     "js::ToNumberSlow",
447     "js::ToStringSlow",
448     "js::ToUint16Slow",
449     "js::ToUint32Slow",
450     "js::ToUint64Slow",
451     "JS_TransplantObject",
452     "js::detail::ToWindowProxyIfWindowSlow",
453     "JS::UnhideScriptedCaller",
454     "JS::UnwrapArrayBuffer",
455     "js::UnwrapArrayBufferView",
456     "js::UnwrapFloat32Array",
457     "js::UnwrapFloat64Array",
458     "js::UnwrapInt16Array",
459     "js::UnwrapInt32Array",
460     "js::UnwrapInt8Array",
461     "js::UnwrapUint16Array",
462     "js::UnwrapUint32Array",
463     "js::UnwrapUint8Array",
464     "js::UnwrapUint8ClampedArray",
465     "js::UseInternalJobQueues",
466     "JS_ValueToFunction",
469 /// Types that should be treated as an opaque blob of bytes whenever they show
470 /// up within a whitelisted type.
472 /// These are types which are too tricky for bindgen to handle, and/or use C++
473 /// features that don't have an equivalent in rust, such as partial template
474 /// specialization.
475 const OPAQUE_TYPES: &'static [&'static str] = &[
476     "JS::ReadOnlyCompileOptions",
477     "mozilla::BufferList",
478     "mozilla::UniquePtr.*",
479     "JS::PersistentRooted",
480     "JS::StackGCVector",
483 /// Types for which we should NEVER generate bindings, even if it is used within
484 /// a type or function signature that we are generating bindings for.
485 const BLACKLIST_TYPES: &'static [&'static str] = &[
486     // We provide our own definition because we need to express trait bounds in
487     // the definition of the struct to make our Drop implementation correct.
488     "JS::Heap",