This commit is contained in:
2026-02-26 18:09:07 +08:00
parent 83061cc460
commit c22d2dbddc
31 changed files with 781 additions and 431 deletions

View File

@@ -1,2 +1,35 @@
# Introduction
DCR (Dexoron Cargo Realization) is a Cargo-style CLI for C/C++ projects.
Current DCR focuses on a simple, predictable workflow:
- create or initialize a project (`dcr new`, `dcr init`)
- build with `debug` or `release` profiles (`dcr build`)
- run binaries (`dcr run`)
- clean artifacts (`dcr clean`)
- update the installed binary (`dcr --update`)
## What is implemented in this version
- Project configuration in `dcr.toml` with `[package]`, `[build]`, `[dependencies]`.
- Recursive source discovery in `src/`:
- C: `*.c`
- C++: `*.cpp`, `*.cxx`, `*.cc`
- Compiler selection from `dcr.toml` (`clang`, `gcc`, `cl`, `clang-cl`, etc.).
- Two build kinds:
- `bin` (default)
- `staticlib`
- Optional custom output directory via `build.target`.
- Path dependencies with include/lib resolution and `dcr.lock` generation.
## Important behavior notes
- `dcr.toml` is required for `build`, `run`, and `clean`.
- `run` works only with `build.kind = "bin"`.
- Incremental rebuild currently tracks source file timestamps (not header dependency graphs).
- Object files are always created under `target/<profile>/obj/`.
## Repository
- <https://github.com/dexoron/dcr>

View File

@@ -20,7 +20,7 @@
## Commands
* [Global options](commands/global-options.md)
* [dcr init/new](commands/dcr-init-new.md)
* [dcr init/new](commands/dcr-init-or-new.md)
* [dcr build](commands/dcr-build.md)
* [dcr run](commands/dcr-run.md)
* [dcr clean](commands/dcr-clean.md)

View File

@@ -1,2 +1,42 @@
# dcr build
Builds the project in `debug` or `release` profile.
## Usage
```sh
dcr build
dcr build --debug
dcr build --release
```
## What `build` does
1. Checks that `dcr.toml` exists and is valid.
2. Reads build settings from `[build]`.
3. Resolves path dependencies from `[dependencies]`.
4. Creates required output directories.
5. Recursively compiles sources from `src/`.
6. Links final artifact (binary or static library).
## Config values used
- `package.name`
- `build.compiler`
- `build.language`
- `build.standard`
- `build.kind`
- `build.target`
- `build.cflags`
- `build.ldflags`
## Source selection
- `language = "c"` -> `*.c`
- `language = "c++" | "cpp" | "cxx"` -> `*.cpp`, `*.cxx`, `*.cc`
## Notes
- The profile is selected from the first argument only.
- Unknown profile flags return an error.
- Incremental rebuild is based on source/object mtime comparison.

View File

@@ -1,2 +1,23 @@
# dcr clean
Removes build artifacts in `target/`.
## Usage
```sh
dcr clean
dcr clean --debug
dcr clean --release
```
## Behavior
- Without arguments: removes entire `target/`.
- With profile: removes only `target/<profile>/`.
## Validation
- `dcr.toml` must exist.
- More than one argument is treated as error.
- Unknown profile is treated as error.
- If `target` or selected profile directory does not exist, command prints a warning.

View File

@@ -1,2 +0,0 @@
# dcr init/new

View File

@@ -0,0 +1,43 @@
# dcr init/new
## `dcr new <name>`
Creates a new project directory and initializes it.
```sh
dcr new hello
```
Behavior:
1. Validates arguments (`<name>` is required, only one name is allowed).
2. Creates `<name>/`.
3. Creates `<name>/dcr.toml`.
4. Sets `package.name = "<name>"`.
5. Creates `<name>/src/main.c` with a Hello World template.
Errors:
- Missing project name.
- Extra arguments.
- Target directory already exists.
## `dcr init`
Initializes DCR in the current directory.
```sh
dcr init
```
Behavior:
1. Requires current directory to be empty.
2. Creates `dcr.toml`.
3. Sets `package.name` from the current directory name.
4. Creates `src/main.c`.
Errors:
- Any arguments are treated as invalid.
- Non-empty directory is rejected.

