git.lucas.co / cce-browser
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 }