use std::env; use std::ffi::OsString; use std::fs; use std::path::Path; use std::path::PathBuf; use std::process::Command; use cargo_metadata::MetadataCommand; use indoc::formatdoc; const TARGETS: &[(&str, &str)] = &[ ("linux-arm", "arm-unknown-linux-gnueabi"), ("linux-arm64", "aarch64-unknown-linux-gnu"), ("linux-x64", "x86_64-unknown-linux-gnu"), ("linux-x86", "i686-unknown-linux-gnu"), ("macos-arm64", "aarch64-apple-darwin"), ("macos-x64", "x86_64-apple-darwin"), ]; const fn platform_for_target(target: &str) -> &str { let mut i = 0; while i < TARGETS.len() { if const_str::equal!(TARGETS[i].1, target) { return TARGETS[i].0; } i += 1; } target } fn main() { let out_dir = env::var_os("OUT_DIR").unwrap(); let build_target = env::var_os("TARGET").unwrap(); let metadata = MetadataCommand::new().exec().unwrap(); let meta = metadata .root_package() .unwrap() .metadata .as_object() .unwrap(); write_tree_sitter_consts(meta, &build_target, &out_dir); write_tsdl_consts(meta, &out_dir); let sha1 = Command::new("git") .args(["rev-parse", "HEAD"]) .output() .ok() .and_then(|output| String::from_utf8(output.stdout).ok()) .map(|str| format!(" ({})", str.trim())) .unwrap_or_default(); fs::write( Path::new(&out_dir).join("tsdl.version"), format!("{}{}", env!("CARGO_PKG_VERSION"), sha1), ) .unwrap(); } fn write_tsdl_consts(meta: &serde_json::Map, out_dir: &OsString) { let root = PathBuf::from(file!()); let tsdl_bin_build_dir = root.parent().unwrap().join("src").canonicalize().unwrap(); let tsdl_bin_build_dir = tsdl_bin_build_dir.to_str().unwrap(); let tsdl = meta.get("tsdl").unwrap(); let tsdl_build_dir = tsdl.get("build-dir").unwrap().as_str().unwrap(); let tsdl_config_file = tsdl.get("config").unwrap().as_str().unwrap(); let tsdl_fresh = tsdl.get("fresh").unwrap().as_bool().unwrap(); let tsdl_from = tsdl.get("from").unwrap().as_str().unwrap(); let tsdl_out_dir = tsdl.get("out").unwrap().as_str().unwrap(); let tsdl_prefix = tsdl.get("prefix").unwrap().as_str().unwrap(); let tsdl_ref = tsdl.get("ref").unwrap().as_str().unwrap(); let tsdl_show_config = tsdl.get("show-config").unwrap().as_bool().unwrap(); let tsdl_consts = Path::new(&out_dir).join("tsdl_consts.rs"); fs::write( tsdl_consts, formatdoc!( r#" pub const TSDL_BIN_BUILD_DIR: &str = "{tsdl_bin_build_dir}/"; pub const TSDL_BUILD_DIR: &str = "{tsdl_build_dir}"; pub const TSDL_CONFIG_FILE: &str = "{tsdl_config_file}"; pub const TSDL_FRESH: bool = {tsdl_fresh}; pub const TSDL_FROM: &str = "{tsdl_from}"; pub const TSDL_OUT_DIR: &str = "{tsdl_out_dir}"; pub const TSDL_PREFIX: &str = "{tsdl_prefix}"; pub const TSDL_REF: &str = "{tsdl_ref}"; pub const TSDL_SHOW_CONFIG: bool = {tsdl_show_config}; "# ), ) .unwrap(); } fn write_tree_sitter_consts( meta: &serde_json::Map, build_target: &OsString, out_dir: &OsString, ) { let tree_sitter = meta.get("tree-sitter").unwrap(); let tree_sitter_version = tree_sitter.get("version").unwrap().as_str().unwrap(); let tree_sitter_repo = tree_sitter.get("repo").unwrap().as_str().unwrap(); let tree_sitter_platform = platform_for_target(build_target.to_str().unwrap()); let tree_sitter_consts = Path::new(out_dir).join("tree_sitter_consts.rs"); fs::write( tree_sitter_consts, formatdoc!( r#" pub const TREE_SITTER_PLATFORM: &str = "{tree_sitter_platform}"; pub const TREE_SITTER_REPO: &str = "{tree_sitter_repo}"; pub const TREE_SITTER_VERSION: &str = "{tree_sitter_version}"; "# ), ) .unwrap(); }