View File

@@ -1,2 +1,27 @@
# dcr run
Builds the project and runs the resulting binary.
## Usage
```sh
dcr run
dcr run --debug
dcr run --release
```
## Behavior
1. Validates `dcr.toml`.
2. Reads `package.name`, `build.kind`, and optional `build.target`.
3. Runs the same build flow as `dcr build`.
4. Executes the built artifact path for the selected profile.
## Restrictions
- If `build.kind = "staticlib"`, `run` exits with error.
- The profile is selected from the first argument.
## On build failure
`dcr run` attempts to launch an existing binary from the same profile if present; otherwise it reports that code errors must be fixed.

View File

@@ -1,2 +1,44 @@
# Global options
## `dcr --help`
```sh
dcr --help
```
Prints top-level CLI usage, commands, flags, and examples.
## `dcr --version`
```sh
dcr --version
```
Prints:
```text
dcr <version> (<target>)
```
## `dcr --update`
```sh
dcr --update
```
Update flow:
1. Requests latest release from GitHub API.
2. Finds asset matching current `DCR_TARGET`.
3. Downloads replacement binary.
4. Replaces current executable via `self-replace`.
Limitations and behavior:
- No extra arguments are accepted.
- Requires network access to GitHub API/assets.
- On Linux, if binary is owned by pacman, DCR prints package-manager update instructions instead of self-updating.
## Running without command
Running plain `dcr` (without arguments) shows help output.

View File

@@ -1,2 +1,39 @@
# Build profiles
DCR supports two profiles:
- `debug` (default)
- `release`
## How to select
```sh
dcr build --debug
dcr build --release
dcr run --release
dcr clean --debug
```
## Default profile flags
### GCC/Clang-like toolchains
- `debug`: `-O0 -g -Wall -Wextra -fno-omit-frame-pointer -DDEBUG`
- `release`: `-O3 -DNDEBUG -march=native`
### MSVC toolchain
- `debug`: `/Od /Zi /W4 /DDEBUG /Oy-`
- `release`: `/O2 /DNDEBUG`
## Artifacts
By default:
- `target/debug/<name>` (or `.exe` on Windows)
- `target/release/<name>` (or `.exe` on Windows)
Static library mode (`kind = "staticlib"`):
- Linux/macOS: `lib<name>.a`
- Windows: `<name>.lib`

View File

@@ -1,2 +1,31 @@
# Build section
## Schema
```toml
[build]
language = "c"
standard = "c11"
compiler = "clang"
kind = "bin"
# optional:
# target = "./dist"
# cflags = ["-Wall"]
# ldflags = ["-lm"]
```
## Fields
- `language` (string, required): `c`, `c++`, `cpp`, or `cxx`.
- `standard` (string, required): language standard passed to compiler.
- `compiler` (string, required): compiler command (for example `clang`, `gcc`, `cl`).
- `kind` (string, required): `bin` or `staticlib`.
- `target` (string, optional): custom output directory for final artifact.
- `cflags` (string array, optional): extra compile flags.
- `ldflags` (string array, optional): extra link flags.
## Behavior notes
- Compiler backend is selected by compiler string (`gcc`, `clang`, `cl`, `clang-cl`).
- Empty or unknown compiler value falls back to clang-like build path.
- `run` is not allowed for `kind = "staticlib"`.

View File

@@ -1,2 +1,45 @@
# dcr.toml overview
`dcr.toml` is the main project file used by DCR.
## Minimal generated template
```toml
[package]
name = "hello"
version = "0.1.0"
[build]
language = "c"
standard = "c11"
compiler = "clang"
kind = "bin"
[dependencies]
```
`dcr new` and `dcr init` generate this structure automatically.
## Required sections
- `[package]`
- `[build]`
- `[dependencies]`
## Required keys
- `package.name`
- `package.version`
- `build.language`
- `build.standard`
- `build.compiler`
- `build.kind`
`build.kind` must be either `bin` or `staticlib`.
## Optional keys
- `build.target`
- `build.cflags`
- `build.ldflags`
- dependency fields (`include`, `lib`, `libs`, `system`)

