mirror of
https://github.com/dexoron/dcr.git
synced 2026-10-22 05:29:36 +00:00
Fixed:
- Path dependencies now work correctly: `dcr add` stores them as `{ path =
"./..." }` tables, `is_registry_dep` properly distinguishes registry strings
from path/git strings, and `deps/mod.rs` resolves both table-form and
legacy string-form path dependencies
- Registry dependency paths no longer hardcoded to `project_root/dcr-index`;
now use `package_root_from_registry_info()` which resolves relative to the
registry cache root (`~/.dcr/`)
- Registry dependencies are now actually built: `build_project_at()` is
called when `include_dir` or `lib_dir` is missing
Added:
- `SIGINT`/`Ctrl+C` handler via `ctrlc` crate — `dcr build` now checks
`BUILD_INTERRUPTED` flag at key points and aborts cleanly
- `utils/build.rs` — extracted shared utilities: `parse_version_info`,
`normalize_target_os`, `resolve_compiler`, `primary_language`,
`resolve_pkg_config_flags` and config helpers. Eliminates code duplication
between `cli/build.rs`, `cli/run.rs`, `cli/clean.rs`, `cli/gen.rs`
- `utils/fs.rs::with_dir` — extracted common directory-scoped execution
- `run_command_sync_output` in `builder/common.rs` with global `OUTPUT_MUTEX`
— synchronized compiler output across all backends (unix_cc, gas, nasm, msvc)
- New helper functions in `deps/register.rs`: `get_registry_cache_root`,
`package_root_from_registry_info`, `registry_include_dir`, `registry_lib_dir`,
`path_from_string_dep`
- Unit tests for `register.rs` (`is_registry_dep`, `package_root_from_registry_info`),
`deps/mod.rs` (`path_dep_path`, `push_default_lib_dirs`),
`utils/build.rs` (`normalize_target_os`, `parse_version_info`)
Removed:
- Removed unused dependencies `indicatif` and `console` from `Cargo.toml`
This commit is contained in:
@@ -31,51 +31,59 @@ pub fn resolve_deps(
|
||||
if let Some(deps) = deps_table {
|
||||
for (name, value) in deps {
|
||||
if register::is_registry_dep(value) {
|
||||
let _pkg_info = register::resolve_package_from_registry(name)?;
|
||||
// Используем путь относительно project_root или системный путь, если нужно
|
||||
let dep_root = project_root.join("dcr-index");
|
||||
let pkg_info = register::resolve_package_from_registry(name)?;
|
||||
let dep_root = register::package_root_from_registry_info(&pkg_info)?;
|
||||
|
||||
resolved.include_dirs.push(
|
||||
dep_root
|
||||
.join("target")
|
||||
.join("include")
|
||||
register::registry_include_dir(&dep_root)
|
||||
.to_string_lossy()
|
||||
.to_string(),
|
||||
);
|
||||
resolved.lib_dirs.push(
|
||||
dep_root
|
||||
.join("target")
|
||||
.join("lib")
|
||||
register::registry_lib_dir(&dep_root)
|
||||
.to_string_lossy()
|
||||
.to_string(),
|
||||
);
|
||||
resolved.libs.push(name.clone());
|
||||
} else if let Some(table) = value.as_table()
|
||||
&& let Some(path) = table.get("path").and_then(|v| v.as_str())
|
||||
{
|
||||
} else if let Some(path) = path_dep_path(value) {
|
||||
let dep_root = project_root.join(path);
|
||||
if let Some(includes) = table.get("include").and_then(|v| v.as_array()) {
|
||||
for inc in includes {
|
||||
if let Some(inc_str) = inc.as_str() {
|
||||
resolved
|
||||
.include_dirs
|
||||
.push(dep_root.join(inc_str).to_string_lossy().to_string());
|
||||
if let Some(table) = value.as_table() {
|
||||
if let Some(includes) = table.get("include").and_then(|v| v.as_array()) {
|
||||
for inc in includes {
|
||||
if let Some(inc_str) = inc.as_str() {
|
||||
resolved
|
||||
.include_dirs
|
||||
.push(dep_root.join(inc_str).to_string_lossy().to_string());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
push_if_exists(&mut resolved.include_dirs, &dep_root.join("include"));
|
||||
}
|
||||
}
|
||||
let lib_path = dep_root.join("target").join("lib");
|
||||
if lib_path.exists() {
|
||||
resolved
|
||||
.lib_dirs
|
||||
.push(lib_path.to_string_lossy().to_string());
|
||||
}
|
||||
if let Some(libs) = table.get("libs").and_then(|v| v.as_array()) {
|
||||
for lib in libs {
|
||||
if let Some(lib_str) = lib.as_str() {
|
||||
resolved.libs.push(lib_str.to_string());
|
||||
|
||||
if let Some(lib_dirs) = table.get("lib").and_then(|v| v.as_array()) {
|
||||
for lib_dir in lib_dirs {
|
||||
if let Some(lib_dir_str) = lib_dir.as_str() {
|
||||
resolved
|
||||
.lib_dirs
|
||||
.push(dep_root.join(lib_dir_str).to_string_lossy().to_string());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
push_default_lib_dirs(&mut resolved.lib_dirs, &dep_root);
|
||||
}
|
||||
|
||||
if let Some(libs) = table.get("libs").and_then(|v| v.as_array()) {
|
||||
for lib in libs {
|
||||
if let Some(lib_str) = lib.as_str() {
|
||||
resolved.libs.push(lib_str.to_string());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
resolved.libs.push(name.clone());
|
||||
}
|
||||
} else {
|
||||
push_if_exists(&mut resolved.include_dirs, &dep_root.join("include"));
|
||||
push_default_lib_dirs(&mut resolved.lib_dirs, &dep_root);
|
||||
resolved.libs.push(name.clone());
|
||||
}
|
||||
}
|
||||
@@ -91,3 +99,68 @@ pub fn resolve_deps(
|
||||
|
||||
Ok(resolved)
|
||||
}
|
||||
|
||||
fn path_dep_path(value: &toml::Value) -> Option<&str> {
|
||||
if let Some(table) = value.as_table() {
|
||||
return table.get("path").and_then(|v| v.as_str());
|
||||
}
|
||||
register::path_from_string_dep(value)
|
||||
}
|
||||
|
||||
fn push_if_exists(paths: &mut Vec<String>, path: &Path) {
|
||||
if path.exists() {
|
||||
paths.push(path.to_string_lossy().to_string());
|
||||
}
|
||||
}
|
||||
|
||||
fn push_default_lib_dirs(paths: &mut Vec<String>, dep_root: &Path) {
|
||||
for dir in ["lib", "lib64"] {
|
||||
push_if_exists(paths, &dep_root.join(dir));
|
||||
}
|
||||
push_if_exists(paths, &dep_root.join("target").join("lib"));
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use toml::Value;
|
||||
|
||||
#[test]
|
||||
fn path_dep_path_supports_table_and_legacy_strings() {
|
||||
let table = Value::Table(
|
||||
[(
|
||||
"path".to_string(),
|
||||
Value::String("./libs/mylib".to_string()),
|
||||
)]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
);
|
||||
assert_eq!(path_dep_path(&table), Some("./libs/mylib"));
|
||||
assert_eq!(
|
||||
path_dep_path(&Value::String("path:./libs/mylib".to_string())),
|
||||
Some("./libs/mylib")
|
||||
);
|
||||
assert_eq!(
|
||||
path_dep_path(&Value::String("./libs/mylib".to_string())),
|
||||
Some("./libs/mylib")
|
||||
);
|
||||
assert_eq!(path_dep_path(&Value::String("1.2.3".to_string())), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn default_lib_dirs_include_packaged_library_output() {
|
||||
let root = std::env::temp_dir().join(format!(
|
||||
"dcr_default_lib_dirs_{}_{}",
|
||||
std::process::id(),
|
||||
std::time::SystemTime::now()
|
||||
.duration_since(std::time::UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_nanos()
|
||||
));
|
||||
std::fs::create_dir_all(root.join("target/lib")).unwrap();
|
||||
let mut paths = Vec::new();
|
||||
push_default_lib_dirs(&mut paths, &root);
|
||||
assert!(paths.iter().any(|p| p.ends_with("target/lib")));
|
||||
let _ = std::fs::remove_dir_all(root);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user