mirror of
https://github.com/dexoron/dcr.git
synced 2026-10-21 13:28:30 +00:00
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
This commit is contained in:
@@ -32,7 +32,6 @@ pub fn build(args: &[String]) -> i32 {
|
|||||||
let build_standard = get_config_str(&config, "build.standard");
|
let build_standard = get_config_str(&config, "build.standard");
|
||||||
let build_target = get_config_str(&config, "build.target");
|
let build_target = get_config_str(&config, "build.target");
|
||||||
let build_kind = get_config_str(&config, "build.kind");
|
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") {
|
let build_cflags = match get_config_list(&config, "build.cflags") {
|
||||||
Ok(v) => v,
|
Ok(v) => v,
|
||||||
Err(msg) => {
|
Err(msg) => {
|
||||||
@@ -79,7 +78,6 @@ pub fn build(args: &[String]) -> i32 {
|
|||||||
standard: &build_standard,
|
standard: &build_standard,
|
||||||
target_dir: normalize_target(&build_target),
|
target_dir: normalize_target(&build_target),
|
||||||
kind: normalize_kind(&build_kind),
|
kind: normalize_kind(&build_kind),
|
||||||
platform: normalize_platform(&build_platform),
|
|
||||||
include_dirs: &resolved.include_dirs,
|
include_dirs: &resolved.include_dirs,
|
||||||
lib_dirs: &resolved.lib_dirs,
|
lib_dirs: &resolved.lib_dirs,
|
||||||
libs: &resolved.libs,
|
libs: &resolved.libs,
|
||||||
@@ -186,8 +184,3 @@ fn normalize_kind(kind: &str) -> &str {
|
|||||||
let trimmed = kind.trim();
|
let trimmed = kind.trim();
|
||||||
if trimmed.is_empty() { "bin" } else { trimmed }
|
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) }
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -150,10 +150,10 @@ fn build_objects(
|
|||||||
if ctx.kind == "sharedlib" {
|
if ctx.kind == "sharedlib" {
|
||||||
cmd.arg("-fPIC");
|
cmd.arg("-fPIC");
|
||||||
}
|
}
|
||||||
if let Some(platform) = ctx.platform {
|
if let Some(platform) = ctx.platform
|
||||||
if !platform.trim().is_empty() {
|
&& !platform.trim().is_empty()
|
||||||
cmd.arg(format!("-march={}", platform));
|
{
|
||||||
}
|
cmd.arg(format!("-march={}", platform));
|
||||||
}
|
}
|
||||||
if !ctx.standard.is_empty() && ctx.language.to_lowercase() != "asm" {
|
if !ctx.standard.is_empty() && ctx.language.to_lowercase() != "asm" {
|
||||||
cmd.arg(format!("-std={}", ctx.standard));
|
cmd.arg(format!("-std={}", ctx.standard));
|
||||||
|
|||||||
@@ -9,7 +9,11 @@ pub fn build(ctx: &BuildContext) -> Result<f64, String> {
|
|||||||
if ctx.language.to_lowercase().as_str() != "asm" {
|
if ctx.language.to_lowercase().as_str() != "asm" {
|
||||||
return Err("GAS backend requires build.language = \"asm\"".to_string());
|
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 start_time = Instant::now();
|
||||||
let sources = collect_sources(ctx.language)?;
|
let sources = collect_sources(ctx.language)?;
|
||||||
let obj_dir = Path::new("./target").join(ctx.profile).join("obj");
|
let obj_dir = Path::new("./target").join(ctx.profile).join("obj");
|
||||||
@@ -17,7 +21,11 @@ pub fn build(ctx: &BuildContext) -> Result<f64, String> {
|
|||||||
|
|
||||||
if ctx.kind == "staticlib" {
|
if ctx.kind == "staticlib" {
|
||||||
let lib_path = platform::lib_path(ctx.profile, ctx.project_name, ctx.target_dir);
|
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") {
|
if cfg!(target_os = "windows") {
|
||||||
cmd.arg("/nologo").arg(format!("/OUT:{lib_path}"));
|
cmd.arg("/nologo").arg(format!("/OUT:{lib_path}"));
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -150,10 +150,10 @@ fn build_objects(
|
|||||||
if ctx.kind == "sharedlib" {
|
if ctx.kind == "sharedlib" {
|
||||||
cmd.arg("-fPIC");
|
cmd.arg("-fPIC");
|
||||||
}
|
}
|
||||||
if let Some(platform) = ctx.platform {
|
if let Some(platform) = ctx.platform
|
||||||
if !platform.trim().is_empty() {
|
&& !platform.trim().is_empty()
|
||||||
cmd.arg(format!("-march={}", platform));
|
{
|
||||||
}
|
cmd.arg(format!("-march={}", platform));
|
||||||
}
|
}
|
||||||
if !ctx.standard.is_empty() && ctx.language.to_lowercase() != "asm" {
|
if !ctx.standard.is_empty() && ctx.language.to_lowercase() != "asm" {
|
||||||
cmd.arg(format!("-std={}", ctx.standard));
|
cmd.arg(format!("-std={}", ctx.standard));
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
pub mod clang;
|
pub mod clang;
|
||||||
|
pub mod gas;
|
||||||
pub mod gcc;
|
pub mod gcc;
|
||||||
pub mod gas;
|
pub mod gas;
|
||||||
pub mod msvc;
|
pub mod msvc;
|
||||||
|
|||||||
@@ -21,7 +21,11 @@ pub fn build(ctx: &BuildContext) -> Result<f64, String> {
|
|||||||
|
|
||||||
if ctx.kind == "staticlib" {
|
if ctx.kind == "staticlib" {
|
||||||
let lib_path = platform::lib_path(ctx.profile, ctx.project_name, ctx.target_dir);
|
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") {
|
if cfg!(target_os = "windows") {
|
||||||
cmd.arg("/nologo").arg(format!("/OUT:{lib_path}"));
|
cmd.arg("/nologo").arg(format!("/OUT:{lib_path}"));
|
||||||
} else {
|
} else {
|
||||||
@@ -40,7 +44,7 @@ pub fn build(ctx: &BuildContext) -> Result<f64, String> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let linker = if cfg!(target_os = "windows") { "cc" } else { "cc" };
|
let linker = "cc";
|
||||||
let mut cmd = Command::new(linker);
|
let mut cmd = Command::new(linker);
|
||||||
if ctx.kind == "sharedlib" {
|
if ctx.kind == "sharedlib" {
|
||||||
if cfg!(target_os = "macos") {
|
if cfg!(target_os = "macos") {
|
||||||
@@ -128,7 +132,11 @@ fn build_objects(
|
|||||||
}
|
}
|
||||||
if needs_rebuild(source, &obj_path) {
|
if needs_rebuild(source, &obj_path) {
|
||||||
let mut cmd = Command::new(assembler);
|
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 {
|
for flag in ctx.cflags {
|
||||||
cmd.arg(flag);
|
cmd.arg(flag);
|
||||||
}
|
}
|
||||||
@@ -163,15 +171,15 @@ fn nasm_format(platform: Option<&str>) -> &'static str {
|
|||||||
}
|
}
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
{
|
{
|
||||||
return "elf64";
|
"elf64"
|
||||||
}
|
}
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
{
|
{
|
||||||
return "macho64";
|
"macho64"
|
||||||
}
|
}
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
{
|
{
|
||||||
return "win64";
|
"win64"
|
||||||
}
|
}
|
||||||
#[cfg(not(any(target_os = "linux", target_os = "macos", target_os = "windows")))]
|
#[cfg(not(any(target_os = "linux", target_os = "macos", target_os = "windows")))]
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -121,10 +121,13 @@ impl Config {
|
|||||||
return Err(ConfigError::Invalid(format!("build.{key} is empty")));
|
return Err(ConfigError::Invalid(format!("build.{key} is empty")));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Some(platform) = build.get("platform") {
|
if let Some(platform) = build.get("platform")
|
||||||
if !platform.as_str().map(|v| !v.trim().is_empty()).unwrap_or(false) {
|
&& !platform
|
||||||
return Err(ConfigError::Invalid("build.platform is empty".into()));
|
.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()) {
|
if let Some(kind) = build.get("kind").and_then(|v| v.as_str()) {
|
||||||
let kind = kind.trim();
|
let kind = kind.trim();
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
|
||||||
use std::sync::Once;
|
use std::sync::Once;
|
||||||
|
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||||
use std::time::{SystemTime, UNIX_EPOCH};
|
use std::time::{SystemTime, UNIX_EPOCH};
|
||||||
|
|
||||||
static COUNTER: AtomicUsize = AtomicUsize::new(0);
|
static COUNTER: AtomicUsize = AtomicUsize::new(0);
|
||||||
|
|||||||
Reference in New Issue
Block a user