From e63f0b578faf1d95772cf59f8f6fc5f0139e33db Mon Sep 17 00:00:00 2001 From: gram Date: Thu, 16 Apr 2026 09:15:26 +0200 Subject: [PATCH 1/4] build Odin projects --- src/commands/new.rs | 38 ++++++++++++++++++++++------------- src/config.rs | 1 + src/langs.rs | 49 ++++++++++++++++++++++++++++++++++++++------- 3 files changed, 67 insertions(+), 21 deletions(-) diff --git a/src/commands/new.rs b/src/commands/new.rs index fae60a3..8d5f277 100644 --- a/src/commands/new.rs +++ b/src/commands/new.rs @@ -22,17 +22,18 @@ pub fn cmd_new(args: &NewArgs) -> Result<()> { } let lang = parse_lang(&args.lang)?; match lang { - Lang::Go => new_go(&args.name).context("new Go project")?, - Lang::Rust => new_rust(&args.name).context("new Rust project")?, - Lang::Zig => new_zig(&args.name).context("new Zig project")?, Lang::AS | Lang::TS => new_as(&args.name).context("new AssemblyScript project")?, + Lang::Bitsy => new_bitsy(&args.name).context("new Bitsy project")?, + Lang::Bulb => new_bulb(&args.name).context("new Bulb project")?, Lang::C => new_c(&args.name).context("new C project")?, Lang::Cpp => new_cpp(&args.name).context("new C++ project")?, - Lang::Python => bail!("Python is not supported yet"), + Lang::Go => new_go(&args.name).context("new Go project")?, Lang::Lua => new_lua(&args.name).context("new Lua project")?, Lang::Moon => new_moon(&args.name).context("new Moon project")?, - Lang::Bitsy => new_bitsy(&args.name).context("new Bitsy project")?, - Lang::Bulb => new_bulb(&args.name).context("new Bulb project")?, + Lang::Odin => new_odin(&args.name).context("new Odin project")?, + Lang::Python => bail!("Python is not supported yet"), + Lang::Rust => new_rust(&args.name).context("new Rust project")?, + Lang::Zig => new_zig(&args.name).context("new Zig project")?, } write_config(lang, &args.name)?; init_git(&args.name)?; @@ -98,18 +99,19 @@ fn init_git(name: &str) -> Result<()> { /// Convert `--lang` CLI flag into [`Lang`]. fn parse_lang(lang: &str) -> Result { let result = match lang.to_lowercase().as_str() { + "as" | "assemblyscript" => Lang::AS, + "bitsy" => Lang::Bitsy, + "bulb" | "bulbscript" | "bulb-script" => Lang::Bulb, "c" => Lang::C, + "cpp" | "c++" => Lang::Cpp, "go" | "golang" | "tinygo" => Lang::Go, + "lua" => Lang::Lua, + "moon" | "moonbit" | "mbt" => Lang::Moon, + "odin" => Lang::Odin, + "python" | "py" => Lang::Python, "rust" | "rs" => Lang::Rust, - "zig" => Lang::Zig, - "as" | "assemblyscript" => Lang::AS, "ts" | "typescript" | "js" | "javascript" => Lang::TS, - "cpp" | "c++" => Lang::Cpp, - "python" | "py" => Lang::Python, - "moon" | "moonbit" | "mbt" => Lang::Moon, - "lua" => Lang::Lua, - "bitsy" => Lang::Bitsy, - "bulb" | "bulbscript" | "bulb-script" => Lang::Bulb, + "zig" => Lang::Zig, _ => bail!("unsupported language: {lang}"), }; Ok(result) @@ -150,6 +152,14 @@ fn new_zig(name: &str) -> Result<()> { Ok(()) } +/// Create a new Odin project. +fn new_odin(name: &str) -> Result<()> { + let mut c = Commander::default(); + c.cd(name)?; + // ... + Ok(()) +} + fn get_latest_zig_sdk_version() -> Result { let url = "https://github.com/firefly-zero/firefly-zig/releases/latest"; let req = ureq::get(url); diff --git a/src/config.rs b/src/config.rs index a2af0a3..8a0734f 100644 --- a/src/config.rs +++ b/src/config.rs @@ -190,6 +190,7 @@ pub enum Lang { Go, // 🏃 Lua, // 🌙 Moon, // 🐰 + Odin, // 🐦‍⬛ Python, // 🐍 Rust, // 🦀 TS, // 🟦 diff --git a/src/langs.rs b/src/langs.rs index 86aee8a..8be1e52 100644 --- a/src/langs.rs +++ b/src/langs.rs @@ -21,18 +21,19 @@ pub fn build_bin(config: &Config, args: &BuildArgs) -> anyhow::Result<()> { None => detect_lang(&config.root_path)?, }; match lang { - Lang::Go => build_go(config), - Lang::Rust => build_rust(config), - Lang::Zig => build_zig(config), Lang::AS => build_as(config), - Lang::TS => build_ts(config), + Lang::Bitsy => build_bitsy(config), + Lang::Bulb => build_bulb(config), Lang::C => build_c(config), Lang::Cpp => build_cpp(config), - Lang::Python => build_python(config), + Lang::Go => build_go(config), Lang::Lua => build_lua(config), - Lang::Bitsy => build_bitsy(config), - Lang::Bulb => build_bulb(config), Lang::Moon => build_moon(config), + Lang::Odin => build_odin(config), + Lang::Python => build_python(config), + Lang::Rust => build_rust(config), + Lang::TS => build_ts(config), + Lang::Zig => build_zig(config), }?; let bin_path = config.rom_path.join(BIN); if !bin_path.is_file() { @@ -65,6 +66,9 @@ fn detect_lang(root: &Path) -> anyhow::Result { if root.join("build.zig.zon").exists() { return Ok(Lang::Zig); } + if root.join("ols.json").exists() { + return Ok(Lang::Odin); + } if root.join("asconfig.json").exists() { return Ok(Lang::AS); } @@ -92,6 +96,9 @@ fn detect_lang(root: &Path) -> anyhow::Result { if root.join("main.cpp").exists() { return Ok(Lang::Cpp); } + if root.join("main.odin").exists() { + return Ok(Lang::Odin); + } if root.join("main.lua").exists() { return Ok(Lang::Lua); } @@ -372,6 +379,34 @@ fn build_zig(config: &Config) -> anyhow::Result<()> { Ok(()) } +// Build Odin project. +fn build_odin(config: &Config) -> anyhow::Result<()> { + check_installed("Odin", "odin", "version")?; + let mut cmd_args = vec![ + "build", + ".", + "-target:freestanding_wasm32", + "-out:firefly.wasm", + ]; + if let Some(additional_args) = &config.compile_args { + for arg in additional_args { + cmd_args.push(arg.as_str()); + } + } + let output = Command::new("odin") + .args(cmd_args) + .current_dir(&config.root_path) + .output() + .context("run odin build")?; + check_output(&output)?; + + let from_path = config.root_path.join("firefly.wasm"); + let out_path = config.rom_path.join(BIN); + std::fs::copy(&from_path, out_path).context("copy wasm binary")?; + std::fs::remove_file(from_path).context("remove wasm file")?; + Ok(()) +} + // Build Moon project. fn build_moon(config: &Config) -> anyhow::Result<()> { check_installed("Moon", "moon", "version")?; From e4e32fa05fe7e8b7434450465a953dc1cdb62d06 Mon Sep 17 00:00:00 2001 From: gram Date: Thu, 16 Apr 2026 10:08:27 +0200 Subject: [PATCH 2/4] detect wasi-sdk for odin --- src/langs.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/langs.rs b/src/langs.rs index 8be1e52..e3bc071 100644 --- a/src/langs.rs +++ b/src/langs.rs @@ -382,6 +382,14 @@ fn build_zig(config: &Config) -> anyhow::Result<()> { // Build Odin project. fn build_odin(config: &Config) -> anyhow::Result<()> { check_installed("Odin", "odin", "version")?; + + // Find wasi-sdk and add it into $PATH. + let wasi_sdk = find_wasi_sdk()?; + let wasi_sdk_bin = wasi_sdk.join("bin"); + let wasi_sdk_bin = path_to_utf8(&wasi_sdk_bin)?; + let path = std::env::var("PATH").unwrap_or_default(); + let path = format!("{path}:{wasi_sdk_bin}"); + let mut cmd_args = vec![ "build", ".", @@ -396,6 +404,7 @@ fn build_odin(config: &Config) -> anyhow::Result<()> { let output = Command::new("odin") .args(cmd_args) .current_dir(&config.root_path) + .env("PATH", path) .output() .context("run odin build")?; check_output(&output)?; From 962f2d6a1ebc8fe7e410bb6c48f26eeb6f411435 Mon Sep 17 00:00:00 2001 From: gram Date: Thu, 16 Apr 2026 11:32:45 +0200 Subject: [PATCH 3/4] new: support Odin --- assets/main.odin | 28 ++++++++++++++++++++++++++++ src/commands/new.rs | 5 ++++- 2 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 assets/main.odin diff --git a/assets/main.odin b/assets/main.odin new file mode 100644 index 0000000..0c65319 --- /dev/null +++ b/assets/main.odin @@ -0,0 +1,28 @@ +package main + +import "./vendor/firefly" +import "base:runtime" + +@(export = true) +boot :: proc "contextless" () { + context = runtime.default_context() + // ... +} + +@(export = true) +update :: proc "contextless" () { + context = runtime.default_context() + // ... +} + +@(export = true) +render :: proc "contextless" () { + context = runtime.default_context() + firefly.clear_screen(firefly.Color.White) + firefly.draw_triangle( + firefly.p(60, 10), + firefly.p(40, 40), + firefly.p(80, 40), + firefly.Style{firefly.Color.DarkBlue, firefly.Color.Blue, 1}, + ) +} diff --git a/src/commands/new.rs b/src/commands/new.rs index 8d5f277..e1abd70 100644 --- a/src/commands/new.rs +++ b/src/commands/new.rs @@ -154,9 +154,12 @@ fn new_zig(name: &str) -> Result<()> { /// Create a new Odin project. fn new_odin(name: &str) -> Result<()> { + const URL: &str = + "https://github.com/firefly-zero/firefly-odin/raw/refs/heads/main/firefly/firefly.odin"; let mut c = Commander::default(); c.cd(name)?; - // ... + c.wget(&["vendor", "firefly", "firefly.odin"], URL)?; + c.copy_asset(&["main.odin"], "main.odin")?; Ok(()) } From b0d2563fb5e9c9b129b87dff58de03847ca2fef1 Mon Sep 17 00:00:00 2001 From: gram Date: Thu, 16 Apr 2026 11:34:54 +0200 Subject: [PATCH 4/4] abadidea --- src/commands/new.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/commands/new.rs b/src/commands/new.rs index e1abd70..9891c2f 100644 --- a/src/commands/new.rs +++ b/src/commands/new.rs @@ -107,7 +107,7 @@ fn parse_lang(lang: &str) -> Result { "go" | "golang" | "tinygo" => Lang::Go, "lua" => Lang::Lua, "moon" | "moonbit" | "mbt" => Lang::Moon, - "odin" => Lang::Odin, + "odin" | "abadidea" => Lang::Odin, "python" | "py" => Lang::Python, "rust" | "rs" => Lang::Rust, "ts" | "typescript" | "js" | "javascript" => Lang::TS,