web browser (Servo)
git clone https://git.lucas.co/cce-browser.git
build.rs (3K)
1 //! Generates the WPE WebKit FFI bindings, but **only under the `wpe` feature**.
2 //!
3 //! Without it this is a no-op, so a default (Servo) build needs no WPE headers
4 //! and behaves exactly as it did before the port started. See WPE-PORT.md.
5
6 fn main() {
7 println!("cargo:rerun-if-changed=build.rs");
8 println!("cargo:rerun-if-changed=src/wpe/wrapper.h");
9 if std::env::var("CARGO_FEATURE_WPE").is_err() {
10 return;
11 }
12
13 // Both modules are needed: wpe-webkit-2.0 is the engine, wpe-platform-2.0
14 // is the embedding layer (WPEDisplay / WPEView / WPEToplevel) the port
15 // subclasses. pkg-config emits the link flags for us.
16 let mut clang_args = Vec::new();
17 for module in ["wpe-webkit-2.0", "wpe-platform-2.0"] {
18 let lib = pkg_config::Config::new()
19 .probe(module)
20 .unwrap_or_else(|e| panic!("`{module}` not found — pacman -S wpewebkit ({e})"));
21 for path in &lib.include_paths {
22 clang_args.push(format!("-I{}", path.display()));
23 }
24 }
25
26 let bindings = bindgen::Builder::default()
27 .header("src/wpe/wrapper.h")
28 .clang_args(&clang_args)
29 // The engine, the embedding layer, and just enough GObject to
30 // register subclasses and turn a main loop.
31 .allowlist_item("(wpe|WPE|webkit|WebKit)_?.*")
32 // JavaScriptCore: a script message from the page arrives as a
33 // JSCValue, so reading one needs `jsc_value_*`. webkit.h already
34 // pulls in jsc.h; only the allowlist kept these out.
35 .allowlist_item("(jsc|JSC)_?.*")
36 .allowlist_item("g_(object|type|signal|bytes|timeout|free|error)_.*")
37 // `g_free` itself, with no trailing word, misses the pattern above —
38 // and a JSC string comes back owned, so it is needed to hand it back.
39 .allowlist_function("g_free")
40 // The main loop AND the context: `pump` drains the context directly.
41 .allowlist_item("g_main_(loop|context)_.*")
42 .allowlist_item("G(Object|Type|Value|Bytes|Error|MainLoop|ParamSpec|Closure).*")
43 // The main-context poll protocol: GPollFD is what `query` fills in.
44 .allowlist_item("G(MainContext|PollFD|Source).*")
45 // Serving `cce:` pages: the handler answers with an input stream.
46 .allowlist_item("g_(memory_input_stream|input_stream|file)_.*")
47 .allowlist_item("G(InputStream|MemoryInputStream|File|Cancellable|AsyncResult).*")
48 .allowlist_item("g_(type|object)_.*")
49 // GObject's generated enums are plain C enums; keep them as consts so
50 // vfunc tables and property flags stay comparable without casts.
51 .default_enum_style(bindgen::EnumVariation::ModuleConsts)
52 .derive_default(true)
53 .layout_tests(false)
54 .generate()
55 .expect("bindgen failed over the WPE headers");
56
57 let out = std::path::PathBuf::from(std::env::var("OUT_DIR").unwrap());
58 bindings
59 .write_to_file(out.join("wpe_bindings.rs"))
60 .expect("could not write wpe_bindings.rs");
61 }