From a247e33555c03c979a3cbc130f32e4851ddce0c1 Mon Sep 17 00:00:00 2001 From: Dexoron Date: Sun, 1 Mar 2026 19:47:38 +0800 Subject: [PATCH] Added: - `sharedlib` build kind (shared library output) - ASM projects (`build.language = "asm"`) - NASM and GAS backends - `build.platform` architecture hint for `-march` / `/arch` - Basic CLI integration tests --- src/cli/build.rs | 7 ------- src/core/builder/clang.rs | 8 ++++---- src/core/builder/gas.rs | 12 ++++++++++-- src/core/builder/gcc.rs | 8 ++++---- src/core/builder/mod.rs | 1 + src/core/builder/nasm.rs | 20 ++++++++++++++------ src/core/config.rs | 11 +++++++---- tests/cli_basic.rs | 2 +- 8 files changed, 41 insertions(+), 28 deletions(-) diff --git a/src/cli/build.rs b/src/cli/build.rs index fec8b69..f5e852d 100644 --- a/src/cli/build.rs +++ b/src/cli/build.rs @@ -32,7 +32,6 @@ pub fn build(args: &[String]) -> i32 { let build_standard = get_config_str(&config, "build.standard"); let build_target = get_config_str(&config, "build.target"); let build_kind = get_config_str(&config, "build.kind"); - let build_platform = get_config_str(&config, "build.platform"); let build_cflags = match get_config_list(&config, "build.cflags") { Ok(v) => v, Err(msg) => { @@ -79,7 +78,6 @@ pub fn build(args: &[String]) -> i32 { standard: &build_standard, target_dir: normalize_target(&build_target), kind: normalize_kind(&build_kind), - platform: normalize_platform(&build_platform), include_dirs: &resolved.include_dirs, lib_dirs: &resolved.lib_dirs, libs: &resolved.libs, @@ -186,8 +184,3 @@ fn normalize_kind(kind: &str) -> &str { let trimmed = kind.trim(); if trimmed.is_empty() { "bin" } else { trimmed } } - -fn normalize_platform(platform: &str) -> Option<&str> { - let trimmed = platform.trim(); - if trimmed.is_empty() { None } else { Some(trimmed) } -} diff --git a/src/core/builder/clang.rs b/src/core/builder/clang.rs index c80333b..9d4f4ca 100644 --- a/src/core/builder/clang.rs +++ b/src/core/builder/clang.rs @@ -150,10 +150,10 @@ fn build_objects( if ctx.kind == "sharedlib" { cmd.arg("-fPIC"); } - if let Some(platform) = ctx.platform { - if !platform.trim().is_empty() { - cmd.arg(format!("-march={}", platform)); - } + if let Some(platform) = ctx.platform + && !platform.trim().is_empty() + { + cmd.arg(format!("-march={}", platform)); } if !ctx.standard.is_empty() && ctx.language.to_lowercase() != "asm" { cmd.arg(format!("-std={}", ctx.standard)); diff --git a/src/core/builder/gas.rs b/src/core/builder/gas.rs index 7c56045..d4ac729 100644 --- a/src/core/builder/gas.rs +++ b/src/core/builder/gas.rs @@ -9,7 +9,11 @@ pub fn build(ctx: &BuildContext) -> Result { if ctx.language.to_lowercase().as_str() != "asm" { return Err("GAS backend requires build.language = \"asm\"".to_string()); } - let assembler = if ctx.compiler.is_empty() { "as" } else { ctx.compiler }; + let assembler = if ctx.compiler.is_empty() { + "as" + } else { + ctx.compiler + }; let start_time = Instant::now(); let sources = collect_sources(ctx.language)?; let obj_dir = Path::new("./target").join(ctx.profile).join("obj"); @@ -17,7 +21,11 @@ pub fn build(ctx: &BuildContext) -> Result { if ctx.kind == "staticlib" { let lib_path = platform::lib_path(ctx.profile, ctx.project_name, ctx.target_dir); - let mut cmd = Command::new(if cfg!(target_os = "windows") { "lib" } else { "ar" }); + let mut cmd = Command::new(if cfg!(target_os = "windows") { + "lib" + } else { + "ar" + }); if cfg!(target_os = "windows") { cmd.arg("/nologo").arg(format!("/OUT:{lib_path}")); } else { diff --git a/src/core/builder/gcc.rs b/src/core/builder/gcc.rs index c80333b..9d4f4ca 100644 --- a/src/core/builder/gcc.rs +++ b/src/core/builder/gcc.rs @@ -150,10 +150,10 @@ fn build_objects( if ctx.kind == "sharedlib" { cmd.arg("-fPIC"); } - if let Some(platform) = ctx.platform { - if !platform.trim().is_empty() { - cmd.arg(format!("-march={}", platform)); - } + if let Some(platform) = ctx.platform + && !platform.trim().is_empty() + { + cmd.arg(format!("-march={}", platform)); } if !ctx.standard.is_empty() && ctx.language.to_lowercase() != "asm" { cmd.arg(format!("-std={}", ctx.standard)); diff --git a/src/core/builder/mod.rs b/src/core/builder/mod.rs index fb777bc..f6efd46 100644 --- a/src/core/builder/mod.rs +++ b/src/core/builder/mod.rs @@ -1,4 +1,5 @@ pub mod clang; +pub mod gas; pub mod gcc; pub mod gas; pub mod msvc; diff --git a/src/core/builder/nasm.rs b/src/core/builder/nasm.rs index b85c523..dbd8778 100644 --- a/src/core/builder/nasm.rs +++ b/src/core/builder/nasm.rs @@ -21,7 +21,11 @@ pub fn build(ctx: &BuildContext) -> Result { if ctx.kind == "staticlib" { let lib_path = platform::lib_path(ctx.profile, ctx.project_name, ctx.target_dir); - let mut cmd = Command::new(if cfg!(target_os = "windows") { "lib" } else { "ar" }); + let mut cmd = Command::new(if cfg!(target_os = "windows") { + "lib" + } else { + "ar" + }); if cfg!(target_os = "windows") { cmd.arg("/nologo").arg(format!("/OUT:{lib_path}")); } else { @@ -40,7 +44,7 @@ pub fn build(ctx: &BuildContext) -> Result { } } - let linker = if cfg!(target_os = "windows") { "cc" } else { "cc" }; + let linker = "cc"; let mut cmd = Command::new(linker); if ctx.kind == "sharedlib" { if cfg!(target_os = "macos") { @@ -128,7 +132,11 @@ fn build_objects( } if needs_rebuild(source, &obj_path) { let mut cmd = Command::new(assembler); - cmd.arg("-f").arg(format).arg(source).arg("-o").arg(&obj_path); + cmd.arg("-f") + .arg(format) + .arg(source) + .arg("-o") + .arg(&obj_path); for flag in ctx.cflags { cmd.arg(flag); } @@ -163,15 +171,15 @@ fn nasm_format(platform: Option<&str>) -> &'static str { } #[cfg(target_os = "linux")] { - return "elf64"; + "elf64" } #[cfg(target_os = "macos")] { - return "macho64"; + "macho64" } #[cfg(target_os = "windows")] { - return "win64"; + "win64" } #[cfg(not(any(target_os = "linux", target_os = "macos", target_os = "windows")))] { diff --git a/src/core/config.rs b/src/core/config.rs index bfab2ec..81cda4c 100644 --- a/src/core/config.rs +++ b/src/core/config.rs @@ -121,10 +121,13 @@ impl Config { return Err(ConfigError::Invalid(format!("build.{key} is empty"))); } } - if let Some(platform) = build.get("platform") { - if !platform.as_str().map(|v| !v.trim().is_empty()).unwrap_or(false) { - return Err(ConfigError::Invalid("build.platform is empty".into())); - } + if let Some(platform) = build.get("platform") + && !platform + .as_str() + .map(|v| !v.trim().is_empty()) + .unwrap_or(false) + { + return Err(ConfigError::Invalid("build.platform is empty".into())); } if let Some(kind) = build.get("kind").and_then(|v| v.as_str()) { let kind = kind.trim(); diff --git a/tests/cli_basic.rs b/tests/cli_basic.rs index bab020b..68fb8f1 100644 --- a/tests/cli_basic.rs +++ b/tests/cli_basic.rs @@ -1,7 +1,7 @@ use std::path::{Path, PathBuf}; use std::process::Command; -use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::Once; +use std::sync::atomic::{AtomicUsize, Ordering}; use std::time::{SystemTime, UNIX_EPOCH}; static COUNTER: AtomicUsize = AtomicUsize::new(0);