feat: support grammar cross-compilation

This commit is contained in:
yvt 2022-07-20 23:56:26 +09:00 committed by Blaž Hrastnik
parent f6f054ae5b
commit 6d16d2cbc9
3 changed files with 19 additions and 9 deletions

View file

@ -92,8 +92,12 @@ pub fn fetch_grammars() -> Result<()> {
run_parallel(grammars, fetch_grammar, "fetch") run_parallel(grammars, fetch_grammar, "fetch")
} }
pub fn build_grammars() -> Result<()> { pub fn build_grammars(target: Option<String>) -> Result<()> {
run_parallel(get_grammar_configs()?, build_grammar, "build") run_parallel(
get_grammar_configs()?,
move |grammar| build_grammar(grammar, target.as_deref()),
"build",
)
} }
// Returns the set of grammar configurations the user requests. // Returns the set of grammar configurations the user requests.
@ -124,13 +128,14 @@ fn get_grammar_configs() -> Result<Vec<GrammarConfiguration>> {
fn run_parallel<F>(grammars: Vec<GrammarConfiguration>, job: F, action: &'static str) -> Result<()> fn run_parallel<F>(grammars: Vec<GrammarConfiguration>, job: F, action: &'static str) -> Result<()>
where where
F: Fn(GrammarConfiguration) -> Result<()> + std::marker::Send + 'static + Copy, F: Fn(GrammarConfiguration) -> Result<()> + std::marker::Send + 'static + Clone,
{ {
let pool = threadpool::Builder::new().build(); let pool = threadpool::Builder::new().build();
let (tx, rx) = channel(); let (tx, rx) = channel();
for grammar in grammars { for grammar in grammars {
let tx = tx.clone(); let tx = tx.clone();
let job = job.clone();
pool.execute(move || { pool.execute(move || {
// Ignore any SendErrors, if any job in another thread has encountered an // Ignore any SendErrors, if any job in another thread has encountered an
@ -240,7 +245,7 @@ where
} }
} }
fn build_grammar(grammar: GrammarConfiguration) -> Result<()> { fn build_grammar(grammar: GrammarConfiguration, target: Option<&str>) -> Result<()> {
let grammar_dir = if let GrammarSource::Local { path } = &grammar.source { let grammar_dir = if let GrammarSource::Local { path } = &grammar.source {
PathBuf::from(&path) PathBuf::from(&path)
} else { } else {
@ -273,10 +278,14 @@ fn build_grammar(grammar: GrammarConfiguration) -> Result<()> {
} }
.join("src"); .join("src");
build_tree_sitter_library(&path, grammar) build_tree_sitter_library(&path, grammar, target)
} }
fn build_tree_sitter_library(src_path: &Path, grammar: GrammarConfiguration) -> Result<()> { fn build_tree_sitter_library(
src_path: &Path,
grammar: GrammarConfiguration,
target: Option<&str>,
) -> Result<()> {
let header_path = src_path; let header_path = src_path;
let parser_path = src_path.join("parser.c"); let parser_path = src_path.join("parser.c");
let mut scanner_path = src_path.join("scanner.c"); let mut scanner_path = src_path.join("scanner.c");
@ -311,7 +320,7 @@ fn build_tree_sitter_library(src_path: &Path, grammar: GrammarConfiguration) ->
.opt_level(3) .opt_level(3)
.cargo_metadata(false) .cargo_metadata(false)
.host(BUILD_TARGET) .host(BUILD_TARGET)
.target(BUILD_TARGET); .target(target.unwrap_or(BUILD_TARGET));
let compiler = config.get_compiler(); let compiler = config.get_compiler();
let mut command = Command::new(compiler.path()); let mut command = Command::new(compiler.path());
command.current_dir(src_path); command.current_dir(src_path);

View file

@ -19,7 +19,8 @@ fn main() {
if std::env::var("HELIX_DISABLE_AUTO_GRAMMAR_BUILD").is_err() { if std::env::var("HELIX_DISABLE_AUTO_GRAMMAR_BUILD").is_err() {
fetch_grammars().expect("Failed to fetch tree-sitter grammars"); fetch_grammars().expect("Failed to fetch tree-sitter grammars");
build_grammars().expect("Failed to compile tree-sitter grammars"); build_grammars(Some(std::env::var("TARGET").unwrap()))
.expect("Failed to compile tree-sitter grammars");
} }
println!("cargo:rerun-if-changed=../runtime/grammars/"); println!("cargo:rerun-if-changed=../runtime/grammars/");

View file

@ -108,7 +108,7 @@ FLAGS:
} }
if args.build_grammars { if args.build_grammars {
helix_loader::grammar::build_grammars()?; helix_loader::grammar::build_grammars(None)?;
return Ok(0); return Ok(0);
} }