aboutsummaryrefslogtreecommitdiffstats
path: root/components/script_bindings/build.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/script_bindings/build.rs')
-rw-r--r--components/script_bindings/build.rs124
1 files changed, 124 insertions, 0 deletions
diff --git a/components/script_bindings/build.rs b/components/script_bindings/build.rs
new file mode 100644
index 00000000000..25b5e10a24d
--- /dev/null
+++ b/components/script_bindings/build.rs
@@ -0,0 +1,124 @@
+/* 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/. */
+
+use std::fs::File;
+use std::io::Write;
+use std::path::PathBuf;
+use std::process::Command;
+use std::time::Instant;
+use std::{env, fmt};
+
+use phf_shared::{self, FmtConst};
+use serde_json::{self, Value};
+
+fn main() {
+ let start = Instant::now();
+
+ let style_out_dir = PathBuf::from(env::var_os("DEP_SERVO_STYLE_CRATE_OUT_DIR").unwrap());
+ let css_properties_json = style_out_dir.join("css-properties.json");
+ let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap());
+
+ println!("cargo:out_dir={}", out_dir.display());
+
+ println!("cargo::rerun-if-changed=webidls");
+ println!("cargo::rerun-if-changed=codegen");
+ println!("cargo::rerun-if-changed={}", css_properties_json.display());
+ println!("cargo::rerun-if-changed=../../third_party/WebIDL/WebIDL.py");
+ // NB: We aren't handling changes in `third_party/ply` here.
+
+ let status = Command::new(find_python())
+ .arg("codegen/run.py")
+ .arg(&css_properties_json)
+ .arg(&out_dir)
+ .status()
+ .unwrap();
+ if !status.success() {
+ std::process::exit(1)
+ }
+
+ println!("Binding generation completed in {:?}", start.elapsed());
+
+ let json = out_dir.join("InterfaceObjectMapData.json");
+ let json: Value = serde_json::from_reader(File::open(json).unwrap()).unwrap();
+ let mut map = phf_codegen::Map::new();
+ for (key, value) in json.as_object().unwrap() {
+ map.entry(Bytes(key), value.as_str().unwrap());
+ }
+ let phf = PathBuf::from(env::var_os("OUT_DIR").unwrap()).join("InterfaceObjectMapPhf.rs");
+ let mut phf = File::create(phf).unwrap();
+ writeln!(
+ &mut phf,
+ "pub(crate) static MAP: phf::Map<&'static [u8], fn(JSContext, HandleObject)> = {};",
+ map.build(),
+ )
+ .unwrap();
+}
+
+#[derive(Eq, Hash, PartialEq)]
+struct Bytes<'a>(&'a str);
+
+impl FmtConst for Bytes<'_> {
+ fn fmt_const(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ write!(formatter, "b\"{}\"", self.0)
+ }
+}
+
+impl phf_shared::PhfHash for Bytes<'_> {
+ fn phf_hash<H: std::hash::Hasher>(&self, hasher: &mut H) {
+ self.0.as_bytes().phf_hash(hasher)
+ }
+}
+
+/// Tries to find a suitable python
+///
+/// Algorithm
+/// 1. Trying to find python3/python in $VIRTUAL_ENV (this should be from Servo's venv)
+/// 2. Checking PYTHON3 (set by mach)
+/// 3. Falling back to the system installation.
+///
+/// Note: This function should be kept in sync with the version in `components/servo/build.rs`
+fn find_python() -> PathBuf {
+ let mut candidates = vec![];
+ if let Some(venv) = env::var_os("VIRTUAL_ENV") {
+ let bin_directory = PathBuf::from(venv).join("bin");
+
+ let python3 = bin_directory.join("python3");
+ if python3.exists() {
+ candidates.push(python3);
+ }
+ let python = bin_directory.join("python");
+ if python.exists() {
+ candidates.push(python);
+ }
+ };
+ if let Some(python3) = env::var_os("PYTHON3") {
+ let python3 = PathBuf::from(python3);
+ if python3.exists() {
+ candidates.push(python3);
+ }
+ }
+
+ let system_python = ["python3", "python"].map(PathBuf::from);
+ candidates.extend_from_slice(&system_python);
+
+ for name in &candidates {
+ // Command::new() allows us to omit the `.exe` suffix on windows
+ if Command::new(name)
+ .arg("--version")
+ .output()
+ .is_ok_and(|out| out.status.success())
+ {
+ return name.to_owned();
+ }
+ }
+ let candidates = candidates
+ .into_iter()
+ .map(|c| c.into_os_string())
+ .collect::<Vec<_>>();
+ panic!(
+ "Can't find python (tried {:?})! Try enabling Servo's Python venv, \
+ setting the PYTHON3 env var or adding python3 to PATH.",
+ candidates.join(", ".as_ref())
+ )
+}