View File

@@ -1,2 +1,30 @@
# Dependencies section
DCR currently supports path dependencies.
## Example
```toml
[dependencies]
frecli = { path = "./lib/frecli", include = ["."], lib = ["."], libs = ["frecli"] }
```
## Supported fields per dependency
- `path` (string, required): absolute path or path relative to project root.
- `include` (string array, optional): include directories inside dependency.
- `lib` (string array, optional): library directories inside dependency.
- `libs` (string array, optional): library names for linker.
- `system` (bool, optional): currently `system = true` is rejected.
## Defaults
- If `include` is omitted, DCR tries `<dep>/include`.
- If `lib` is omitted, DCR tries `<dep>/lib`, then `<dep>/lib64`.
- If `libs` is omitted, dependency key name is used.
## Validation
- Dependency value must be a TOML table.
- `path` is mandatory.
- `include`/`lib`/`libs` must be arrays of strings if provided.

View File

@@ -1,2 +1,20 @@
# Package section
## Schema
```toml
[package]
name = "my-app"
version = "0.1.0"
```
## Fields
- `name` (string, required): used as output artifact base name.
- `version` (string, required): used in `dcr.lock` project entry.
## Notes
- Empty `name` or `version` makes config invalid.
- `dcr new` sets `name` from the passed project name.
- `dcr init` sets `name` from current directory name.

View File

@@ -1,2 +1,30 @@
# Compilers & linking
## Compiler backend selection
DCR picks a backend from `build.compiler`:
- contains `clang-cl` -> MSVC backend
- contains `gcc` or `g++` -> GCC backend
- contains `clang` or `clang++` -> Clang backend
- equals `cl` or contains `msvc` -> MSVC backend
- otherwise -> Clang backend fallback
## Compilation model
- Source files are found recursively in `src/` based on `build.language`.
- Each source is compiled to `target/<profile>/obj/<relative-path>.o` (`.obj` on MSVC).
- Recompile happens when source mtime is newer than object mtime.
## Linking
For `kind = "bin"`:
- Object files are linked into executable artifact.
- Dependency lib dirs and library names are passed to linker.
- `build.ldflags` are appended to link command.
For `kind = "staticlib"`:
- Linux/macOS (GCC/Clang): `ar rcs` creates `.a` archive.
- Windows (MSVC): `lib` creates `.lib` archive.

View File

@@ -1,2 +1,26 @@
# Dependency format
Dependencies are defined in `dcr.toml` under `[dependencies]`.
## Full example
```toml
[dependencies]
fmt = { path = "./third_party/fmt", include = ["include"], lib = ["lib"], libs = ["fmt"] }
```
## Field reference
- `path`: required dependency root path.
- `include`: optional include subpaths (absolute or relative to dep root).
- `lib`: optional library subpaths (absolute or relative to dep root).
- `libs`: optional linker library names.
## Common valid compact form
```toml
[dependencies]
mylib = { path = "./libs/mylib" }
```
In this form DCR will try defaults for include/lib dirs and use `mylib` as the linker library name.

View File

@@ -1,2 +1,19 @@
# Local dependencies
## Resolution flow during build
For each dependency in `[dependencies]`, DCR:
1. Resolves `path` (absolute or project-relative).
2. Resolves include dirs (`include` or default `include`).
3. Resolves lib dirs (`lib` or defaults `lib`, `lib64`).
4. Resolves link libs (`libs` or dependency name).
5. Synchronizes dependency files to `target/<profile>/deps/<dep-name>/`.
6. Adds include/lib/link options to compile/link commands.
## Failure cases
- Dependency path is missing or not a directory.
- No valid include/lib directories were found.
- Any configured include/lib path does not exist.
- Invalid field types in dependency config.

View File

@@ -1,2 +1,23 @@
# Target directory
By default, DCR writes final artifacts to `target/<profile>/`.
You can override this with `build.target`:
```toml
[build]
target = "./dist"
```
## Behavior
- Binary mode:
- Linux/macOS: `<target>/<name>`
- Windows: `<target>/<name>.exe`
- Static library mode:
- Linux/macOS: `<target>/lib<name>.a`
- Windows: `<target>/<name>.lib`
## Important detail
`build.target` changes only the final artifact location. Object cache and dependency sync directories still use `target/<profile>/...`.

View File

@@ -1,2 +1,32 @@
# Versioning & lock file
DCR generates `dcr.lock` when dependency resolution succeeds and at least one dependency exists.
## What is stored
- Project entry (`name`, `version`, dependency names).
- One entry per resolved dependency:
- `name`
- `version` (from dependency `dcr.toml`, fallback `0.0.0`)
- `source` (`path+...`)
- `checksum` (SHA-256 over dependency files, excluding nested `target/`).
## Example shape
```toml
[[package]]
name = "my-app"
version = "0.1.0"
dependencies = ["fmt"]
[[package]]
name = "fmt"
version = "1.2.3"
source = "path+./third_party/fmt"
checksum = "..."
```
## Notes
- `dcr.lock` is rewritten on successful dependency resolution.
- If `[dependencies]` is empty, lock generation is skipped.

View File

@@ -1,2 +1,46 @@
# Build and run
## Build
Debug (default):
```sh
dcr build
# or
dcr build --debug
```
Release:
```sh
dcr build --release
```
## Run
```sh
dcr run
# or
dcr run --release
```
`dcr run` first builds, then launches the produced binary.
## Clean artifacts
```sh
dcr clean
```
Profile-only cleanup:
```sh
dcr clean --debug
dcr clean --release
```
## Notes
- `run` is unavailable for `build.kind = "staticlib"`.
- Build profile flag is parsed from the first command argument.
- Unknown profile flags produce an error.

View File

@@ -1,2 +1,41 @@
# Create your first project
## Create in a new folder
```sh
dcr new hello
cd hello
```
This creates:
```text
hello/
- dcr.toml
- src/
- - main.c
```
## Or initialize current folder
```sh
mkdir hello
cd hello
dcr init
```
`dcr init` requires the current directory to be empty.
## Next steps
Build and run:
```sh
dcr run
```
Release build/run:
```sh
dcr run --release
```

View File

@@ -1,2 +1,56 @@
# Installation
## Option 1: Install via script
### Linux/macOS
```sh
curl -fsSL https://dcr.dexoron.su/install.sh | bash
```
Alternative with `wget`:
```sh
wget -qO- https://dcr.dexoron.su/install.sh | bash
```
### Windows (PowerShell)
```powershell
powershell -ExecutionPolicy ByPass -c "irm https://dcr.dexoron.su/install.ps1 | iex"
```
## Option 2: Build from source
```sh
git clone https://github.com/dexoron/dcr.git
cd dcr
cargo build --release
mkdir -p ~/.local/bin
ln -sf "$PWD/target/release/dcr" ~/.local/bin/dcr
```
## Option 3: Arch Linux (AUR)
```sh
yay -S dcr
```
(You can also use `paru` or other AUR helpers.)
## Verify installation
```sh
dcr --version
```
Expected format:
```text
dcr <version> (<target>)
```
## Update policy
- If DCR was installed from GitHub releases, scripts, or manual build: use `dcr --update`.
- If DCR is managed by `pacman/AUR`: update via package manager. On Linux, `dcr --update` detects pacman-owned binaries and prints a package-manager hint.

View File

