mirror of
https://github.com/servo/servo.git
synced 2025-06-04 07:35:36 +00:00
Auto merge of #16762 - upsuper:buildtime-pseudo, r=emilio
Generate atom files at build-time The commits here basically do the following things: 1. move all generated files for gecko into "gecko/generated" so that we can copy all of them around 2. make regen_atoms.py generate file to the out dir rather than in-tree 3. make the build script invoke regen_atoms.py when bindgen feature is enabled <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/16762) <!-- Reviewable:end -->
This commit is contained in:
commit
a5fe464e4a
14 changed files with 129 additions and 111 deletions
|
@ -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])
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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<P, Q, F>(from: P, to: Q, callback: F) -> io::Result<()>
|
||||
where P: AsRef<Path>, Q: AsRef<Path>, 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<SystemTime> =
|
||||
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<SystemTime> {
|
||||
|
@ -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<String> {
|
||||
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue