File: build.rs

package info (click to toggle)
firefox 147.0.2-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 4,683,484 kB
  • sloc: cpp: 7,607,246; javascript: 6,533,185; ansic: 3,775,227; python: 1,415,393; xml: 634,561; asm: 438,951; java: 186,241; sh: 62,752; makefile: 18,079; objc: 13,092; perl: 12,808; yacc: 4,583; cs: 3,846; pascal: 3,448; lex: 1,720; ruby: 1,003; php: 436; lisp: 258; awk: 247; sql: 66; sed: 54; csh: 10; exp: 6
file content (121 lines) | stat: -rw-r--r-- 4,274 bytes parent folder | download | duplicates (3)
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
113
114
115
116
117
118
119
120
121
/* 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 https://mozilla.org/MPL/2.0/. */

//! Build script for the Gecko Profiler bindings.
//!
//! This file is executed by cargo when this crate is built. It generates the
//! `$OUT_DIR/bindings.rs` file which is then included by `src/gecko_bindings/mod.rs`.

#[macro_use]
extern crate lazy_static;

use bindgen::{Builder, CodegenConfig};
use std::env;
use std::fs;
use std::path::PathBuf;

lazy_static! {
    static ref OUTDIR_PATH: PathBuf = PathBuf::from(env::var_os("OUT_DIR").unwrap()).join("gecko");
}

const BINDINGS_FILE: &str = "bindings.rs";

lazy_static! {
    static ref BINDGEN_FLAGS: Vec<String> = {
        mozbuild::config::BINDGEN_SYSTEM_FLAGS
            .iter()
            .chain(&mozbuild::config::NSPR_CFLAGS)
            .map(|s| s.to_string())
            .collect()
    };
    static ref SEARCH_PATHS: Vec<PathBuf> = vec![
        mozbuild::TOPOBJDIR.join("dist/include"),
        mozbuild::TOPOBJDIR.join("dist/include/nspr"),
    ];
}

fn search_include(name: &str) -> Option<PathBuf> {
    for path in SEARCH_PATHS.iter() {
        let file = path.join(name);
        if file.is_file() {
            return Some(file);
        }
    }
    None
}

fn add_include(name: &str) -> String {
    let file = match search_include(name) {
        Some(file) => file,
        None => panic!("Include not found: {}", name),
    };
    let file_path = String::from(file.to_str().unwrap());
    println!("cargo:rerun-if-changed={}", file_path);
    file_path
}

fn generate_bindings() {
    let mut builder = Builder::default()
        .enable_cxx_namespaces()
        .with_codegen_config(CodegenConfig::TYPES | CodegenConfig::VARS | CodegenConfig::FUNCTIONS)
        .disable_untagged_union()
        .size_t_is_usize(true);

    for dir in SEARCH_PATHS.iter() {
        builder = builder.clang_arg("-I").clang_arg(dir.to_str().unwrap());
    }

    builder = builder
        .clang_arg("-include")
        .clang_arg(add_include("mozilla-config.h"));

    for item in &*BINDGEN_FLAGS {
        builder = builder.clang_arg(item);
    }

    let bindings = builder
        .header(add_include("GeckoProfiler.h"))
        .header(add_include("ProfilerBindings.h"))
        .allowlist_function("gecko_profiler_.*")
        .allowlist_var("mozilla::profiler::detail::RacyFeatures::sActiveAndFeatures")
        .allowlist_type("mozilla::profiler::detail::RacyFeatures")
        .rustified_enum("mozilla::StackCaptureOptions")
        .rustified_enum("mozilla::MarkerSchema_Location")
        .rustified_enum("mozilla::MarkerSchema_Format")
        .rustified_enum("mozilla::MarkerSchema_PayloadFlags")
        // Converting std::string to an opaque type makes some platforms build
        // successfully. Otherwise, it fails to build because MarkerSchema has
        // some std::strings as its fields.
        .opaque_type("std::string")
        .opaque_type("std::unique_ptr")
        .opaque_type("mozilla::Maybe")
        .opaque_type("mozilla::MallocAllocPolicy")
        .opaque_type("mozilla::Variant")
        .opaque_type("mozilla::baseprofiler::UniqueJSONStrings")
        // std::vector needs to be converted to an opaque type because, if it's
        // not an opaque type, bindgen can't find its size properly and
        // MarkerSchema's total size reduces. That causes a heap buffer overflow.
        .opaque_type("std::vector")
        .raw_line("pub use self::root::*;")
        // Tell cargo to invalidate the built crate whenever any of the
        // included header files changed.
        .parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
        // Finish the builder and generate the bindings.
        .generate()
        // Unwrap the Result and panic on failure.
        .expect("Unable to generate bindings");

    let out_file = OUTDIR_PATH.join(BINDINGS_FILE);
    bindings
        .write_to_file(out_file)
        .expect("Couldn't write bindings!");
}

fn main() {
    println!("cargo:rerun-if-changed=build.rs");
    println!("cargo:out_dir={}", env::var("OUT_DIR").unwrap());

    fs::create_dir_all(&*OUTDIR_PATH).unwrap();
    generate_bindings();
}