@@ -1,2 +1,39 @@
# Project structure
## Minimal project
```text
project/
- dcr.toml
- src/
- - main.c
```
## Typical generated/optional files
```text
project/
- dcr.toml
- dcr.lock
- src/
- - ... source files ...
- target/
- - debug/
- - - obj/
- - - deps/
- - release/
- - - obj/
- - - deps/
```
## Meaning
- `dcr.toml`: main project configuration.
- `dcr.lock`: generated lock file for resolved path dependencies.
- `src/`: recursively scanned source directory.
- `target/<profile>/obj/`: cached object files for incremental rebuild.
- `target/<profile>/deps/`: synchronized copies of path dependencies.
- `target/<profile>/<name>` (or `.exe` on Windows): output for `kind = "bin"`.
- `target/<profile>/lib<name>.a` (or `<name>.lib` on Windows): output for `kind = "staticlib"`.
If `build.target` is set, the final artifact is written to that custom directory, while object cache still stays in `target/<profile>/obj`.

View File

@@ -1,2 +1,26 @@
# CLI reference
## Command list
```text
dcr new <name>
dcr init
dcr build [--debug|--release]
dcr run [--debug|--release]
dcr clean [--debug|--release]
dcr --help
dcr --version
dcr --update
```
## Notes on argument parsing
- Most commands parse profile from the first argument.
- `new` requires exactly one argument.
- `init` and `--update` do not accept extra arguments.
- `clean` accepts at most one argument.
## Exit behavior overview
- Successful command execution returns `0`.
- Validation/build/runtime errors return non-zero status.

View File

@@ -1,2 +1,41 @@
# Config reference
## Full schema
```toml
[package]
name = "string" # required
version = "string" # required
[build]
language = "c|c++|cpp|cxx" # required
standard = "string" # required
compiler = "string" # required
kind = "bin|staticlib" # required
target = "string" # optional
cflags = ["string", "..."] # optional
ldflags = ["string", "..."] # optional
[dependencies]
name = {
path = "string", # required for each dependency
include = ["string", "..."], # optional
lib = ["string", "..."], # optional
libs = ["string", "..."], # optional
}
```
## Validation rules
- `[package]`, `[build]`, `[dependencies]` must exist.
- Required string fields must be non-empty.
- `build.kind` must be `bin` or `staticlib`.
- Dependency fields `include/lib/libs` must be string arrays when provided.
## Generated defaults (`dcr new` / `dcr init`)
- `package.version = "0.1.0"`
- `build.language = "c"`
- `build.standard = "c11"`
- `build.compiler = "clang"`
- `build.kind = "bin"`

View File

@@ -1,2 +1,34 @@
# Contributing & Bug reports
## Contribution workflow
1. Fork `dexoron/dcr` (and `dexoron/dcr-site` if docs website changes are needed).
2. Make focused changes.
3. Run checks locally:
```bash
cargo fmt --all
cargo clippy --all-targets --all-features -- -D warnings
cargo check
```
4. Open a PR with short rationale and behavior impact.
5. Update docs when CLI behavior changes.
## Bug report checklist
Include:
1. DCR version (`dcr --version`).
2. OS and compiler/toolchain version.
3. Reproduction steps.
4. Expected result.
5. Actual result and full error output.
6. Minimal reproducible project.
## Where to report
Use GitHub Issues in the relevant repository:
- <https://github.com/dexoron/dcr>
- <https://github.com/dexoron/dcr-site>

View File

@@ -1,2 +1,34 @@
# FAQ
## What commands are available?
`new`, `init`, `build`, `run`, `clean`, `--help`, `--version`, `--update`.
## Is `dcr.toml` mandatory?
Yes, for `build`, `run`, and `clean`.
## What source files are compiled?
DCR scans `src/` recursively:
- for C: `*.c`
- for C++: `*.cpp`, `*.cxx`, `*.cc`
## Can I switch compiler?
Yes. Set `build.compiler` in `dcr.toml` (for example `gcc`, `clang`, `cl`, `clang-cl`).
## How does incremental rebuild work?
It compares source file mtime with object file mtime. Header dependency tracking is not implemented yet.
## What does `dcr run` do if build fails?
It tries to run an existing binary from the selected profile; if none exists, it reports an error.
## How do I update DCR?
Use `dcr --update` for non-package-managed installs.
If installed through pacman/AUR, update via package manager.