refactor: modularize build core engine, update workspaces, cache, and test suite

This commit is contained in:
2026-07-18 20:02:12 +08:00
parent 9326e23a53
commit 9eaa4635d5
49 changed files with 3385 additions and 2312 deletions

View File

@@ -12,8 +12,12 @@ Only ASCII letters, digits, underscores `_` and hyphens `-` are allowed in the p
```bash
dcr new my-app
dcr new my-app --vcs none
```
Flags:
- `--vcs <git|none>` — Initialize version control system (defaults to `git` if available, or `none`).
Generates:
- `dcr.toml` with basic fields
- `src/main.c` with a `main` template
@@ -23,8 +27,11 @@ Generates:
Initializes a DCR project in the current (empty) directory.
```bash
mkdir app && cd app
dcr init
dcr init --vcs none
```
Flags:
- `--vcs <git|none>` — Initialize version control system (defaults to `git` if available, or `none`).
The project name is taken from the current directory name. The directory name must follow the same naming rules as `dcr new`.

View File

@@ -15,9 +15,9 @@ dcr setup
If `~/.dcr/config.toml` is not found, DCR returns an error. Create it manually:
```toml
[[registry]]
name = "default"
[registry.default]
url = "https://index.dcr.pm"
priority = 1
```
## `dcr --help`

View File

@@ -13,9 +13,9 @@ error: registry not found
**Solution:** Make sure `~/.dcr/config.toml` exists:
```toml
[[registry]]
name = "default"
[registry.default]
url = "https://index.dcr.pm"
priority = 1
```
And check `DCR_INDEX_PATH`:

View File

@@ -100,7 +100,7 @@ man dcr-build
To use the registry, create `~/.dcr/config.toml`:
```toml
[[registry]]
name = "default"
[registry.default]
url = "https://index.dcr.pm"
priority = 1
```

View File

