2019-11-04 11:35:28 -06:00
|
|
|
use anyhow::{Context, Result};
|
2018-07-26 18:09:04 +01:00
|
|
|
use sourcefile::SourceFile;
|
2018-09-05 12:55:30 -07:00
|
|
|
use std::collections::HashSet;
|
2018-07-09 16:35:25 -07:00
|
|
|
use std::env;
|
2018-07-14 18:04:20 +02:00
|
|
|
use std::ffi::OsStr;
|
2018-07-09 16:35:25 -07:00
|
|
|
use std::fs;
|
2018-09-05 12:55:30 -07:00
|
|
|
use std::path::{self, PathBuf};
|
2019-11-04 11:35:28 -06:00
|
|
|
use std::process::Command;
|
2018-07-09 16:35:25 -07:00
|
|
|
|
2019-11-04 11:35:28 -06:00
|
|
|
fn main() -> Result<()> {
|
2019-06-10 07:12:44 -07:00
|
|
|
#[cfg(feature = "env_logger")]
|
2018-08-09 21:38:37 +01:00
|
|
|
env_logger::init();
|
2018-07-09 16:35:25 -07:00
|
|
|
println!("cargo:rerun-if-changed=build.rs");
|
|
|
|
println!("cargo:rerun-if-changed=webidls/enabled");
|
|
|
|
|
2018-08-09 21:38:37 +01:00
|
|
|
let entries = fs::read_dir("webidls/enabled").context("reading webidls/enabled directory")?;
|
2018-07-26 18:09:04 +01:00
|
|
|
let mut source = SourceFile::default();
|
2018-07-09 16:35:25 -07:00
|
|
|
for entry in entries {
|
2018-07-14 18:04:20 +02:00
|
|
|
let entry = entry.context("getting webidls/enabled/*.webidl entry")?;
|
2018-08-03 14:39:33 -07:00
|
|
|
let path = entry.path();
|
|
|
|
if path.extension() != Some(OsStr::new("webidl")) {
|
2018-09-26 08:26:00 -07:00
|
|
|
continue;
|
2018-07-14 18:04:20 +02:00
|
|
|
}
|
2018-08-03 14:39:33 -07:00
|
|
|
println!("cargo:rerun-if-changed={}", path.display());
|
2018-09-26 08:26:00 -07:00
|
|
|
source = source
|
|
|
|
.add_file(&path)
|
2019-11-04 11:35:28 -06:00
|
|
|
.with_context(|| format!("reading contents of file \"{}\"", path.display()))?;
|
2018-07-09 16:35:25 -07:00
|
|
|
}
|
|
|
|
|
2018-09-05 12:55:30 -07:00
|
|
|
// Read our manifest, learn all `[feature]` directives with "toml parsing".
|
|
|
|
// Use all these names to match against environment variables set by Cargo
|
|
|
|
// to figure out which features are activated to we can pass that down to
|
|
|
|
// the webidl compiler.
|
|
|
|
let manifest_dir = PathBuf::from(env::var_os("CARGO_MANIFEST_DIR").unwrap());
|
|
|
|
let manifest = fs::read_to_string(manifest_dir.join("Cargo.toml"))?;
|
2018-09-26 08:26:00 -07:00
|
|
|
let features = manifest
|
|
|
|
.lines()
|
|
|
|
.skip_while(|f| !f.starts_with("[features]"));
|
2018-09-05 12:55:30 -07:00
|
|
|
|
|
|
|
let enabled_features = env::vars()
|
|
|
|
.map(|p| p.0)
|
|
|
|
.filter(|p| p.starts_with("CARGO_FEATURE_"))
|
|
|
|
.map(|mut p| {
|
|
|
|
p.drain(0.."CARGO_FEATURE_".len());
|
|
|
|
p
|
2018-11-27 12:07:59 -08:00
|
|
|
})
|
|
|
|
.collect::<HashSet<_>>();
|
2018-09-05 12:55:30 -07:00
|
|
|
|
|
|
|
let mut allowed = Vec::new();
|
|
|
|
for feature in features.filter(|f| !f.starts_with("#") && !f.starts_with("[")) {
|
|
|
|
let mut parts = feature.split('=');
|
|
|
|
let name = parts.next().unwrap().trim();
|
|
|
|
if enabled_features.contains(&name.to_uppercase()) {
|
|
|
|
allowed.push(name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// If we're printing all features don't filter anything
|
2018-09-25 11:25:14 -07:00
|
|
|
println!("cargo:rerun-if-env-changed=__WASM_BINDGEN_DUMP_FEATURES");
|
2018-09-05 12:55:30 -07:00
|
|
|
let allowed = if env::var("__WASM_BINDGEN_DUMP_FEATURES").is_ok() {
|
|
|
|
None
|
|
|
|
} else {
|
|
|
|
Some(&allowed[..])
|
|
|
|
};
|
|
|
|
|
|
|
|
let bindings = match wasm_bindgen_webidl::compile(&source.contents, allowed) {
|
2018-07-26 18:09:04 +01:00
|
|
|
Ok(bindings) => bindings,
|
2019-11-04 11:35:28 -06:00
|
|
|
Err(e) => {
|
|
|
|
if let Some(err) = e.downcast_ref::<wasm_bindgen_webidl::WebIDLParseError>() {
|
|
|
|
if let Some(pos) = source.resolve_offset(err.0) {
|
2018-09-26 08:26:00 -07:00
|
|
|
let ctx = format!(
|
|
|
|
"compiling WebIDL into wasm-bindgen bindings in file \
|
|
|
|
\"{}\", line {} column {}",
|
|
|
|
pos.filename,
|
|
|
|
pos.line + 1,
|
|
|
|
pos.col + 1
|
|
|
|
);
|
2019-11-04 11:35:28 -06:00
|
|
|
return Err(e.context(ctx));
|
2018-07-26 18:09:04 +01:00
|
|
|
} else {
|
2019-11-04 11:35:28 -06:00
|
|
|
return Err(e.context("compiling WebIDL into wasm-bindgen bindings"));
|
2018-07-26 18:09:04 +01:00
|
|
|
}
|
|
|
|
}
|
2019-11-04 11:35:28 -06:00
|
|
|
return Err(e.context("compiling WebIDL into wasm-bindgen bindings"));
|
|
|
|
}
|
2018-07-26 18:09:04 +01:00
|
|
|
};
|
2018-07-09 16:35:25 -07:00
|
|
|
|
|
|
|
let out_dir = env::var("OUT_DIR").context("reading OUT_DIR environment variable")?;
|
2018-07-30 00:07:19 +01:00
|
|
|
let out_file_path = path::Path::new(&out_dir).join("bindings.rs");
|
2018-09-26 08:26:00 -07:00
|
|
|
fs::write(&out_file_path, bindings).context("writing bindings to output file")?;
|
2018-10-08 10:15:51 -07:00
|
|
|
println!("cargo:rustc-env=BINDINGS={}", out_file_path.display());
|
2018-07-09 16:35:25 -07:00
|
|
|
|
2018-07-30 00:07:19 +01:00
|
|
|
// run rustfmt on the generated file - really handy for debugging
|
2019-05-03 14:59:01 -07:00
|
|
|
//
|
|
|
|
// This is opportunistic though so don't assert that it succeeds.
|
2018-08-07 15:50:27 -07:00
|
|
|
println!("cargo:rerun-if-env-changed=WEBIDL_RUSTFMT_BINDINGS");
|
2019-04-15 08:31:54 -07:00
|
|
|
if env::var("WEBIDL_RUSTFMT_BINDINGS").ok() != Some("0".to_string()) {
|
2019-05-03 14:59:01 -07:00
|
|
|
drop(Command::new("rustfmt").arg(&out_file_path).status());
|
2018-08-03 14:39:33 -07:00
|
|
|
}
|
2018-07-30 00:07:19 +01:00
|
|
|
|
2018-07-09 16:35:25 -07:00
|
|
|
Ok(())
|
|
|
|
}
|