plum

#treesitter#compiler#wasm

git clone https://git.pyrossh.dev/plum

A statically typed, imperative programming language inspired by rust, python


plum-cli/build.rs
b5f5be1 1
//! Precompiles the `tree-sitter-plum` grammar into a native shared library at
b5f5be1 2
//! `plum`-build time (using whatever C compiler is already on the machine —
b5f5be1 3
//! the same one Cargo itself needs to build `tree-sitter-plum`'s own
b5f5be1 4
//! `scanner.c`/`parser.c` for in-process parsing), so `plum editor helix` can
b5f5be1 5
//! just copy the finished `.so` into Helix's `runtime/grammars/` directory
b5f5be1 6
//! instead of shelling out to `hx --grammar build` (which requires `hx` on
b5f5be1 7
//! PATH, a working C compiler on the *installing* machine again, and a
b5f5be1 8
//! `languages.toml` grammar `source.path` that still resolves).
b5f5be1 9
//!
b5f5be1 10
//! If the compiler invocation fails (no C compiler found), this falls back to
b5f5be1 11
//! writing an empty placeholder rather than failing the whole `plum-cli`
b5f5be1 12
//! build — `editor::installHelix` detects the empty payload and falls back to
b5f5be1 13
//! the old `hx --grammar build` codepath at install time instead.
b5f5be1 14
b5f5be1 15
use std::env;
b5f5be1 16
use std::path::PathBuf;
b5f5be1 17
use std::process::Command;
b5f5be1 18
b5f5be1 19
fn main() {
b5f5be1 20
    let manifest_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());
b5f5be1 21
    let src_dir = manifest_dir.join("../plum-tooling/tree-sitter-plum/src");
b5f5be1 22
    let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
b5f5be1 23
    let so_path = out_dir.join("plum-grammar.so");
b5f5be1 24
b5f5be1 25
    println!("cargo:rerun-if-changed={}", src_dir.join("parser.c").display());
b5f5be1 26
    println!("cargo:rerun-if-changed={}", src_dir.join("scanner.c").display());
b5f5be1 27
b5f5be1 28
    let cc = env::var("CC").unwrap_or_else(|_| "cc".to_string());
b5f5be1 29
    let status = Command::new(&cc)
b5f5be1 30
        .arg("-shared")
b5f5be1 31
        .arg("-fPIC")
b5f5be1 32
        .arg("-O2")
b5f5be1 33
        .arg("-I")
b5f5be1 34
        .arg(&src_dir)
b5f5be1 35
        .arg("-o")
b5f5be1 36
        .arg(&so_path)
b5f5be1 37
        .arg(src_dir.join("parser.c"))
b5f5be1 38
        .arg(src_dir.join("scanner.c"))
b5f5be1 39
        .status();
b5f5be1 40
b5f5be1 41
    match status {
b5f5be1 42
        Ok(s) if s.success() => {
b5f5be1 43
            println!("cargo:rustc-env=PLUM_GRAMMAR_SO={}", so_path.display());
b5f5be1 44
        }
b5f5be1 45
        other => {
b5f5be1 46
            std::fs::write(&so_path, []).expect("failed to write placeholder grammar .so");
b5f5be1 47
            println!("cargo:rustc-env=PLUM_GRAMMAR_SO={}", so_path.display());
b5f5be1 48
            match other {
b5f5be1 49
                Ok(s) => println!(
b5f5be1 50
                    "cargo:warning=`{cc}` exited with {s} while precompiling the Plum tree-sitter grammar; `plum editor helix` will fall back to `hx --grammar build`"
b5f5be1 51
                ),
b5f5be1 52
                Err(e) => println!(
b5f5be1 53
                    "cargo:warning=could not run `{cc}` to precompile the Plum tree-sitter grammar ({e}); `plum editor helix` will fall back to `hx --grammar build`"
b5f5be1 54
                ),
b5f5be1 55
            }
b5f5be1 56
        }
b5f5be1 57
    }
b5f5be1 58
}