@@ -10,36 +10,23 @@ DCR itself is [GPL-3.0-or-later](https://spdx.org/licenses/GPL-3.0-or-later.html
> **Note:** DCR is a build tool, not a library. The GPL applies only to DCR's own source code. Projects built with DCR are not subject to DCR's license — their licensing is determined solely by their own code and dependencies.
## Vendored libraries
DCR statically links the following C libraries through its vendored Rust dependencies:
| Library | License | Bundled by |
|---|---|---|
| [libgit2](https://libgit2.org) | MIT OR Apache-2.0 | `git2` / `libgit2-sys` |
| [libssh2](https://libssh2.org) | MIT OR Apache-2.0 | `libgit2-sys` |
| [zlib](https://zlib.net) | MIT OR Apache-2.0 | `libgit2-sys` |
| [OpenSSL](https://openssl.org) | Apache-2.0 | `openssl-sys` / `openssl-src` |
| [ring](https://github.com/briansmith/ring) | Apache-2.0 AND ISC | `rustls` |
## Rust dependencies
DCR is written in Rust. The following notable Rust crates are statically linked:
| Crate | License |
|---|---|
| [`reqwest`](https://crates.io/crates/reqwest) | MIT OR Apache-2.0 |
| [`rustls`](https://crates.io/crates/rustls) | Apache-2.0 OR ISC OR MIT |
| [`ureq`](https://crates.io/crates/ureq) | MIT OR Apache-2.0 |
| [`serde`](https://crates.io/crates/serde) | MIT OR Apache-2.0 |
| [`toml`](https://crates.io/crates/toml) | MIT OR Apache-2.0 |
| [`toml_edit`](https://crates.io/crates/toml_edit) | MIT OR Apache-2.0 |
| [`serde_json`](https://crates.io/crates/serde_json) | MIT OR Apache-2.0 |
| [`sha2`](https://crates.io/crates/sha2) | MIT OR Apache-2.0 |
| [`git2`](https://crates.io/crates/git2) | MIT OR Apache-2.0 |
| [`openssl`](https://crates.io/crates/openssl) | Apache-2.0 |
| [`tokio`](https://crates.io/crates/tokio) | MIT |
| [`hyper`](https://crates.io/crates/hyper) | MIT |
| [`glob`](https://crates.io/crates/glob) | MIT OR Apache-2.0 |
| [`self-replace`](https://crates.io/crates/self-replace) | MIT OR Apache-2.0 |
| [`ctrlc`](https://crates.io/crates/ctrlc) | MIT OR Apache-2.0 |
Full dependency tree (143 packages) is available in [`Cargo.lock`](https://github.com/dexoron/dcr/blob/main/Cargo.lock). The overwhelming majority are dual-licensed under MIT OR Apache-2.0.
Full dependency tree is available in [`Cargo.lock`](https://github.com/dexoron/dcr/blob/main/Cargo.lock). The overwhelming majority are dual-licensed under MIT OR Apache-2.0.
## Additional credits

View File

@@ -34,6 +34,7 @@ type = "none"
inherit = true
language = "c"
standard = "c11"
workspace_only = true
[workspace.lib-core]
path = "lib-core"

View File

@@ -41,7 +41,7 @@ Main project configuration file. Located at the project root.
|-------|----------|-------------|
| `name` | yes | Project name |
| `version` | yes | Semantic version |
| `type` | yes | `app`, `lib`, `none` |
| `type` | no | `app`, `lib`, `none` (defaults to `"none"`) |
| `license` | no | SPDX license identifier |
| `author` | no | Author |
@@ -62,10 +62,10 @@ author = "John Doe"
| Field | Default | Description |
|-------|---------|-------------|
| `language` | `"c"` | `"c"`, `"c++"`, `"cpp"`, `"cxx"`, `"asm"` |
| `language` | `"c"` | `"c"`, `"c++"`, `"cpp"`, `"cxx"`, `"asm"` (optional, defaults to `"c"`) |
| `standard` | `"c11"` | C standard (`c11`, `c17`, `c23`) |
| `cxx_standard` | `"c++20"` | C++ standard (`c++17`, `c++20`, `c++23`) |
| `compiler` | `"clang"` | Preferred compiler |
| `cxx_standard` | — | C++ standard (`c++17`, `c++20`, `c++23`) |
| `compiler` | `"clang"` | Preferred compiler (optional, defaults to `"clang"`) |
| `kind` | `"bin"` | `bin`, `staticlib`, `sharedlib`, `efi`, `elf`, `none`, `custom` |
| `target` | host | Target triple for cross-compilation |
| `platform` | `"native"` | `native`, `efi` |
@@ -80,13 +80,13 @@ author = "John Doe"
| `inherit` | `false` | Inherit build from workspace root |
| `clean` | `[]` | Glob patterns for custom clean paths |
| `out_dir` | `""` | Custom output directory |
| `workspace_only` | `false` | Workspace-only, not built standalone |
| `workspace_only` | `false` | Workspace-only, not built standalone (no `language`/`compiler` required) |
| `freestanding` | `false` | Compile in freestanding mode (`-ffreestanding` + `-nostdlib -static`) |
| `opt_level` | `"0"` (debug) / `"3"` (release) | Optimization level: `0`-`3`, `"s"`, `"z"` |
| `debug` | `true` (debug) / `false` (release) | Emit debug symbols (`-g`) |
| `opt_level` | — | Optimization level: `0`-`3`, `"s"`, `"z"` (derived from profile if omitted) |
| `debug` | profile-based | Emit debug symbols (`-g`): `true` in debug, `false` in release |
| `lto` | `false` | Link-time optimization (`-flto` for both compiler and linker) |
| `strip` | `false` | Strip symbols from output (`-s` in ldflags) |
| `warnings` | `["all", "extra"]` (debug) / `[]` (release) | Warning flags (e.g. `"all"`, `"extra"`, `"pedantic"`) |
| `warnings` | `[]` | Warning flags (e.g. `"all"`, `"extra"`, `"pedantic"`); engine adds `-Wall -Wextra` in debug if empty |
| `panic` | `""` | Panic strategy: `"abort"` disables exceptions and unwind tables |
| `codegen-units` | `""` | Max parallel compilation jobs (`"0"` = auto) |
| `qt` | `false` | Enable automatic Qt meta-object handling (MOC, UIC, RCC) |
@@ -96,6 +96,30 @@ Settings from raw config (not in typed struct):
- `ldscript` — linker script path
- `build.steps` / `build.post_steps` — codegen steps
## Per-language overrides: `[build.c]`, `[build.cxx]`, `[build.asm]`
Each language can have its own table that overrides the flat `[build]` settings:
```toml
[build]
compiler = "clang"
standard = "c11"
[build.c]
standard = "c23"
compiler = "gcc"
[build.cxx]
standard = "c++23"
compiler = "g++"
[build.asm]
compiler = "nasm"
flags = ["-felf64"]
```
The flat `[build]` acts as fallback; per-language tables take precedence for their language.
Example:
```toml

View File

@@ -41,24 +41,22 @@ DCR uses a package registry for dependency lookup by name.
```toml
# ~/.dcr/config.toml
[[registry]]
name = "default"
[registry.default]
url = "https://index.dcr.pm"
priority = 1
```
Registry priority: order in `config.toml`. The `DCR_INDEX_PATH` variable overrides the path to `index.json`.
## Git dependencies
DCR clones git repositories via `git2`:
Git dependencies are parsed and recorded in `dcr.lock`. DCR supports specifying branch/tag/rev for git sources:
- `branch` — switch to a branch
- `tag` — switch to a tag
- `rev` — switch to a specific commit
- `features` — feature flags (parsed, but does not affect build)
Cache path: `~/.dcr/git/<hash>/`.
## Path dependencies
Local paths. DCR automatically discovers include and lib directories from the neighbor's `dcr.toml`.

View File

@@ -65,3 +65,21 @@ standard = "c17"
# member inherits language and standard
```
## Workspace-only root (no build of its own)
A workspace root can set `workspace_only = true` — it won't be built itself, and doesn't need `language` or `compiler`:
```toml
[package]
name = "my-workspace"
version = "0.1.0"
[build]
workspace_only = true
kind = "bin"
[workspace]
lib-core = { path = "lib-core" }
app = { path = "app", deps = ["lib-core"] }
```