Gleam-authored Zed extension (Gleam → Wasm guest) for Gleam LSP + highlighting
1

Configure Feed

Select the types of activity you want to include in your feed.

zed-gleam-native / build.rs
3.3 kB 98 lines
1//! Build the real Zed guest with Gleam, then leave the component where the 2//! custom wasm linker (`scripts/gleam-wasm-linker`) can install it as the 3//! crate's `cdylib` output (what Zed copies to `extension.wasm`). 4 5use std::env; 6use std::fs; 7use std::path::{Path, PathBuf}; 8use std::process::Command; 9 10fn main() { 11 println!("cargo:rerun-if-changed=src/zed_gleam.gleam"); 12 println!("cargo:rerun-if-changed=gleam.toml"); 13 println!("cargo:rerun-if-changed=manifest.toml"); 14 println!("cargo:rerun-if-changed=scripts/gleam-wasm-linker"); 15 println!("cargo:rerun-if-env-changed=GLEAM"); 16 17 let manifest_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()); 18 let gleam = find_gleam(&manifest_dir); 19 eprintln!("zed_gleam build.rs: using gleam at {}", gleam.display()); 20 21 // Fixed path the linker wrapper reads (relative to package root). 22 let out_wasm = manifest_dir.join("target/gleam-extension.wasm"); 23 if let Some(parent) = out_wasm.parent() { 24 fs::create_dir_all(parent).expect("create target/"); 25 } 26 27 let status = Command::new(&gleam) 28 .current_dir(&manifest_dir) 29 .args(["export", "zed-extension"]) 30 .status() 31 .unwrap_or_else(|err| { 32 panic!( 33 "failed to spawn gleam at {}: {err}\n\ 34 Set GLEAM to a wasm-capable gleam binary \ 35 (https://tangled.org/nandi.uk/gleam , branch wasm).", 36 gleam.display() 37 ) 38 }); 39 40 if !status.success() { 41 panic!( 42 "`gleam export zed-extension` failed (status {status}).\n\ 43 You need a Gleam build with Zed Wasm support:\n\ 44 https://tangled.org/nandi.uk/gleam (branch wasm)\n\ 45 cargo build -p gleam\n\ 46 export GLEAM=/path/to/gleam/target/debug/gleam\n\ 47 Current GLEAM candidate: {}", 48 gleam.display() 49 ); 50 } 51 52 // CLI writes package-root extension.wasm; copy to the linker input path. 53 let exported = manifest_dir.join("extension.wasm"); 54 if !exported.is_file() { 55 panic!( 56 "gleam export succeeded but {} was not created", 57 exported.display() 58 ); 59 } 60 fs::copy(&exported, &out_wasm).unwrap_or_else(|err| { 61 panic!( 62 "copy {}{}: {err}", 63 exported.display(), 64 out_wasm.display() 65 ); 66 }); 67 68 eprintln!( 69 "zed_gleam build.rs: Gleam component ready at {}", 70 out_wasm.display() 71 ); 72} 73 74fn find_gleam(manifest_dir: &Path) -> PathBuf { 75 if let Ok(path) = env::var("GLEAM") { 76 let p = PathBuf::from(path); 77 if p.is_file() { 78 return p; 79 } 80 panic!("GLEAM={p:?} is not a file"); 81 } 82 83 // Common local checkouts (zed-gleam-native and gleam as siblings under code/). 84 let candidates = [ 85 manifest_dir.join("../gleam/target/debug/gleam"), 86 manifest_dir.join("../gleam/target/release/gleam"), 87 manifest_dir.join("../../gleam/target/debug/gleam"), 88 manifest_dir.join("../../gleam/target/release/gleam"), 89 ]; 90 for candidate in candidates { 91 if candidate.is_file() { 92 return candidate.canonicalize().unwrap_or(candidate); 93 } 94 } 95 96 // PATH 97 PathBuf::from("gleam") 98}