mirror of
https://github.com/dexoron/dcr.git
synced 2026-10-21 13:38:30 +00:00
26
CHANGELOG.md
26
CHANGELOG.md
@@ -1,5 +1,31 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## [0.7.2] - 2026-06-07 "Исправление Таргетов и Линковки / Target & Linker Fixes"
|
||||||
|
|
||||||
|
### RU
|
||||||
|
|
||||||
|
**Добавлено:**
|
||||||
|
- Учтён `target_env` в `default_target_triple()` — Linux (gnu/musl) и Windows (msvc/gnu) теперь используют правильное окружение, а не хардкод.
|
||||||
|
|
||||||
|
**Исправлено:**
|
||||||
|
- **Сборка на macOS Apple Silicon падала с `_main` undefined** — `--target=` теперь передаётся и в ldflags, не только в cflags. `default_target_triple()` на macOS использует `std::env::consts::ARCH` вместо хардкода `x86_64`.
|
||||||
|
- **Бейджи GitHub Stars и GPL-3.0 не рендерились в README** — блок бейджей переведён на чистый HTML.
|
||||||
|
|
||||||
|
**Изменено:**
|
||||||
|
- Вычисление таргета по умолчанию вынесено в общую функцию `default_target_triple()` — устранено дублирование в build, run, clean.
|
||||||
|
|
||||||
|
### EN
|
||||||
|
|
||||||
|
**Added:**
|
||||||
|
- `default_target_triple()` now respects `target_env` — Linux (gnu/musl) and Windows (msvc/gnu) use the correct environment instead of hardcoded values.
|
||||||
|
|
||||||
|
**Fixed:**
|
||||||
|
- **macOS Apple Silicon builds failed with `_main` undefined** — `--target=` is now passed to ldflags, not just cflags. `default_target_triple()` uses `std::env::consts::ARCH` on macOS instead of hardcoded `x86_64`.
|
||||||
|
- **GitHub Stars and GPL-3.0 badges not rendering in README** — badge block converted to pure HTML.
|
||||||
|
|
||||||
|
**Changed:**
|
||||||
|
- Default target resolution extracted into shared `default_target_triple()` — removed duplication across build, run, clean.
|
||||||
|
|
||||||
## [0.7.1] - 2026-06-02 "Мультиархитектурное расширение / The Multi-Arch Expansion"
|
## [0.7.1] - 2026-06-02 "Мультиархитектурное расширение / The Multi-Arch Expansion"
|
||||||
|
|
||||||
### RU
|
### RU
|
||||||
|
|||||||
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -112,7 +112,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dcr"
|
name = "dcr"
|
||||||
version = "0.7.1"
|
version = "0.7.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ctrlc",
|
"ctrlc",
|
||||||
"git2",
|
"git2",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "dcr"
|
name = "dcr"
|
||||||
version = "0.7.1"
|
version = "0.7.2"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
build = "build.rs"
|
build = "build.rs"
|
||||||
description = "DCR is a utility for managing C/C++ projects in a Cargo-like style."
|
description = "DCR is a utility for managing C/C++ projects in a Cargo-like style."
|
||||||
|
|||||||
@@ -23,9 +23,9 @@ use crate::core::config::Config;
|
|||||||
use crate::core::deps::{register, resolve_deps};
|
use crate::core::deps::{register, resolve_deps};
|
||||||
use crate::core::workspace::parse_workspace;
|
use crate::core::workspace::parse_workspace;
|
||||||
use crate::utils::build::{
|
use crate::utils::build::{
|
||||||
get_bool_with_profile, get_config_opt, get_config_str, get_language_with_profile,
|
default_target_triple, get_bool_with_profile, get_config_opt, get_config_str,
|
||||||
normalize_target_os, parse_version_info, profile_table, resolve_compiler,
|
get_language_with_profile, normalize_target_os, parse_version_info, prepend_clang_target_flag,
|
||||||
resolve_pkg_config_flags, resolve_tool,
|
profile_table, resolve_compiler, resolve_pkg_config_flags, resolve_tool,
|
||||||
};
|
};
|
||||||
use crate::utils::fs::{check_dir, find_project_root, with_dir};
|
use crate::utils::fs::{check_dir, find_project_root, with_dir};
|
||||||
use crate::utils::log::error;
|
use crate::utils::log::error;
|
||||||
@@ -100,27 +100,7 @@ pub fn build(args: &[String]) -> i32 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if flags.target.is_none() {
|
if flags.target.is_none() {
|
||||||
let default_target = if cfg!(target_os = "linux") {
|
flags.target = Some(default_target_triple());
|
||||||
format!("{}-unknown-linux-gnu", std::env::consts::ARCH)
|
|
||||||
} else if cfg!(target_os = "macos") {
|
|
||||||
"x86_64-apple-darwin".to_string()
|
|
||||||
} else if cfg!(target_os = "windows") {
|
|
||||||
"x86_64-pc-windows-msvc".to_string()
|
|
||||||
} else if cfg!(any(
|
|
||||||
target_os = "freebsd",
|
|
||||||
target_os = "openbsd",
|
|
||||||
target_os = "netbsd",
|
|
||||||
target_os = "dragonfly"
|
|
||||||
)) {
|
|
||||||
format!(
|
|
||||||
"{}-unknown-{}",
|
|
||||||
std::env::consts::ARCH,
|
|
||||||
std::env::consts::OS
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
"unknown".to_string()
|
|
||||||
};
|
|
||||||
flags.target = Some(default_target);
|
|
||||||
}
|
}
|
||||||
if flags.clean {
|
if flags.clean {
|
||||||
let mut clean_args = Vec::new();
|
let mut clean_args = Vec::new();
|
||||||
@@ -718,19 +698,13 @@ fn build_project_at(
|
|||||||
tc_cxx.as_deref(),
|
tc_cxx.as_deref(),
|
||||||
tc_as.as_deref(),
|
tc_as.as_deref(),
|
||||||
);
|
);
|
||||||
if let Some(t) = build_target
|
|
||||||
&& !t.trim().is_empty()
|
|
||||||
&& resolved_compiler.to_lowercase().contains("clang")
|
|
||||||
{
|
|
||||||
let target_flag = format!("--target={}", t.trim());
|
|
||||||
if !build_cflags
|
|
||||||
.iter()
|
|
||||||
.any(|f| f == &target_flag || f.starts_with("--target="))
|
|
||||||
{
|
|
||||||
build_cflags.insert(0, target_flag);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let resolved_linker = resolve_tool("DCR_LD", tc_ld.as_deref());
|
let resolved_linker = resolve_tool("DCR_LD", tc_ld.as_deref());
|
||||||
|
prepend_clang_target_flag(&mut build_cflags, build_target, &resolved_compiler);
|
||||||
|
prepend_clang_target_flag(
|
||||||
|
&mut build_ldflags,
|
||||||
|
build_target,
|
||||||
|
resolved_linker.as_deref().unwrap_or(&resolved_compiler),
|
||||||
|
);
|
||||||
let resolved_archiver = resolve_tool("DCR_AR", tc_ar.as_deref());
|
let resolved_archiver = resolve_tool("DCR_AR", tc_ar.as_deref());
|
||||||
|
|
||||||
let out_dir_config = get_build_string_with_profile(&config, "out_dir", profile);
|
let out_dir_config = get_build_string_with_profile(&config, "out_dir", profile);
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
use crate::config::flags;
|
use crate::config::flags;
|
||||||
use crate::core::config::Config;
|
use crate::core::config::Config;
|
||||||
use crate::core::workspace::parse_workspace;
|
use crate::core::workspace::parse_workspace;
|
||||||
use crate::utils::build::parse_version_info;
|
use crate::utils::build::{default_target_triple, parse_version_info};
|
||||||
use crate::utils::fs::{check_dir, find_project_root, with_dir};
|
use crate::utils::fs::{check_dir, find_project_root, with_dir};
|
||||||
use crate::utils::log::{error, warn};
|
use crate::utils::log::{error, warn};
|
||||||
use crate::utils::text::{BOLD_CYAN, BOLD_GREEN, colored, printc};
|
use crate::utils::text::{BOLD_CYAN, BOLD_GREEN, colored, printc};
|
||||||
@@ -136,28 +136,7 @@ fn clean_from_root(root: &Path, flags: &CleanFlags) -> Result<(), String> {
|
|||||||
.map(|s| s.trim().to_string())
|
.map(|s| s.trim().to_string())
|
||||||
.filter(|s| !s.is_empty())
|
.filter(|s| !s.is_empty())
|
||||||
})
|
})
|
||||||
.or_else(|| {
|
.or_else(|| Some(default_target_triple()));
|
||||||
Some(if cfg!(target_os = "linux") {
|
|
||||||
format!("{}-unknown-linux-gnu", std::env::consts::ARCH)
|
|
||||||
} else if cfg!(target_os = "macos") {
|
|
||||||
"x86_64-apple-darwin".to_string()
|
|
||||||
} else if cfg!(target_os = "windows") {
|
|
||||||
"x86_64-pc-windows-msvc".to_string()
|
|
||||||
} else if cfg!(any(
|
|
||||||
target_os = "freebsd",
|
|
||||||
target_os = "openbsd",
|
|
||||||
target_os = "netbsd",
|
|
||||||
target_os = "dragonfly"
|
|
||||||
)) {
|
|
||||||
format!(
|
|
||||||
"{}-unknown-{}",
|
|
||||||
std::env::consts::ARCH,
|
|
||||||
std::env::consts::OS
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
"unknown".to_string()
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
if flags.all
|
if flags.all
|
||||||
&& let Some(workspace) = parse_workspace(
|
&& let Some(workspace) = parse_workspace(
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ use crate::cli::build::build;
|
|||||||
use crate::cli::flags::parse_build_run_flags;
|
use crate::cli::flags::parse_build_run_flags;
|
||||||
use crate::core::config::Config;
|
use crate::core::config::Config;
|
||||||
use crate::core::runner::run_binary;
|
use crate::core::runner::run_binary;
|
||||||
use crate::utils::build::{normalize_target_os, parse_version_info};
|
use crate::utils::build::{default_target_triple, normalize_target_os, parse_version_info};
|
||||||
use crate::utils::fs::find_project_root;
|
use crate::utils::fs::find_project_root;
|
||||||
use crate::utils::fs::with_dir;
|
use crate::utils::fs::with_dir;
|
||||||
use crate::utils::log::error;
|
use crate::utils::log::error;
|
||||||
@@ -178,27 +178,7 @@ fn run_project(
|
|||||||
// If no target specified, use default host target for target-specific config
|
// If no target specified, use default host target for target-specific config
|
||||||
let mut target = flags.target.clone();
|
let mut target = flags.target.clone();
|
||||||
if target.is_none() {
|
if target.is_none() {
|
||||||
let default_target = if cfg!(target_os = "linux") {
|
target = Some(default_target_triple());
|
||||||
format!("{}-unknown-linux-gnu", std::env::consts::ARCH)
|
|
||||||
} else if cfg!(target_os = "macos") {
|
|
||||||
"x86_64-apple-darwin".to_string()
|
|
||||||
} else if cfg!(target_os = "windows") {
|
|
||||||
"x86_64-pc-windows-msvc".to_string()
|
|
||||||
} else if cfg!(any(
|
|
||||||
target_os = "freebsd",
|
|
||||||
target_os = "openbsd",
|
|
||||||
target_os = "netbsd",
|
|
||||||
target_os = "dragonfly"
|
|
||||||
)) {
|
|
||||||
format!(
|
|
||||||
"{}-unknown-{}",
|
|
||||||
std::env::consts::ARCH,
|
|
||||||
std::env::consts::OS
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
"unknown".to_string()
|
|
||||||
};
|
|
||||||
target = Some(default_target);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let build_kind = config
|
let build_kind = config
|
||||||
|
|||||||
@@ -72,6 +72,53 @@ pub fn normalize_target_os(target: &str) -> &str {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn default_target_triple() -> String {
|
||||||
|
let arch = std::env::consts::ARCH;
|
||||||
|
if cfg!(target_os = "linux") {
|
||||||
|
let env = if cfg!(target_env = "musl") {
|
||||||
|
"musl"
|
||||||
|
} else {
|
||||||
|
"gnu"
|
||||||
|
};
|
||||||
|
format!("{arch}-unknown-linux-{env}")
|
||||||
|
} else if cfg!(target_os = "macos") {
|
||||||
|
format!("{arch}-apple-darwin")
|
||||||
|
} else if cfg!(target_os = "windows") {
|
||||||
|
let env = if cfg!(target_env = "gnu") {
|
||||||
|
"gnu"
|
||||||
|
} else {
|
||||||
|
"msvc"
|
||||||
|
};
|
||||||
|
format!("{arch}-pc-windows-{env}")
|
||||||
|
} else if cfg!(any(
|
||||||
|
target_os = "freebsd",
|
||||||
|
target_os = "openbsd",
|
||||||
|
target_os = "netbsd",
|
||||||
|
target_os = "dragonfly"
|
||||||
|
)) {
|
||||||
|
format!("{arch}-unknown-{}", std::env::consts::OS)
|
||||||
|
} else {
|
||||||
|
"unknown".to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn prepend_clang_target_flag(flags: &mut Vec<String>, target: Option<&str>, tool: &str) {
|
||||||
|
let Some(target) = target.map(str::trim).filter(|t| !t.is_empty()) else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
if !tool.to_lowercase().contains("clang") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let target_flag = format!("--target={target}");
|
||||||
|
if !flags
|
||||||
|
.iter()
|
||||||
|
.any(|f| f == &target_flag || f.starts_with("--target="))
|
||||||
|
{
|
||||||
|
flags.insert(0, target_flag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_config_str(config: &Config, key: &str) -> String {
|
pub fn get_config_str(config: &Config, key: &str) -> String {
|
||||||
config
|
config
|
||||||
.get(key)
|
.get(key)
|
||||||
@@ -380,6 +427,61 @@ mod tests {
|
|||||||
assert_eq!(normalize_target_os("unknown"), "unknown");
|
assert_eq!(normalize_target_os("unknown"), "unknown");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn default_target_triple_uses_host_arch() {
|
||||||
|
let target = default_target_triple();
|
||||||
|
if cfg!(target_os = "linux") {
|
||||||
|
assert_eq!(
|
||||||
|
target,
|
||||||
|
format!("{}-unknown-linux-gnu", std::env::consts::ARCH)
|
||||||
|
);
|
||||||
|
} else if cfg!(target_os = "macos") {
|
||||||
|
assert_eq!(target, format!("{}-apple-darwin", std::env::consts::ARCH));
|
||||||
|
} else if cfg!(target_os = "windows") {
|
||||||
|
assert_eq!(
|
||||||
|
target,
|
||||||
|
format!("{}-pc-windows-msvc", std::env::consts::ARCH)
|
||||||
|
);
|
||||||
|
} else if cfg!(any(
|
||||||
|
target_os = "freebsd",
|
||||||
|
target_os = "openbsd",
|
||||||
|
target_os = "netbsd",
|
||||||
|
target_os = "dragonfly"
|
||||||
|
)) {
|
||||||
|
assert_eq!(
|
||||||
|
target,
|
||||||
|
format!(
|
||||||
|
"{}-unknown-{}",
|
||||||
|
std::env::consts::ARCH,
|
||||||
|
std::env::consts::OS
|
||||||
|
)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
assert_eq!(target, "unknown");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn prepend_clang_target_flag_adds_once_for_clang() {
|
||||||
|
let mut flags = vec!["-O2".to_string()];
|
||||||
|
prepend_clang_target_flag(&mut flags, Some("aarch64-apple-darwin"), "clang");
|
||||||
|
prepend_clang_target_flag(&mut flags, Some("aarch64-apple-darwin"), "clang");
|
||||||
|
assert_eq!(
|
||||||
|
flags,
|
||||||
|
vec![
|
||||||
|
"--target=aarch64-apple-darwin".to_string(),
|
||||||
|
"-O2".to_string()
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn prepend_clang_target_flag_ignores_non_clang_tools() {
|
||||||
|
let mut flags = vec!["-O2".to_string()];
|
||||||
|
prepend_clang_target_flag(&mut flags, Some("aarch64-apple-darwin"), "gcc");
|
||||||
|
assert_eq!(flags, vec!["-O2".to_string()]);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn parse_version_parts() {
|
fn parse_version_parts() {
|
||||||
let info = parse_version_info("1.2.3-beta");
|
let info = parse_version_info("1.2.3-beta");
|
||||||
|
|||||||
Reference in New Issue
Block a user