diff --git a/components/style/binding_tools/regen_atoms.py b/components/style/binding_tools/regen_atoms.py
index 0950c0d7212..05acee47a7d 100755
--- a/components/style/binding_tools/regen_atoms.py
+++ b/components/style/binding_tools/regen_atoms.py
@@ -97,7 +97,9 @@ class Atom:
def collect_atoms(objdir):
atoms = []
for source in SOURCES:
- with open(os.path.join(objdir, source.FILE)) as f:
+ path = os.path.abspath(os.path.join(objdir, source.FILE))
+ print("cargo:rerun-if-changed={}".format(path))
+ with open(path) as f:
for line in f.readlines():
result = re.match(source.PATTERN, line)
if result:
@@ -255,15 +257,14 @@ def write_pseudo_element_helper(atoms, target_filename):
f.write("}\n")
-def generate_atoms(dist):
- style_path = os.path.dirname(os.path.dirname(__file__))
+def generate_atoms(dist, out):
atoms = collect_atoms(dist)
- write_atom_macro(atoms, os.path.join(style_path, "gecko_string_cache/atom_macro.rs"))
- write_pseudo_element_helper(atoms, os.path.join(style_path, "gecko/generated/gecko_pseudo_element_helper.rs"))
+ write_atom_macro(atoms, os.path.join(out, "atom_macro.rs"))
+ write_pseudo_element_helper(atoms, os.path.join(out, "pseudo_element_helper.rs"))
if __name__ == "__main__":
- if len(sys.argv) != 2:
- print("Usage: {} objdir".format(sys.argv[0]))
+ if len(sys.argv) != 3:
+ print("Usage: {} dist out".format(sys.argv[0]))
exit(2)
- generate_atoms(os.path.join(sys.argv[1], "dist"))
+ generate_atoms(sys.argv[1], sys.argv[2])
diff --git a/components/style/build.rs b/components/style/build.rs
index 5ecaf902c2b..8d40ccb9969 100644
--- a/components/style/build.rs
+++ b/components/style/build.rs
@@ -2,7 +2,6 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#[cfg(feature = "gecko")]
#[macro_use]
extern crate lazy_static;
#[cfg(feature = "bindgen")]
@@ -53,6 +52,10 @@ fn find_python() -> String {
}.to_owned()
}
+lazy_static! {
+ pub static ref PYTHON: String = env::var("PYTHON").ok().unwrap_or_else(find_python);
+}
+
fn generate_properties() {
for entry in WalkDir::new("properties") {
let entry = entry.unwrap();
@@ -64,10 +67,9 @@ fn generate_properties() {
}
}
- let python = env::var("PYTHON").ok().unwrap_or_else(find_python);
let script = Path::new(file!()).parent().unwrap().join("properties").join("build.py");
let product = if cfg!(feature = "gecko") { "gecko" } else { "servo" };
- let status = Command::new(python)
+ let status = Command::new(&*PYTHON)
.arg(&script)
.arg(product)
.arg("style-crate")
diff --git a/components/style/build_gecko.rs b/components/style/build_gecko.rs
index 33c5b7a532f..32a94b405f8 100644
--- a/components/style/build_gecko.rs
+++ b/components/style/build_gecko.rs
@@ -3,28 +3,25 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
mod common {
- use std::env;
- use std::path::PathBuf;
+ use std::{env, fs, io};
+ use std::path::{Path, PathBuf};
lazy_static! {
pub static ref OUTDIR_PATH: PathBuf = PathBuf::from(env::var("OUT_DIR").unwrap()).join("gecko");
}
- pub const STRUCTS_DEBUG_FILE: &'static str = "structs_debug.rs";
- pub const STRUCTS_RELEASE_FILE: &'static str = "structs_release.rs";
- pub const BINDINGS_FILE: &'static str = "bindings.rs";
-
- #[derive(Clone, Copy, PartialEq)]
- pub enum BuildType {
- Debug,
- Release,
- }
-
- pub fn structs_file(build_type: BuildType) -> &'static str {
- match build_type {
- BuildType::Debug => STRUCTS_DEBUG_FILE,
- BuildType::Release => STRUCTS_RELEASE_FILE
+ /// Copy contents of one directory into another.
+ /// It currently only does a shallow copy.
+ pub fn copy_dir
(from: P, to: Q, callback: F) -> io::Result<()>
+ where P: AsRef, Q: AsRef, F: Fn(&Path) {
+ let to = to.as_ref();
+ for entry in from.as_ref().read_dir()? {
+ let entry = entry?;
+ let path = entry.path();
+ callback(&path);
+ fs::copy(&path, to.join(entry.file_name()))?;
}
+ Ok(())
}
}
@@ -39,9 +36,28 @@ mod bindings {
use std::fs::{self, File};
use std::io::{Read, Write};
use std::path::{Path, PathBuf};
+ use std::process::{Command, exit};
use std::sync::Mutex;
use std::time::SystemTime;
use super::common::*;
+ use super::super::PYTHON;
+
+ const STRUCTS_DEBUG_FILE: &'static str = "structs_debug.rs";
+ const STRUCTS_RELEASE_FILE: &'static str = "structs_release.rs";
+ const BINDINGS_FILE: &'static str = "bindings.rs";
+
+ #[derive(Clone, Copy, PartialEq)]
+ enum BuildType {
+ Debug,
+ Release,
+ }
+
+ fn structs_file(build_type: BuildType) -> &'static str {
+ match build_type {
+ BuildType::Debug => STRUCTS_DEBUG_FILE,
+ BuildType::Release => STRUCTS_RELEASE_FILE
+ }
+ }
lazy_static! {
static ref INCLUDE_RE: Regex = Regex::new(r#"#include\s*"(.+?)""#).unwrap();
@@ -60,11 +76,6 @@ mod bindings {
pub static ref LAST_MODIFIED: Mutex =
Mutex::new(get_modified_time(&env::current_exe().unwrap())
.expect("Failed to get modified time of executable"));
- static ref BINDING_DISTDIR_PATH: PathBuf = {
- let path = DISTDIR_PATH.join("rust_bindings/style");
- fs::create_dir_all(&path).expect("Fail to create bindings dir in dist");
- path
- };
}
fn get_modified_time(file: &Path) -> Option {
@@ -237,8 +248,6 @@ mod bindings {
}
let bytes = result.into_bytes();
File::create(&out_file).unwrap().write_all(&bytes).expect("Unable to write output");
- File::create(&BINDING_DISTDIR_PATH.join(file)).unwrap()
- .write_all(&bytes).expect("Unable to write output to binding dist");
}
fn get_arc_types() -> Vec {
@@ -276,7 +285,7 @@ mod bindings {
}
}
- pub fn generate_structs(build_type: BuildType) {
+ fn generate_structs(build_type: BuildType) {
let mut builder = Builder::get_initial_builder(build_type)
.enable_cxx_namespaces()
.with_codegen_config(CodegenConfig {
@@ -565,7 +574,7 @@ mod bindings {
write_binding_file(builder, structs_file(build_type), &fixups);
}
- pub fn setup_logging() {
+ fn setup_logging() -> bool {
use log;
struct BuildLogger {
@@ -594,20 +603,23 @@ mod bindings {
}
}
- log::set_logger(|log_level| {
- log_level.set(log::LogLevelFilter::Debug);
- Box::new(BuildLogger {
- file: env::var("STYLO_BUILD_LOG").ok().and_then(|path| {
- fs::File::create(path).ok().map(Mutex::new)
- }),
- filter: env::var("STYLO_BUILD_FILTER").ok()
- .unwrap_or_else(|| "bindgen".to_owned()),
+ if let Ok(path) = env::var("STYLO_BUILD_LOG") {
+ log::set_logger(|log_level| {
+ log_level.set(log::LogLevelFilter::Debug);
+ Box::new(BuildLogger {
+ file: fs::File::create(path).ok().map(Mutex::new),
+ filter: env::var("STYLO_BUILD_FILTER").ok()
+ .unwrap_or_else(|| "bindgen".to_owned()),
+ })
})
- })
- .expect("Failed to set logger.");
+ .expect("Failed to set logger.");
+ true
+ } else {
+ false
+ }
}
- pub fn generate_bindings() {
+ fn generate_bindings() {
let mut builder = Builder::get_initial_builder(BuildType::Release)
.disable_name_namespacing()
.with_codegen_config(CodegenConfig {
@@ -816,52 +828,70 @@ mod bindings {
}
write_binding_file(builder, BINDINGS_FILE, &Vec::new());
}
+
+ fn generate_atoms() {
+ let script = Path::new(file!()).parent().unwrap().join("binding_tools").join("regen_atoms.py");
+ println!("cargo:rerun-if-changed={}", script.display());
+ let status = Command::new(&*PYTHON)
+ .arg(&script)
+ .arg(DISTDIR_PATH.as_os_str())
+ .arg(OUTDIR_PATH.as_os_str())
+ .status()
+ .unwrap();
+ if !status.success() {
+ exit(1);
+ }
+ }
+
+ pub fn generate() {
+ use std::thread;
+ macro_rules! run_tasks {
+ ($($task:expr,)+) => {
+ if setup_logging() {
+ $($task;)+
+ } else {
+ let threads = vec![$( thread::spawn(|| $task) ),+];
+ for thread in threads.into_iter() {
+ thread.join().unwrap();
+ }
+ }
+ }
+ }
+ run_tasks! {
+ generate_structs(BuildType::Debug),
+ generate_structs(BuildType::Release),
+ generate_bindings(),
+ generate_atoms(),
+ }
+
+ // Copy all generated files to dist for the binding package
+ let path = DISTDIR_PATH.join("rust_bindings/style");
+ if path.exists() {
+ fs::remove_dir_all(&path).expect("Fail to remove binding dir in dist");
+ }
+ fs::create_dir_all(&path).expect("Fail to create bindings dir in dist");
+ copy_dir(&*OUTDIR_PATH, &path, |_| {}).expect("Fail to copy generated files to dist dir");
+ }
}
#[cfg(not(feature = "bindgen"))]
mod bindings {
- use std::fs;
- use std::path::{Path, PathBuf};
+ use std::path::Path;
use super::common::*;
- lazy_static! {
- static ref BINDINGS_PATH: PathBuf = Path::new(file!()).parent().unwrap().join("gecko_bindings");
- }
-
- pub fn setup_logging() {}
-
- pub fn generate_structs(build_type: BuildType) {
- let file = structs_file(build_type);
- let source = BINDINGS_PATH.join(file);
- println!("cargo:rerun-if-changed={}", source.display());
- fs::copy(source, OUTDIR_PATH.join(file)).unwrap();
- }
-
- pub fn generate_bindings() {
- let source = BINDINGS_PATH.join(BINDINGS_FILE);
- println!("cargo:rerun-if-changed={}", source.display());
- fs::copy(source, OUTDIR_PATH.join(BINDINGS_FILE)).unwrap();
+ pub fn generate() {
+ let dir = Path::new(file!()).parent().unwrap().join("gecko/generated");
+ println!("cargo:rerun-if-changed={}", dir.display());
+ copy_dir(&dir, &*OUTDIR_PATH, |path| {
+ println!("cargo:rerun-if-changed={}", path.display());
+ }).expect("Fail to copy generated files to out dir");
}
}
pub fn generate() {
use self::common::*;
- use std::{env, fs, thread};
+ use std::fs;
println!("cargo:rerun-if-changed=build_gecko.rs");
fs::create_dir_all(&*OUTDIR_PATH).unwrap();
- bindings::setup_logging();
- if env::var("STYLO_BUILD_LOG").is_ok() {
- bindings::generate_structs(BuildType::Debug);
- bindings::generate_structs(BuildType::Release);
- bindings::generate_bindings();
- } else {
- let threads = vec![
- thread::spawn(|| bindings::generate_structs(BuildType::Debug)),
- thread::spawn(|| bindings::generate_structs(BuildType::Release)),
- thread::spawn(|| bindings::generate_bindings()),
- ];
- for t in threads.into_iter() {
- t.join().unwrap();
- }
- }
+ bindings::generate();
}
diff --git a/components/style/gecko_string_cache/atom_macro.rs b/components/style/gecko/generated/atom_macro.rs
similarity index 100%
rename from components/style/gecko_string_cache/atom_macro.rs
rename to components/style/gecko/generated/atom_macro.rs
diff --git a/components/style/gecko_bindings/bindings.rs b/components/style/gecko/generated/bindings.rs
similarity index 100%
rename from components/style/gecko_bindings/bindings.rs
rename to components/style/gecko/generated/bindings.rs
diff --git a/components/style/gecko/generated/gecko_pseudo_element_helper.rs b/components/style/gecko/generated/pseudo_element_helper.rs
similarity index 100%
rename from components/style/gecko/generated/gecko_pseudo_element_helper.rs
rename to components/style/gecko/generated/pseudo_element_helper.rs
diff --git a/components/style/gecko_bindings/structs_debug.rs b/components/style/gecko/generated/structs_debug.rs
similarity index 100%
rename from components/style/gecko_bindings/structs_debug.rs
rename to components/style/gecko/generated/structs_debug.rs
diff --git a/components/style/gecko_bindings/structs_release.rs b/components/style/gecko/generated/structs_release.rs
similarity index 100%
rename from components/style/gecko_bindings/structs_release.rs
rename to components/style/gecko/generated/structs_release.rs
diff --git a/components/style/gecko/selector_parser.rs b/components/style/gecko/selector_parser.rs
index 4add99e36e8..af7dd323faf 100644
--- a/components/style/gecko/selector_parser.rs
+++ b/components/style/gecko/selector_parser.rs
@@ -165,7 +165,7 @@ impl PseudoElement {
}}
}
- include!("generated/gecko_pseudo_element_helper.rs");
+ include!(concat!(env!("OUT_DIR"), "/gecko/pseudo_element_helper.rs"));
None
}
@@ -190,7 +190,7 @@ impl PseudoElement {
}}
}
- include!("generated/gecko_pseudo_element_helper.rs");
+ include!(concat!(env!("OUT_DIR"), "/gecko/pseudo_element_helper.rs"));
None
}
@@ -492,7 +492,7 @@ impl SelectorImpl {
}}
}
- include!("generated/gecko_pseudo_element_helper.rs")
+ include!(concat!(env!("OUT_DIR"), "/gecko/pseudo_element_helper.rs"));
}
#[inline]
diff --git a/components/style/gecko_string_cache/mod.rs b/components/style/gecko_string_cache/mod.rs
index 741a4a3e534..428d522be11 100644
--- a/components/style/gecko_string_cache/mod.rs
+++ b/components/style/gecko_string_cache/mod.rs
@@ -25,7 +25,10 @@ use std::slice;
#[macro_use]
#[allow(improper_ctypes, non_camel_case_types, missing_docs)]
-pub mod atom_macro;
+pub mod atom_macro {
+ include!(concat!(env!("OUT_DIR"), "/gecko/atom_macro.rs"));
+}
+
#[macro_use]
pub mod namespace;
diff --git a/python/servo/build_commands.py b/python/servo/build_commands.py
index 792b6071145..3a33f5f3b0d 100644
--- a/python/servo/build_commands.py
+++ b/python/servo/build_commands.py
@@ -24,7 +24,7 @@ from mach.decorators import (
Command,
)
-from servo.command_base import CommandBase, cd, call, BIN_SUFFIX, find_dep_path_newest
+from servo.command_base import CommandBase, cd, call, BIN_SUFFIX
from servo.util import host_triple
@@ -413,7 +413,6 @@ class MachCommands(CommandBase):
self.ensure_bootstrapped()
env = self.build_env(is_build=True, geckolib=True)
- geckolib_build_path = path.join(self.context.topdir, "target", "geckolib").encode("UTF-8")
ret = None
opts = []
@@ -433,14 +432,6 @@ class MachCommands(CommandBase):
if features:
opts += ["--features", ' '.join(features)]
- if with_gecko is not None:
- print("Generating atoms data...")
- run_file = path.join(self.context.topdir, "components",
- "style", "binding_tools", "regen_atoms.py")
- run_globals = {"__file__": run_file}
- execfile(run_file, run_globals)
- run_globals["generate_atoms"](env["MOZ_DIST"])
-
build_start = time()
with cd(path.join("ports", "geckolib")):
ret = call(["cargo", "build"] + opts, env=env, verbose=verbose)
@@ -451,15 +442,6 @@ class MachCommands(CommandBase):
print("GeckoLib build completed in %s" % format_duration(elapsed))
- if with_gecko is not None:
- print("Copying binding files to style/gecko_bindings...")
- build_path = path.join(geckolib_build_path, "release" if release else "debug", "")
- target_style_path = find_dep_path_newest("style", build_path)
- out_gecko_path = path.join(target_style_path, "out", "gecko")
- bindings_path = path.join(self.context.topdir, "components", "style", "gecko_bindings")
- for f in ["bindings.rs", "structs_debug.rs", "structs_release.rs"]:
- shutil.copy(path.join(out_gecko_path, f), bindings_path)
-
return ret
@Command('clean',
diff --git a/servo-tidy.toml b/servo-tidy.toml
index 6bc386c85f0..18debdc9a49 100644
--- a/servo-tidy.toml
+++ b/servo-tidy.toml
@@ -37,10 +37,10 @@ files = [
# Helper macro where actually a pseudo-element per line makes sense.
"./components/style/gecko/non_ts_pseudo_class_list.rs",
# Generated and upstream code combined with our own. Could use cleanup
- "./components/style/gecko_bindings/bindings.rs",
- "./components/style/gecko_bindings/structs_debug.rs",
- "./components/style/gecko_bindings/structs_release.rs",
- "./components/style/gecko_string_cache/atom_macro.rs",
+ "./components/style/gecko/generated/bindings.rs",
+ "./components/style/gecko/generated/structs_debug.rs",
+ "./components/style/gecko/generated/structs_release.rs",
+ "./components/style/gecko/generated/atom_macro.rs",
"./resources/hsts_preload.json",
"./tests/wpt/metadata/MANIFEST.json",
"./tests/wpt/metadata-css/MANIFEST.json",
diff --git a/tests/unit/stylo/check_bindings.py b/tests/unit/stylo/check_bindings.py
index db5a11cc3a7..f4cdc5b6655 100755
--- a/tests/unit/stylo/check_bindings.py
+++ b/tests/unit/stylo/check_bindings.py
@@ -8,7 +8,7 @@ import os
import re
ROOT_PATH = os.path.join("..", "..", "..")
-INPUT_FILE = os.path.join(ROOT_PATH, "components", "style", "gecko_bindings", "bindings.rs")
+INPUT_FILE = os.path.join(ROOT_PATH, "components", "style", "gecko", "generated", "bindings.rs")
OUTPUT_FILE = os.path.join(os.environ["OUT_DIR"], "check_bindings.rs")
GLUE_FILE = os.path.join(ROOT_PATH, "ports", "geckolib", "glue.rs")
GLUE_OUTPUT_FILE = os.path.join(os.environ["OUT_DIR"], "glue.rs")
diff --git a/tests/unit/stylo/sanity_checks.rs b/tests/unit/stylo/sanity_checks.rs
index 008779721be..ce0576fe6cf 100644
--- a/tests/unit/stylo/sanity_checks.rs
+++ b/tests/unit/stylo/sanity_checks.rs
@@ -46,7 +46,7 @@ fn assert_basic_pseudo_elements() {
};
}
- include!("../../../components/style/gecko/generated/gecko_pseudo_element_helper.rs");
+ include!("../../../components/style/gecko/generated/pseudo_element_helper.rs");
assert!(saw_before);
assert!(saw_after);