mirror of
https://github.com/servo/servo.git
synced 2025-08-05 13:40:08 +01:00
Skip invoking bindgen if no header changes
This can avoid doing bindgen when build script is called for updating other files, e.g. properties.
This commit is contained in:
parent
7e3c9e2197
commit
b6ea9976ba
1 changed files with 39 additions and 19 deletions
|
@ -4,10 +4,15 @@
|
||||||
|
|
||||||
mod common {
|
mod common {
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::path::PathBuf;
|
use std::path::{Path, PathBuf};
|
||||||
|
use std::sync::Mutex;
|
||||||
|
use std::time::SystemTime;
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
pub static ref OUTDIR_PATH: PathBuf = PathBuf::from(env::var("OUT_DIR").unwrap()).join("gecko");
|
pub static ref OUTDIR_PATH: PathBuf = PathBuf::from(env::var("OUT_DIR").unwrap()).join("gecko");
|
||||||
|
pub static ref LAST_MODIFIED: Mutex<SystemTime> =
|
||||||
|
Mutex::new(get_modified_time(&env::current_exe().unwrap())
|
||||||
|
.expect("Failed to get modified time of executable"));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const STRUCTS_DEBUG_FILE: &'static str = "structs_debug.rs";
|
pub const STRUCTS_DEBUG_FILE: &'static str = "structs_debug.rs";
|
||||||
|
@ -26,16 +31,21 @@ mod common {
|
||||||
BuildType::Release => STRUCTS_RELEASE_FILE
|
BuildType::Release => STRUCTS_RELEASE_FILE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_modified_time(file: &Path) -> Option<SystemTime> {
|
||||||
|
file.metadata().and_then(|m| m.modified()).ok()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "bindgen")]
|
#[cfg(feature = "bindgen")]
|
||||||
mod bindings {
|
mod bindings {
|
||||||
use libbindgen::{Builder, CodegenConfig};
|
use libbindgen::{Builder, CodegenConfig};
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
|
use std::cmp;
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{BufWriter, Read, Write};
|
use std::io::{Read, Write};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
use super::common::*;
|
use super::common::*;
|
||||||
|
@ -59,9 +69,13 @@ mod bindings {
|
||||||
fn search_include(name: &str) -> Option<PathBuf> {
|
fn search_include(name: &str) -> Option<PathBuf> {
|
||||||
for path in SEARCH_PATHS.iter() {
|
for path in SEARCH_PATHS.iter() {
|
||||||
let file = path.join(name);
|
let file = path.join(name);
|
||||||
if file.is_file() {
|
if !file.is_file() {
|
||||||
return Some(file);
|
continue;
|
||||||
}
|
}
|
||||||
|
let modified = get_modified_time(&file).unwrap();
|
||||||
|
let mut last_modified = LAST_MODIFIED.lock().unwrap();
|
||||||
|
*last_modified = cmp::max(modified, *last_modified);
|
||||||
|
return Some(file);
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -178,10 +192,25 @@ mod bindings {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_binding_file(builder: Builder, file: &str) {
|
struct Fixup {
|
||||||
let bindings = builder.generate().expect("Unable to generate bindings");
|
pat: String,
|
||||||
let binding_file = File::create(&OUTDIR_PATH.join(file)).unwrap();
|
rep: String
|
||||||
bindings.write(Box::new(BufWriter::new(binding_file))).expect("Unable to write output");
|
}
|
||||||
|
|
||||||
|
fn write_binding_file(builder: Builder, file: &str, fixups: &[Fixup]) {
|
||||||
|
let out_file = OUTDIR_PATH.join(file);
|
||||||
|
if let Some(modified) = get_modified_time(&out_file) {
|
||||||
|
// Don't generate the file if nothing it depends on was modified.
|
||||||
|
let last_modified = LAST_MODIFIED.lock().unwrap();
|
||||||
|
if *last_modified <= modified {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let mut result = builder.generate().expect("Unable to generate bindings").to_string();
|
||||||
|
for fixup in fixups.iter() {
|
||||||
|
result = Regex::new(&format!(r"\b{}\b", fixup.pat)).unwrap().replace_all(&result, fixup.rep.as_str());
|
||||||
|
}
|
||||||
|
File::create(&out_file).unwrap().write_all(&result.into_bytes()).expect("Unable to write output");
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn generate_structs(build_type: BuildType) {
|
pub fn generate_structs(build_type: BuildType) {
|
||||||
|
@ -392,10 +421,6 @@ mod bindings {
|
||||||
servo: "AtomicRefCell<ElementData>",
|
servo: "AtomicRefCell<ElementData>",
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
struct Fixup {
|
|
||||||
pat: String,
|
|
||||||
rep: String
|
|
||||||
}
|
|
||||||
let mut fixups = vec![
|
let mut fixups = vec![
|
||||||
Fixup {
|
Fixup {
|
||||||
pat: "root::nsString".into(),
|
pat: "root::nsString".into(),
|
||||||
|
@ -421,12 +446,7 @@ mod bindings {
|
||||||
rep: format!("::gecko_bindings::structs::{}", gecko_name)
|
rep: format!("::gecko_bindings::structs::{}", gecko_name)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
let mut result = builder.generate().expect("Unable to generate bindings").to_string();
|
write_binding_file(builder, structs_file(build_type), &fixups);
|
||||||
for fixup in fixups.iter() {
|
|
||||||
result = Regex::new(&format!(r"\b{}\b", fixup.pat)).unwrap().replace_all(&result, fixup.rep.as_str());
|
|
||||||
}
|
|
||||||
File::create(&OUTDIR_PATH.join(structs_file(build_type))).unwrap()
|
|
||||||
.write_all(&result.into_bytes()).unwrap();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn generate_bindings() {
|
pub fn generate_bindings() {
|
||||||
|
@ -588,7 +608,7 @@ mod bindings {
|
||||||
// type with zero_size_type. If we ever introduce immutable borrow types
|
// type with zero_size_type. If we ever introduce immutable borrow types
|
||||||
// which _do_ need to be opaque, we'll need a separate mode.
|
// which _do_ need to be opaque, we'll need a separate mode.
|
||||||
}
|
}
|
||||||
write_binding_file(builder, BINDINGS_FILE);
|
write_binding_file(builder, BINDINGS_FILE, &Vec::new());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue