105 Commits

Author SHA1 Message Date
b0e426c189 Merge pull request #32 from dexoron/dev
feat: add package.dcr-version pin with load-time compatibility warnings
2026-08-08 15:00:02 +08:00
60d7420929 feat: add package.dcr-version pin with load-time compatibility warnings 2026-08-08 14:33:46 +08:00
3bd91e85f9 Merge pull request #31 from dexoron/dev
v0.8.4
2026-08-05 21:22:20 +08:00
a20c61cc88 docs: add and clean up AI-generated rustdoc comments (grok-4.5) 2026-08-05 19:21:00 +08:00
bc308d6996 fix: make cross-target tests and vscode launch path robust for macOS + Windows 2026-08-05 02:21:29 +08:00
09e7f5b880 fix(test): align vscode launch path assertion with native host layout 2026-08-05 01:04:43 +08:00
3f925f437f fix: keep native host artifact paths and cross-platform path assertions 2026-08-05 01:00:26 +08:00
b9cbef43e9 feat: add .dcr/ build facts and canonical artifact paths for IDE integrations 2026-08-05 00:38:00 +08:00
9bf1346d1b Merge pull request #30 from dexoron/dev
v0.8.3
2026-08-03 21:32:18 +08:00
794d571d58 fix: distinguish implicit host builds from explicit targets 2026-08-03 21:26:34 +08:00
d2df85a064 fix: preserve native artifact paths on Windows and macOS 2026-08-03 21:16:11 +08:00
5e8037da97 feat: host-target config resolution and cargo-style run args 2026-08-03 00:40:51 +08:00
f29322a547 Merge pull request #29 from dexoron/dev
v0.8.2
2026-07-24 19:15:55 +08:00
1a6a261cac fix(ci): fix tests 2026-07-23 21:35:59 +08:00
f92cc6ae91 fix(ci): fix tests 2026-07-23 19:59:37 +08:00
5aefbc6498 fix(ci): fix tests 2026-07-23 19:53:48 +08:00
594007f022 fix(ci): fix tests 2026-07-23 19:45:31 +08:00
d10ec84004 fix(ci): fix tests 2026-07-23 19:30:39 +08:00
574ba8b6d0 fix(ci): fix tests 2026-07-23 16:11:39 +08:00
75eace9d73 feat: add dcrup (sh/ps1/cmd) and fix cross-platform unit tests 2026-07-23 14:59:28 +08:00
2446cb7970 feat(docs): remove DPM in install steps 2026-07-23 14:03:08 +08:00
588e4dd13f feat(build): archive feature, progress UI, and workspace path fixes 2026-07-23 14:00:00 +08:00
689fea7465 Merge pull request #28 from dexoron/dev
v0.8.1
2026-07-21 18:12:56 +08:00
a9dd8c1631 feat(build): add flat-bin kind and FAT [archive] packing for OS-dev 2026-07-21 17:45:02 +08:00
9d030cba0c fix(build): skip linking/archiving for custom and none project kinds 2026-07-18 20:21:41 +08:00
1dcc8e614a Merge pull request #25 from dexoron/dev
v0.8.0
2026-07-18 20:05:12 +08:00
9eaa4635d5 refactor: modularize build core engine, update workspaces, cache, and test suite 2026-07-18 20:02:12 +08:00
a3f8444c20 Replace GitLab pipeline trigger with Cloudflare build 2026-07-05 18:24:47 +08:00
1f3fc62cb6 Add GitHub Actions workflow to trigger site rebuild 2026-07-05 18:16:45 +08:00
f8d8c95912 Rename сrowdin.yml to crowdin.yml (latin) 2026-07-05 17:26:00 +08:00
9e07f70c78 fix crowdin file name 2026-07-05 17:24:14 +08:00
0376eded3f add Crowdin 2026-07-05 17:21:33 +08:00
803d5891ce Merge pull request #21 from dexoron/dev
v0.7.4
2026-06-19 17:50:59 +08:00
9326e23a53 feat: add native Qt support and dcr lint command; refactor architecture and integration tests 2026-06-17 12:39:22 +08:00
21932ac94a feat(build): add freestanding, lto, strip, panic-abort, and codegen-units support in dcr.toml 2026-06-16 16:42:56 +08:00
97db82e4f8 Merge pull request #20 from dexoron/dev
v0.7.3
2026-06-15 22:36:12 +08:00
3d596d7280 Update install docs 2026-06-15 22:35:38 +08:00
5cb4473bd1 Update README.md 2026-06-15 22:35:06 +08:00
33f955d4e3 refactor(updater): migrate from reqwest to ureq for lightweight builds 2026-06-13 16:15:24 +08:00
838be72dd2 refactor(deps): replace git2 with system git and add vcs support 2026-06-13 15:28:14 +08:00
39fad31c4f Merge pull request #18 from dexoron/master
v0.7.2
2026-06-07 22:31:43 +08:00
c8ef38a99b release: bump version to 0.7.2 and update changelog 2026-06-07 21:41:02 +08:00
8e0c535cfd fix: improve default target triple generation for various OS environments 2026-06-07 21:29:55 +08:00
de88c160ad Merge pull request #16 from XiaoPengYouCode/codex/fix-macos-host-target-link 2026-06-07 21:21:53 +08:00
4daca925a0 Merge pull request #17 from dexoron/master
master -> dev
2026-06-07 21:17:14 +08:00
595b7ac105 Merge pull request #15 from XiaoPengYouCode/codex/fix-readme-badges 2026-06-07 21:13:10 +08:00
XiaoPengYouCode
11ae3762d0 fix: use host macOS target for default builds 2026-06-07 05:41:07 +08:00
XiaoPengYouCode
4c439317e3 docs: fix README badge rendering 2026-06-07 05:09:38 +08:00
0aa3f87f99 feat: temporarily disable Snap Store publishing and update README instructions 2026-06-06 22:18:03 +08:00
a6ce0a3332 feat: enhance release notes extraction and include release name in GitHub release 2026-06-06 21:41:50 +08:00
cea43e99c8 feat: add Windows target dependencies and update README for MinGW 2026-06-06 21:39:17 +08:00
de4fb0bc29 feat: add .SRCINFO for AUR package metadata 2026-06-06 21:33:34 +08:00
59e27b6f5d Merge pull request #14 from dexoron/dev
v0.7.1 The Multi-Arch Expansion
2026-06-06 21:28:24 +08:00
c8cb155e5a feat: update help flag 2026-06-06 21:22:46 +08:00
6424aab69d feet: add license to docs and updated Cargo.toml to add build with no features flag 2026-06-06 21:19:04 +08:00
peoplemiau1
dabeb411d3 docs: update changelog for 0.7.1 (bilingual & multi-arch) 2026-06-02 16:22:57 +03:00
peoplemiau1
b8338c752b chore: remove i686-pc-windows-gnu from build matrix 2026-06-02 16:00:08 +03:00
b70438b16d feat: update README 2026-06-02 19:38:16 +08:00
0597b5ddb2 feat: add --help for all commands, man pages 2026-06-02 19:27:44 +08:00
peoplemiau1
8866fb0796 Bump version to 0.7.1 2026-06-02 13:55:54 +03:00
peoplemiau1
7d853482aa feat: build deb and rpm packages for all linux architectures 2026-06-02 13:50:57 +03:00
peoplemiau1
ef9ca57295 Add multi-arch support to release workflows and installation scripts 2026-06-02 13:38:42 +03:00
peoplemiau1
8e1fb60692 Add Linux i686, armv7, and riscv64 architectures support to release workflow and installation script 2026-06-02 13:25:38 +03:00
peoplemiau1
d6ddb5da3d Merge origin/master into dev and resolve conflicts in release.yml 2026-06-02 13:06:15 +03:00
peoplemiau1
d26e93dd47 Optimize release binary size and parse_d_file dependency parsing 2026-06-02 12:58:06 +03:00
97d2970727 feat: add dcr-dev and dcr-dev-bin publishing to AUR 2026-06-02 17:34:17 +08:00
kie
35f9b6be94 Update README.md 2026-06-02 11:27:09 +03:00
6885a82be7 feat: add package name validation to init and new commands 2026-06-02 16:26:11 +08:00
5d587db227 fix: update AUR publishing process to handle git initialization and improve build flags 2026-06-02 16:08:58 +08:00
424f4f6929 feat: add support for publishing Snap packages with dynamic file resolution 2026-06-02 16:08:58 +08:00
443306aa5f fix: update AUR publishing process to handle git initialization and improve build flags 2026-06-02 15:17:20 +08:00
f21f50facb feat: add support for publishing Snap packages with dynamic file resolution 2026-06-02 01:27:04 +08:00
23c4f4ca87 Merge pull request #11 from dexoron/dev
Release v0.7.0
2026-06-02 01:10:33 +08:00
c42575e360 docs: rewrite documentation.
add: Nix and Snapcraft support.
2026-06-02 01:04:16 +08:00
c756d94f96 Merge pull request #10 and #8
build(nix): configure flake for dcr project
Update user input prompts to read from /dev/tty 
Create FUNDING.yml
2026-06-01 20:29:07 +08:00
Alexandr_Croitor
8e21432764 chore: remove unused dev shell tools 2026-06-01 13:23:12 +03:00
Alexandr_Croitor
772d50811f build(nix): configure flake for dcr project
- Set package name/version from Cargo.toml (dcr 0.6.9)
- Add cmake and perl for vendored libgit2/openssl builds
- Switch to stable toolchain (complete was overkill)
- Generate flake.lock
2026-05-31 22:37:57 +03:00
ea1546b13a Create FUNDING.yml 2026-06-01 02:49:06 +08:00
f5d5795872 docsL fix URL 2026-05-30 17:15:55 +08:00
e6788b4d71 fix: add missing .cxx/.cc/.hxx/.hh extensions to fmt; update docs for 0.7.0 2026-05-30 15:32:16 +08:00
865d8c52ff fix: split target into target (triple) and out_dir (output directory)
build.target now holds the target triple (e.g. x86_64-unknown-linux-gnu)
build.out_dir is a custom output directory that overrides the default
target/<triple>/<profile> path.
2026-05-30 14:18:54 +08:00
94aa6c0f01 Merge pull request #8 from babichgh/master
Update user input prompts to read from /dev/tty
2026-05-30 13:28:40 +08:00
John Babich
e462de6272 Update user input prompts to read from /dev/tty
Redirect input for user prompts to /dev/tty for better compatibility.
2026-05-29 23:58:03 +03:00
peoplemiau1
0587965283 Make standard optional, allow empty src_disable, and add none/custom kinds 2026-05-29 18:57:45 +03:00
peoplemiau1
478d1ad0c5 Remove DragonFly BSD support 2026-05-29 09:57:07 +03:00
peoplemiau1
060b92111f Fix dcr run to inherit stdout/stderr properly 2026-05-29 09:54:13 +03:00
peoplemiau1
86f0566dc2 Trigger release 2026-05-29 09:21:03 +03:00
peoplemiau1
768e2fc0dc Fix release creation race condition by adding a dedicated create-release job 2026-05-29 09:18:27 +03:00
peoplemiau1
619493bcbd Fix install.sh: support Linux ARM64 and BSD systems, add robust JSON parser checks 2026-05-29 09:13:37 +03:00
peoplemiau1
1dac8661b6 Implement incremental linking and add DragonFly BSD VM build 2026-05-29 09:09:03 +03:00
peoplemiau1
80a6d574a3 Rewrite install_bsd.sh for POSIX sh compliance 2026-05-29 08:27:23 +03:00
peoplemiau1
daf465368f Add BSD install script and update compatibility table in README 2026-05-29 07:51:10 +03:00
peoplemiau1
800fe38fba Fix GHA release: resolve stable toolchain override and sanitize Arch Linux package version 2026-05-28 23:20:48 +03:00
peoplemiau1
a7f9b79b93 Fix release CI/CD: make git2 target-specific, install zig for cross-compilation, set version to 0.7.0 2026-05-28 23:15:09 +03:00
peoplemiau1
b03660a9d7 Bump version to 0.7.0-dev and update changelog for pre-release 2026-05-28 23:01:15 +03:00
peoplemiau1
2cb02aa102 Add full FreeBSD, OpenBSD, NetBSD, and DragonflyBSD target support 2026-05-28 22:55:53 +03:00
peoplemiau1
06a8458ca7 feat: add fmt command 2026-05-28 22:55:26 +03:00
c2ef5483a0 update: update dexoron packages 2026-05-28 21:11:49 +08:00
eb24d616c5 fix: Fix GPG permissions after Docker 2026-05-28 18:16:18 +08:00
4f76f54b63 fix: update GPG signing process to resolve permission issues and clarify Release generation 2026-05-28 18:11:34 +08:00
37b9b855ec feat: streamline artifact download process and enhance repository indexing with signing 2026-05-28 18:08:06 +08:00
8f0f67ad62 fix: correct paths for RPM package artifacts and update repository indexing 2026-05-28 17:49:29 +08:00
49945aa65d feat: add --clobber flag to Download Packages from Release Assets 2026-05-28 17:44:51 +08:00
83593aa592 feat: enhance Dexoron Packages Index workflow with manual dispatch and improved artifact handling 2026-05-28 17:41:50 +08:00
2835188da9 feat: update Dexoron Packages Index workflow and improve release process for NetBSD 2026-05-28 17:09:36 +08:00
184 changed files with 16455 additions and 7134 deletions

15
.github/FUNDING.yml vendored Normal file
View File

@@ -0,0 +1,15 @@
# These are supported funding model platforms
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
polar: # Replace with a single Polar username
buy_me_a_coffee: # Replace with a single Buy Me a Coffee username
thanks_dev: # Replace with a single thanks.dev username
custom: 'https://dalink.to/dexoron'

View File

@@ -5,10 +5,18 @@ on:
branches:
- master
- main
- dev
pull_request:
env:
CARGO_TERM_COLOR: always
RUSTFLAGS: -Dwarnings
CARGO_INCREMENTAL: "0"
SCCACHE_GHA_ENABLED: "true"
jobs:
checks:
name: fmt / clippy / check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
@@ -18,11 +26,129 @@ jobs:
with:
components: rustfmt, clippy
- name: sccache
uses: mozilla-actions/sccache-action@v0.0.9
- uses: Swatinem/rust-cache@v2
with:
shared-key: dcr-ci
cache-all-crates: true
- name: Format
run: cargo fmt --all --check
- name: Lint
- name: Clippy (default features)
run: cargo clippy --all-targets -- -D warnings
- name: Clippy (all features)
run: cargo clippy --all-targets --all-features -- -D warnings
- name: Check
- name: Check (all features)
run: cargo check --all-targets --all-features
test:
name: tests (${{ matrix.os }})
needs: checks
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
- name: sccache
uses: mozilla-actions/sccache-action@v0.0.9
- uses: Swatinem/rust-cache@v2
with:
shared-key: dcr-ci
cache-all-crates: true
cache-on-failure: true
- name: Cache apt packages
if: runner.os == 'Linux'
uses: actions/cache@v4
with:
path: /var/cache/apt/archives
key: apt-${{ runner.os }}-${{ hashFiles('.github/workflows/ci.yml') }}
restore-keys: apt-${{ runner.os }}-
- name: Install Linux tools
if: runner.os == 'Linux'
run: |
sudo apt-get update
sudo apt-get install -y \
build-essential \
clang \
nasm \
clang-format \
clang-tidy \
git \
llvm
- name: Install macOS tools
if: runner.os == 'macOS'
run: |
brew install nasm llvm || true
echo "$(brew --prefix llvm)/bin" >> "$GITHUB_PATH"
- name: Install Windows tools
if: runner.os == 'Windows'
shell: pwsh
run: |
choco install nasm llvm -y
echo "C:\Program Files\NASM" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
if (Test-Path "C:\Program Files\LLVM\bin") {
echo "C:\Program Files\LLVM\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
}
- name: Unit tests (binary crate)
run: cargo test --bins -- --nocapture
- name: Integration tests (default features)
run: cargo test --tests -- --nocapture
- name: Integration tests (archive feature)
if: runner.os != 'Windows'
run: cargo test --tests --features archive -- --nocapture
- name: sccache stats
if: always()
run: sccache --show-stats || true
test-archive-linux:
name: archive feature smoke
needs: checks
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
- name: sccache
uses: mozilla-actions/sccache-action@v0.0.9
- uses: Swatinem/rust-cache@v2
with:
shared-key: dcr-ci
cache-all-crates: true
- name: Install tools
run: |
sudo apt-get update
sudo apt-get install -y build-essential clang nasm llvm
- name: Build with archive
run: cargo build --features archive
- name: Flat-bin + unit suite with archive
run: cargo test --features archive --test cli_build --test cli_workspace --test cli_errors -- --nocapture
- name: sccache stats
if: always()
run: sccache --show-stats || true

View File

@@ -2,6 +2,11 @@ name: Dexoron Packages Index
on:
workflow_dispatch:
inputs:
tag:
description: "Версия (тег) для ручного импорта пакетов (например, v0.6.9)"
required: true
type: string
workflow_run:
workflows: ["Release"]
types:
@@ -13,7 +18,7 @@ permissions:
jobs:
update-packages-index:
runs-on: ubuntu-latest
if: ${{ github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success' }}
if: ${{ github.event_name == 'workflow_dispatch' || github.event_workflow_run.conclusion == 'success' }}
steps:
- name: Checkout Central Packages Repo
@@ -23,105 +28,82 @@ jobs:
token: ${{ secrets.PACKAGES_REPO_TOKEN }}
path: 'central-packages'
# --- СКАЧИВАНИЕ АРТЕФАКТОВ ИЗ РЕЛИЗА ---
- name: Import GPG Key
uses: crazy-max/ghaction-import-gpg@v6
with:
gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
- name: Download Arch package artifact
# --- Загрузка артефактов (сохранена прежняя логика) ---
- name: Download Artifacts
if: ${{ github.event_name == 'workflow_run' }}
uses: actions/download-artifact@v4
with:
name: arch-package
path: central-packages/archlinux/x86_64/
github-token: ${{ secrets.PACKAGES_REPO_TOKEN }}
path: central-packages/
github-token: ${{ secrets.GITHUB_TOKEN }}
run-id: ${{ github.event.workflow_run.id }}
continue-on-error: true
- name: Download Debian package artifact
if: ${{ github.event_name == 'workflow_run' }}
uses: actions/download-artifact@v4
with:
name: debian-package
path: central-packages/debian/
github-token: ${{ secrets.PACKAGES_REPO_TOKEN }}
run-id: ${{ github.event.workflow_run.id }}
continue-on-error: true
- name: Download Packages from Release Assets
if: ${{ github.event_name == 'workflow_dispatch' }}
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAG: ${{ inputs.tag }}
run: |
gh release download "$TAG" --repo dexoron/dcr --pattern "*.pkg.tar.zst" --dir central-packages/archlinux/x86_64/ --clobber
gh release download "$TAG" --repo dexoron/dcr --pattern "*.deb" --dir central-packages/debian/ --clobber
gh release download "$TAG" --repo dexoron/dcr --pattern "*.rpm" --dir central-packages/fedora/x86_64/ --clobber
- name: Download RPM package artifact
if: ${{ github.event_name == 'workflow_run' }}
uses: actions/download-artifact@v4
with:
name: rpm-package
path: central-packages/rpm/x86_64/
github-token: ${{ secrets.PACKAGES_REPO_TOKEN }}
run-id: ${{ github.event.workflow_run.id }}
continue-on-error: true
# --- ИНДЕКСАЦИЯ И ПОДПИСЬ ---
# --- ИНДЕКСАЦИЯ REPO ---
- name: Update Pacman Database (Inside Arch Container)
- name: Update Pacman Database
run: |
docker run --rm \
-v ${{ github.workspace }}/central-packages:/packages \
-v ~/.gnupg:/root/.gnupg \
archlinux:latest \
bash -c '
cd /packages/archlinux/x86_64 && \
rm -f dexoron.db dexoron.files && \
shopt -s nullglob
packages=(*.pkg.tar.zst)
if [ ${#packages[@]} -gt 0 ]; then
echo "Found ${#packages[@]} Arch packages. Updating database..."
repo-add dexoron.db.tar.gz "${packages[@]}" && \
ln -sf dexoron.db.tar.gz dexoron.db && \
ln -sf dexoron.files.tar.gz dexoron.files
else
echo "No .pkg.tar.zst files found. Skipping."
fi
packages=(*.pkg.tar.zst) && \
repo-add --sign dexoron.db.tar.gz "${packages[@]}" && \
ln -sf dexoron.db.tar.gz dexoron.db && \
ln -sf dexoron.files.tar.gz dexoron.files
'
- name: Fix GPG permissions after Docker
run: sudo chown -R runner:runner ~/.gnupg
- name: Update Debian APT Repository Index
run: |
sudo apt-get update && sudo apt-get install -y dpkg-dev
cd central-packages/debian
dpkg-scanpackages . /dev/null | gzip -9c > Packages.gz
shopt -s nullglob
deb_packages=(*.deb)
echo "Origin: Dexoron Packages" > Release
echo "Label: Dexoron Packages" >> Release
echo "Suite: stable" >> Release
echo "Codename: stable" >> Release
echo "Architectures: amd64" >> Release
echo "Components: main" >> Release
echo "Description: Dexoron binary package repository" >> Release
echo "Date: $(date -uR)" >> Release
echo "SHA256:" >> Release
echo " $(sha256sum Packages.gz | awk '{print $1" "$2}')" >> Release
if [ ${#deb_packages[@]} -gt 0 ]; then
echo "Found ${#deb_packages[@]} Debian packages. Generating Packages.gz..."
# Генерируем индекс для плоского (flat) репозитория
dpkg-scanpackages . /dev/null | gzip -9c > Packages.gz
else
echo "No .deb files found. Skipping Debian index update."
fi
gpg --batch --yes --pinentry-mode loopback --local-user 74322D39483E9C9E8C86C0AA0770A5C2A2A82DAC --detach-sign --armor --output Release.gpg Release
gpg --batch --yes --pinentry-mode loopback --local-user 74322D39483E9C9E8C86C0AA0770A5C2A2A82DAC --clearsign --output InRelease Release
- name: Update Fedora DNF Repository Index
run: |
sudo apt-get update && sudo apt-get install -y createrepo-c
cd central-packages/rpm/x86_64
shopt -s nullglob
rpm_packages=(*.rpm)
if [ ${#rpm_packages[@]} -gt 0 ]; then
echo "Found ${#rpm_packages[@]} RPM packages. Generating repodata..."
# Пересоздаем метаданные для dnf
createrepo_c .
else
echo "No .rpm files found. Skipping Fedora index update."
fi
# --- ПУШ ИЗМЕНЕНИЙ ---
cd central-packages/fedora/x86_64
createrepo_c .
gpg --batch --yes --detach-sign --armor --output repodata/repomd.xml.asc repodata/repomd.xml
- name: Push to dexoron/packages
run: |
cd central-packages
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
# Проверяем изменения во всех трех целевых папках
if [ -n "$(git status --porcelain)" ]; then
git add archlinux/ debian/ rpm/
git commit -m "chore: update repositories index (arch, debian, rpm)"
git add .
if ! git diff --cached --quiet; then
git commit -m "chore: update and sign repositories"
git push
else
echo "No changes detected in repository databases."
fi

View File

@@ -21,6 +21,10 @@ on:
description: "Update AUR packages (dcr & dcr-bin)"
type: boolean
default: false
run_aur_dev:
description: "Update Dev AUR packages (dcr-dev, dcr-dev-bin)"
type: boolean
default: false
run_bsd:
description: "Build BSD"
type: boolean
@@ -52,6 +56,7 @@ jobs:
outputs:
tag: ${{ steps.tag.outputs.value }}
version: ${{ steps.tag.outputs.version }}
clean_version: ${{ steps.tag.outputs.clean_version }}
prerelease: ${{ steps.tag.outputs.prerelease }}
steps:
- name: Resolve tag
@@ -63,33 +68,53 @@ jobs:
TAG="${GITHUB_REF_NAME}"
fi
VERSION="${TAG#v}"
CLEAN_VERSION="${VERSION%-dev}"
[[ "$TAG" == *"-"* ]] && PRERELEASE="true" || PRERELEASE="false"
echo "value=${TAG}" >> "$GITHUB_OUTPUT"
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
echo "clean_version=${CLEAN_VERSION}" >> "$GITHUB_OUTPUT"
echo "prerelease=${PRERELEASE}" >> "$GITHUB_OUTPUT"
# ── Release Notes ──────────────────────────────────────────────────────────
notes:
needs: setup
runs-on: ubuntu-latest
outputs:
release_name: ${{ steps.extract.outputs.release_name }}
steps:
- uses: actions/checkout@v4
with:
ref: ${{ needs.setup.outputs.tag }}
- name: Prepare Release Notes
id: extract
shell: bash
run: |
set -euo pipefail
tag="${{ needs.setup.outputs.version }}"
notes_file=".github/release-notes.md"
if grep -q "^## \\[${tag}\\]" CHANGELOG.md; then
awk -v ver="$tag" '
# Strip -dev suffix to match base version in CHANGELOG
changelog_tag="${tag%-dev}"
if grep -q "^## \\[${changelog_tag}\\]" CHANGELOG.md; then
# Extract release name from header: ## [0.7.1] - 2026-06-02 "Title"
release_name=$(awk -v search_ver="$changelog_tag" -v display_ver="$tag" '
$0 ~ "^## \\[" search_ver "\\]" {
match($0, /"([^"]+)"/, arr)
if (arr[1] != "") {
print "v" display_ver " - " arr[1]
} else {
print "v" display_ver
}
}
' CHANGELOG.md)
echo "release_name=${release_name}" >> "$GITHUB_OUTPUT"
awk -v ver="$changelog_tag" '
$0 ~ "^## \\[" ver "\\]" {found=1; next}
found && $0 ~ "^## \\[" {exit}
found {print}
' CHANGELOG.md | sed -e '${/^$/d;}' > "$notes_file"
else
echo "release_name=v${tag}" >> "$GITHUB_OUTPUT"
echo "No CHANGELOG section for $tag." > "$notes_file"
git log -1 --pretty=format:"%s%n%n%b" >> "$notes_file"
fi
@@ -100,10 +125,59 @@ jobs:
name: release-notes
path: .github/release-notes.md
# ── Create Release (prevent race conditions) ───────────────────────────────
create-release:
needs: [setup, notes]
runs-on: ubuntu-latest
steps:
- name: Download Release Notes
uses: actions/download-artifact@v4
with:
name: release-notes
path: .github
- name: Create Release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ needs.setup.outputs.tag }}
name: ${{ needs.notes.outputs.release_name }}
body_path: .github/release-notes.md
prerelease: ${{ needs.setup.outputs.prerelease == 'true' }}
# ── Man Pages Archive ──────────────────────────────────────────────────────
man-pages:
if: ${{ github.event_name == 'push' || github.event.inputs.run_linux == 'true' }}
needs: [setup, notes, create-release]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: ${{ needs.setup.outputs.tag }}
- name: Download Release Notes
uses: actions/download-artifact@v4
with:
name: release-notes
path: .github
- name: Create Man Pages Archive
run: |
tar czf "dcr-man-pages-${{ needs.setup.outputs.version }}.tar.gz" \
--transform 's/^man\/man1\//usr\/share\/man\/man1\//' \
man/man1/*.1
- name: Upload Man Pages to Release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ needs.setup.outputs.tag }}
files: dcr-man-pages-${{ needs.setup.outputs.version }}.tar.gz
body_path: .github/release-notes.md
prerelease: ${{ needs.setup.outputs.prerelease == 'true' }}
# ── Linux Binaries Matrix ──────────────────────────────────────────────────
build-linux:
if: ${{ github.event_name == 'push' || github.event.inputs.run_linux == 'true' }}
needs: [setup, notes]
needs: [setup, notes, create-release]
runs-on: ubuntu-latest
strategy:
fail-fast: false
@@ -113,6 +187,12 @@ jobs:
- target: aarch64-unknown-linux-gnu
- target: x86_64-unknown-linux-musl
- target: aarch64-unknown-linux-musl
- target: i686-unknown-linux-gnu
- target: i686-unknown-linux-musl
- target: armv7-unknown-linux-gnueabihf
- target: armv7-unknown-linux-musleabihf
- target: riscv64gc-unknown-linux-gnu
- target: riscv64gc-unknown-linux-musl
steps:
- uses: actions/checkout@v4
with:
@@ -129,6 +209,12 @@ jobs:
pip install cargo-zigbuild
echo "$HOME/.local/bin" >> $GITHUB_PATH
- name: Setup Zig
if: matrix.target != 'x86_64-unknown-linux-gnu'
uses: mlugg/setup-zig@v1
with:
version: 0.13.0
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
with:
@@ -137,9 +223,9 @@ jobs:
- name: Build
run: |
if [ "${{ matrix.target }}" != "x86_64-unknown-linux-gnu" ]; then
cargo zigbuild --release --target ${{ matrix.target }}
cargo zigbuild --release --features archive --target ${{ matrix.target }}
else
cargo build --release --target ${{ matrix.target }}
cargo build --release --features archive --target ${{ matrix.target }}
fi
- name: Prepare Artifact
@@ -164,49 +250,82 @@ jobs:
strategy:
fail-fast: false
matrix:
include:
- package_type: deb
artifact_name: debian-package
- package_type: rpm
artifact_name: rpm-package
package_type: [deb, rpm, arch, snap]
target: [x86_64-unknown-linux-gnu, aarch64-unknown-linux-gnu, i686-unknown-linux-gnu, armv7-unknown-linux-gnueabihf, riscv64gc-unknown-linux-gnu]
exclude:
- package_type: arch
artifact_name: arch-package
target: aarch64-unknown-linux-gnu
- package_type: arch
target: i686-unknown-linux-gnu
- package_type: arch
target: armv7-unknown-linux-gnueabihf
- package_type: arch
target: riscv64gc-unknown-linux-gnu
- package_type: snap
artifact_name: snap-package
target: aarch64-unknown-linux-gnu
- package_type: snap
target: i686-unknown-linux-gnu
- package_type: snap
target: armv7-unknown-linux-gnueabihf
- package_type: snap
target: riscv64gc-unknown-linux-gnu
steps:
- uses: actions/checkout@v4
with:
ref: ${{ needs.setup.outputs.tag }}
- name: Setup Rust (For non-container builds)
- name: Install cargo-zigbuild
if: matrix.package_type == 'deb' || matrix.package_type == 'rpm'
run: |
pip install cargo-zigbuild
echo "$HOME/.local/bin" >> $GITHUB_PATH
- name: Setup Zig
if: (matrix.package_type == 'deb' || matrix.package_type == 'rpm') && matrix.target != 'x86_64-unknown-linux-gnu'
uses: mlugg/setup-zig@v1
with:
version: 0.13.0
- name: Setup Rust
if: matrix.package_type != 'arch'
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}
# ── DEB Build ──
- name: Build Debian Package
if: matrix.package_type == 'deb'
run: |
cargo install cargo-deb
cargo build --release
cargo deb --no-build
mkdir -p dist-packages && cp target/debian/*.deb dist-packages/
if [ "${{ matrix.target }}" != "x86_64-unknown-linux-gnu" ]; then
cargo zigbuild --release --features archive --target ${{ matrix.target }}
else
cargo build --release --features archive --target ${{ matrix.target }}
fi
cargo deb --no-build --target ${{ matrix.target }}
mkdir -p dist-packages && cp target/${{ matrix.target }}/debian/*.deb dist-packages/
# ── RPM Build ──
- name: Build RPM Package
if: matrix.package_type == 'rpm'
run: |
cargo install cargo-generate-rpm
cargo build --release
cargo generate-rpm
mkdir -p dist-packages && cp target/generate-rpm/*.rpm dist-packages/
if [ "${{ matrix.target }}" != "x86_64-unknown-linux-gnu" ]; then
cargo zigbuild --release --features archive --target ${{ matrix.target }}
else
cargo build --release --features archive --target ${{ matrix.target }}
fi
cargo generate-rpm --target ${{ matrix.target }}
mkdir -p dist-packages && cp target/${{ matrix.target }}/generate-rpm/*.rpm dist-packages/
# ── Snap Build ──
- name: Build Snap Package
if: matrix.package_type == 'snap'
run: |
cargo build --release
cargo build --release --features archive
mkdir -p packaging/snap/dist/bin
cp target/release/dcr packaging/snap/dist/bin/
cp -r man packaging/snap/dist/man
- name: Snapcraft Build Action
if: matrix.package_type == 'snap'
@@ -222,14 +341,15 @@ jobs:
- name: Build Arch Package inside Container
if: matrix.package_type == 'arch'
run: |
PKGVER='${{ needs.setup.outputs.version }}'
PKGVER_ORIG='${{ needs.setup.outputs.version }}'
PKGVER_CLEAN="${PKGVER_ORIG//-/.}"
TAG='${{ needs.setup.outputs.tag }}'
SRC_URL="https://github.com/dexoron/dcr/archive/refs/tags/${TAG}.tar.gz"
SHA256="$(curl -fsSL "$SRC_URL" | sha256sum | awk '{print $1}')"
mkdir -p arch-build
cat > arch-build/PKGBUILD <<PKG
pkgname=dcr
pkgver=${PKGVER}
pkgver=${PKGVER_CLEAN}
pkgrel=1
pkgdesc="Cargo-like utility to manage C/C++ projects"
arch=('x86_64')
@@ -238,16 +358,21 @@ jobs:
depends=('gcc-libs')
makedepends=('cargo')
options=('!lto')
source=("\$pkgname-\$pkgver.tar.gz::\$url/archive/refs/tags/v\$pkgver.tar.gz")
source=("\$pkgname-\$pkgver.tar.gz::\$url/archive/refs/tags/${TAG}.tar.gz")
sha256sums=('${SHA256}')
build() {
cd "\$srcdir/\$pkgname-\$pkgver"
cargo build --release --locked
cd "\$srcdir/\$pkgname-${PKGVER_ORIG}"
unset CFLAGS CXXFLAGS LDFLAGS
export RUSTFLAGS="-C linker=cc"
cargo build --release --locked --features archive
}
package() {
cd "\$srcdir/\$pkgname-\$pkgver"
cd "\$srcdir/dcr-${PKGVER_ORIG}"
install -Dm755 "target/release/dcr" "\$pkgdir/usr/bin/dcr"
install -Dm644 LICENSE "\$pkgdir/usr/share/licenses/\$pkgname/LICENSE"
for manpage in man/man1/*.1; do
install -Dm644 "\$manpage" "\$pkgdir/usr/share/man/man1/\$(basename "\$manpage")"
done
}
PKG
docker run --rm \
@@ -267,13 +392,13 @@ jobs:
- name: Upload Package Artifact
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.artifact_name }}
name: ${{ matrix.package_type }}-package-${{ matrix.target }}
path: dist-packages/*
if-no-files-found: ignore
# ── Publish Packages to Release (Out of Matrix) ────────────────────────────
publish-dexoron-packages:
needs: [setup, notes, build-linux-packages]
needs: [setup, notes, build-linux-packages, create-release]
runs-on: ubuntu-latest
steps:
- name: Download Release Notes
@@ -292,17 +417,17 @@ jobs:
with:
tag_name: ${{ needs.setup.outputs.tag }}
files: |
collected-packages/debian-package/*
collected-packages/rpm-package/*
collected-packages/arch-package/*
collected-packages/snap-package/*
collected-packages/deb-package-*/*
collected-packages/rpm-package-*/*
collected-packages/arch-package-*/*
collected-packages/snap-package-*/*
body_path: .github/release-notes.md
prerelease: ${{ needs.setup.outputs.prerelease == 'true' }}
# ── macOS Matrix ───────────────────────────────────────────────────────────
build-macos:
if: ${{ github.event_name == 'push' || github.event.inputs.run_macos == 'true' }}
needs: [setup, notes]
needs: [setup, notes, create-release]
strategy:
fail-fast: false
matrix:
@@ -329,7 +454,7 @@ jobs:
targets: ${{ matrix.target }}
- name: Build
run: cargo build --release --target ${{ matrix.target }}
run: cargo build --release --features archive --target ${{ matrix.target }}
- name: Prepare Artifact
run: |
@@ -348,7 +473,7 @@ jobs:
# ── BSD Systems Matrix ─────────────────────────────────────────────────────
build-bsd:
if: ${{ github.event_name == 'push' || github.event.inputs.run_bsd == 'true' }}
needs: [setup, notes]
needs: [setup, notes, create-release]
runs-on: ubuntu-latest
strategy:
fail-fast: false
@@ -374,7 +499,7 @@ jobs:
run: |
export PATH="/usr/local/bin:/usr/local/sbin:$PATH"
pkg install -y rust perl5 gmake
cargo build --release
cargo build --release --features archive
- name: Prepare FreeBSD Artifact
if: matrix.system == 'freebsd'
@@ -392,7 +517,7 @@ jobs:
run: |
export PATH="/usr/local/bin:$PATH"
pkg_add rust perl gmake
cargo build --release
cargo build --release --features archive
- name: Prepare OpenBSD Artifact
if: matrix.system == 'openbsd'
@@ -408,10 +533,11 @@ jobs:
with:
usesh: true
run: |
export PATH="/usr/pkg/bin:/usr/pkg/sbin:$PATH"
pkg_add rust perl gmake
export MAKE=gmake
cargo build --release
mkdir -p /tmp/bin
ln -sf /usr/pkg/bin/gmake /tmp/bin/make
export PATH="/tmp/bin:/usr/pkg/bin:/usr/pkg/sbin:$PATH"
cargo build --release --features archive
- name: Prepare NetBSD Artifact
if: matrix.system == 'netbsd'
@@ -432,7 +558,7 @@ jobs:
# ── Windows Matrix ─────────────────────────────────────────────────────────
build-windows:
if: ${{ github.event_name == 'push' || github.event.inputs.run_windows == 'true' }}
needs: [setup, notes]
needs: [setup, notes, create-release]
runs-on: windows-latest
strategy:
fail-fast: false
@@ -440,6 +566,7 @@ jobs:
include:
- target: x86_64-pc-windows-msvc
- target: aarch64-pc-windows-msvc
- target: i686-pc-windows-msvc
- target: x86_64-pc-windows-gnu
steps:
- uses: actions/checkout@v4
@@ -458,7 +585,7 @@ jobs:
targets: ${{ matrix.target }}
- name: Build
run: cargo build --release --target ${{ matrix.target }}
run: cargo build --release --features archive --target ${{ matrix.target }}
- name: Prepare Artifact
shell: pwsh
@@ -499,14 +626,15 @@ jobs:
shell: bash
run: |
set -euo pipefail
PKGVER='${{ needs.setup.outputs.version }}'
PKGVER_ORIG='${{ needs.setup.outputs.version }}'
PKGVER_CLEAN="${PKGVER_ORIG//-/.}"
SRC_URL='${{ steps.meta.outputs.source_url }}'
SHA256='${{ steps.meta.outputs.sha256 }}'
mkdir -p packages/aur/dcr
cat > packages/aur/dcr/PKGBUILD <<PKG
pkgname=dcr
pkgver=${PKGVER}
pkgver=${PKGVER_CLEAN}
pkgrel=1
pkgdesc="Cargo-like utility to manage C/C++ projects"
arch=('x86_64' 'aarch64')
@@ -519,28 +647,30 @@ jobs:
'gcc: build C/C++ projects with GCC'
'clang: build C/C++ projects with Clang'
)
source=("\$pkgname-\$pkgver.tar.gz::\$url/archive/refs/tags/v\$pkgver.tar.gz")
source=("\$pkgname-\$pkgver.tar.gz::${SRC_URL}")
sha256sums=('${SHA256}')
build() {
cd "\$srcdir/\$pkgname-\$pkgver"
export CARGO_PROFILE_RELEASE_LTO=false
export RUSTFLAGS="\${RUSTFLAGS:-}"
export RUSTFLAGS="\${RUSTFLAGS/-C link-arg=-fuse-ld=lld/}"
cargo build --release --locked
cd "\$srcdir/\$pkgname-${PKGVER_ORIG}"
unset CFLAGS CXXFLAGS LDFLAGS
export RUSTFLAGS="-C linker=cc"
cargo build --release --locked --features archive
}
package() {
cd "\$srcdir/\$pkgname-\$pkgver"
cd "\$srcdir/\$pkgname-${PKGVER_ORIG}"
install -Dm755 "target/release/dcr" "\$pkgdir/usr/bin/dcr"
install -Dm644 LICENSE "\$pkgdir/usr/share/licenses/\$pkgname/LICENSE"
for manpage in man/man1/*.1; do
install -Dm644 "\$manpage" "\$pkgdir/usr/share/man/man1/\$(basename "\$manpage")"
done
}
PKG
cat > packages/aur/dcr/.SRCINFO <<SRC
pkgbase = dcr
pkgdesc = Cargo-like utility to manage C/C++ projects
pkgver = ${PKGVER}
pkgver = ${PKGVER_CLEAN}
pkgrel = 1
url = https://github.com/dexoron/dcr
arch = x86_64
@@ -551,7 +681,7 @@ jobs:
optdepends = gcc: build C/C++ projects with GCC
optdepends = clang: build C/C++ projects with Clang
options = !lto
source = dcr-${PKGVER}.tar.gz::${SRC_URL}
source = dcr-${PKGVER_CLEAN}.tar.gz::${SRC_URL}
sha256sums = ${SHA256}
pkgname = dcr
@@ -570,22 +700,31 @@ jobs:
ssh-keyscan aur.archlinux.org >> ~/.ssh/known_hosts
export GIT_SSH_COMMAND='ssh -i ~/.ssh/aur -o IdentitiesOnly=yes'
git clone "ssh://aur@aur.archlinux.org/${AUR_PACKAGE}.git" aur-repo
cp packages/aur/dcr/PKGBUILD aur-repo/PKGBUILD
cp packages/aur/dcr/.SRCINFO aur-repo/.SRCINFO
mkdir -p aur-repo
cd aur-repo
git init
git remote add origin "ssh://aur@aur.archlinux.org/${AUR_PACKAGE}.git"
git fetch origin master || true
git checkout master || git checkout -b master
cp ../packages/aur/dcr/PKGBUILD .
cp ../packages/aur/dcr/.SRCINFO .
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
if git diff --quiet; then
echo "No AUR changes"
exit 0
if git rev-parse --verify HEAD >/dev/null 2>&1; then
if git diff --quiet; then
echo "No AUR changes"
exit 0
fi
fi
git add PKGBUILD .SRCINFO
git commit -m "dcr ${{ needs.setup.outputs.version }}"
git push
git push -u origin master
# ── Arch User Repository (dcr-bin) ────────────────────────────────
publish-aur-bin:
@@ -602,26 +741,36 @@ jobs:
shell: bash
run: |
set -euo pipefail
BIN_URL="https://github.com/dexoron/dcr/releases/download/${{ needs.setup.outputs.tag }}/dcr-x86_64-unknown-linux-musl-${{ needs.setup.outputs.version }}"
SHA256="$(curl -fsSL "$BIN_URL" | sha256sum | awk '{print $1}')"
echo "bin_url=$BIN_URL" >> "$GITHUB_OUTPUT"
echo "sha256=$SHA256" >> "$GITHUB_OUTPUT"
TAG="${{ needs.setup.outputs.tag }}"
VER="${{ needs.setup.outputs.version }}"
BASE_URL="https://github.com/dexoron/dcr/releases/download/${TAG}"
for arch in x86_64 aarch64 i686 armv7h riscv64; do
case "$arch" in
x86_64) triple="x86_64-unknown-linux-musl" ;;
aarch64) triple="aarch64-unknown-linux-musl" ;;
i686) triple="i686-unknown-linux-musl" ;;
armv7h) triple="armv7-unknown-linux-musleabihf" ;;
riscv64) triple="riscv64gc-unknown-linux-musl" ;;
esac
url="${BASE_URL}/dcr-${triple}-${VER}"
sha256="$(curl -fsSL "$url" | sha256sum | awk '{print $1}')"
echo "${arch}_url=${url}" >> "$GITHUB_OUTPUT"
echo "${arch}_sha256=${sha256}" >> "$GITHUB_OUTPUT"
done
- name: Render AUR Metadata
shell: bash
run: |
set -euo pipefail
PKGVER='${{ needs.setup.outputs.version }}'
BIN_URL='${{ steps.meta.outputs.bin_url }}'
SHA256='${{ steps.meta.outputs.sha256 }}'
PKGVER_ORIG='${{ needs.setup.outputs.version }}'
PKGVER_CLEAN="${PKGVER_ORIG//-/.}"
mkdir -p packages/aur/dcr-bin
cat > packages/aur/dcr-bin/PKGBUILD <<PKG
pkgname=dcr-bin
pkgver=${PKGVER}
pkgver=${PKGVER_CLEAN}
pkgrel=1
pkgdesc="Cargo-like utility to manage C/C++ projects (pre-compiled musl binary)"
arch=('x86_64')
arch=('x86_64' 'aarch64' 'i686' 'armv7h' 'riscv64')
url="https://github.com/dexoron/dcr"
license=('GPL-3.0-or-later')
provides=('dcr')
@@ -630,8 +779,16 @@ jobs:
'gcc: build C/C++ projects with GCC'
'clang: build C/C++ projects with Clang'
)
source_x86_64=("dcr-\$pkgver::${BIN_URL}")
sha256sums_x86_64=('${SHA256}')
source_x86_64=("dcr-\$pkgver::${{ steps.meta.outputs.x86_64_url }}")
sha256sums_x86_64=('${{ steps.meta.outputs.x86_64_sha256 }}')
source_aarch64=("dcr-\$pkgver::${{ steps.meta.outputs.aarch64_url }}")
sha256sums_aarch64=('${{ steps.meta.outputs.aarch64_sha256 }}')
source_i686=("dcr-\$pkgver::${{ steps.meta.outputs.i686_url }}")
sha256sums_i686=('${{ steps.meta.outputs.i686_sha256 }}')
source_armv7h=("dcr-\$pkgver::${{ steps.meta.outputs.armv7h_url }}")
sha256sums_armv7h=('${{ steps.meta.outputs.armv7h_sha256 }}')
source_riscv64=("dcr-\$pkgver::${{ steps.meta.outputs.riscv64_url }}")
sha256sums_riscv64=('${{ steps.meta.outputs.riscv64_sha256 }}')
package() {
install -Dm755 "\$srcdir/dcr-\$pkgver" "\$pkgdir/usr/bin/dcr"
@@ -641,17 +798,29 @@ jobs:
cat > packages/aur/dcr-bin/.SRCINFO <<SRC
pkgbase = dcr-bin
pkgdesc = Cargo-like utility to manage C/C++ projects (pre-compiled musl binary)
pkgver = ${PKGVER}
pkgver = ${PKGVER_CLEAN}
pkgrel = 1
url = https://github.com/dexoron/dcr
arch = x86_64
arch = aarch64
arch = i686
arch = armv7h
arch = riscv64
license = GPL-3.0-or-later
provides = dcr
conflicts = dcr
optdepends = gcc: build C/C++ projects with GCC
optdepends = clang: build C/C++ projects with Clang
source_x86_64 = dcr-${PKGVER}::${BIN_URL}
sha256sums_x86_64 = ${SHA256}
source_x86_64 = dcr-${PKGVER_CLEAN}::${{ steps.meta.outputs.x86_64_url }}
sha256sums_x86_64 = ${{ steps.meta.outputs.x86_64_sha256 }}
source_aarch64 = dcr-${PKGVER_CLEAN}::${{ steps.meta.outputs.aarch64_url }}
sha256sums_aarch64 = ${{ steps.meta.outputs.aarch64_sha256 }}
source_i686 = dcr-${PKGVER_CLEAN}::${{ steps.meta.outputs.i686_url }}
sha256sums_i686 = ${{ steps.meta.outputs.i686_sha256 }}
source_armv7h = dcr-${PKGVER_CLEAN}::${{ steps.meta.outputs.armv7h_url }}
sha256sums_armv7h = ${{ steps.meta.outputs.armv7h_sha256 }}
source_riscv64 = dcr-${PKGVER_CLEAN}::${{ steps.meta.outputs.riscv64_url }}
sha256sums_riscv64 = ${{ steps.meta.outputs.riscv64_sha256 }}
pkgname = dcr-bin
SRC
@@ -669,22 +838,299 @@ jobs:
ssh-keyscan aur.archlinux.org >> ~/.ssh/known_hosts
export GIT_SSH_COMMAND='ssh -i ~/.ssh/aur -o IdentitiesOnly=yes'
git clone "ssh://aur@aur.archlinux.org/${AUR_PACKAGE}.git" aur-repo
cp packages/aur/dcr-bin/PKGBUILD aur-repo/PKGBUILD
cp packages/aur/dcr-bin/.SRCINFO aur-repo/.SRCINFO
mkdir -p aur-repo
cd aur-repo
git init
git remote add origin "ssh://aur@aur.archlinux.org/${AUR_PACKAGE}.git"
git fetch origin master || true
git checkout master || git checkout -b master
cp ../packages/aur/dcr-bin/PKGBUILD .
cp ../packages/aur/dcr-bin/.SRCINFO .
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
if git diff --quiet; then
echo "No AUR changes"
exit 0
if git rev-parse --verify HEAD >/dev/null 2>&1; then
if git diff --quiet; then
echo "No AUR changes"
exit 0
fi
fi
git add PKGBUILD .SRCINFO
git commit -m "dcr-bin ${{ needs.setup.outputs.version }}"
git push
git push -u origin master
# ── Arch User Repository (dcr-dev) ────────────────────────────────
publish-aur-dev:
if: ${{ (github.event_name == 'push' && needs.setup.outputs.prerelease == 'true') || github.event.inputs.run_aur_dev == 'true' }}
needs: [setup]
runs-on: ubuntu-latest
environment: aur
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Derive checksum
id: meta
shell: bash
run: |
set -euo pipefail
SRC_URL="https://github.com/dexoron/dcr/archive/refs/tags/${{ needs.setup.outputs.tag }}.tar.gz"
SHA256="$(curl -fsSL "$SRC_URL" | sha256sum | awk '{print $1}')"
echo "source_url=$SRC_URL" >> "$GITHUB_OUTPUT"
echo "sha256=$SHA256" >> "$GITHUB_OUTPUT"
- name: Render AUR metadata
shell: bash
run: |
set -euo pipefail
PKGVER_ORIG='${{ needs.setup.outputs.version }}'
PKGVER_CLEAN='${{ needs.setup.outputs.clean_version }}'
SRC_URL='${{ steps.meta.outputs.source_url }}'
SHA256='${{ steps.meta.outputs.sha256 }}'
mkdir -p packages/aur/dcr-dev
cat > packages/aur/dcr-dev/PKGBUILD <<PKG
pkgname=dcr-dev
pkgver=${PKGVER_CLEAN}
pkgrel=1
pkgdesc="Cargo-like utility to manage C/C++ projects (development release)"
arch=('x86_64' 'aarch64')
url="https://github.com/dexoron/dcr"
license=('GPL-3.0-or-later')
depends=('gcc-libs')
makedepends=('cargo')
options=('!lto')
provides=('dcr')
conflicts=('dcr')
optdepends=(
'gcc: build C/C++ projects with GCC'
'clang: build C/C++ projects with Clang'
)
source=("\$pkgname-\$pkgver.tar.gz::${SRC_URL}")
sha256sums=('${SHA256}')
build() {
cd "\$srcdir/dcr-${PKGVER_ORIG}"
unset CFLAGS CXXFLAGS LDFLAGS
export RUSTFLAGS="-C linker=cc"
cargo build --release --locked --features archive
}
package() {
cd "\$srcdir/\$pkgname-${PKGVER_ORIG}"
install -Dm755 "target/release/dcr" "\$pkgdir/usr/bin/dcr"
install -Dm644 LICENSE "\$pkgdir/usr/share/licenses/\$pkgname/LICENSE"
for manpage in man/man1/*.1; do
install -Dm644 "\$manpage" "\$pkgdir/usr/share/man/man1/\$(basename "\$manpage")"
done
}
PKG
cat > packages/aur/dcr-dev/.SRCINFO <<SRC
pkgbase = dcr-dev
pkgdesc = Cargo-like utility to manage C/C++ projects (development release)
pkgver = ${PKGVER_CLEAN}
pkgrel = 1
url = https://github.com/dexoron/dcr
arch = x86_64
arch = aarch64
license = GPL-3.0-or-later
makedepends = cargo
depends = gcc-libs
provides = dcr
conflicts = dcr
optdepends = gcc: build C/C++ projects with GCC
optdepends = clang: build C/C++ projects with Clang
options = !lto
source = dcr-${PKGVER_CLEAN}.tar.gz::${SRC_URL}
sha256sums = ${SHA256}
pkgname = dcr-dev
SRC
- name: Push to AUR
env:
AUR_SSH_PRIVATE_KEY: ${{ secrets.AUR_SSH_PRIVATE_KEY }}
AUR_PACKAGE: dcr-dev
shell: bash
run: |
set -euo pipefail
install -d -m 700 ~/.ssh
printf '%s\n' "$AUR_SSH_PRIVATE_KEY" > ~/.ssh/aur
chmod 600 ~/.ssh/aur
ssh-keyscan aur.archlinux.org >> ~/.ssh/known_hosts
export GIT_SSH_COMMAND='ssh -i ~/.ssh/aur -o IdentitiesOnly=yes'
mkdir -p aur-repo
cd aur-repo
git init
git remote add origin "ssh://aur@aur.archlinux.org/${AUR_PACKAGE}.git"
git fetch origin master || true
git checkout master || git checkout -b master
cp ../packages/aur/dcr-dev/PKGBUILD .
cp ../packages/aur/dcr-dev/.SRCINFO .
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
if git rev-parse --verify HEAD >/dev/null 2>&1; then
if git diff --quiet; then
echo "No AUR changes"
exit 0
fi
fi
git add PKGBUILD .SRCINFO
git commit -m "dcr-dev ${{ needs.setup.outputs.version }}"
git push -u origin master
# ── Arch User Repository (dcr-dev-bin) ────────────────────────────
publish-aur-dev-bin:
if: ${{ (github.event_name == 'push' && needs.setup.outputs.prerelease == 'true') || github.event.inputs.run_aur_dev == 'true' }}
needs: [setup, build-linux]
runs-on: ubuntu-latest
environment: aur
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Derive checksum
id: meta
shell: bash
run: |
set -euo pipefail
TAG="${{ needs.setup.outputs.tag }}"
VER="${{ needs.setup.outputs.version }}"
BASE_URL="https://github.com/dexoron/dcr/releases/download/${TAG}"
for arch in x86_64 aarch64 i686 armv7h riscv64; do
case "$arch" in
x86_64) triple="x86_64-unknown-linux-musl" ;;
aarch64) triple="aarch64-unknown-linux-musl" ;;
i686) triple="i686-unknown-linux-musl" ;;
armv7h) triple="armv7-unknown-linux-musleabihf" ;;
riscv64) triple="riscv64gc-unknown-linux-musl" ;;
esac
url="${BASE_URL}/dcr-${triple}-${VER}"
sha256="$(curl -fsSL "$url" | sha256sum | awk '{print $1}')"
echo "${arch}_url=${url}" >> "$GITHUB_OUTPUT"
echo "${arch}_sha256=${sha256}" >> "$GITHUB_OUTPUT"
done
- name: Render AUR Metadata
shell: bash
run: |
set -euo pipefail
PKGVER_ORIG='${{ needs.setup.outputs.version }}'
PKGVER_CLEAN='${{ needs.setup.outputs.clean_version }}'
mkdir -p packages/aur/dcr-dev-bin
cat > packages/aur/dcr-dev-bin/PKGBUILD <<PKG
pkgname=dcr-dev-bin
pkgver=${PKGVER_CLEAN}
pkgrel=1
pkgdesc="Cargo-like utility to manage C/C++ projects (pre-compiled musl binary dev release)"
arch=('x86_64' 'aarch64' 'i686' 'armv7h' 'riscv64')
url="https://github.com/dexoron/dcr"
license=('GPL-3.0-or-later')
provides=('dcr')
conflicts=('dcr')
optdepends=(
'gcc: build C/C++ projects with GCC'
'clang: build C/C++ projects with Clang'
)
source_x86_64=("dcr-\$pkgver::${{ steps.meta.outputs.x86_64_url }}")
sha256sums_x86_64=('${{ steps.meta.outputs.x86_64_sha256 }}')
source_aarch64=("dcr-\$pkgver::${{ steps.meta.outputs.aarch64_url }}")
sha256sums_aarch64=('${{ steps.meta.outputs.aarch64_sha256 }}')
source_i686=("dcr-\$pkgver::${{ steps.meta.outputs.i686_url }}")
sha256sums_i686=('${{ steps.meta.outputs.i686_sha256 }}')
source_armv7h=("dcr-\$pkgver::${{ steps.meta.outputs.armv7h_url }}")
sha256sums_armv7h=('${{ steps.meta.outputs.armv7h_sha256 }}')
source_riscv64=("dcr-\$pkgver::${{ steps.meta.outputs.riscv64_url }}")
sha256sums_riscv64=('${{ steps.meta.outputs.riscv64_sha256 }}')
package() {
install -Dm755 "\$srcdir/dcr-\$pkgver" "\$pkgdir/usr/bin/dcr"
}
PKG
cat > packages/aur/dcr-dev-bin/.SRCINFO <<SRC
pkgbase = dcr-dev-bin
pkgdesc = Cargo-like utility to manage C/C++ projects (pre-compiled musl binary dev release)
pkgver = ${PKGVER_CLEAN}
pkgrel = 1
url = https://github.com/dexoron/dcr
arch = x86_64
arch = aarch64
arch = i686
arch = armv7h
arch = riscv64
license = GPL-3.0-or-later
provides = dcr
conflicts = dcr
optdepends = gcc: build C/C++ projects with GCC
optdepends = clang: build C/C++ projects with Clang
source_x86_64 = dcr-${PKGVER_CLEAN}::${{ steps.meta.outputs.x86_64_url }}
sha256sums_x86_64 = ${{ steps.meta.outputs.x86_64_sha256 }}
source_aarch64 = dcr-${PKGVER_CLEAN}::${{ steps.meta.outputs.aarch64_url }}
sha256sums_aarch64 = ${{ steps.meta.outputs.aarch64_sha256 }}
source_i686 = dcr-${PKGVER_CLEAN}::${{ steps.meta.outputs.i686_url }}
sha256sums_i686 = ${{ steps.meta.outputs.i686_sha256 }}
source_armv7h = dcr-${PKGVER_CLEAN}::${{ steps.meta.outputs.armv7h_url }}
sha256sums_armv7h = ${{ steps.meta.outputs.armv7h_sha256 }}
source_riscv64 = dcr-${PKGVER_CLEAN}::${{ steps.meta.outputs.riscv64_url }}
sha256sums_riscv64 = ${{ steps.meta.outputs.riscv64_sha256 }}
pkgname = dcr-dev-bin
SRC
- name: Push to AUR
env:
AUR_SSH_PRIVATE_KEY: ${{ secrets.AUR_SSH_PRIVATE_KEY }}
AUR_PACKAGE: dcr-dev-bin
shell: bash
run: |
set -euo pipefail
install -d -m 700 ~/.ssh
printf '%s\n' "$AUR_SSH_PRIVATE_KEY" > ~/.ssh/aur
chmod 600 ~/.ssh/aur
ssh-keyscan aur.archlinux.org >> ~/.ssh/known_hosts
export GIT_SSH_COMMAND='ssh -i ~/.ssh/aur -o IdentitiesOnly=yes'
mkdir -p aur-repo
cd aur-repo
git init
git remote add origin "ssh://aur@aur.archlinux.org/${AUR_PACKAGE}.git"
git fetch origin master || true
git checkout master || git checkout -b master
cp ../packages/aur/dcr-dev-bin/PKGBUILD .
cp ../packages/aur/dcr-dev-bin/.SRCINFO .
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
if git rev-parse --verify HEAD >/dev/null 2>&1; then
if git diff --quiet; then
echo "No AUR changes"
exit 0
fi
fi
git add PKGBUILD .SRCINFO
git commit -m "dcr-dev-bin ${{ needs.setup.outputs.version }}"
git push -u origin master
# ── crates.io ──────────────────────────────────────────────────────────────
publish-crates:
@@ -704,6 +1150,8 @@ jobs:
- uses: dtolnay/rust-toolchain@stable
- name: Publish to crates.io
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
run: cargo publish
# ── Homebrew tap ───────────────────────────────────────────────────────────
@@ -728,6 +1176,7 @@ jobs:
echo "linux_arm=$(download_sha "dcr-aarch64-unknown-linux-gnu-${VERSION}")" >> "$GITHUB_OUTPUT"
echo "macos_x86=$(download_sha "dcr-x86_64-apple-darwin-${VERSION}")" >> "$GITHUB_OUTPUT"
echo "macos_arm=$(download_sha "dcr-aarch64-apple-darwin-${VERSION}")" >> "$GITHUB_OUTPUT"
echo "man_pages=$(download_sha "dcr-man-pages-${VERSION}.tar.gz")" >> "$GITHUB_OUTPUT"
- name: Checkout homebrew-dexoron
uses: actions/checkout@v4
@@ -770,6 +1219,18 @@ jobs:
bin.install Dir["dcr*"].first => "dcr"
end
resource "man-pages" do
url "https://github.com/dexoron/dcr/releases/download/v#{version}/dcr-man-pages-#{version}.tar.gz"
sha256 "${{ steps.sha.outputs.man_pages }}"
end
def install
bin.install Dir["dcr*"].first => "dcr"
resource("man-pages").stage do
man1.install Dir["usr/share/man/man1/*.1"]
end
end
test do
system "#{bin}/dcr", "--version"
end
@@ -783,4 +1244,13 @@ jobs:
git add Formula/dcr.rb
git diff --staged --quiet && echo "No changes" && exit 0
git commit -m "dcr ${{ needs.setup.outputs.version }}"
git push
git push
# ── Snap Store (dcrup) — temporarily disabled ────────────────────────────
# Classic confinement was denied for this project (too new).
# Snap artifact is still built and attached to the release via
# publish-dexoron-packages. Users can install manually:
# sudo snap install --classic --dangerous dcrup_*.snap
#
# publish-snap:
# if: ...

View File

@@ -0,0 +1,14 @@
name: Trigger site rebuild
on:
push:
branches: [master]
paths:
- 'docs/**'
jobs:
trigger:
runs-on: ubuntu-latest
steps:
- name: Trigger Cloudflare Pages build
run: curl -sS -X POST "${{ secrets.CF_PAGES_DEPLOY_HOOK }}"

5
.gitignore vendored
View File

@@ -2,6 +2,9 @@ target/
sandbox/**
.idea/
.vscode/
.cargo/
.env
personal/
personal/
.*
!.gitignore

View File

@@ -1,56 +0,0 @@
# AGENTS.md
## Quick start
```bash
cargo build --release && ./target/release/dcr setup
```
## Pre-PR (CI) gate
```bash
cargo fmt --all --check
cargo clippy --all-targets --all-features -- -D warnings
cargo check --all-targets --all-features
cargo test
```
CI (`.github/workflows/ci.yml`) runs fmt, clippy, check — **not** tests.
## Tests
- Integration tests in `tests/` build the dcr binary and run it in temp dirs under `sandbox/cli-tests/` (gitignored).
- Some tests **skip** if no C compiler (`gcc`/`clang`/`cc`) is found at runtime.
- Compiler can be overridden via `DCR_COMPILER` or `DCR_CC` env vars.
- Tests use `$CARGO_BIN_EXE_dcr` when available, else `target/debug/dcr`.
## Architecture
- **Single Rust package** (edition 2024), not a workspace. Only one binary: `dcr`.
- **Entrypoint**: `src/main.rs` — matches `args[1]` against command names.
- **Compiler backends** in `src/core/builder/`: `unix_cc` (gcc/clang), `msvc` (cl/clang-cl), `gas`, `nasm`. Dispatched by matching compiler name string.
- **Config**: `dcr.toml` (per-project), `~/.dcr/config.toml` (registry), `~/.dcr/index.json` (index). Defaults: `language=c`, `standard=c11`, `compiler=clang`, `kind=bin`.
- **`build.rs`** embeds `TARGET` as `DCR_TARGET` env var (shown in `--version`).
- **CLI output** must be in English. Use `utils::log` for messaging.
## Key commands
| Command | Notes |
|---|---|
| `dcr new <name>` | Creates project dir |
| `dcr init` | Init from CWD (must be empty) |
| `dcr build [--debug\|--release] [--target <triple>]` | Default profile: `--debug` |
| `dcr run [--debug\|--release]` | Only for `kind = "bin"` |
| `dcr clean [--debug\|--release] [--all]` | `--all` for workspace roots |
| `dcr tree` | Dependency tree viewer |
| `dcr test [--init]` | Runs/test project tests |
| `dcr gen <vscode\|clion\|compile-commands>` | IDE integration |
| `dcr --update` | Self-update from GitHub Releases |
## Cross-compilation
`--target` accepts short names (`linux`, `macos`, `windows`) or full triples. In CI, Linux cross-builds use `cargo-zigbuild`. When `build.target` is set in `dcr.toml`, DCR auto-injects `--target=<value>` into cflags (clang). Bare-metal targets (containing `none`/`-elf`/`eabi`/`baremetal`) skip DCR's default compiler flags.
## Dependencies (Cargo)
reqwest (blocking+json+rustls-tls), serde, toml, git2, openssl (vendored), self-replace, sha2, ctrlc.

View File

@@ -1,5 +1,487 @@
# Changelog
## [v0.8.5] - 2026-08-08 "Фиксация версии dcr-version и предупреждения совместимости / Config Version Pinning & Compatibility Warnings"
### RU
**Добавлено:**
- **`package.dcr-version`** — опциональный pin версии CLI в `dcr.toml`.
`dcr new` / `dcr init` пишут текущую версию. При загрузке конфига:
- нет / пустой pin → warn «добавь dcr-version»;
- dcr старше pin → warn «обнови dcr»;
- dcr новее pin → warn «проверь changelog, подними pin»;
- равенство — тишина.
Команды не падают, только предупреждение (раз на path за процесс).
### EN
**Added:**
- **`package.dcr-version`** — optional CLI version pin in `dcr.toml`.
`dcr new` / `dcr init` write the current version. On config load:
- missing / empty pin → warn "add dcr-version";
- dcr older than pin → warn "update dcr";
- dcr newer than pin → warn "check changelog, update pin";
- equal → silent.
Commands do not fail, warning only (once per path per process).
## [0.8.4] - 2026-08-04 "Инфраструктура .dcr/ и интеграция с IDE / Internal .dcr/ Layout & IDE Integration"
### RU
**Добавлено:**
- **Директория `.dcr/`** — единый machine-readable источник фактов о сборке для IDE/расширений:
- `.dcr/compile_commands.json`
- `.dcr/build-info.json` (`schemaVersion`, `artifact_path`, `profile`, …)
- `.dcr/toolchain.json` (compiler/debugger paths, moc/uic/rcc)
- `.dcr/ide/` (заготовки lock-файлов для расширений)
- **`dcr gen project-info`** — поля `target`, `target_dir`, `artifact_path`, `artifact_kind`, `source_roots`, `include_globs`, `exclude_globs`; пути абсолютные/канонические.
- **`dcr build --print-artifact-path`** — после успешной сборки одна строка absolute path на stdout.
- **`dcr gen … --quiet` / `-q`** — без human-лога на stdout для `compile-commands` / `project-info`.
- **`.clangd`** — при первом `gen` создаётся с `CompilationDatabase: .dcr` (маркер `# managed by dcr gen`); ручной `.clangd` не перезаписывается.
- **Хелперы** `canonicalize_path`, `atomic_write`, `ensure_dcr_dir`; pure `resolve_artifact_path` через `platform::*`.
- **`dcr new` / `dcr init`** — `.dcr/` в `.gitignore`.
**Изменено (breaking):**
- **`compile_commands.json` перенесён** из корня проекта в **`.dcr/compile_commands.json`**.
clangd находит базу через `.clangd` / `clangd.arguments --compile-commands-dir=.dcr`.
CLion `misc.xml` и VSCode `settings.json` обновлены под новый путь.
- **Атомарная запись** `compile_commands.json` (tmp + rename).
- **`gen vscode` / `gen clion` launch/run** — `program`/`executable` через тот же artifact resolver, что `project-info` / `build-info.json` (Linux triple, Windows `.exe`, custom `target`/`filename`).
**Исправлено:**
- Launch-конфиги больше не указывают `target/<profile>/<name>` без triple на Linux.
- Симлинки/mount: root и пути в compile database канонизируются best-effort.
### EN
**Added:**
- **`.dcr/` directory** — shared machine-readable build facts for IDE integrations:
- `.dcr/compile_commands.json`
- `.dcr/build-info.json` (`schemaVersion`, `artifact_path`, `profile`, …)
- `.dcr/toolchain.json` (compiler/debugger paths, moc/uic/rcc)
- `.dcr/ide/` (placeholder for IDE lock files)
- **`dcr gen project-info`** — `target`, `target_dir`, `artifact_path`, `artifact_kind`, `source_roots`, `include_globs`, `exclude_globs`; absolute/canonical paths.
- **`dcr build --print-artifact-path`** — one absolute artifact path line on stdout after a successful build.
- **`dcr gen … --quiet` / `-q`** — suppress human success logs for gen subcommands.
- **`.clangd`** — created on first gen with `CompilationDatabase: .dcr` (`# managed by dcr gen`); custom `.clangd` is not overwritten.
- **Helpers** `canonicalize_path`, `atomic_write`, `ensure_dcr_dir`; pure `resolve_artifact_path` via `platform::*`.
- **`dcr new` / `dcr init`** — add `.dcr/` to `.gitignore`.
**Changed (breaking):**
- **`compile_commands.json` moved** from project root to **`.dcr/compile_commands.json`**.
clangd discovers it via `.clangd` / `--compile-commands-dir=.dcr`.
CLion and VSCode generators updated accordingly.
- **Atomic write** for compile_commands (tmp + rename).
- **`gen vscode` / `gen clion` launch/run** — use the same artifact path resolver as `project-info` / `build-info.json`.
**Fixed:**
- Launch configs no longer hardcode `target/<profile>/<name>` without the Linux triple segment.
- Symlink/mount roots: best-effort canonicalize for root and compile database paths.
## [0.8.3] - 2026-08-03 "Конфигурация host target, аргументы run и нативные пути артефактов / Host Target Config, Run Args & Native Artifact Paths"
### RU
**Добавлено:**
- **`dcr run -- <args>...`** — cargo-style: всё после bare `--` передаётся собранному бинарнику
(`dcr run --release -- --test_help`). Работает и для прямого запуска, и для `[run].cmd`.
- **Интеграционные / unit-тесты** — host target sections применяют `ldflags` без `--target`; проброс аргументов после `--`; парсер `split_double_dash`.
**Изменено:**
- **Native-сборка резолвит host triple** — без `--target` / без `build.target` конфиг-секции вида
`[build.x86_64-unknown-linux-gnu]` (и аналоги host) снова применяются (`cflags` / `ldflags` / toolchain).
Раньше target был «пустым», секции молча игнорировались, а артефакты уже лежали под host triple — линковка без `-L`/`-l`.
- **Пустой target** — `normalize_target_os("")` больше не warn'ит `Unknown target ''`.
- **`dcr run --help` / man `dcr-run`** — документирован разделитель `--` и forwarding args.
**Исправлено:**
- **Нативные пути артефактов на Windows и macOS** — без явного `--target` / `build.target` артефакты снова сохраняются в `target/<profile>`, поэтому `dcr run` и flat-bin находят результат сборки.
- Target-specific `ldflags` на native Linux/macOS/Windows (host triple) не доходили до линкера.
- Ложный warning на пустой target string.
### EN
**Added:**
- **`dcr run -- <args>...`** — cargo-style: arguments after a bare `--` are forwarded to the built binary
(`dcr run --release -- --test_help`). Works for direct binary runs and `[run].cmd`.
- **Tests** — host target sections apply `ldflags` without CLI `--target`; run-arg forwarding; `split_double_dash` unit tests.
**Changed:**
- **Native builds resolve the host triple** — without `--target` / without package `build.target`, host sections such as
`[build.x86_64-unknown-linux-gnu]` (and host equivalents) apply again (`cflags` / `ldflags` / toolchain).
Previously the target was empty, those sections were silently ignored while artifacts already used the host triple path — link failed without `-L`/`-l` (e.g. sandbox micro-lang + `libsct-elf`).
- **Empty target** — `normalize_target_os("")` no longer warns `Unknown target ''`.
- **`dcr run --help` / man `dcr-run`** — document `--` and argument forwarding.
**Fixed:**
- **Native artifact paths on Windows and macOS** — without an explicit `--target` / `build.target`, artifacts again use `target/<profile>`, so `dcr run` and flat-bin find the build output.
- Target-specific `ldflags` on native host builds not reaching the linker.
- Spurious warning for an empty target string.
## [0.8.2] - 2026-07-22 "CLI Progress, archive Feature, Workspace Path Fixes / CLI Progress, archive Feature, Workspace Path Fixes"
### RU
**Добавлено:**
- **Прогресс компиляции `[N/M]`** — live-строка `compile pkg v0.1.0 [12/41]` на TTY (stderr), чтобы длинные mono-package сборки не выглядели «зависшими».
- **Свой стиль статуса build** — фиксированная колонка глаголов: `project`, `compile`, `dep`, `ready`, `pack`, `done`, `run` (не cargo-clone).
- **Cargo feature `archive`** — `fatfs` и упаковка FAT-образов опциональны (`cargo build --features archive`). Release CI собирает с feature; без feature `[archive]` даёт явную ошибку.
- **Интеграционные тесты** — `flat_bin_nasm_build`, `package_build_target_used_without_cli_flag`, усилен workspace `clean --all`.
- **Расширенный CI** — unit + integration на Linux/macOS/Windows, отдельный job с `--features archive`, rust-cache, clippy default + all-features.
**Изменено:**
- **CLI host triple больше не форсится** — без `--target` используется `build.target` пакета/member (важно для bare-metal / post_steps ISO).
- **Relative `-I`/`-L`/`-T` (и `-isystem`/`-idirafter`)** в cflags/ldflags абсолютизируются относительно корня пакета (workspace CWD = root).
- **`dcr clean --all`** — не спамит `target not found` по members без локального `target/` (общий root `target/`).
- **`error` / `warn`** — красный / жёлтый, вывод на stderr; `Подсказка:` → `Hint:`.
- **`dcr --help` / man** — добавлены `add`, `lint`, `setup`; unknown command → exit code 1.
- **Сообщения NotFound** — `linker not found: ld.lld …` / `{tool} not found …` вместо сырого `os error 2`.
### EN
**Added:**
- **Compile progress `[N/M]`** — live TTY line `compile pkg v0.1.0 [12/41]` so long mono-package builds do not look hung.
- **DCR status verbs** — fixed-width column: `project`, `compile`, `dep`, `ready`, `pack`, `done`, `run`.
- **Cargo feature `archive`** — optional `fatfs` / FAT packing (`cargo build --features archive`). Release CI builds with the feature; without it `[archive]` errors clearly.
- **Integration tests** — `flat_bin_nasm_build`, package `build.target` without CLI flag, stricter workspace `clean --all`.
- **Expanded CI** — unit + integration on Linux/macOS/Windows, archive feature job, rust-cache, clippy default + all-features.
**Changed:**
- **CLI no longer forces host triple** — without `--target`, package/member `build.target` is used (bare-metal / ISO post_steps).
- **Relative `-I`/`-L`/`-T` (and `-isystem`/`-idirafter`)** in flags are absolutized against the package root when workspace CWD is the root.
- **`dcr clean --all`** — no spam for members without a local `target/` (shared root `target/`).
- **`error` / `warn`** — red / yellow on stderr; Russian `Подсказка:` → `Hint:`.
- **`dcr --help` / man** — list `add`, `lint`, `setup`; unknown command exits 1.
- **NotFound messages** — `linker not found: ld.lld …` / `{tool} not found …` instead of raw `os error 2`.
## [0.8.1] - 2026-07-20 "OS-Dev: flat-bin, FAT-образы / OS-Dev: flat-bin & FAT Images"
### RU
**Добавлено:**
- **`build.kind = "flat-bin"`** — сырой бинарный артефакт (расширение по умолчанию `.bin`):
- **NASM** — `-f bin`, прямой вывод `<stem>.bin`
- **FASM** — прямой вывод (ожидается `format binary` в исходнике)
- **GAS / MASM / LLVM IR (`llc`)** — объект → `objcopy -O binary` → `<stem>.bin`
- **C/C++ (gcc/clang/MSVC)** — compile → link (nostdlib/static) → `objcopy -O binary` → `<name>.bin`
- Требуется `llvm-objcopy` / `objcopy` / `gobjcopy` в PATH (кроме NASM/FASM direct)
- **Секция `[archive]`** — после успешной сборки DCR собирает образ диска (FAT12/16/32): размер, offset, volume label, опциональный bootsector и `layout`. С 0.8.2 — за feature `archive`.
- **Одиночные файлы в `build.roots`** — корень может быть файлом (`.c`, `.asm`, header), а не только каталогом.
**Изменено:**
- **`dcr build --force` / `dcr run --force`** — force также перезапускает `build.steps` и `build.post_steps`.
- **`dcr run` на workspace-only root** — если задан `[run].cmd`, сначала build + run по конфигу корня; иначе делегирование члену workspace.
### EN
**Added:**
- **`build.kind = "flat-bin"`** — raw binary (default `.bin`) across NASM/FASM/GAS/MASM/LLC and C/C++ (objcopy where needed).
- **`[archive]` section** — FAT12/16/32 disk images after build (from 0.8.2 gated by feature `archive`).
- **Single-file `build.roots`**.
**Changed:**
- **`--force`** re-runs steps/post_steps; workspace-only **`dcr run`** prefers root `[run].cmd` when set.
## [0.8.0] - 2026-07-18 "Модульный Движок Сборки, Новая Архитектура Ядра и Улучшение Workspaces / Modular Build Engine, New Core Architecture, & Workspace Improvements"
### RU
**Добавлено:**
- **Выделенное ядро сборки (Build Engine extraction)** — вся логика оркестрации компиляции и сборки полностью вынесена из интерфейсного модуля `src/cli/build.rs` в изолированный, переиспользуемый модуль ядра `src/core/build/engine.rs`.
- **Полиморфная модель языков (Трейт `Language`)** — введение абстрактного трейта `Language` (`src/core/build/language/mod.rs`). Логика поиска файлов, сопоставления расширений и компиляторов распределена по выделенным языковым бэкендам для C, C++ (включая шаги генерации Qt), LLVM IR и ассемблера (GAS, NASM, FASM, MASM).
- **Абстракция сборщиков (Трейт `Builder`)** — введение трейта `Builder` для полиморфного управления процессами компиляции (`src/core/build/builder/mod.rs`). Логика вызова компиляторов семейства GCC/Clang вынесена в общий модуль `builder/cc_common.rs`, а MSVC — в `builder/msvc/`.
- **Поязыковая конфигурация (`[build.<lang>]`)** — добавлена поддержка индивидуальных настроек для каждого языка в `dcr.toml` (например, `[build.c]`, `[build.cpp]`, `[build.asm]`), позволяя независимо настраивать компилятор, стандарт и флаги сборки.
- **Интеграция путей зависимостей в Workspaces** — сборщик теперь автоматически инжектирует пути заголовков (включая исходники `src/` членов, папки `include/` и директорию `target/include`) и библиотек (`target/lib`, а также специфичные для целевой платформы папки сборки) зависимых членов workspace при сборке.
- **Система событий `BuildReporter`** — весь вывод сборщика переведён на событийную модель (`src/core/build/report.rs`), что делает движок пригодным для программного встраивания (например, в IDE) без необходимости перехвата stdout/stderr.
- **Поддержка отмены сборки** — добавлен потокобезопасный токен отмены (`Arc<AtomicBool>`), позволяющий безопасно прервать выполнение компиляции на любом этапе.
- **Сохранение кастомных ключей TOML** — парсер `dcr.toml` переведен на `toml_edit`, что гарантирует сохранение всех неизвестных/пользовательских ключей, комментариев и форматирования при перезаписи файла (например, через `dcr add`).
- **Разрешение заголовков для локальных path-зависимостей** — исправлена проблема, при которой потребители не могли найти заголовочные файлы статических/динамических библиотек, лежащие в упакованной папке `target/include` локальных path-зависимостей.
- **Новая система интеграционных тестов** — старый громоздкий файл `tests/cli_basic.rs` разделен на изолированные и структурированные интеграционные тесты для каждой команды и фичи: `cli_build.rs`, `cli_deps.rs`, `cli_lint.rs`, `cli_new.rs`, `cli_qt.rs`, `cli_test.rs`, `cli_workspace.rs`.
**Изменено:**
- **Дедупликация генерации артефактов** — логика линковки бинарных файлов (ELF, PE, EXE), динамических библиотек (`.so`, `.dll`, `.dylib`) и архивации статических библиотек (`.a`, `.lib`) полностью перенесена в выделенный модуль `src/core/build/builder/artifact.rs`.
- **Запуск членов workspace из корня** — команда `dcr run` при вызове из корня workspace-only проекта теперь запускает сборку выбранного пакета в контексте workspace (через флаг `--workspace`), исключая изолированные ошибки сборки.
- **Отказ от глобального состояния** — все операции сборки изолированы внутри структуры `BuildContext`, обеспечивая многопоточную безопасность сборщика.
- **Вынос логики кэширования** — проверка инкрементальных изменений, отслеживание заголовков (`#include`) и вычисление хэшей сборки перенесено в изолированный модуль `src/core/build/cache.rs`.
- **Модуляризация кастомных шагов** — обработка этапа `build.steps` для препроцессоров вынесена в `src/core/build/steps.rs`.
### EN
**Added:**
- **Dedicated Build Engine (`src/core/build/engine.rs`)** — decoupled the build orchestration logic completely from the CLI front-end wrapper in `src/cli/build.rs` to a reusable, decoupled core build engine.
- **Polymorphic Language Model (`Language` trait)** — introduced the abstract `Language` trait (`src/core/build/language/mod.rs`). File scanning, compiler resolution, and flags handling are now encapsulated in dedicated language modules for C, C++ (including Qt code generation), LLVM IR, and ASM (GAS, NASM, FASM, MASM).
- **Polymorphic Compilation Dispatch (`Builder` trait)** — introduced the `Builder` trait to generalize builder invocations (`src/core/build/builder/mod.rs`). Consolidated GCC/Clang logic into `builder/cc_common.rs` and Microsoft Visual C++ logic into `builder/msvc/`.
- **Per-Language Configuration overrides (`[build.<lang>]`)** — introduced support for configuring language-specific compiler, standard, and flags (e.g. `[build.c]`, `[build.cpp]`, `[build.asm]`) independently in `dcr.toml`.
- **Automatic Workspace Dependency Injection** — during workspace builds, include/lib paths of dependent workspace members (including their source headers, local `include/` folders, and build target `target/include` / `target/lib` folders) are automatically resolved and injected.
- **`BuildReporter` Event System** — decoupled build orchestration output into a structured event-driven reporter model (`src/core/build/report.rs`), making DCR suitable for library embedding and IDE integrations without stderr capturing.
- **Build Cancellation Support** — introduced thread-safe cancellation tokens (`Arc<AtomicBool>`) allowing clients to safely abort compile runs mid-execution.
- **TOML Formatting & Custom Keys Preservation** — migrated the config editor to `toml_edit`, preserving all unknown/user-defined TOML keys, structures, and comments during file write operations (e.g., in `dcr add`).
- **Path Dependencies Target Include Resolution** — local path dependencies configured via tables now correctly expose headers built and packaged into their `target/include` folder to consumer packages.
- **Modular Integration Test Suite** — refactored the monolith `tests/cli_basic.rs` file into clean, specialized integration tests: `cli_build.rs`, `cli_deps.rs`, `cli_lint.rs`, `cli_new.rs`, `cli_qt.rs`, `cli_test.rs`, `cli_workspace.rs`.
**Changed:**
- **Consolidated Linking and Archiving** — artifact generation (linking executables/shared libraries and archiving static libraries) consolidated into a single `src/core/build/builder/artifact.rs` module.
- **Workspace-Aware member execution** — `dcr run` executed at the workspace root of a `workspace_only` project now triggers the member build inside the workspace context using the `--workspace` parameter, preventing standalone build issues.
- **Elimination of Global State** — removed global variables and states from the build core, encapsulating build logic inside isolated `BuildContext` structs for thread safety.
- **Build Cache Separation** — relocated mtime tracking, incremental caching, and header-dependency checking logic to `src/core/build/cache.rs`.
- **Modularized Pre-build Steps** — decoupled generator scripts and pre-build commands parsing into `src/core/build/steps.rs`.
## [0.7.4] - 2026-06-17 "Qt Поддержка, Linting и Рефакторинг Архитектуры / Qt Support, Linting, & Architecture Refactor"
### RU
**Добавлено:**
- **Нативная поддержка Qt** — добавлена автоматическая обработка мета-объектов (MOC, UIC, RCC) при включении `build.qt = true` в `dcr.toml`.
- **Команда `dcr lint`** — статический анализ C/C++ через `clang-tidy`. Поддерживает `--fix` для автоматического исправления. Уважает `build.roots` и `build.src_disable` из конфига.
- **Три новых ассемблерных бэкенда**:
- **MASM** (`compiler = "ml"` / `"ml64"`) — Microsoft Macro Assembler.
- **FASM** (`compiler = "fasm"`) — Flat Assembler.
- **LLVM IR** (`compiler = "llc"`) — компиляция `.ll` → объектный файл.
- **Общий ASM-пайплайн** — линковка и архивирование вынесены в `core/builder/asm.rs`. Новый ассемблерный бэкенд теперь пишется за ~30 строк.
- **Утилиты для файловой системы** — `to_hex()` и `home_dir()` вынесены в `utils/fs.rs`.
- **Утилиты для сборки** — `normalize_target()`, `normalize_kind()`, `normalize_platform()`, `default_profile_flags()` вынесены в `utils/build.rs`.
- **Утилиты для бэкендов** — `asm_lang_flag()`, `source_extensions()`, `elapsed_secs()` добавлены в `core/builder/common.rs`.
- **Полноценная автоматизация Bare-Metal / Freestanding** — добавлен конфигурационный флаг `build.freestanding = true`. При его включении (или при обнаружении bare-metal таргета) DCR автоматически инжектирует флаг `-ffreestanding` на этапе компиляции, а также `-nostdlib` и `-static` на этапе линковки.
- **Оптимизация артефактов (LTO и Strip)** — в `dcr.toml` добавлены параметры `build.lto` (авто-инжекция флага `-flto` для компилятора и линкера) и `build.strip` (автоматическое отсекание отладочной информации через флаг `-s` линкера).
- **Контроль многопоточности сборки** — добавлен параметр `build.codegen-units`, позволяющий жестко ограничить максимальное количество параллельных потоков сборки для кастомного движка `parallel_build`.
- **Управление паникой (Panic Abort)** — добавлен параметр `build.panic = "abort"`. Для C++ проектов он автоматически отключает генерацию таблиц раскрутки стека и исключений через флаги `-fno-exceptions`, `-fno-unwind-tables` и `-fno-asynchronous-unwind-tables`.
**Изменено:**
- **Интеллектуальные дефолтные флаги (DCR Defaults)** — генерация дефолтных флагов оптимизации (`-O3`/`-O0`), отладки (`-g`) и предупреждений (`-Wall -Wextra`) теперь автоматически отключается для bare-metal и freestanding целей, если пользователь переопределил `build.cflags`.
- **Глобальный вынос bare-metal детектора** — функция `is_bare_metal_target` вынесена в общие утилиты `src/utils/build.rs` для сквозного использования в конвейере сборки.
- **Рефакторинг архитектуры**:
- `src/config.rs` переименован в `src/templates.rs`.
- Начата консолидация конфигурационной логики и оркестрации сборки.
### EN
**Added:**
- **Native Qt support** — automatic meta-object handling (MOC, UIC, RCC) added when `build.qt = true` is set in `dcr.toml`.
- **`dcr lint` command** — C/C++ static analysis via `clang-tidy`. Supports `--fix` for automatic fixes. Respects `build.roots` and `build.src_disable` from config.
- **Three new assembler backends**:
- **MASM** (`compiler = "ml"` / `"ml64"`) — Microsoft Macro Assembler.
- **FASM** (`compiler = "fasm"`) — Flat Assembler.
- **LLVM IR** (`compiler = "llc"`) — compiles `.ll` files via `llc -filetype=obj`.
- **Shared ASM pipeline** — linking and archiving logic consolidated into `core/builder/asm.rs`. Adding a new assembler backend now takes ~30 lines.
- **Filesystem utilities** — `to_hex()` and `home_dir()` extracted to `utils/fs.rs`.
- **Build utilities** — `normalize_target()`, `normalize_kind()`, `normalize_platform()`, `default_profile_flags()` extracted to `utils/build.rs`.
- **Backend helpers** — `asm_lang_flag()`, `source_extensions()`, `elapsed_secs()` added to `core/builder/common.rs`.
- **Full Bare-Metal / Freestanding Automation** — introduced the `build.freestanding = true` configuration option. When enabled (or when a bare-metal target is detected), DCR automatically injects `-ffreestanding` during compilation and both `-nostdlib` and `-static` during linking.
- **Artifact Optimization (LTO & Strip)** — added `build.lto` (auto-injects `-flto` for compiler and linker) and `build.strip` (automatically strips debug symbols via linker `-s` flag) options to `dcr.toml`.
- **Compilation Thread Control** — added the `build.codegen-units` option to strictly limit the maximum number of parallel jobs utilized by the custom `parallel_build` worker pool.
- **Panic Behavior Management** — added `build.panic = "abort"` support. For C++ targets, it automatically strips exception handling and unwind tables via `-fno-exceptions`, `-fno-unwind-tables`, and `-fno-asynchronous-unwind-tables`.
**Changed:**
- **Intelligent Default Flags Generation** — automated injection of fallback optimization (`-O3`/`-O0`), debug (`-g`), and warning (`-Wall -Wextra`) flags is now suppressed for bare-metal and freestanding builds if `build.cflags` are overridden.
- **Centralized Bare-Metal Detection** — relocated the `is_bare_metal_target` helper to common build utilities (`src/utils/build.rs`) for unified access across the building core.
- **Architectural Refactoring**:
- Renamed `src/config.rs` to `src/templates.rs`.
- Started consolidation of configuration and build orchestration logic.
## [0.7.3] - 2026-06-13 "Оптимизация Зависимостей и VCS / Dependency Optimization & VCS"
### RU
**Добавлено:**
- **Параметр `--vcs` для команд `new` и `init`** — добавлена возможность явно указывать систему контроля версий через `--vcs <git|none>`.
- **Интеграция Git-информации в `--version`** — утилита теперь выводит текущий короткий хэш коммита и суффикс `-dirty`, если в репозитории DCR есть незакоммиченные изменения.
- **Автоматическая генерация `.gitignore`** — при инициализации Git-репозитория автоматически создается файл `.gitignore` с исключением директории `/target`.
- **Защита от вложенных репозиториев** — автоматическая инициализация Git теперь пропускается, если `dcr new` или `dcr init` запускаются внутри уже существующего Git-репозитория.
- **Тесты для верификации VCS** — добавлены интеграционные тесты `new_vcs_options_work` и `init_vcs_options_work` для проверки логики инициализации репозиториев.
**Изменено:**
- **Полный отказ от библиотеки `git2`** — работа с Git (клонирование зависимостей, инициализация VCS, проверка статуса) переведена на вызовы системного `git` через `Command`. Это облегчает сборку проекта и убирает необходимость в фичах `vendored` и `openssl`.
- **Миграция с `reqwest` на `ureq`** — в модуле обновления (`flag_update.rs`) тяжелый `reqwest` заменен на легковесный синхронный клиент `ureq 2.10`, что уменьшило оверхед и размер итогового бинарника.
### EN
**Added:**
- **`--vcs` option for `new` and `init` commands** — introduced explicit version control system selection via `--vcs <git|none>`.
- **Git metadata integration in `--version`** — the CLI now appends the current short commit hash and a `-dirty` suffix if there are uncommitted changes in the DCR repository.
- **Automatic `.gitignore` generation** — Git repository initialization now automatically writes a `.gitignore` file excluding the `/target` directory.
- **Nested repository prevention** — automatic Git initialization is now skipped if `dcr new` or `dcr init` is executed inside an already existing Git repository.
- **VCS verification tests** — added `new_vcs_options_work` and `init_vcs_options_work` integration tests to ensure reliable repository behavior.
**Changed:**
- **Complete removal of `git2` dependency** — all Git actions (dependency fetching, VCS setup, status checks) are now delegated to the system `git` executable via `Command`. This simplifies compilation and drops the need for `vendored` and `openssl` features.
- **Migrated from `reqwest` to `ureq`** — replaced the heavy `reqwest` crate in `flag_update.rs` with the lightweight synchronous `ureq 2.10` client, reducing overhead and the final binary size.
## [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"
### RU
**Добавлено:**
- Вывод `--help` для всех команд с цветным форматированием.
- man-страницы (12 штук в `man/man1/`) и их установка во всех пакетах.
- Валидация имен проектов в `dcr init` и `dcr new` (только ASCII буквы, цифры, `_` и `-`).
- Метаданные `documentation` и `homepage` в `Cargo.toml`.
- Оптимизация сборки: `opt-level = "z"`, LTO, `codegen-units = 1`, `panic = "abort"`, `strip = true`.
- Поддержка новых архитектур (i686, armv7, riscv64gc, aarch64) в рабочих процессах и установочных скриптах.
- Сборка пакетов `deb` и `rpm` для всех 5 архитектур Linux через `cargo-zigbuild`.
- Пакеты AUR (`dcr-dev`, `dcr-dev-bin`) и сборка Snap в CI.
**Изменено:**
- Функция `validate_package_name` стала публичной.
- Команды `gen`, `tree`, `fmt`, `setup` больше не игнорируют аргументы и используют цветной вывод.
- Инструкция в README изменена с `| bash` на `| sh` для POSIX.
- Отключена архитектура Windows 32-bit (GNU) из-за проблем со сборкой.
**Исправлено:**
- **`dcr new <invalid-name>` создаёт директорию, затем падает** — валидация теперь происходит до операций с файлами.
- **`dcr init` создаёт dcr.toml, затем падает при невалидном имени директории** — то же исправление.
- **Man-страницы отсутствовали после установки** — теперь устанавливаются через скрипты установки, пакетные менеджеры и Homebrew.
- **Ложное срабатывание на букву диска в Windows** — в парсинге файлов зависимостей.
- **CRLF `\r\n` ломает парсер зависимостей** — теперь обрабатываются смешанные окончания строк.
- **Новая строка после обратного слеша не поглощалась** — в обработке escape-последовательностей `parse_d_file`.
### EN
**Added:**
- `--help` for all commands with styled headers and usage lines.
- Man pages (12 troff man pages in `man/man1/`) and their installation across all packaging formats.
- Project name validation in `dcr init` and `dcr new` (ASCII letters, digits, `_`, `-` only).
- `documentation` and `homepage` metadata in `Cargo.toml`.
- Release profile optimizations (`opt-level = "z"`, LTO, `codegen-units = 1`, `panic = "abort"`, `strip = true`).
- Linux i686, armv7, riscv64gc, aarch64 architecture support in release workflows and installation scripts.
- Multi-arch `deb` and `rpm` package builds for all 5 Linux architectures via `cargo-zigbuild`.
- AUR packages (`dcr-dev`, `dcr-dev-bin`) and Snap build in CI.
**Changed:**
- `validate_package_name` made public and callable from CLI commands directly.
- `gen.rs`, `tree.rs`, `fmt.rs`, `setup.rs` no longer ignore arguments and use styled output.
- README install instructions changed from `| bash` to `| sh` for POSIX compatibility.
- Disabled Windows 32-bit (GNU) target due to build issues.
Fixed:
- **`dcr new <invalid-name>` creates directory then fails** — validation now happens
before any file operations.
- **`dcr init` creates dcr.toml then fails on invalid directory name** — same fix.
- **Man pages missing after installation** — now installed via install scripts,
package managers, and Homebrew.
- **Windows drive letter false positive** — in dependency file parsing.
- **CRLF `\r\n` breaks dependency parser** — now handles mixed line endings.
- **Newline after backslash not consumed** — in `parse_d_file` escape handling.
## [0.7.0] - 2026-06-02
Added:
- **OpenBSD and NetBSD target support** — full platform routing with dynamically generated target triples using `std::env::consts::ARCH` and `std::env::consts::OS`. Affects `build`, `run`, `clean`, and the platform module.
- **`src/platform/bsd.rs`** — new dedicated BSD platform module shared by FreeBSD, OpenBSD, NetBSD, providing `bin_path`, `lib_path`, `elf_path`, `efi_path`, and `shared_lib_path`.
- **`build.out_dir` configuration option** — custom output directory that overrides the default `target/<triple>/<profile>` path for final artifacts. Supported in `build`, `run`, and config validation.
- **`dcr fmt` command** — new CLI command that formats all C/C++ source files (`*.c`, `*.cpp`, `*.h`, `*.hpp`) in `src/` and `tests/` using `clang-format`.
- **Incremental linking** — `needs_link()` function in `common.rs` that checks whether any object file is newer than the linked output, skipping unnecessary re-linking. Implemented for all backends (`unix_cc`, `msvc`, `gas`, `nasm`).
- **`build.kind = "none"` and `"custom"`** — two new project kind types for special build scenarios where no standard artifact is produced.
- **`install_bsd.sh`** — dedicated POSIX-compliant install script for BSD systems (FreeBSD, OpenBSD, NetBSD) with binary download and source build modes.
- **Linux ARM64 support in `install.sh`** — added `Linux:aarch64|Linux:arm64` target triple detection for pre-built binary downloads.
- **BSD OS detection in `install.sh`** — FreeBSD, OpenBSD, NetBSD detection and target triple resolution.
- **`rust-toolchain.toml`** — explicit `stable` channel toolchain pinning.
- **Nix support** — `flake.nix` for Nix package manager. Run via `nix run github:dexoron/dcr` or install with `nix profile install github:dexoron/dcr`. Contributed by community contributor.
- **Snapcraft publish** — `dcrup` published on Snapcraft. Install with `sudo snap install dcrup`.
- **Integration tests** — `build_with_target_config` (verifies `build.target = "linux"`) and `build_with_out_dir` (verifies custom output directory).
- **`get_build_string_with_profile` made `pub`** — so `run.rs` can resolve custom output directory configuration.
Changed:
- **`build.target` semantics changed** — now strictly holds the target triple (e.g. `x86_64-unknown-linux-gnu`) or a short name (`linux`, `macos`, `windows`). No longer doubles as a custom output directory — that functionality moved to `build.out_dir`.
- **`build.standard` made optional** — changed from `String` to `Option<String>`. Validation only enforces non-empty for non-ASM languages. Skipped in `dcr.toml` output when empty.
- **`dcr run` with `out_dir`** — now resolves target directory respecting `build.out_dir` when configured, via `get_build_string_with_profile()` from `build.rs`.
- **`collect_sources()` returns empty vec** instead of error when no source files are found, allowing `kind = "none"` or `kind = "custom"` projects to have no source files.
- **CI/CD release workflow refactored** — `git2` made target-specific (no vendored-openssl on Windows), Zig-based cross-compilation for non-x86_64 Linux targets, Arch Linux package version sanitization (dashes → dots), NetBSD `gmake` symlink.
- **README compatibility table** — FreeBSD, OpenBSD, NetBSD build/runtime status upgraded from community/best-effort to officially supported.
- **Documentation rewritten** — available at [dcr.dexoron.su/docs](https://dcr.dexoron.su/docs) or in the `docs/` directory. Installation guides, commands, and reference updated to reflect current CLI and config format.
- **Site rewritten** — `dcr-site` migrated to Docusaurus with internationalization (i18n) support, improved navigation, and updated content across all sections.
- **Dev channel dependency check in `install.sh`** — checks for `python3` or `jq` before attempting dev channel installations.
Fixed:
- **`dcr run` stdout/stderr not inherited** — child process output was captured and manually printed, breaking interactive programs. Fixed by switching to `Command::status()`.
- **Release CI race condition** — build matrix jobs could upload assets to a release that did not yet exist. Fixed by adding a dedicated `create-release` job.
- **GHA release — stable toolchain override** — resolved Rust toolchain override issues in CI.
- **Arch Linux package version sanitization** — version strings with dashes (e.g. `0.7.0-dev`) are invalid for Arch Linux `pkgver`. Fixed by replacing dashes with dots.
- **GPG permissions after Docker** — Docker operations changed GPG directory ownership. Fixed by running `chown` after Docker commands.
- **RPM package artifact paths** — RPM artifacts placed under `rpm/x86_64/` instead of `fedora/x86_64/`. Corrected in Dexoron Packages Index workflow.
- **`install.sh` JSON parsing robustness** — added `jq` as primary parser with `python3` fallback for dev channel release lookups.
Removed:
- **`format_roots()` helper** — removed from `common.rs`. Was only used by the old error path in `collect_sources()`.
- **Individual per-distro artifact download steps** — three separate `actions/download-artifact` steps replaced with unified `gh release download --clobber`.
## [0.6.9] - 2026-05-28
Added:
@@ -114,6 +596,7 @@ Added:
```
Produces `KERNEL.EFI` (works for `bin`, `staticlib`, and `sharedlib`).
- Automatic injection of `--target=<build.target>` into compiler flags when `build.target` is set in `dcr.toml`. This greatly simplifies clang-based cross-compilation (especially for bare-metal targets like `aarch64-none-elf`).
- Bare-metal targets (containing `none`, `-elf`, `eabi`, `baremetal`) no longer receive DCR's internal default flags (`-g`, `-Wall`, `-Wextra`, `-fno-omit-frame-pointer`, `-DDCR_DEBUG`, etc.). Prevents unwanted sections (`.comment`, debug info, etc.) that break custom linker scripts when `inherit = true`.
- `build.ldscript` in `dcr.toml` — linker script path passed as `-T <path>` to the linker. Essential for bare-metal/embedded/freestanding targets.
@@ -148,28 +631,28 @@ 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
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/`)
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
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
`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`
`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)
— 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`
`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`)

View File

@@ -33,7 +33,7 @@ DCR supports cross-compilation via `--target <triple>` or short names:
- Configure multiple targets in `dcr.toml`:
```toml
[build.targets]
[build]
targets = ["linux", "macos"]
[build.linux]

1321
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,11 +1,13 @@
[package]
name = "dcr"
version = "0.6.9"
version = "0.8.5"
edition = "2024"
build = "build.rs"
description = "DCR is a utility for managing C/C++ projects in a Cargo-like style."
license = "GPL-3.0-or-later"
repository = "https://github.com/dexoron/dcr"
documentation = "https://dcr-tool.ru/docs"
homepage = "https://dcr-tool.ru"
[package.metadata.binstall]
pkg-fmt = "bin"
@@ -21,6 +23,18 @@ section = "devel"
priority = "optional"
assets = [
["target/release/dcr", "usr/bin/dcr", "755"],
["man/man1/dcr.1", "usr/share/man/man1/dcr.1", "644"],
["man/man1/dcr-add.1", "usr/share/man/man1/dcr-add.1", "644"],
["man/man1/dcr-build.1", "usr/share/man/man1/dcr-build.1", "644"],
["man/man1/dcr-clean.1", "usr/share/man/man1/dcr-clean.1", "644"],
["man/man1/dcr-fmt.1", "usr/share/man/man1/dcr-fmt.1", "644"],
["man/man1/dcr-gen.1", "usr/share/man/man1/dcr-gen.1", "644"],
["man/man1/dcr-init.1", "usr/share/man/man1/dcr-init.1", "644"],
["man/man1/dcr-new.1", "usr/share/man/man1/dcr-new.1", "644"],
["man/man1/dcr-run.1", "usr/share/man/man1/dcr-run.1", "644"],
["man/man1/dcr-setup.1", "usr/share/man/man1/dcr-setup.1", "644"],
["man/man1/dcr-test.1", "usr/share/man/man1/dcr-test.1", "644"],
["man/man1/dcr-tree.1", "usr/share/man/man1/dcr-tree.1", "644"],
]
[package.metadata.generate-rpm]
@@ -30,19 +44,48 @@ Cargo-like utility to manage C/C++ projects.
"""
assets = [
{ source = "target/release/dcr", dest = "/usr/bin/dcr", mode = "755" }
{ source = "target/release/dcr", dest = "/usr/bin/dcr", mode = "755" },
{ source = "man/man1/dcr.1", dest = "/usr/share/man/man1/dcr.1", mode = "644" },
{ source = "man/man1/dcr-add.1", dest = "/usr/share/man/man1/dcr-add.1", mode = "644" },
{ source = "man/man1/dcr-build.1", dest = "/usr/share/man/man1/dcr-build.1", mode = "644" },
{ source = "man/man1/dcr-clean.1", dest = "/usr/share/man/man1/dcr-clean.1", mode = "644" },
{ source = "man/man1/dcr-fmt.1", dest = "/usr/share/man/man1/dcr-fmt.1", mode = "644" },
{ source = "man/man1/dcr-gen.1", dest = "/usr/share/man/man1/dcr-gen.1", mode = "644" },
{ source = "man/man1/dcr-init.1", dest = "/usr/share/man/man1/dcr-init.1", mode = "644" },
{ source = "man/man1/dcr-new.1", dest = "/usr/share/man/man1/dcr-new.1", mode = "644" },
{ source = "man/man1/dcr-run.1", dest = "/usr/share/man/man1/dcr-run.1", mode = "644" },
{ source = "man/man1/dcr-setup.1", dest = "/usr/share/man/man1/dcr-setup.1", mode = "644" },
{ source = "man/man1/dcr-test.1", dest = "/usr/share/man/man1/dcr-test.1", mode = "644" },
{ source = "man/man1/dcr-tree.1", dest = "/usr/share/man/man1/dcr-tree.1", mode = "644" },
]
[features]
default = []
archive = ["dep:fatfs"]
[dependencies]
glob = "0.3"
reqwest = { version = "0.12", default-features = false, features = ["blocking", "json", "rustls-tls"] }
ureq = { version = "2.10", default-features = false, features = ["json", "native-certs"] }
serde = { version = "1", features = ["derive"] }
self-replace = "1"
sha2 = "0.10"
toml = "1.0.3"
toml_edit = "0.22"
serde_json = "1"
ctrlc = "3"
git2 = { version = "0.20.4", features = ["vendored-libgit2", "vendored-openssl"] }
fatfs = { version = "0.3", optional = true }
[target.'cfg(not(windows))'.dependencies]
openssl = { version = "0.10", features = ["vendored"] }
[profile.release]
opt-level = "z"
lto = "thin"
codegen-units = 1
panic = "abort"
strip = true
[profile.fast]
inherits = "release"
opt-level = 1
lto = false
codegen-units = 16
panic = "abort"
strip = true

108
README.md
View File

@@ -1,31 +1,32 @@
<div align="center">
<h1 align="center">DCR — Dexoron Cargo Realization</h1>
# DCR — Dexoron Cargo Realization
<p align="center"><strong>A Cargo-style build tool for C/C++ projects</strong></p>
**A Cargo-style build tool for C/C++ projects**
<p align="center">
<a href="https://github.com/dexoron/dcr/actions/workflows/ci.yml"><img alt="CI" src="https://github.com/dexoron/dcr/actions/workflows/ci.yml/badge.svg"></a>
<a href="https://github.com/dexoron/dcr/releases/latest"><img alt="GitHub Release" src="https://img.shields.io/github/v/release/dexoron/dcr"></a>
<a href="https://github.com/dexoron/dcr/releases"><img alt="Platform" src="https://img.shields.io/badge/platform-linux%20%7C%20macos%20%7C%20windows-lightgrey"></a>
<br>
<a href="https://aur.archlinux.org/packages/dcr"><img alt="AUR" src="https://img.shields.io/aur/version/dcr"></a>
<a href="https://crates.io/crates/dcr"><img alt="Crates.io" src="https://img.shields.io/crates/v/dcr"></a>
<a href="https://github.com/dexoron/homebrew-dexoron"><img alt="Homebrew" src="https://img.shields.io/badge/homebrew-dexoron%2Fdexoron-orange"></a>
<br>
<a href="https://github.com/dexoron/dcr/stargazers"><img alt="GitHub Stars" src="https://img.shields.io/github/stars/dexoron/dcr?style=flat"></a>
<a href="LICENSE"><img alt="License: GPL-3.0" src="https://img.shields.io/badge/License-GPL--3.0-blue.svg"></a>
</p>
[![CI](https://github.com/dexoron/dcr/actions/workflows/ci.yml/badge.svg)](https://github.com/dexoron/dcr/actions/workflows/ci.yml)
[![GitHub Release](https://img.shields.io/github/v/release/dexoron/dcr)](https://github.com/dexoron/dcr/releases/latest)
[![Platform](https://img.shields.io/badge/platform-linux%20%7C%20macos%20%7C%20windows-lightgrey)](https://github.com/dexoron/dcr/releases)
<br/>
[![AUR](https://img.shields.io/aur/version/dcr)](https://aur.archlinux.org/packages/dcr)
[![Crates.io](https://img.shields.io/crates/v/dcr)](https://crates.io/crates/dcr)
[![Homebrew](https://img.shields.io/badge/homebrew-dexoron%2Fdexoron-orange)](https://github.com/dexoron/homebrew-dexoron)
<br/>
[![GitHub Stars](https://img.shields.io/github/stars/dexoron/dcr?style=flat)](https://github.com/dexoron/dcr/stargazers)
[![License: GPL-3.0](https://img.shields.io/badge/License-GPL--3.0-blue.svg)](LICENSE)
</div>
<!-- Snap badge removed: classic confinement was denied for this project. -->
---
## Why DCR?
- **No boilerplate** — one config file, predictable structure
- **Cargo-like workflow** — `build`, `run`, `clean`, `test`, `add`
- **Cargo-like workflow** — `build`, `run`, `clean`, `test`, `add`, `fmt`
- **Cross-compilation** — full target triple support with short names
- **IDE integration** — VS Code, CLion, `compile_commands.json` out of the box
- **Dependencies** — path, git, and registry-based with lock file
- **Man pages** — `man dcr` and per-command pages (`man dcr-build`, `man dcr-new`, etc.)
---
@@ -51,6 +52,18 @@ brew tap dexoron/dexoron
brew install dcr
```
</td>
</tr>
<tr>
<td><b>Nix (flake)</b></td>
<td>
```sh
nix run github:dexoron/dcr
# or install to profile:
nix profile install github:dexoron/dcr
```
</td>
</tr>
<tr>
@@ -64,21 +77,41 @@ cargo install dcr
</td>
</tr>
<tr>
<td><b>Linux / macOS (script)</b></td>
<td><b>dcrup (Linux / macOS / BSD / Windows(Bash))</b></td>
<td>
```sh
curl -fsSL https://dcr.dexoron.su/install.sh | bash
curl -fsSL https://sh.dcr-tool.ru | sh -s -- self-install
export PATH="$HOME/.dcr/bin:$PATH"
dcrup install stable
```
</td>
</tr>
<tr>
<td><b>Windows (PowerShell)</b></td>
<td><b>dcrup (Windows PowerShell)</b></td>
<td>
```powershell
irm https://dcr.dexoron.su/install.ps1 | iex
irm https://ps1.dcr-tool.ru | iex
# or:
# irm https://ps1.dcr-tool.ru -OutFile dcrup.ps1
# powershell -File .\dcrup.ps1 self-install
# $env:Path += ";$env:USERPROFILE\.dcr\bin"
dcrup install stable
```
</td>
</tr>
<tr>
<td><b>Snap (Linux)</b></td>
<td>
> Snap Store publishing temporarily disabled — see [#51671](https://forum.snapcraft.io/t/classic-confinement-request-for-dcrup/51671).
> Download the `.snap` from [GitHub Releases](https://github.com/dexoron/dcr/releases/latest) and install manually:
```sh
sudo snap install --classic --dangerous dcrup_*.snap
```
</td>
@@ -89,7 +122,7 @@ irm https://dcr.dexoron.su/install.ps1 | iex
```sh
git clone https://github.com/dexoron/dcr.git
cd dcr && cargo build --release
cd dcr && cargo build --release --features archive
ln -sf "$PWD/target/release/dcr" ~/.local/bin/dcr
```
@@ -142,28 +175,36 @@ kind = "bin"
|---|---|
| `dcr new <name>` | Create a new project |
| `dcr init` | Initialize current directory |
| `dcr add <dep>` | Add a dependency |
| `dcr build [--release]` | Build the project |
| `dcr run [--release]` | Build and run |
| `dcr clean` | Remove build artifacts |
| `dcr test` | Run project tests |
| `dcr fmt` | Format C/C++ sources (clang-format) |
| `dcr tree` | View dependency tree |
| `dcr gen <vscode\|clion\|compile-commands>` | Generate IDE integration |
| `dcr setup` | Initialize DCR registry |
other in [docs/](docs/) and `dcr --help`
other in [docs/](docs/), `dcr --help` and `dcr <command> --help`
---
## Platforms
## Platforms (pre-built binary)
<div align="center">
| OS | x86_64 | aarch64 | armv7 | i686 | riscv64 | GNU | Musl | MSVC | MinGW |
|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
| Linux | ✅ | ✅ | ❌ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ |
| macOS | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Windows | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ |
| FreeBSD | ⚠️ | ⚠️ | ❌ | ❌ | ❌ | ⚠️ | ❌ | ❌ | ❌ |
| OpenBSD | ⚠️ | ⚠️ | ❌ | ❌ | ❌ | ⚠️ | ❌ | ❌ | ❌ |
| NetBSD | ⚠️ | ⚠️ | ❌ | ❌ | ❌ | ⚠️ | ❌ | ❌ | ❌ |
| OS | x86_64 | aarch64 | armv7 | i686 | riscv64 |
|:---:|:---:|:---:|:---:|:---:|:---:|
| Linux (GNU) | ✅ | ✅ | ✅ | ✅ | ✅ |
| Linux (Musl) | ✅ | ✅ | ✅ | ✅ | 🚧 |
| macOS | ✅ | ✅ | ❌ | ❌ | ❌ |
| Windows (MSVC) | ✅ | ✅ | ❌ | ✅ | ❌ |
| Windows (MinGW) | ✅ | 🚧 | ❌ | ❌ | ❌ |
| FreeBSD | ✅ | 🚧 | ❌ | ❌ | ❌ |
| OpenBSD | ✅ | 🚧 | ❌ | ❌ | ❌ |
| NetBSD | ✅ | 🚧 | ❌ | ❌ | ❌ |
✅ officially supported · ⚠️ community / best-effort · ❌ not supported
✅ pre-built binary · 🚧 planned · ❌ not supported by platform or CI
</div>
@@ -203,6 +244,7 @@ cargo test
<div align="center">
GPL-3.0 — see [LICENSE](LICENSE)<br/>
DCR is a build tool, not a library. The GPL applies only to DCR's own source code, not to projects built with it.<br/>
Made with ❤️ by [Dexoron](https://github.com/dexoron) and contributors.
</div>
</div>

69
TODO.md
View File

@@ -1,69 +0,0 @@
# DCR TODO.md
Priority list of tasks to turn DCR into a true Cargo killer for C/C++ developers.
## 🔥 High Priority (Next Releases)
- [x] **Git dependencies support**
`git = "https://github.com/user/repo.git#branch"` and `git = "..."@tag`
- [ ] **Conan and vcpkg integration**
Automatic download, installation and linking of packages
- [ ] **Full freestanding / embedded support**
`-nostdlib`, linker scripts, bare-metal targets (i686-elf, aarch64-none-elf, etc.)
- [ ] **EFI support**
Dedicated platform configuration for EFI targets
- [ ] **Custom project name**
Override binary name in `dcr.toml`
- [ ] **Custom build steps / targets**
Ability to define custom pre-build, post-build, codegen steps in `dcr.toml`
- [ ] **Improved mixed C/C++/ASM projects**
Better handling of `.S` and `.asm` files with correct flags
- [ ] **dcr publish + official package registry**
Publish and fetch your own libraries easily
## ✅ Medium Priority
- [ ] **Static analysis** (`dcr check`)
Integration with clang-tidy, cppcheck, include-what-you-use
- [ ] **Linter + Formatter** (`dcr fmt`, `dcr lint`)
- [ ] **Hot reload / Live reload** for applications (raylib, SFML, SDL, etc.)
- [ ] **Better cross-compilation experience**
Ready-to-use toolchains + automatic download
- [ ] **Linker script support** + direct linker control
- [ ] **Workspaces improvements**
Per-member include directories, selective builds, better dependency graph
- [ ] **Build-time code generation**
Support for protobuf, flatbuffers, Qt moc, custom generators
## 📌 Low Priority / Nice to Have
- [ ] Support for Meson and Ninja as alternative backends
- [ ] Dockerfile generation (`dcr docker init`)
- [ ] First-class Windows MSVC support (currently works but rough)
- [ ] Documentation generation (`dcr doc`)
- [ ] Sanitizers integration (`dcr sanitize`)
- [ ] Benchmarks and comparison with CMake/Meson
- [ ] C++20 modules support (when it becomes stable)
## 🧠 Future Ideas
- Official DCR package registry (dcrhub)
- GUI wrapper (dcr-gui)
- Plugin system
- Toolchain manager (like rustup)
- Zig as alternative compiler
- deb/rpm/flatpak/AppImage packaging support
---
**Currently in progress:**
- ...
**Completed in recent releases:**
- Workspaces
- Cross-compilation
- IDE config generation (VS Code, CLion, compile_commands.json)
- Self-update (`dcr --update`)
- Header tracking

View File

@@ -18,4 +18,37 @@
fn main() {
let target = std::env::var("TARGET").unwrap_or_else(|_| "unknown-target".to_string());
println!("cargo:rustc-env=DCR_TARGET={target}");
// Let's try to retrieve the commit hash for the version
let commit = std::process::Command::new("git")
.args(["rev-parse", "--short", "HEAD"])
.output()
.ok()
.and_then(|o| {
if o.status.success() {
String::from_utf8(o.stdout)
.ok()
.map(|s| s.trim().to_string())
} else {
None
}
});
// Check if there are any uncommitted changes in the repository
let is_dirty = std::process::Command::new("git")
.args(["status", "--porcelain"])
.output()
.ok()
.map(|o| o.status.success() && !o.stdout.is_empty())
.unwrap_or(false);
if let Some(commit_hash) = commit {
let dirty_suffix = if is_dirty { "-dirty" } else { "" };
println!(
"cargo:rustc-env=DCR_GIT_INFO= (git {}{})",
commit_hash, dirty_suffix
);
} else {
println!("cargo:rustc-env=DCR_GIT_INFO=");
}
}

3
crowdin.yml Normal file
View File

@@ -0,0 +1,3 @@
files:
- source: /docs/**/*.mdx
translation: /docs-crowdin-export/%locale%/%original_path%/%original_file_name%.%file_extension%

13
dcrup.cmd Executable file
View File

@@ -0,0 +1,13 @@
@echo off
setlocal
set "SCRIPT_DIR=%~dp0"
if exist "%SCRIPT_DIR%dcrup.ps1" (
powershell -NoProfile -ExecutionPolicy Bypass -File "%SCRIPT_DIR%dcrup.ps1" %*
exit /b %ERRORLEVEL%
)
if exist "%USERPROFILE%\.dcr\bin\dcrup.ps1" (
powershell -NoProfile -ExecutionPolicy Bypass -File "%USERPROFILE%\.dcr\bin\dcrup.ps1" %*
exit /b %ERRORLEVEL%
)
echo [error] dcrup.ps1 not found near dcrup.cmd >&2
exit /b 1

367
dcrup.ps1 Normal file
View File

@@ -0,0 +1,367 @@
#Requires -Version 5.1
$ErrorActionPreference = 'Stop'
$DcrupHome = if ($env:DCRUP_HOME) { $env:DCRUP_HOME } else { Join-Path $env:USERPROFILE '.dcr' }
$DcrupBin = if ($env:DCRUP_BIN) { $env:DCRUP_BIN } else { Join-Path $DcrupHome 'bin' }
$DcrupTc = Join-Path $DcrupHome 'toolchains'
$DcrupMeta = Join-Path $DcrupHome 'meta'
$RepoUrl = if ($env:DCRUP_REPO) { $env:DCRUP_REPO } else { 'https://github.com/dexoron/dcr' }
$ApiLatest = 'https://api.github.com/repos/dexoron/dcr/releases/latest'
$ApiAll = 'https://api.github.com/repos/dexoron/dcr/releases'
$Features = if ($env:DCR_FEATURES) { $env:DCR_FEATURES } else { 'archive' }
function Info($m) { Write-Host "[dcrup] $m" -ForegroundColor Cyan }
function Ok($m) { Write-Host "[ok] $m" -ForegroundColor Green }
function Warn($m) { Write-Host "[warn] $m" -ForegroundColor Yellow }
function Die($m) { Write-Host "[error] $m" -ForegroundColor Red; exit 1 }
function Show-Usage {
@'
dcrup — install and switch DCR versions (Windows)
Usage:
dcrup install <spec> [--build|--release] [--force]
dcrup default <spec>
dcrup update
dcrup list
dcrup show
dcrup which
dcrup uninstall [<spec>|--all]
dcrup self-install [--to DIR]
dcrup help
Spec:
stable | dev | night
VERSION → VERSION@stable (e.g. 0.8.2)
VERSION@stable
VERSION@dev
night → always build from branch "dev" HEAD
Modes:
--release download GitHub Release binary (default for stable/dev)
--build cargo build --release --features archive
night always --build (prebuilt not available)
Env:
DCRUP_HOME default ~/.dcr
DCRUP_BIN default $DCRUP_HOME/bin
DCR_FEATURES default archive
DCRUP_REPO git/GitHub repo URL
'@ | Write-Host
}
function Ensure-Dirs {
New-Item -ItemType Directory -Force -Path $DcrupTc, $DcrupBin, $DcrupMeta | Out-Null
}
function Get-Target {
$arch = $env:PROCESSOR_ARCHITECTURE
if ($env:PROCESSOR_ARCHITEW6432) { $arch = $env:PROCESSOR_ARCHITEW6432 }
switch ($arch) {
'AMD64' { return 'x86_64-pc-windows-msvc' }
'ARM64' { return 'aarch64-pc-windows-msvc' }
'x86' { return 'i686-pc-windows-msvc' }
default { Die "unsupported arch: $arch" }
}
}
function Normalize-Version([string]$v) {
if ($v.StartsWith('v')) { return $v.Substring(1) }
return $v
}
function Parse-Spec([string]$raw) {
$script:SpecRaw = $raw
$script:SpecChannel = $null
$script:SpecVersion = $null
$script:SpecFloating = $false
if ($raw -in @('stable', 'dev', 'night')) {
$script:SpecChannel = $raw
$script:SpecFloating = $true
return
}
if ($raw -match '^(.*)@(.*)$') {
$script:SpecVersion = Normalize-Version $Matches[1]
$script:SpecChannel = $Matches[2]
if ($script:SpecChannel -eq 'night') { Die 'cannot pin version on night' }
if ($script:SpecChannel -notin @('stable', 'dev')) { Die "unknown channel: $($script:SpecChannel)" }
return
}
$script:SpecVersion = Normalize-Version $raw
$script:SpecChannel = 'stable'
}
function Toolchain-Id([string]$extra = '') {
if ($script:SpecChannel -eq 'night') {
return "night-$extra"
}
if ($script:SpecFloating) {
return "$($script:SpecChannel)-$extra"
}
return "$($script:SpecVersion)-$($script:SpecChannel)"
}
function Active-Path { Join-Path $DcrupMeta 'active' }
function Read-Active {
$p = Active-Path
if (Test-Path $p) { return (Get-Content $p -Raw).Trim() }
return $null
}
function Write-Active([string]$id) {
Set-Content -Path (Active-Path) -Value $id -NoNewline
}
function Link-Default([string]$id) {
$src = Join-Path (Join-Path $DcrupTc $id) 'dcr.exe'
if (-not (Test-Path $src)) { Die "toolchain not installed: $id" }
$dst = Join-Path $DcrupBin 'dcr.exe'
Copy-Item $src $dst -Force
Write-Active $id
Ok "default → $id ($dst)"
}
function Fetch-Release($channel, $version) {
if ($version) {
return Invoke-RestMethod -Uri "https://api.github.com/repos/dexoron/dcr/releases/tags/v$version"
}
if ($channel -eq 'dev') {
$all = Invoke-RestMethod -Uri $ApiAll
$pre = $all | Where-Object { $_.prerelease } | Select-Object -First 1
if (-not $pre) { Die 'no prerelease (dev) found' }
return $pre
}
return Invoke-RestMethod -Uri $ApiLatest
}
function Install-Prebuilt([switch]$Force) {
$triple = Get-Target
$rel = Fetch-Release $script:SpecChannel $script:SpecVersion
$tag = $rel.tag_name
$ver = Normalize-Version $tag
$assetName = "dcr-$triple-$ver.exe"
$asset = $rel.assets | Where-Object { $_.name -eq $assetName } | Select-Object -First 1
if (-not $asset) { Die "asset not found: $assetName" }
$id = if ($script:SpecFloating) { Toolchain-Id $ver } else { Toolchain-Id }
$dest = Join-Path $DcrupTc $id
$bin = Join-Path $dest 'dcr.exe'
if ((Test-Path $bin) -and -not $Force) {
Ok "already installed: $id"
Link-Default $id
return
}
Ensure-Dirs
New-Item -ItemType Directory -Force -Path $dest | Out-Null
Info "downloading $assetName …"
Invoke-WebRequest -Uri $asset.browser_download_url -OutFile $bin
@"
channel=$($script:SpecChannel)
version=$ver
tag=$tag
source=release
triple=$triple
"@ | Set-Content (Join-Path $dest 'dcrup-meta')
Ok "installed prebuilt $id"
Link-Default $id
}
function Install-Build([switch]$Force) {
if (-not (Get-Command git -ErrorAction SilentlyContinue)) { Die 'git not found' }
if (-not (Get-Command cargo -ErrorAction SilentlyContinue)) { Die 'cargo not found' }
$tmp = Join-Path $env:TEMP ("dcrup-" + [guid]::NewGuid().ToString('N'))
New-Item -ItemType Directory -Path $tmp | Out-Null
try {
$src = Join-Path $tmp 'src'
if ($script:SpecChannel -eq 'night') {
Info "cloning dev for night …"
git clone --depth 1 --branch dev $RepoUrl $src 2>$null
if ($LASTEXITCODE -ne 0) { git clone --depth 1 $RepoUrl $src | Out-Null }
$sha = (git -C $src rev-parse --short HEAD).Trim()
$id = Toolchain-Id $sha
$ver = 'night'
} elseif ($script:SpecFloating) {
$rel = Fetch-Release $script:SpecChannel $null
$tag = $rel.tag_name
$ver = Normalize-Version $tag
$id = Toolchain-Id $ver
Info "cloning $tag …"
git clone --depth 1 --branch $tag $RepoUrl $src 2>$null
if ($LASTEXITCODE -ne 0) {
git clone --depth 1 $RepoUrl $src | Out-Null
git -C $src fetch --depth 1 origin "refs/tags/${tag}:refs/tags/${tag}"
git -C $src checkout $tag
}
$sha = (git -C $src rev-parse --short HEAD).Trim()
} else {
$tag = "v$($script:SpecVersion)"
$ver = $script:SpecVersion
$id = Toolchain-Id
Info "cloning $tag …"
git clone --depth 1 --branch $tag $RepoUrl $src 2>$null
if ($LASTEXITCODE -ne 0) {
git clone --depth 1 $RepoUrl $src | Out-Null
git -C $src fetch --depth 1 origin "refs/tags/${tag}:refs/tags/${tag}"
git -C $src checkout $tag
}
$sha = (git -C $src rev-parse --short HEAD).Trim()
}
$dest = Join-Path $DcrupTc $id
$bin = Join-Path $dest 'dcr.exe'
if ((Test-Path $bin) -and -not $Force) {
Ok "already installed: $id"
Link-Default $id
return
}
$triple = Get-Target
Info "building release (features: $Features) …"
Push-Location $src
cargo build --release --features $Features --target $triple
if ($LASTEXITCODE -ne 0) { Die 'cargo build failed' }
Pop-Location
New-Item -ItemType Directory -Force -Path $dest | Out-Null
Copy-Item (Join-Path $src "target\$triple\release\dcr.exe") $bin -Force
@"
channel=$($script:SpecChannel)
version=$ver
git=$sha
source=build
features=$Features
"@ | Set-Content (Join-Path $dest 'dcrup-meta')
Ok "installed build $id"
Link-Default $id
} finally {
Remove-Item -Recurse -Force $tmp -ErrorAction SilentlyContinue
}
}
function Ensure-UserPath {
$userPath = [Environment]::GetEnvironmentVariable('Path', 'User')
if (-not $userPath) { $userPath = '' }
if (-not ($userPath -split ';' | Where-Object { $_ -eq $DcrupBin })) {
$new = if ($userPath) { "$userPath;$DcrupBin" } else { $DcrupBin }
[Environment]::SetEnvironmentVariable('Path', $new, 'User')
$env:Path = "$env:Path;$DcrupBin"
Warn "added to user PATH: $DcrupBin (restart shell if needed)"
}
}
function Install-CmdShim {
$cmd = Join-Path $DcrupBin 'dcrup.cmd'
$ps1 = Join-Path $DcrupBin 'dcrup.ps1'
@"
@echo off
setlocal
powershell -NoProfile -ExecutionPolicy Bypass -File "%~dp0dcrup.ps1" %*
"@ | Set-Content -Path $cmd -Encoding ASCII
if (-not (Test-Path $ps1)) {
Copy-Item $PSCommandPath $ps1 -Force
}
}
function Cmd-Install {
param([string[]]$Args)
$mode = 'release'
$force = $false
$spec = $null
foreach ($a in $Args) {
switch -Regex ($a) {
'^--build$' { $mode = 'build'; continue }
'^--release$' { $mode = 'release'; continue }
'^--force$' { $force = $true; continue }
'^-' { Die "unknown flag: $a" }
default {
if ($spec) { Die "unexpected: $a" }
$spec = $a
}
}
}
if (-not $spec) { Die 'usage: dcrup install <spec> [--build|--release] [--force]' }
Parse-Spec $spec
Ensure-Dirs
if ($script:SpecChannel -eq 'night') { $mode = 'build' }
Info "install spec=$spec channel=$($script:SpecChannel) mode=$mode"
if ($mode -eq 'build') { Install-Build -Force:$force } else { Install-Prebuilt -Force:$force }
Ensure-UserPath
Install-CmdShim
}
function Cmd-List {
Ensure-Dirs
$active = Read-Active
Get-ChildItem $DcrupTc -Directory -ErrorAction SilentlyContinue | ForEach-Object {
$mark = if ($_.Name -eq $active) { ' *' } else { ' ' }
Write-Host "$mark $($_.Name)"
}
}
function Cmd-Show {
Ensure-Dirs
Write-Host "DCRUP_HOME=$DcrupHome"
Write-Host "DCRUP_BIN=$DcrupBin"
Write-Host "active=$(Read-Active)"
$exe = Join-Path $DcrupBin 'dcr.exe'
if (Test-Path $exe) { & $exe --version }
}
function Cmd-SelfInstall {
Ensure-Dirs
Copy-Item $PSCommandPath (Join-Path $DcrupBin 'dcrup.ps1') -Force
Install-CmdShim
Ensure-UserPath
Ok "dcrup installed to $DcrupBin (use: dcrup …)"
}
$cmd = if ($args.Count -ge 1) { $args[0] } else { 'help' }
$rest = @()
if ($args.Count -gt 1) { $rest = $args[1..($args.Count - 1)] }
switch ($cmd) {
{ $_ -in @('help', '-h', '--help') } { Show-Usage }
'install' { Cmd-Install $rest }
'list' { Cmd-List }
'show' { Cmd-Show }
'which' {
$p = Join-Path $DcrupBin 'dcr.exe'
if (Test-Path $p) { $p } else { Die 'dcr not installed' }
}
'default' {
if ($rest.Count -ne 1) { Die 'usage: dcrup default <spec>' }
Parse-Spec $rest[0]
if ($script:SpecFloating -or $script:SpecChannel -eq 'night') {
$id = Get-ChildItem $DcrupTc -Directory |
Where-Object { $_.Name -like "$($script:SpecChannel)-*" } |
Sort-Object Name | Select-Object -Last 1
if (-not $id) { Die "not installed: $($rest[0])" }
Link-Default $id.Name
} else {
Link-Default (Toolchain-Id)
}
}
'update' {
$a = Read-Active
if (-not $a) { Die 'no active toolchain' }
if ($a -like 'night-*') { Cmd-Install @('night', '--build', '--force') }
elseif ($a -like 'stable-*') { Cmd-Install @('stable', '--force') }
elseif ($a -like 'dev-*') { Cmd-Install @('dev', '--force') }
else { Ok "pinned $a — install a newer version explicitly" }
}
'uninstall' {
if ($rest -contains '--all') {
Remove-Item -Recurse -Force $DcrupTc -ErrorAction SilentlyContinue
Remove-Item (Join-Path $DcrupBin 'dcr.exe') -ErrorAction SilentlyContinue
Remove-Item (Active-Path) -ErrorAction SilentlyContinue
Ok 'removed all'
} else {
Die 'use: dcrup uninstall --all (or install a replacement first)'
}
}
'self-install' { Cmd-SelfInstall }
default { Die "unknown command: $cmd" }
}

599
dcrup.sh Executable file
View File

@@ -0,0 +1,599 @@
#!/usr/bin/env bash
set -Eeuo pipefail
DCRUP_HOME="${DCRUP_HOME:-$HOME/.dcr}"
DCRUP_BIN="${DCRUP_BIN:-$DCRUP_HOME/bin}"
DCRUP_TC="${DCRUP_HOME}/toolchains"
DCRUP_META="${DCRUP_HOME}/meta"
REPO_URL="${DCRUP_REPO:-https://github.com/dexoron/dcr}"
API_LATEST="https://api.github.com/repos/dexoron/dcr/releases/latest"
API_ALL="https://api.github.com/repos/dexoron/dcr/releases"
FEATURES="${DCR_FEATURES:-archive}"
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
CYAN='\033[0;36m'
NC='\033[0m'
log() { printf "${CYAN}[dcrup]${NC} %s\n" "$*"; }
ok() { printf "${GREEN}[ok]${NC} %s\n" "$*"; }
warn() { printf "${YELLOW}[warn]${NC} %s\n" "$*"; }
die() { printf "${RED}[error]${NC} %s\n" "$*" >&2; exit 1; }
usage() {
cat <<'EOF'
dcrup — install and switch DCR versions
Usage:
dcrup install <spec> [--build|--release] [--force] [--libc gnu|musl|auto]
dcrup default <spec>
dcrup update
dcrup list
dcrup show
dcrup which
dcrup uninstall [<spec>|--all]
dcrup self-install [--to DIR]
dcrup help
Spec:
stable | dev | night
VERSION → VERSION@stable (e.g. 0.8.2)
VERSION@stable
VERSION@dev
night → always build from branch "dev" HEAD
Modes:
--release download GitHub Release binary (default for stable/dev)
--build cargo build --release --features archive
night always --build (prebuilt not available)
Linux libc (prebuilt triple only):
--libc gnu x86_64-unknown-linux-gnu (default)
--libc musl x86_64-unknown-linux-musl
--libc auto musl if host ldd/libc is musl, else gnu
Env:
DCRUP_HOME default ~/.dcr
DCRUP_BIN default $DCRUP_HOME/bin
DCR_FEATURES default archive
DCRUP_REPO git/GitHub repo URL
DCRUP_LIBC gnu|musl|auto (default: gnu)
EOF
}
need_cmd() {
command -v "$1" >/dev/null 2>&1 || die "required command not found: $1"
}
detect_linux_libc() {
local pref="${DCRUP_LIBC:-gnu}"
case "$pref" in
gnu|glibc) echo "gnu" ;;
musl) echo "musl" ;;
auto)
if command -v ldd >/dev/null 2>&1; then
if ldd --version 2>&1 | grep -qi musl; then
echo "musl"
return 0
fi
fi
if [[ -e /lib/ld-musl-x86_64.so.1 || -e /lib/ld-musl-aarch64.so.1 ]]; then
echo "musl"
return 0
fi
if command -v getconf >/dev/null 2>&1 && getconf GNU_LIBC_VERSION >/dev/null 2>&1; then
echo "gnu"
return 0
fi
echo "gnu"
;;
*) die "invalid DCRUP_LIBC / --libc: $pref (use gnu|musl|auto)" ;;
esac
}
detect_triple() {
local os arch libc
os="$(uname -s)"
arch="$(uname -m)"
case "$os:$arch" in
Linux:x86_64)
libc="$(detect_linux_libc)"
if [[ "$libc" == "musl" ]]; then
echo "x86_64-unknown-linux-musl"
else
echo "x86_64-unknown-linux-gnu"
fi
;;
Linux:aarch64|Linux:arm64)
libc="$(detect_linux_libc)"
if [[ "$libc" == "musl" ]]; then
echo "aarch64-unknown-linux-musl"
else
echo "aarch64-unknown-linux-gnu"
fi
;;
Linux:i686|Linux:i386)
libc="$(detect_linux_libc)"
if [[ "$libc" == "musl" ]]; then
echo "i686-unknown-linux-musl"
else
echo "i686-unknown-linux-gnu"
fi
;;
Linux:armv7l|Linux:armv7)
libc="$(detect_linux_libc)"
if [[ "$libc" == "musl" ]]; then
echo "armv7-unknown-linux-musleabihf"
else
echo "armv7-unknown-linux-gnueabihf"
fi
;;
Linux:riscv64)
libc="$(detect_linux_libc)"
if [[ "$libc" == "musl" ]]; then
echo "riscv64gc-unknown-linux-musl"
else
echo "riscv64gc-unknown-linux-gnu"
fi
;;
Darwin:x86_64) echo "x86_64-apple-darwin" ;;
Darwin:arm64|Darwin:aarch64) echo "aarch64-apple-darwin" ;;
FreeBSD:x86_64|FreeBSD:amd64) echo "x86_64-unknown-freebsd" ;;
FreeBSD:aarch64|FreeBSD:arm64) echo "aarch64-unknown-freebsd" ;;
OpenBSD:x86_64|OpenBSD:amd64) echo "x86_64-unknown-openbsd" ;;
NetBSD:x86_64|NetBSD:amd64) echo "x86_64-unknown-netbsd" ;;
MINGW*|MSYS*|CYGWIN*)
case "$arch" in
x86_64|amd64) echo "x86_64-pc-windows-gnu" ;;
aarch64|arm64) echo "aarch64-pc-windows-gnullvm" ;;
i686|i386) echo "i686-pc-windows-gnu" ;;
*) die "unsupported Windows arch under MSYS: $arch" ;;
esac
;;
*) die "unsupported platform: $os/$arch" ;;
esac
}
normalize_version() {
local v="$1"
v="${v#v}"
printf '%s' "$v"
}
parse_spec() {
local raw="$1"
SPEC_RAW="$raw"
SPEC_CHANNEL=""
SPEC_VERSION=""
SPEC_FLOATING=0
case "$raw" in
"") die "missing version/channel spec" ;;
stable|dev|night)
SPEC_CHANNEL="$raw"
SPEC_VERSION=""
SPEC_FLOATING=1
;;
*@*)
SPEC_VERSION="$(normalize_version "${raw%@*}")"
SPEC_CHANNEL="${raw#*@}"
case "$SPEC_CHANNEL" in
stable|dev) ;;
night) die "cannot pin a version on night (use: dcrup install night)" ;;
*) die "unknown channel in spec: $SPEC_CHANNEL (use stable|dev)" ;;
esac
[[ -n "$SPEC_VERSION" ]] || die "empty version in spec: $raw"
;;
*)
SPEC_VERSION="$(normalize_version "$raw")"
SPEC_CHANNEL="stable"
[[ -n "$SPEC_VERSION" ]] || die "invalid spec: $raw"
;;
esac
}
toolchain_id() {
if [[ "$SPEC_CHANNEL" == "night" ]]; then
local sha="${1:-unknown}"
echo "night-${sha}"
elif [[ "$SPEC_FLOATING" -eq 1 ]]; then
local ver="${1:-latest}"
echo "${SPEC_CHANNEL}-${ver}"
else
echo "${SPEC_VERSION}-${SPEC_CHANNEL}"
fi
}
ensure_dirs() {
mkdir -p "$DCRUP_TC" "$DCRUP_BIN" "$DCRUP_META"
}
active_file() { echo "$DCRUP_META/active"; }
read_active() {
if [[ -f "$(active_file)" ]]; then
cat "$(active_file)"
fi
}
write_active() {
printf '%s\n' "$1" >"$(active_file)"
}
link_default() {
local id="$1"
local src="$DCRUP_TC/$id/dcr"
[[ -x "$src" ]] || die "toolchain not installed: $id"
ln -sfn "$src" "$DCRUP_BIN/dcr"
write_active "$id"
ok "default → $id ($DCRUP_BIN/dcr)"
}
fetch_json() {
need_cmd curl
curl -fsSL "$1"
}
json_tag() {
printf '%s' "$1" | sed -n 's/.*"tag_name"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' | head -n1
}
json_asset_url() {
local json="$1" asset="$2"
printf '%s' "$json" | sed -n "s#.*\"browser_download_url\"[[:space:]]*:[[:space:]]*\"\([^\"]*/${asset}\)\"#\1#p" | head -n1
}
latest_stable_json() {
fetch_json "$API_LATEST"
}
latest_dev_json() {
need_cmd curl
local json result
json="$(fetch_json "$API_ALL")"
if command -v jq >/dev/null 2>&1; then
result="$(printf '%s' "$json" | jq -e -c '[.[] | select(.prerelease == true)][0]')" || true
elif command -v python3 >/dev/null 2>&1; then
result="$(printf '%s' "$json" | python3 -c '
import sys, json
rels = json.load(sys.stdin)
pre = [r for r in rels if r.get("prerelease")]
print(json.dumps(pre[0]) if pre else "", end="")
')"
else
die "dev channel needs jq or python3 to parse GitHub API"
fi
[[ -n "$result" && "$result" != "null" ]] || die "no prerelease (dev) found"
printf '%s' "$result"
}
release_json_for_spec() {
if [[ "$SPEC_FLOATING" -eq 1 ]]; then
case "$SPEC_CHANNEL" in
stable) latest_stable_json ;;
dev) latest_dev_json ;;
night) die "night has no GitHub release binary" ;;
esac
else
fetch_json "https://api.github.com/repos/dexoron/dcr/releases/tags/v${SPEC_VERSION}"
fi
}
install_prebuilt() {
local triple asset tag version url json id dest
need_cmd curl
triple="$(detect_triple)"
json="$(release_json_for_spec)"
tag="$(json_tag "$json")"
[[ -n "$tag" ]] || die "failed to parse release tag"
version="$(normalize_version "$tag")"
asset="dcr-${triple}-${version}"
case "$triple" in
*windows*) asset="${asset}.exe" ;;
esac
url="$(json_asset_url "$json" "$asset")"
[[ -n "$url" ]] || die "asset not found: $asset (tag $tag)"
id="$(toolchain_id "$version")"
dest="$DCRUP_TC/$id"
if [[ -x "$dest/dcr" && "${FORCE:-0}" != "1" ]]; then
ok "already installed: $id"
link_default "$id"
return 0
fi
log "downloading $asset …"
mkdir -p "$dest"
curl -fL "$url" -o "$dest/dcr"
chmod +x "$dest/dcr"
printf '%s\n' \
"channel=$SPEC_CHANNEL" \
"version=$version" \
"tag=$tag" \
"source=release" \
"triple=$triple" \
"libc=${DCRUP_LIBC:-gnu}" \
>"$dest/dcrup-meta"
ok "installed prebuilt $id ($triple)"
link_default "$id"
}
install_build() {
local tmp id dest sha version branch_or_tag
need_cmd git
need_cmd cargo
tmp="$(mktemp -d "${TMPDIR:-/tmp}/dcrup.XXXXXX")"
cleanup_tmp() { rm -rf "$tmp"; }
trap cleanup_tmp EXIT
if [[ "$SPEC_CHANNEL" == "night" ]]; then
log "cloning $REPO_URL (branch dev) for night …"
git clone --depth 1 --branch dev "$REPO_URL" "$tmp/src" 2>/dev/null \
|| git clone --depth 1 "$REPO_URL" "$tmp/src"
sha="$(git -C "$tmp/src" rev-parse --short HEAD)"
version="night"
id="$(toolchain_id "$sha")"
elif [[ "$SPEC_FLOATING" -eq 1 ]]; then
local json tag
json="$(release_json_for_spec)"
tag="$(json_tag "$json")"
[[ -n "$tag" ]] || die "failed to resolve floating channel tag"
version="$(normalize_version "$tag")"
id="$(toolchain_id "$version")"
log "cloning $REPO_URL @ $tag …"
git clone --depth 1 --branch "$tag" "$REPO_URL" "$tmp/src" 2>/dev/null \
|| {
git clone --depth 1 "$REPO_URL" "$tmp/src"
git -C "$tmp/src" fetch --depth 1 origin "refs/tags/${tag}:refs/tags/${tag}"
git -C "$tmp/src" checkout "$tag"
}
sha="$(git -C "$tmp/src" rev-parse --short HEAD)"
else
version="$SPEC_VERSION"
id="$(toolchain_id)"
local tag="v${SPEC_VERSION}"
log "cloning $REPO_URL @ $tag …"
git clone --depth 1 --branch "$tag" "$REPO_URL" "$tmp/src" 2>/dev/null \
|| {
git clone --depth 1 "$REPO_URL" "$tmp/src"
git -C "$tmp/src" fetch --depth 1 origin "refs/tags/${tag}:refs/tags/${tag}"
git -C "$tmp/src" checkout "$tag"
}
sha="$(git -C "$tmp/src" rev-parse --short HEAD)"
fi
dest="$DCRUP_TC/$id"
if [[ -x "$dest/dcr" && "${FORCE:-0}" != "1" ]]; then
ok "already installed: $id"
link_default "$id"
return 0
fi
log "building release (features: $FEATURES) …"
(
cd "$tmp/src"
# shellcheck disable=SC2086
cargo build --release --features $FEATURES
)
mkdir -p "$dest"
cp "$tmp/src/target/release/dcr" "$dest/dcr"
chmod +x "$dest/dcr"
printf '%s\n' "channel=$SPEC_CHANNEL" "version=$version" "git=$sha" "source=build" "features=$FEATURES" >"$dest/dcrup-meta"
ok "installed build $id"
link_default "$id"
trap - EXIT
cleanup_tmp
}
cmd_install() {
local mode="release" FORCE=0
local spec=""
local libc_cli=""
while [[ $# -gt 0 ]]; do
case "$1" in
--build) mode="build"; shift ;;
--release) mode="release"; shift ;;
--force) FORCE=1; shift ;;
--libc)
[[ $# -ge 2 ]] || die "--libc needs gnu|musl|auto"
libc_cli="$2"
shift 2
;;
--libc=*)
libc_cli="${1#--libc=}"
shift
;;
-h|--help) usage; exit 0 ;;
-*) die "unknown flag: $1" ;;
*)
[[ -z "$spec" ]] || die "unexpected argument: $1"
spec="$1"
shift
;;
esac
done
[[ -n "$spec" ]] || die "usage: dcrup install <spec> [--build|--release] [--force] [--libc gnu|musl|auto]"
parse_spec "$spec"
ensure_dirs
if [[ -n "$libc_cli" ]]; then
case "$libc_cli" in
gnu|glibc|musl|auto) DCRUP_LIBC="$libc_cli" ;;
*) die "invalid --libc: $libc_cli (use gnu|musl|auto)" ;;
esac
fi
export DCRUP_LIBC="${DCRUP_LIBC:-gnu}"
if [[ "$SPEC_CHANNEL" == "night" ]]; then
mode="build"
fi
export FORCE
log "install spec=$SPEC_RAW channel=$SPEC_CHANNEL version=${SPEC_VERSION:-∅} mode=$mode libc=$DCRUP_LIBC"
if [[ "$mode" == "build" ]]; then
install_build
else
install_prebuilt
fi
check_path
}
cmd_default() {
[[ $# -eq 1 ]] || die "usage: dcrup default <spec>"
parse_spec "$1"
ensure_dirs
local id
if [[ "$SPEC_CHANNEL" == "night" || "$SPEC_FLOATING" -eq 1 ]]; then
id="$(ls -1 "$DCRUP_TC" 2>/dev/null | grep -E "^${SPEC_CHANNEL}-" | sort | tail -n1 || true)"
[[ -n "$id" ]] || die "no installed toolchain for channel $SPEC_CHANNEL (run: dcrup install $SPEC_CHANNEL)"
else
id="$(toolchain_id)"
[[ -d "$DCRUP_TC/$id" ]] || die "not installed: $id (run: dcrup install $1)"
fi
link_default "$id"
}
cmd_update() {
ensure_dirs
local active
active="$(read_active)"
[[ -n "$active" ]] || die "no active toolchain (run: dcrup install stable)"
case "$active" in
night-*)
log "updating night (rebuild HEAD) …"
FORCE=1 cmd_install night --build --force
;;
stable-*|dev-*)
local ch="${active%%-*}"
log "updating floating channel $ch …"
FORCE=1 cmd_install "$ch" --force
;;
*-stable|*-dev)
ok "pinned toolchain $active — not floating; install a newer version explicitly"
;;
*)
warn "unknown active id $active; try: dcrup install stable"
;;
esac
}
cmd_list() {
ensure_dirs
local active
active="$(read_active)"
if [[ ! -d "$DCRUP_TC" ]] || [[ -z "$(ls -A "$DCRUP_TC" 2>/dev/null || true)" ]]; then
warn "no toolchains installed"
return 0
fi
local d base
for d in "$DCRUP_TC"/*; do
[[ -d "$d" ]] || continue
base="$(basename "$d")"
if [[ "$base" == "$active" ]]; then
printf ' * %s\n' "$base"
else
printf ' %s\n' "$base"
fi
done
}
cmd_show() {
ensure_dirs
local active
active="$(read_active)"
echo "DCRUP_HOME=$DCRUP_HOME"
echo "DCRUP_BIN=$DCRUP_BIN"
echo "active=${active:-none}"
if [[ -n "$active" && -f "$DCRUP_TC/$active/dcrup-meta" ]]; then
echo "--- meta ---"
cat "$DCRUP_TC/$active/dcrup-meta"
fi
if [[ -x "$DCRUP_BIN/dcr" ]]; then
echo "--- dcr --version ---"
"$DCRUP_BIN/dcr" --version 2>/dev/null || true
fi
}
cmd_which() {
if [[ -L "$DCRUP_BIN/dcr" || -e "$DCRUP_BIN/dcr" ]]; then
readlink -f "$DCRUP_BIN/dcr" 2>/dev/null || readlink "$DCRUP_BIN/dcr" 2>/dev/null || echo "$DCRUP_BIN/dcr"
else
die "dcr not linked (run: dcrup install stable)"
fi
}
cmd_uninstall() {
ensure_dirs
if [[ "${1:-}" == "--all" ]]; then
rm -rf "$DCRUP_TC"
rm -f "$DCRUP_BIN/dcr" "$(active_file)"
ok "removed all toolchains"
return 0
fi
[[ $# -eq 1 ]] || die "usage: dcrup uninstall <spec>|--all"
parse_spec "$1"
local id
if [[ "$SPEC_FLOATING" -eq 1 || "$SPEC_CHANNEL" == "night" ]]; then
id="$(ls -1 "$DCRUP_TC" 2>/dev/null | grep -E "^${SPEC_CHANNEL}-" | sort | tail -n1 || true)"
else
id="$(toolchain_id)"
fi
[[ -n "$id" && -d "$DCRUP_TC/$id" ]] || die "not installed: $1"
rm -rf "$DCRUP_TC/$id"
if [[ "$(read_active)" == "$id" ]]; then
rm -f "$DCRUP_BIN/dcr" "$(active_file)"
warn "removed active toolchain; run: dcrup install stable"
fi
ok "removed $id"
}
check_path() {
case ":$PATH:" in
*":$DCRUP_BIN:"*) ;;
*)
warn "$DCRUP_BIN is not in PATH"
echo "Add to ~/.bashrc / ~/.zshrc / ~/.profile:"
echo " export PATH=\"$DCRUP_BIN:\$PATH\""
;;
esac
}
cmd_self_install() {
local dest="$DCRUP_BIN"
while [[ $# -gt 0 ]]; do
case "$1" in
--to) dest="$2"; shift 2 ;;
*) die "usage: dcrup self-install [--to DIR]" ;;
esac
done
ensure_dirs
mkdir -p "$dest"
local self
self="$(readlink -f "$0" 2>/dev/null || realpath "$0" 2>/dev/null || echo "$0")"
cp "$self" "$dest/dcrup"
chmod +x "$dest/dcrup"
ok "dcrup installed to $dest/dcrup"
check_path
echo "Then: dcrup install stable"
}
main() {
local cmd="${1:-}"
shift || true
case "$cmd" in
""|-h|--help|help) usage ;;
install) cmd_install "$@" ;;
default) cmd_default "$@" ;;
update) cmd_update "$@" ;;
list) cmd_list "$@" ;;
show) cmd_show "$@" ;;
which) cmd_which "$@" ;;
uninstall) cmd_uninstall "$@" ;;
self-install) cmd_self_install "$@" ;;
*) die "unknown command: $cmd (try: dcrup help)" ;;
esac
}
main "$@"

View File

@@ -1,46 +0,0 @@
# 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.).
- ASM support via `language = "asm"` (GCC/Clang, NASM, GAS).
- Mixed language builds via `language = ["c", "asm"]` and similar combinations.
- Three build kinds:
- `bin` (default)
- `staticlib`
- `sharedlib`
- Optional custom output directory via `build.target`.
- Optional `build.platform` to pass architecture hints (`-march` / `/arch`).
- Optional `build.exclude`/`build.include` for source/header selection.
- Optional `build.roots`/`build.src_disable` to replace the default `src/` root.
- Optional build steps with `build.steps` and `build.post_steps`.
- Optional `build.pkg_config` integration.
- Optional `build.clean` and `build.expect`.
- Optional `[run].cmd` to override run command.
- Workspace builds via `[workspace]` with per-project `dcr.toml`.
- 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 tracks source file timestamps and header dependencies (rebuilds when either source or included headers change).
- Object files are always created under `target/<profile>/obj/`.
## Repository
- <https://github.com/dexoron/dcr>

66
docs/README.mdx Normal file
View File

@@ -0,0 +1,66 @@
---
sidebar_label: Introduction
---
# DCR — C/C++ Build Tool & Package Manager
<details>
<summary>Quick reference</summary>
```bash
# Installation (dcrup)
curl -fsSL https://sh.dcr-tool.ru | sh -s -- self-install
export PATH="$HOME/.dcr/bin:$PATH"
dcrup install stable
# Create a project
dcr new my-app
cd my-app
# Build and run
dcr build
dcr run
# Run tests
dcr test
# Add a dependency
dcr add fmt
# Generate IDE files
dcr gen vscode
```
</details>
## Contents
| Section | Description |
|---------|-------------|
| [Getting Started](/docs/getting-started/installation) | Installation and first steps |
| [Commands](/docs/commands/project-commands) | All CLI commands |
| [Reference](/docs/reference/dcr-toml) | Configuration, build, dependencies, platforms |
| [Testing](/docs/testing/test-framework) | Built-in test framework |
| [Recipes](/docs/recipes/cross-to-windows) | Common scenarios |
| [IDE Integration](/docs/ide-integration) | VS Code, CLion, compile_commands.json |
| [Self Update](/docs/self-update) | Auto-update |
| [FAQ](/docs/faq) | Frequently asked questions |
| [Changelog](/docs/changelog) | Version history |
| [License](/docs/license) | DCR and vendored library licenses |
| [Contributing](/docs/contributing) | DCR development |
## Features
- **Incremental builds** — mtime + `.d` headers + SHA256 fingerprint
- **Parallel compilation** — thread::scope, atomic task queue
- **7 backends** — gcc/clang (unix_cc), MSVC/clang-cl (msvc), GAS, NASM, MASM, FASM, LLVM IR
- **8 project kinds** — bin, staticlib, sharedlib, efi, elf, none, custom, flat-bin
- **Disk images** — optional `[archive]` packs FAT12/16/32 images after build
- **Cross-compilation** — short names and full triples
- **Profiles** — debug / release with field overrides
- **Workspaces** — multi-package projects with topological sort
- **Registry + Git + Path** — three dependency mechanisms
- **IDE generation** — VS Code, CLion, compile_commands.json, JSON metadata
- **pkg-config** — automatic system library discovery
- **Per-command `--help`** — `dcr build --help`, `dcr new --help`, etc.
- **Man pages** — `man dcr`, `man dcr-build`, `man dcr-new`

View File

@@ -1,49 +0,0 @@
# Table of contents
* [Introduction](README.md)
## Getting started
* [Installation](getting-started/installation.md)
* [Create your first project](getting-started/create-your-first-project.md)
* [Project structure](getting-started/project-structure.md)
* [Build and run](getting-started/build-and-run.md)
## Configuration
* [dcr.toml overview](configuration/dcr.toml-overview.md)
* [Package section](configuration/package-section.md)
* [Build section](configuration/build-section.md)
* [Dependencies section](configuration/dependencies-section.md)
* [Build profiles](configuration/build-profiles.md)
## Commands
* [Global options](commands/global-options.md)
* [dcr init/new](commands/dcr-init-or-new.md)
* [dcr add](commands/dcr-add.md)
* [dcr build](commands/dcr-build.md)
* [dcr run](commands/dcr-run.md)
* [dcr clean](commands/dcr-clean.md)
* [dcr gen](commands/dcr-gen.md)
* [dcr test](commands/dcr-test.md)
* [dcr tree](commands/dcr-tree.md)
## Dependencies & Build
* [Dependency format](dependencies-and-build/dependency-format.md)
* [Local dependencies](dependencies-and-build/local-dependencies.md)
* [Versioning & lock file](dependencies-and-build/versioning-and-lock-file.md)
* [Target directory](dependencies-and-build/target-directory.md)
* [Cross-compilation and targets](dependencies-and-build/cross-compilation.md)
* [Compilers & linking](dependencies-and-build/compilers-and-linking.md)
## Reference & Help
* [CLI reference](reference-and-help/cli-reference.md)
* [Config reference](reference-and-help/config-reference.md)
* [Workspace guide](reference-and-help/workspace-guide.md)
* [Flags & environment](reference-and-help/flags-and-environment.md)
* [Troubleshooting map](reference-and-help/troubleshooting-map.md)
* [FAQ](reference-and-help/faq.md)
* [Contributing & Bug reports](reference-and-help/contributing-and-bug-reports.md)

269
docs/changelog.mdx Normal file
View File

@@ -0,0 +1,269 @@
---
sidebar_label: Changelog
---
# Changelog
## 0.8.5 (2026-08-08)
- **`package.dcr-version`** — optional CLI version pin in `dcr.toml`.
`dcr new` / `dcr init` write the current version. On config load:
- missing / empty pin → warn "add dcr-version";
- dcr older than pin → warn "update dcr";
- dcr newer than pin → warn "check changelog, update pin";
- equal → silent.
Commands do not fail, warning only (once per path per process).
## 0.8.4 (2026-08-04)
**Added:**
- **`.dcr/` directory** — shared machine-readable build facts for IDE integrations:
- `.dcr/compile_commands.json`
- `.dcr/build-info.json` (`schemaVersion`, `artifact_path`, `profile`, …)
- `.dcr/toolchain.json` (compiler/debugger paths, moc/uic/rcc)
- `.dcr/ide/` (placeholder for IDE lock files)
- **`dcr gen project-info`** — `target`, `target_dir`, `artifact_path`, `artifact_kind`, `source_roots`, `include_globs`, `exclude_globs`; absolute/canonical paths.
- **`dcr build --print-artifact-path`** — one absolute artifact path line on stdout after a successful build.
- **`dcr gen … --quiet` / `-q`** — suppress human success logs for gen subcommands.
- **`.clangd`** — created on first gen with `CompilationDatabase: .dcr` (`# managed by dcr gen`); custom `.clangd` is not overwritten.
- **Helpers** `canonicalize_path`, `atomic_write`, `ensure_dcr_dir`; pure `resolve_artifact_path` via `platform::*`.
- **`dcr new` / `dcr init`** — add `.dcr/` to `.gitignore`.
**Changed (breaking):**
- **`compile_commands.json` moved** from project root to **`.dcr/compile_commands.json`**.
clangd discovers it via `.clangd` / `--compile-commands-dir=.dcr`.
CLion and VSCode generators updated accordingly.
- **Atomic write** for compile_commands (tmp + rename).
- **`gen vscode` / `gen clion` launch/run** — use the same artifact path resolver as `project-info` / `build-info.json`.
**Fixed:**
- Launch configs no longer hardcode `target/<profile>/<name>` without the Linux triple segment.
- Symlink/mount roots: best-effort canonicalize for root and compile database paths.
## 0.8.3 (2026-08-03)
### Added
- **`dcr run -- <args>...`** — cargo-style argument forwarding after a bare `--`
(`dcr run --release -- --test_help`). Applies to direct binary runs and `[run].cmd`.
- **Tests** — host target section `ldflags` without CLI `--target`; run-arg forwarding; `split_double_dash` unit tests.
### Changed
- **Native builds resolve the host triple** — without `--target` / package `build.target`, host sections such as
`[build.x86_64-unknown-linux-gnu]` apply again (`cflags` / `ldflags` / toolchain).
Previously the target was empty and those sections were ignored while artifacts already used the host triple path.
- **Empty target** — no more `Unknown target ''` warning.
- **`dcr run --help` / man `dcr-run`** — document `--` forwarding.
### Fixed
- **Native artifact paths on Windows and macOS** — without an explicit `--target` / `build.target`, artifacts use `target/<profile>`, so `dcr run` and flat-bin find the build output.
- Target-specific `ldflags` missing on native host builds (e.g. micro-lang + `libsct-elf`).
- Spurious empty-target warning.
## 0.8.2 (2026-07-22)
### Added
- **Compile progress `[N/M]`** — live TTY status line (`compile pkg v0.1.0 [12/41]`) so long mono-package builds do not look hung.
- **DCR status style** — fixed-width verbs: `project`, `compile`, `dep`, `ready`, `pack`, `done`, `run`.
- **Cargo feature `archive`** — optional FAT packing via `fatfs` (`cargo build --features archive`). Release CI builds with the feature; without it `[archive]` fails with a clear message.
- **Tests** — `flat_bin_nasm_build`, package `build.target` without CLI `--target`, stricter workspace `clean --all`.
- **CI expansion** — unit + integration on Linux/macOS/Windows, archive feature job, rust-cache, clippy default + all-features (see `.github/workflows/ci.yml`).
### Changed
- **No forced host triple from CLI** — without `--target`, package/member `build.target` is honored (bare-metal / ISO `post_steps` paths).
- **Relative include/lib flags** (`-I`, `-i`, `-isystem`, `-idirafter`, `-L`, `-T`) absolutized against the package root under workspace builds.
- **`dcr clean --all`** — no spam for members without a local `target/` (shared root `target/`).
- **`error` / `warn`** — red / yellow on stderr; CLI fully English (`Hint:`).
- **Help / man** — list `add`, `lint`, `setup`; unknown command exits with code 1.
- **Tool NotFound** — `linker not found: ld.lld …` / `{tool} not found …` instead of raw `os error 2`.
## 0.8.1 (2026-07-20)
### Added
- **`build.kind = "flat-bin"`** — raw binary (default `.bin`) for OS-dev payloads:
- **NASM** — `-f bin` → `<stem>.bin`
- **FASM** — direct output (`format binary` in source)
- **GAS / MASM / LLC** — object → `objcopy -O binary` → `<stem>.bin`
- **C/C++** — objects → freestanding link → `objcopy -O binary` → `<name>.bin`
- Requires `llvm-objcopy` / `objcopy` / `gobjcopy` except for NASM/FASM direct emit
- **`[archive]` section** — FAT12/16/32 disk images after build (`output`, `format`, `size`, `offset`, `label`, `bootsector`, `layout`). From 0.8.2 requires feature `archive`.
- **Single-file `build.roots`** — a root may be a single source or header file, not only a directory.
### Changed
- **`--force`** also re-runs `build.steps` and `build.post_steps`.
- **`dcr run` on workspace-only root** — if `[run].cmd` is set, run that after build; otherwise delegate to a workspace member.
## 0.8.0 (2026-07-18)
### Added
- **Dedicated Build Engine (`src/core/build/engine.rs`)** — decoupled the build orchestration logic completely from the CLI front-end wrapper in `src/cli/build.rs` to a reusable, decoupled core build engine.
- **Polymorphic Language Model (`Language` trait)** — introduced the abstract `Language` trait (`src/core/build/language/mod.rs`). File scanning, compiler resolution, and flags handling are now encapsulated in dedicated language modules for C, C++ (including Qt code generation), LLVM IR, and ASM (GAS, NASM, FASM, MASM).
- **Polymorphic Compilation Dispatch (`Builder` trait)** — introduced the `Builder` trait to generalize builder invocations (`src/core/build/builder/mod.rs`). Consolidated GCC/Clang logic into `builder/cc_common.rs` and Microsoft Visual C++ logic into `builder/msvc/`.
- **Per-Language Configuration overrides (`[build.<lang>]`)** — introduced support for configuring language-specific compiler, standard, and flags (e.g. `[build.c]`, `[build.cxx]`, `[build.asm]`) independently in `dcr.toml`.
- **Automatic Workspace Dependency Injection** — during workspace builds, include/lib paths of dependent workspace members (including their source headers, local `include/` folders, and build target `target/include` / `target/lib` folders) are automatically resolved and injected.
- **`BuildReporter` Event System** — decoupled build orchestration output into a structured event-driven reporter model (`src/core/build/report.rs`), making DCR suitable for library embedding and IDE integrations without stderr capturing.
- **Build Cancellation Support** — introduced thread-safe cancellation tokens (`Arc<AtomicBool>`) allowing clients to safely abort compile runs mid-execution.
- **TOML Formatting & Custom Keys Preservation** — migrated the config editor to `toml_edit`, preserving all unknown/user-defined TOML keys, structures, and comments during file write operations (e.g., in `dcr add`).
- **Path Dependencies Target Include Resolution** — local path dependencies configured via tables now correctly expose headers built and packaged into their `target/include` folder to consumer packages.
- **Modular Integration Test Suite** — refactored the monolith `tests/cli_basic.rs` file into clean, specialized integration tests: `cli_build.rs`, `cli_deps.rs`, `cli_lint.rs`, `cli_new.rs`, `cli_qt.rs`, `cli_test.rs`, `cli_workspace.rs`.
### Changed
- **Consolidated Linking and Archiving** — artifact generation (linking executables/shared libraries and archiving static libraries) consolidated into a single `src/core/build/builder/artifact.rs` module.
- **Workspace-Aware member execution** — `dcr run` executed at the workspace root of a `workspace_only` project now triggers the member build inside the workspace context using the `--workspace` parameter, preventing standalone build issues.
- **Elimination of Global State** — removed global variables and states from the build core, encapsulating build logic inside isolated `BuildContext` structs for thread safety.
- **Build Cache Separation** — relocated mtime tracking, incremental caching, and header-dependency checking logic to `src/core/build/cache.rs`.
- **Modularized Pre-build Steps** — decoupled generator scripts and pre-build commands parsing into `src/core/build/steps.rs`.
## 0.7.4 (2026-06-17)
### Added
- **Native Qt support** — automatic meta-object handling (MOC, UIC, RCC) added when `build.qt = true` is set in `dcr.toml`.
- **`dcr lint` command** — C/C++ static analysis via `clang-tidy`. Supports `--fix` for automatic fixes. Respects `build.roots` and `build.src_disable` from config.
- **Three new assembler backends**:
- **MASM** (`compiler = "ml"` / `"ml64"`) — Microsoft Macro Assembler.
- **FASM** (`compiler = "fasm"`) — Flat Assembler.
- **LLVM IR** (`compiler = "llc"`) — compiles `.ll` files via `llc -filetype=obj`.
- **Shared ASM pipeline** — linking and archiving logic consolidated into `core/builder/asm.rs`. Adding a new assembler backend now takes ~30 lines.
- **Filesystem utilities** — `to_hex()` and `home_dir()` extracted to `utils/fs.rs`.
- **Build utilities** — `normalize_target()`, `normalize_kind()`, `normalize_platform()`, `default_profile_flags()` extracted to `utils/build.rs`.
- **Backend helpers** — `asm_lang_flag()`, `source_extensions()`, `elapsed_secs()` added to `core/builder/common.rs`.
- **Full Bare-Metal / Freestanding Automation** — introduced the `build.freestanding = true` configuration option. When enabled (or when a bare-metal target is detected), DCR automatically injects `-ffreestanding` during compilation and both `-nostdlib` and `-static` during linking.
- **Artifact Optimization (LTO & Strip)** — added `build.lto` (auto-injects `-flto` for compiler and linker) and `build.strip` (automatically strips debug symbols via linker `-s` flag) options to `dcr.toml`.
- **Compilation Thread Control** — added the `build.codegen-units` option to strictly limit the maximum number of parallel jobs utilized by the custom `parallel_build` worker pool.
- **Panic Behavior Management** — added `build.panic = "abort"` support. For C++ targets, it automatically strips exception handling and unwind tables via `-fno-exceptions`, `-fno-unwind-tables`, and `-fno-asynchronous-unwind-tables`.
### Changed
- **Intelligent Default Flags Generation** — automated injection of fallback optimization (`-O3`/`-O0`), debug (`-g`), and warning (`-Wall -Wextra`) flags is now suppressed for bare-metal and freestanding builds if `build.cflags` are overridden.
- **Centralized Bare-Metal Detection** — relocated the `is_bare_metal_target` helper to common build utilities (`src/utils/build.rs`) for unified access across the building core.
- **Architectural Refactoring**:
- Renamed `src/config.rs` to `src/templates.rs`.
- Started consolidation of configuration and build orchestration logic.
## 0.7.3 (2026-06-13)
### Added
- **`--vcs` option for `new` and `init` commands** — introduced explicit version control system selection via `--vcs <git|none>`.
- **Git metadata integration in `--version`** — the CLI now appends the current short commit hash and a `-dirty` suffix if there are uncommitted changes in the DCR repository.
- **Automatic `.gitignore` generation** — Git repository initialization now automatically writes a `.gitignore` file excluding the `/target` directory.
- **Nested repository prevention** — automatic Git initialization is now skipped if `dcr new` or `dcr init` is executed inside an already existing Git repository.
- **VCS verification tests** — added `new_vcs_options_work` and `init_vcs_options_work` integration tests to ensure reliable repository behavior.
### Changed
- **Complete removal of `git2` dependency** — all Git actions (dependency fetching, VCS setup, status checks) are now delegated to the system `git` executable via `Command`. This simplifies compilation and drops the need for `vendored` and `openssl` features.
- **Migrated from `reqwest` to `ureq`** — replaced the heavy `reqwest` crate in `flag_update.rs` with the lightweight synchronous `ureq 2.10` client, reducing overhead and the final binary size.
## 0.7.2 (2026-06-07)
### 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)
### Added
- **`--help` for all commands** — `dcr build --help`, `dcr run --help`, `dcr new --help`,
`dcr init --help`, `dcr clean --help`, `dcr add --help`, `dcr fmt --help`,
`dcr setup --help`, `dcr tree --help`, `dcr gen --help`, `dcr --update --help`,
`dcr test --help`. All output uses styled headers (green) and usage lines (cyan).
- **Man pages** — 12 troff pages in `man/man1/`: `dcr.1`, `dcr-build.1`,
`dcr-run.1`, `dcr-new.1`, `dcr-init.1`, `dcr-clean.1`, `dcr-add.1`, `dcr-test.1`,
`dcr-gen.1`, `dcr-fmt.1`, `dcr-tree.1`, `dcr-setup.1`.
- **Man pages in all packaging** — install.sh, install_bsd.sh, AUR PKGBUILD,
Debian (cargo-deb), RPM (cargo-generate-rpm), Nix (postInstall), Homebrew
(resource), Snap, GitHub Release assets.
- **Project name validation** — `dcr init` and `dcr new` now validate names before
creating files. Only ASCII letters, digits, `_` and `-` are allowed.
- **`documentation` and `homepage` fields** — added to `Cargo.toml`.
- **Release profile optimizations** — `opt-level = "z"`, LTO, `codegen-units = 1`,
`panic = "abort"`, `strip = true` for smaller binaries.
- **Linux i686, armv7, riscv64 targets** — added to release workflow and install scripts.
- **Linux musl i686, armv7 targets** — cross-compiled via zigbuild in CI.
- **AUR packages** — `dcr-dev`, `dcr-dev-bin` publishing workflow.
- **Snap publishing** — automated Snapcraft publishing in CI.
- **Snap badge** — in README.
### Changed
- **`validate_package_name` made public** — callable from CLI commands.
- **README platform table** — reorganized: libc variants as separate OS rows,
removed extra columns. Linux architecture list updated.
- **`gen.rs` no-args output** — now uses styled output instead of raw `eprintln!`.
- **`tree.rs`, `fmt.rs`, and `setup.rs`** — now accept arguments for `--help`.
- **README install commands** — `| bash` → `| sh` for POSIX compatibility.
### Fixed
- **`dcr new <invalid-name>` creates directory then fails** — validation now
happens before any file operations.
- **`dcr init` on invalid directory name** — same fix.
- **Man pages missing in installed packages** — now shipped in all formats.
- **Windows drive letter false positive** — in dependency file parser.
- **CRLF (`\r\n`) breaks dependency parser** — now handles mixed line endings.
- **Newline after backslash not consumed** — in `parse_d_file` escape handling.
## 0.7.0 (2026-06-01)
### Added
- **OpenBSD and NetBSD target support** — full platform routing with dynamic target triples using `std::env::consts::ARCH` and `std::env::consts::OS`. Affects `build`, `run`, `clean` commands and the platform module.
- **`src/platform/bsd.rs`** — new BSD platform module (shared by FreeBSD, OpenBSD, NetBSD) providing `bin_path`, `lib_path`, `elf_path`, `efi_path`, `shared_lib_path`.
- **`build.out_dir` config option** — custom output directory that overrides the default `target/<triple>/<profile>` path for final artifacts. Supported in `build`, `run`, and config validation.
- **`dcr fmt` command** — new CLI command that formats all C/C++ source files (`*.c`, `*.cpp`, `*.h`, `*.hpp`) in `src/` and `tests/` using `clang-format`.
- **Incremental linking** — `needs_link()` in `common.rs` checks if any object file is newer than the linked output, skipping unnecessary relinking. Implemented for all backends (`unix_cc`, `msvc`, `gas`, `nasm`).
- **`build.kind = "none"` and `"custom"`** — two new project kinds for special build scenarios that don't produce standard artifacts.
- **`install_bsd.sh`** — POSIX-compliant installation script for BSD systems (FreeBSD, OpenBSD, NetBSD) with binary download and source build modes.
- **Linux ARM64 support in `install.sh`** — added `Linux:aarch64|Linux:arm64` target detection for pre-built binary downloads.
- **BSD OS detection in `install.sh`** — detects FreeBSD, OpenBSD, NetBSD and determines target triple.
- **`rust-toolchain.toml`** — explicit toolchain pinning to `stable` channel.
- **Integration tests** — `build_with_target_config` (verifies `build.target = "linux"`) and `build_with_out_dir` (validates custom output directory).
- **`get_build_string_with_profile` made `pub`** — so `run.rs` can determine custom output directory configuration.
### Changed
- **`build.target` semantics changed** — now strictly contains a target triple (e.g., `x86_64-unknown-linux-gnu`) or short name (`linux`, `macos`, `windows`). No longer used as custom output directory — this functionality moved to `build.out_dir`.
- **`build.standard` made optional** — changed from `String` to `Option<String>`. Validation only enforces non-empty for non-ASM languages. Skipped in `dcr.toml` output if empty.
- **`dcr run` with `out_dir`** — now determines target directory respecting `build.out_dir` via `get_build_string_with_profile()` from `build.rs`.
- **`collect_sources()` returns empty vector** instead of error when no sources are found, allowing `kind = "none"` or `kind = "custom"` projects with no source files.
- **CI/CD release workflow refactored** — `git2` made target-specific (no vendored-openssl on Windows), Zig-based cross-compilation for non-x86_64 Linux targets, Arch Linux package version cleanup (dashes → dots), `gmake` symlink for NetBSD.
- **README compatibility table** — FreeBSD, OpenBSD, NetBSD build/run status upgraded from "community/best-effort" to "officially supported".
- **Documentation updated** — `build-section.md` describes new `build.target` and `build.out_dir` fields. `target-directory.md` rewritten to clarify the distinction.
### Fixed
- **stdout/stderr not inherited in `dcr run`** — child process output was captured and manually printed, breaking interactive programs. Fixed by switching to `Command::status()`.
- **Race condition in release CI** — matrix build jobs could upload assets to a release that didn't exist yet. Fixed by adding a dedicated `create-release` job.
- **Release GHA — stable toolchain override** — fixed Rust toolchain override issues in CI.
- **Arch Linux package version sanitization** — version strings with dashes (e.g., `0.7.0-dev`) are invalid for `pkgver`. Fixed by replacing dashes with dots.
- **GPG permissions after Docker** — Docker operations changed GPG directory ownership. Fixed by running `chown` after Docker commands.
- **RPM artifact paths** — RPM artifacts were placed in `rpm/x86_64/` instead of `fedora/x86_64/`. Fixed in Dexoron Packages Index workflow.
- **JSON parsing reliability in `install.sh`** — added `jq` as primary parser with `python3` fallback for dev channel release lookup.
### Removed
- **`format_roots()` helper function** — removed from `common.rs`. Was only used by the old error handling path in `collect_sources()`.
- **Per-distribution artifact download steps** — three separate `actions/download-artifact` steps replaced with unified `gh release download --clobber`.

View File

@@ -0,0 +1,47 @@
---
sidebar_label: Build commands (build, run, clean)
---
# Build Commands
## `dcr build`
Builds the project according to `dcr.toml`.
```bash
dcr build # debug profile
dcr build --release # release build
dcr build --debug # explicit debug
dcr build --target aarch64-unknown-linux-gnu
dcr build --force # full rebuild (also re-runs build.steps / post_steps)
dcr build --clean # clean + build
dcr build --verbose # show compilation commands
dcr build --workspace pkg-a # build specific workspace package
```
Artifacts: `target/<triple>/<profile>/<binary-name>` (Linux with explicit target).
With `[archive]` in `dcr.toml`, a FAT disk image is packed after a successful build.
## `dcr run`
Builds (if sources are newer than artifacts) and runs the binary.
```bash
dcr run
dcr run --release
dcr run --force # force rebuild then run
```
On a **workspace-only** root: if `[run].cmd` is set, that command is used after build; otherwise DCR delegates to a workspace member.
## `dcr clean`
Removes `target/` directory (or `target/<target>/<profile>`).
```bash
dcr clean
dcr clean --release # target/release/ only
dcr clean --target windows # target/x86_64-pc-windows-msvc/
dcr clean --all # clean all workspace packages
```

View File

@@ -1,37 +0,0 @@
# dcr add
Add a dependency to `dcr.toml`.
## Usage
```bash
dcr add <name> [source] [options]
```
If `<source>` is omitted and a registry is configured, DCR will look up the
package by name in the registry and add it as a version dependency.
## Sources
- *omitted*: Look up in the configured registry.
- `path:./path/to/lib`: Local directory.
- `github:user/repo`: GitHub repository.
- `gitlab:user/repo`: GitLab repository.
- `git:host.com/user/repo`: Generic Git repository (HTTPS).
- `https://...`: Full Git URL.
## Options
- `--branch <name>`: Use a specific branch.
- `--tag <name>`: Use a specific tag.
- `--rev <sha>`: Use a specific commit hash.
## Examples
```bash
dcr add my_lib path:./libs/my_lib
dcr add cool_lib github:user/cool_lib
dcr add shared_lib gitlab:org/shared --branch develop
dcr add custom_lib git:git.internal.com/r/lib --tag v1.0.0
dcr add mylib # Looks up in registry
```

View File

@@ -1,76 +0,0 @@
# dcr build
Builds the project in `debug` or `release` profile.
## Usage
```sh
dcr build
dcr build --debug
dcr build --release
dcr build --target linux --release
dcr build --release --force
dcr build --debug --clean
```
## 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 library).
## Config values used
- `package.name`
- `build.filename`
- `build.extension`
- `build.compiler`
- `build.language`
- `build.standard`
- `build.kind`
- `build.target`
- `build.platform`
- `build.cflags`
- `build.ldflags`
- `build.ldscript`
- `build.debug` / `build.release`
- `build.exclude`
- `build.include`
- `build.pkg_config`
- `build.steps`
- `build.post_steps`
- `build.generated`
- `build.expect`
- `build.clean`
## Source selection
- `language = "c"` -> `*.c`
- `language = "c++" | "cpp" | "cxx"` -> `*.cpp`, `*.cxx`, `*.cc`
- `language = "asm"` -> `*.s`, `*.S`, `*.asm`
- Mixed languages are supported with arrays, for example `language = ["c", "asm"]`.
- By default sources are searched in `src/`; use `build.roots` and `build.src_disable` to override.
## Notes
- Profile flag (`--debug` / `--release`) can appear in any argument position (duplicates are rejected).
- Unknown profile flags return an error.
- `--target <triple>` builds for specified target (short names: `linux`, `macos`, `windows`).
- `--verbose` prints the compiler/linker command lines to stderr (also works via `DCR_DEBUG` env var).
- If no `--target`, builds for `build.targets` or native.
- Incremental rebuild checks source/object mtime and tracked header dependencies.
- `--force` skips build cache checks and recompiles.
- `--clean` removes `target/<profile>` and `build.clean` paths before building.
- `build.filename` + `build.extension` allow full control over the final artifact name (e.g. `KERNEL.BIN` instead of using `package.name`). When `build.kind = "efi"`, the output is a PE32+ executable with `.efi` extension.
- `build.kind = "efi"` links with `-shared -nostdlib -Wl,-dll -Wl,--subsystem,10` for UEFI PE32+ format. Use `build.filename` and `build.extension` for full control over the artifact name.
- `build.kind = "elf"` produces a bare-metal ELF executable. Linking flags are user-controlled via `build.ldflags` (no PIE/CRT defaults are added).
- Default GCC/Clang profile flags: `debug` -> `-O0 -g -Wall -Wextra -fno-omit-frame-pointer -DDCR_DEBUG`, `release` -> `-O3 -DNDEBUG`.
These defaults are **not applied** for bare-metal targets (e.g. `aarch64-none-elf`, targets containing `none` / `-elf` / `eabi`).
- For `language = "asm"` with `compiler = "as"`/`"gas"`, use `.s` files (no preprocessing). For `.S`, use `gcc` or `clang`.
- In workspace root, `dcr build` builds all members in dependency order.
- `build.exclude` removes paths from source/header collection; `build.include` re-allows matching paths and has priority over `exclude`.
- `build.steps` run before compilation; `build.post_steps` run after linking.
- `build.generated` is cleaned when `build.steps` need to rerun; `build.expect` is verified after post-steps.

View File

@@ -1,27 +0,0 @@
# dcr clean
Removes build artifacts in `target/`.
## Usage
```sh
dcr clean
dcr clean --debug
dcr clean --release
dcr clean --all
dcr clean --release --all
```
## Behavior
- Without arguments: removes entire `target/`.
- With profile: removes only the profile-specific directory. Respects `build.target` from config: if `build.target = "aarch64-unknown-linux-gnu"`, cleans `target/aarch64-unknown-linux-gnu/<profile>/`.
- With `--all`: also cleans all workspace members.
- Additionally removes paths from `build.clean` if configured.
- `build.clean` supports `{profile}` and version placeholders.
## Validation
- `dcr.toml` must exist.
- Unknown flags are treated as error.
- If `target` or selected profile directory does not exist, command prints a warning.

View File

@@ -1,170 +0,0 @@
# dcr gen
Generates IDE and build tool integration files for C/C++ development environments.
## Usage
```sh
dcr gen project-info
dcr gen project-info --release
dcr gen compile-commands
dcr gen compile-commands --debug
dcr gen vscode
dcr gen vscode --release
dcr gen clion
dcr gen clion --debug
```
## Subcommands
### `dcr gen project-info`
Outputs project metadata as JSON array.
```sh
dcr gen project-info [--debug | --release]
```
Outputs structured information about the project (root project + all workspace members if present):
```json
[
{
"name": "my-project",
"version": "1.0.0",
"root": "/path/to/root",
"profile": "debug",
"language": "c++",
"standard": "c++17",
"compiler": "g++",
"kind": "bin",
"sources": ["/path/to/root/src/main.cpp", ...],
"include_dirs": ["/path/to/dep/include", ...],
"lib_dirs": ["/path/to/dep/lib", ...],
"libs": ["somelib", ...],
"cflags": ["-Wall", ...],
"ldflags": ["-lm", ...]
}
]
```
This is useful for integrating DCR projects with custom build tools or scripts.
### `dcr gen compile-commands`
Generates `compile_commands.json` for use by `clangd`, `clang-tidy`, and other tools.
```sh
dcr gen compile-commands [--debug | --release]
```
Writes `./compile_commands.json` containing compilation database entries for all source files. This file is recognized by:
- LSP servers (`clangd`, `clang-tools-extra`)
- Linters (`clang-tidy`)
- Format tools (`clang-format`)
The entries include:
- Full compiler command with flags
- Source file path
- Object file output path
- Project root as working directory
### `dcr gen vscode`
Generates Visual Studio Code integration files.
```sh
dcr gen vscode [--debug | --release]
```
Creates `.vscode/` directory with:
- **`launch.json`**: Debug configurations (one per binary target, debug + release variants)
- **`tasks.json`**: Build/run/clean tasks using `dcr` commands
- **`settings.json`**: Clangd configuration pointing to `compile_commands.json`
- **`extensions.json`**: Recommends `clangd`, disables `cpptools`
- **`compile_commands.json`**: Compilation database (same as `dcr gen compile-commands`)
Usage in VSCode:
- Open the Command Palette (`Ctrl+Shift+P`) and select **"Debug: Start Debugging"** to run debugger
- Press `Ctrl+Shift+B` to run the build task
- Clangd will provide IntelliSense and diagnostics based on `compile_commands.json`
- Generated `launch.json` uses CodeLLDB (`type: "lldb"`), so install `vadimcn.vscode-lldb`
### `dcr gen clion`
Generates JetBrains CLion integration files.
```sh
dcr gen clion [--debug | --release]
```
Creates `.idea/` directory with:
- **`externalTools.xml`**: Registers DCR build/clean/gen commands as external tools
- **`customTargets.xml`**: Defines build targets for debug and release
- **`misc.xml`**: Points CLion to `compile_commands.json` for compilation database
- **`.idea/.gitignore`**: Ignores auto-generated files
- **`runConfigurations/*.xml`**: Debug run configs (one per binary target)
- **`compile_commands.json`**: Compilation database (same as `dcr gen compile-commands`)
Usage in CLion:
- Build/clean via **Tools → DCR → Build Debug/Release/Clean**
- Run/debug via **Run → Run Configurations** (dropdown) → select generated config
- Code completion and diagnostics come from the compilation database
## Config values used
- `package.name`
- `build.compiler`
- `build.language`
- `build.standard`
- `build.kind`
- `build.target`
- `build.platform`
- `build.cflags`
- `build.ldflags`
- `build.debug` / `build.release`
- `build.exclude`
- `build.include`
- `build.pkg_config`
- `build.roots`
- `build.src_disable`
- Workspace members (if `[workspace]` is present)
## Workspace support
When running `dcr gen` in a workspace root, all commands process both the root project and all workspace members:
- `project-info` returns an array with entries for each member + root
- `compile-commands` includes entries from all members
- `vscode` and `clion` generate unified configurations that work across all members
## Troubleshooting
### Clangd not picking up includes
- Ensure `compile_commands.json` exists in the workspace root
- In VSCode settings, verify `clangd.arguments` includes `--compile-commands-dir=<workspace-root>`
- Rebuild via `dcr gen compile-commands` if sources or dependencies changed
### Debug configuration not working
- Verify binary paths in `launch.json` match actual build output (`target/<profile>/binary-name`)
- For workspace projects, each member's debug config uses its own `target/` directory
- Ensure GDB/LLDB is installed: `gdb --version` or `lldb --version`
- If VSCode reports unsupported debugger type, install the extension that matches `launch.json` type (`vadimcn.vscode-lldb` for `lldb`)
### CLion not recognizing includes
- Regenerate via `dcr gen clion --debug`
- File → Invalidate Caches → Invalidate and Restart
- Verify `.idea/misc.xml` points to correct `compile_commands.json` path
## Notes
- Profiles default to `debug` if not specified
- Generation does not require the project to be built first
- Generated files are safe to commit; they are generated from `dcr.toml` and thus repeatable
- IDE configurations may be customized after generation, but changes will be overwritten on next `dcr gen` run
- For multi-binary projects, `vscode` and `clion` generate debug configs for all binaries (both debug + release variants)

View File

@@ -1,43 +0,0 @@
# 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,40 +0,0 @@
# dcr run
Builds the project and runs the resulting binary.
## Usage
```sh
dcr run
dcr run --debug
dcr run --release
dcr run --target linux --release
dcr run --release --force
dcr run --debug --clean
```
## 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.
5. If `[run].cmd` is set, runs that command instead of the built binary.
## Restrictions
- If `build.kind` (or `build.{profile}.kind`) is `"staticlib"` or `"sharedlib"`, `run` exits with error.
- The profile is selected from the first argument.
- `--target <triple>` runs the binary for specified target (short names: `linux`, `macos`, `windows`).
- `--force` skips build cache checks and recompiles.
- `--clean` removes `target/<profile>` and `build.clean` paths before building.
## `run.cmd` variables
`run.cmd` supports the same variables as build steps: `{profile}`, `{version}`, `{version_major}`,
`{version_minor}`, `{version_patch}`, `{version_suffix}`, `{version_suffix_dash}`.
The command runs via `sh -c` on Unix and `cmd /C` on Windows.
## 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,45 +0,0 @@
# dcr test
Runs the project's test suite.
## Usage
```sh
dcr test
dcr test --debug
dcr test --release
dcr test --target linux
dcr test --init
```
## What `test` does
1. Builds the project with the specified profile/target.
2. Compiles test files in `tests/` (e.g., `tests/test.c`) into a test binary.
3. Runs the test binary and parses output for PASS/SKIP/FAIL results.
4. Reports summary with colored output.
## Test Structure
DCR uses a simple test framework:
- Header: `tests/dcr_test.h` (generated by `dcr test --init`)
- Test file: `tests/test.c` (template generated by `dcr test --init`)
- Macros: `TEST(name)`, `TEST_CASE(name)`, `EXPECT(condition)`, `SKIP(reason)`
- Output: `[PASS] test_name`, `[FAIL] test_name`, or `[SKIP] test_name`
## Config values used
- `package.name`
- `build.compiler`, `build.language`, `build.standard`
- `build.cflags`, `build.ldflags`
- `build.debug` / `build.release`
- `build.targets` (if specified)
## Notes
- Test binary is linked with the main project (for lib projects) or standalone.
- `--init` creates `tests/dcr_test.h` and `tests/test.c` if missing.
- Tests run in debug mode by default. Use `--release` for release mode.
- Custom test logic can be added by editing `tests/test.c`.
- Fails if no `tests/test.c` exists (run `dcr test --init` first).

View File

@@ -1,22 +0,0 @@
# dcr tree
Displays a visual dependency tree for the current project (similar to `cargo tree`).
## Usage
```sh
dcr tree
dcr tree --invert
dcr tree -p some-package
```
## What it shows
- All direct and transitive dependencies
- Version of each dependency
- Whether a dependency is a registry, git, or path dependency
## Notes
- Useful for debugging dependency issues and understanding the build graph.
- Output format is inspired by `cargo tree`.

View File

@@ -0,0 +1,51 @@
---
sidebar_label: Dependency commands (add, tree)
---
# Dependency Commands
## `dcr add <name> [source]`
Adds a dependency to `dcr.toml`.
```bash
dcr add fmt # registry lookup
dcr add mylib ../path/to/lib # path as source
dcr add mylib path:./lib # explicit path prefix
dcr add mylib git:https://github.com/user/repo # explicit git prefix
dcr add mylib github:user/repo # GitHub shorthand
dcr add mylib gitlab:user/repo # GitLab shorthand
```
Source prefixes:
- `path:` — local path
- `git:` — generic git URL
- `github:` — expands to `https://github.com/<user>/<repo>`
- `gitlab:` — expands to `https://gitlab.com/<user>/<repo>`
- `http://` / `https://` / `git@` — full URL
Flags:
- `--branch <name>` — git branch
- `--tag <name>` — git tag
- `--rev <hash>` — git commit
If source is omitted — DCR searches connected registries.
## `dcr tree`
Displays the project dependency tree.
```bash
dcr tree
```
Example output:
```
my-app v0.1.0
├── fmt (registry)
│ └── spdlog (registry)
└── catch2 (registry)
```
For path dependencies, recursively shows their own dependencies (from their `dcr.toml`).

View File

@@ -0,0 +1,71 @@
---
sidebar_label: Gen commands (vscode, clion, ...)
---
# Gen Commands
## `dcr gen <target>`
Generates IDE integration files.
### vscode
```bash
dcr gen vscode
```
Creates:
- `.vscode/tasks.json` — `build` task (dcr build)
- `.vscode/launch.json` — debug launch configuration
- `.vscode/settings.json` — C/C++ settings (clangd paths, includes)
- `.vscode/extensions.json` — recommended extensions (vscode-clangd, vscode-lldb)
### clion
```bash
dcr gen clion
```
Creates:
- `.idea/externalTools.xml` — external tools (build, run, clean, test)
- `.idea/customTargets.xml` — custom build targets
- `.idea/misc.xml` — C/C++ project settings
- `.idea/runConfigurations/<name>.xml` — per-binary run configurations
### compile-commands
```bash
dcr gen compile-commands
```
Generates `compile_commands.json` — standard format for clangd, cpptools, static analyzers.
### project-info
```bash
dcr gen project-info
```
Outputs JSON array with project metadata:
```json
[
{
"name": "my-app",
"version": "0.1.0",
"root": "/path/to/project",
"profile": "debug",
"language": "c",
"standard": "c17",
"cxx_standard": null,
"compiler": "/usr/bin/clang",
"kind": "bin",
"sources": ["src/main.c"],
"include_dirs": ["src"],
"lib_dirs": [],
"libs": [],
"cflags": ["-std=c17", "-O0", "-g"],
"ldflags": []
}
]
```

View File

@@ -1,44 +0,0 @@
# 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

@@ -0,0 +1,37 @@
---
sidebar_label: Project commands (new, init)
---
# Project Commands
## `dcr new <name>`
Creates a new project with a standard structure and `dcr.toml`. The `name` argument is required.
Only ASCII letters, digits, underscores `_` and hyphens `-` are allowed in the project name.
```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
## `dcr init`
Initializes a DCR project in the current (empty) directory.
```bash
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

@@ -0,0 +1,59 @@
---
sidebar_label: Quality commands (test, fmt)
---
# Quality Commands
## `dcr test`
Runs tests.
```bash
dcr test # debug profile
dcr test --release # release profile
dcr test --debug # explicit debug
dcr test --help # detailed help
```
Before first use, initialize tests:
```bash
dcr test --init
```
This creates `tests/dcr_test.h` (framework) and `tests/test.c` (template).
What `dcr test` does:
1. Builds the project
2. Collects `tests/*.c` files (`.c` only, not `.cpp`)
3. Compiles and links each test file
4. Runs each test binary
5. Prints summary: TOTAL, PASS, SKIP, FAIL
6. Returns non-zero exit code on any FAIL
## `dcr fmt`
Formats C/C++ source files using `clang-format`.
```bash
dcr fmt
```
Processes: `src/**/*.{c,cpp,cxx,cc,h,hpp,hxx,hh}` and `tests/**/*.{c,cpp,cxx,cc,h,hpp,hxx,hh}`.
Uses `.clang-format` at the project root (if present), otherwise default clang-format style.
## `dcr lint`
Runs `clang-tidy` on C/C++ source files for static analysis.
```bash
dcr lint # show diagnostics
dcr lint --fix # apply fixes automatically
dcr lint --help # detailed help
```
Processes: `src/**/*.{c,cpp,cxx,cc}` and `tests/**/*.{c,cpp,cxx,cc}`.
Without `--fix`, clang-tidy reports warnings and errors without modifying files.
With `--fix`, clang-tidy applies automatic suggestions in place.

View File

@@ -0,0 +1,50 @@
---
sidebar_label: System commands (setup, --help, ...)
---
# System Commands
## `dcr setup`
Shows configured registries from `~/.dcr/config.toml`.
```bash
dcr setup
```
If `~/.dcr/config.toml` is not found, DCR returns an error. Create it manually:
```toml
[registry.default]
url = "https://index.dcr.pm"
priority = 1
```
## `dcr --help`
Shows help for all commands.
```bash
dcr --help
```
## `dcr --version`
Shows version and target triple.
```bash
dcr --version # dcr 0.7.0 (x86_64-unknown-linux-gnu)
```
## `dcr --update`
Self-update. Downloads the latest release binary from GitHub Releases and replaces the current one.
```bash
dcr --update
```
Features:
- Auto-detects platform and architecture
- Warns if installed via AUR (use package manager instead)
- Works on Linux, macOS, Windows

View File

@@ -1,74 +0,0 @@
# 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
```
You can also add `--force` or `--clean` to `build`/`run`.
## Default profile flags
### GCC/Clang-like toolchains
- `debug`: `-O0 -g -Wall -Wextra -fno-omit-frame-pointer -DDCR_DEBUG`
- `release`: `-O3 -DNDEBUG`
### MSVC toolchain
- `debug`: `/Od /Zi /W4 /DDCR_DEBUG /Oy-`
- `release`: `/O2 /DNDEBUG`
## Artifacts
By default:
- `target/debug/<name>` (or `.exe` on Windows)
- `target/release/<name>` (or `.exe` on Windows)
Default compiler flags:
GCC/Clang:
- `debug`: `-O0 -g -Wall -Wextra -fno-omit-frame-pointer -DDCR_DEBUG`
- `release`: `-O3 -DNDEBUG`
MSVC:
- `debug`: `/Od /Zi /W4 /DDCR_DEBUG /Oy-`
- `release`: `/O2 /DNDEBUG`
Static library mode (`kind = "staticlib"`):
- Linux/macOS: `lib<name>.a`
- Windows: `<name>.lib`
Shared library mode (`kind = "sharedlib"`):
- Linux: `lib<name>.so`
- macOS: `lib<name>.dylib`
- Windows: `<name>.dll`
## Profile overrides
Use `[build.debug]` and `[build.release]` to override build settings per profile.
All values inherit from `[build]`. If a field is present in the profile table, it replaces the base value.
For arrays (like `cflags`/`ldflags`), the profile value is appended to the base array.
```toml
[build.debug]
cflags = ["-g3"]
[build.release]
cflags = ["-O3"]
ldflags = ["-s"]
```

View File

@@ -1,179 +0,0 @@
# Build section
## Schema
```toml
[build]
language = "c"
standard = "c11"
compiler = "clang"
kind = "bin"
# filename = "KERNEL"
# extension = "BIN"
# optional:
# inherit = true # Inherit from base (default true)
# targets = ["linux", "macos"] # Multiple targets to build
# target = "./dist"
# platform = "x86_64"
# cflags = ["-Wall"]
# ldflags = ["-lm"]
# exclude = ["src/vendor", "src/legacy/**"]
# include = ["src/legacy/boot/**"]
# roots = ["kernel", "drivers"]
# src_disable = true
# pkg_config = ["Qt6Core", "Qt6Widgets"]
# generated = ["src/ui/*.h"]
# expect = ["./target/{profile}/boot/*.bin"]
# clean = ["./target/{profile}/boot", "/tmp/image/*.img"]
```
## Fields
- `language` (string or array, required): `c`, `c++`, `cpp`, `cxx`, or `asm`.
Mixed languages can be specified as an array, for example `["c", "c++", "asm"]`.
- `standard` (string, required): C language standard passed to compiler (e.g. `c11`, `c17`, `gnu11`).
- `cxx_standard` (string, optional): C++ language standard passed to compiler for `.cpp`/`.cxx`/`.cc` files
(e.g. `c++17`, `gnu++17`, `c++20`). When set, overrides `standard` for C++ sources.
- `compiler` (string, required): compiler command (for example `clang`, `gcc`, `cl`).
- `kind` (string, required): `bin`, `staticlib`, `sharedlib`, `efi`, or `elf`.
- `filename` (string, optional): custom output filename (without extension). Overrides `package.name` for the final artifact.
- `extension` (string, optional): custom file extension without the leading dot (e.g. `BIN`, `efi`, `EFI`). Combined with `filename`.
- `inherit` (bool, optional): inherit settings from base `[build]` (default `true`). If `false`, only use target/profile specific settings.
- `targets` (string array, optional): list of targets to build simultaneously. Supports short names (`linux`, `macos`, `windows`).
- `target` (string, optional): custom output directory for final artifact.
When set, DCR automatically injects `--target=<value>` into `cflags` (useful for clang cross-compilation).
- `platform` (string, optional): architecture hint for compiler (used for `-march` or `/arch`).
- `cflags` (string array, optional): extra compile flags.
Supports variable substitution — see [Variable substitution](#variable-substitution) below.
- `ldflags` (string array, optional): extra link flags.
Supports variable substitution — see [Variable substitution](#variable-substitution) below.
- `ldscript` (string, optional): linker script path. Passed as `-T <path>` to the linker. Useful for bare-metal/embedded/freestanding targets.
- `exclude` (string array, optional): paths or glob patterns to skip during source/header collection.
- `include` (string array, optional): allowlist paths or globs that override `exclude`.
- `include` directory entries (non-glob) are also passed to the compiler as `-I` include paths.
- `roots` (string array, optional): additional source roots to scan instead of `src/`.
- `src_disable` (bool, optional): disables default `src/` root when true.
- `pkg_config` (string array, optional): packages used to append `pkg-config --cflags/--libs`.
- `generated` (string array, optional): generated files to delete when build steps rerun.
- `expect` (string array, optional): artifacts that must exist after build/post-steps.
- `clean` (string array, optional): additional paths removed by `dcr clean` and `--clean`.
Notes for `exclude`/`include`:
- Supports `*` and `**` glob patterns.
- If `include` is set, it has priority over `exclude`.
- Use `include` to re-allow nested paths, for example exclude `src/boot` but allow `src/boot/arch/**`.
When using glob patterns in `exclude`, DCR converts them internally, so `exclude` globs still work as expected.
### Variable substitution
`cflags`, `ldflags`, and `include` directory entries support the same `{placeholder}` variables
as build/post steps:
| Variable | Description |
|---|---|
| `{profile}` | Build profile (`debug` / `release`) |
| `{name}` | Package name |
| `{version}` | Full package version (e.g. `0.2.1`) |
| `{version_major}` | Major version number |
| `{version_minor}` | Minor version number |
| `{version_patch}` | Patch version number |
| `{version_suffix}` | Version suffix (e.g. `-rc1`) |
| `{version_suffix_dash}` | Suffix with leading dash (or empty) |
Example:
```toml
[build]
cflags = ['-DPROJECT_VERSION="{version}"', '-DVERSION_MAJOR={version_major}']
```
## Build steps
```toml
[[build.steps]]
name = "uic"
in = "src/ui/*.ui"
out = "src/ui/{stem}.h"
cmd = "{uic} {in} -o {out}"
[[build.post_steps]]
name = "image"
in = "target/{profile}/boot/*.bin"
out = "/tmp/image/os-{version}.img"
cmd = "dd if=/dev/zero of={out} bs=1M count=8"
```
Step notes:
- `in` supports glob patterns.
- If `in` expands to multiple files, `out` must include `{stem}`.
- Steps run only when inputs are newer than outputs.
- Variables: `{in}`, `{out}`, `{stem}`, `{cflags}`, `{uic}`, `{moc}`, `{rcc}`, `{profile}`,
`{version}`, `{version_major}`, `{version_minor}`, `{version_patch}`, `{version_suffix}`, `{version_suffix_dash}`.
`build.clean` supports `{profile}` and version placeholders (`{version}`, `{version_major}`, ...).
### Profile overrides
Profile tables inherit all values from `[build]`. Any field present in the profile table replaces the base value.
Array fields (like `cflags`/`ldflags`) are appended to the base array.
Target tables override profile and base settings for specific targets. Full inheritance order:
1. `[build.<target>.<profile>]`
2. `[build.<profile>.<target>]`
3. `[build.<target>]`
4. `[build.<profile>]`
5. `[build]`
If custom `cflags` are set (non-empty), default compiler flags are disabled.
```toml
[build.debug]
cflags = ["-g3"]
[build.release]
cflags = ["-O3"]
ldflags = ["-s"]
# Target-specific overrides (applied after profile)
[build.linux]
compiler = "gcc"
cflags = ["-march=x86_64"]
[build.macos]
compiler = "clang"
cflags = ["-arch", "x86_64"]
# Full inheritance example
[build.linux.release]
cflags = ["-O3", "-march=native"] # Overrides profile and base
[build.release.linux]
ldflags = ["-static"] # Alternative order
[build.windows.debug]
compiler = "x86_64-w64-mingw32-gcc"
cflags = [] # Empty to disable defaults
[build.release]
inherit = false # No inheritance, only explicit settings
```
## Toolchain section
```toml
[toolchain]
cc = "clang"
cxx = "clang++"
as = "as"
ar = "ar"
ld = "ld"
uic = "uic"
moc = "moc"
rcc = "rcc"
```
## 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 library kinds (`staticlib`, `sharedlib`), `efi`, or `elf`.

View File

@@ -1,71 +0,0 @@
# 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]`
Workspace-only root:
- `[workspace]` can be added to a normal root config to define members and dependency order.
- Root config still requires `[package]`, `[build]`, and `[dependencies]`.
## Required keys
- `package.name`
- `package.version`
- `build.language`
- `build.standard`
- `build.compiler`
- `build.kind`
`build.kind` must be either `bin`, `staticlib`, or `sharedlib`.
## Optional keys
- `build.inherit`
- `build.targets`
- `build.target`
- `build.platform`
- `build.cflags`
- `build.ldflags`
- `build.exclude`
- `build.include`
- `build.roots`
- `build.src_disable`
- `build.pkg_config`
- `build.steps`
- `build.post_steps`
- `build.generated`
- `build.expect`
- `build.clean`
- `build.debug`
- `build.release`
- `build.<target>` (target-specific overrides)
- dependency fields (`include`, `lib`, `libs`, `system`)
- `[toolchain]` overrides (`cc`, `cxx`, `as`, `ar`, `ld`, `uic`, `moc`, `rcc`)
- `[toolchain.<target>]` (target-specific toolchain)
- `[workspace]` members
- `[workspace.<target>]` (target-specific workspace)
- `[run]` overrides (`cmd`)
- `[run.<target>]` (target-specific run)

View File

@@ -1,44 +0,0 @@
# Dependencies section
DCR supports registry-based dependencies and path dependencies.
## Example
```toml
[dependencies]
# Registry dependency
mylib = "0.1.0"
# Git dependency
json = { git = "https://github.com/nlohmann/json", tag = "v3.11.2" }
# Path dependency
frecli = { path = "./lib/frecli", include = ["."], lib = ["."], libs = ["frecli"] }
```
## Supported dependency types
### Registry dependencies
Defined by name and version string. DCR automatically resolves the package from the configured registry index.
### Git dependencies
Defined by repository URL and optionally branch, tag, or revision.
- `git` (string, required): repository URL.
- `branch`, `tag`, `rev` (string, optional): Git reference.
### Path dependencies
- `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.
## Defaults for path dependencies
- 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 string (registry) or a TOML table (path).
- Registry dependencies use the version string to match versions in the registry.
- `path` is mandatory for path dependencies.
- `include`/`lib`/`libs` must be arrays of strings if provided.

View File

@@ -1,35 +0,0 @@
# Package section
## Schema
```toml
[package]
name = "my-app"
version = "0.1.0"
type = "app"
description = "My application"
author = "John Doe"
license = "MIT"
```
## Fields
- `name` (string, required): used as output artifact base name.
- `version` (string, required): used in `dcr.lock` project entry.
- `type` (string, optional): project type (`app`, `lib`, `none`).
- `description` (string, optional): human-readable project description.
- `author` (string, optional): single author name.
- `authors` (array of strings, optional): list of authors.
- `license` (string, optional): project license identifier (e.g. `MIT`, `GPL-3.0-or-later`).
- `homepage` (string, optional): project homepage URL.
- `repository` (string, optional): source repository URL.
- `readme` (string, optional): path to README file.
- `keywords` (array of strings, optional): project keywords.
- `categories` (array of strings, optional): project categories.
## 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.
- If `type = "lib"`, DCR generates `include/` and `lib/` directories in the target path, copying public headers and built libraries.

51
docs/contributing.mdx Normal file
View File

@@ -0,0 +1,51 @@
---
sidebar_label: Contributing
---
# Contributing
## Setup
```bash
git clone https://github.com/dexoron/dcr
cd dcr
cargo build
```
## Code style
All code must be formatted with `cargo fmt`:
```bash
cargo fmt
```
## Linting
```bash
cargo clippy --all-targets -- -D warnings
```
## Tests
```bash
cargo test --all-targets
```
## PR process
1. Fork the repository
2. Create a branch: `git checkout -b feature/description`
3. Make changes
4. Run `cargo fmt && cargo clippy && cargo test`
5. Open a Pull Request
## CI
CI runs (see `.github/workflows/ci.yml`):
- `cargo fmt --check`
- `cargo clippy` (default + `--all-features`)
- `cargo check --all-targets --all-features`
- Unit + integration tests on Linux, macOS, Windows
- Extra Linux job with `--features archive` (FAT images)
- Tools on runners: clang, nasm, clang-format/tidy (Linux)

View File

@@ -1,78 +0,0 @@
# Compilers & linking
## Compiler backend selection
DCR picks a backend from `build.compiler`:
- contains `clang-cl` -> MSVC backend
- equals `as` or contains `gas` -> GAS backend (standalone assembler)
- contains `gcc` or `g++` -> GCC backend
- contains `clang` or `clang++` -> Clang backend
- equals `cl` or contains `msvc` -> MSVC backend
- contains `nasm` -> NASM backend
- otherwise -> Clang backend fallback
## Compilation model
- Source files are found recursively in `src/` based on `build.language`.
- `build.roots` and `build.src_disable` can replace the default `src/` root.
- Mixed language builds use arrays, for example `build.language = ["c", "asm"]`.
- Each source is compiled to `target/<target>/<profile>/obj/<relative-path>.o` (`.obj` on MSVC, where `<target>` is `native` or target triple).
- Recompile happens when source mtime is newer than object mtime.
- `build.exclude` removes paths from source/header collection; `build.include` re-allows matching paths and has priority over `exclude`.
## Default build flags
These flags are applied automatically based on profile and compiler backend.
GCC/Clang:
- `debug`: `-O0 -g -Wall -Wextra -fno-omit-frame-pointer -DDCR_DEBUG`
- `release`: `-O3 -DNDEBUG`
MSVC:
- `debug`: `/Od /Zi /W4 /DDCR_DEBUG /Oy-`
- `release`: `/O2 /DNDEBUG`
Note: If custom `cflags` are set in `dcr.toml`, default profile flags are disabled to allow full control.
## Platform hint
If `build.platform` is set, DCR passes it as an architecture hint:
- GCC/Clang: `-march=<platform>`
- MSVC: maps to `/arch:*` for known values (`x86`, `i386`, `i486`, `i586`, `i686`, `sse2`, `avx`, `avx2`)
## Toolchain overrides
If `[toolchain]` is set, DCR uses its values to override compiler/linker tools:
- `cc`, `cxx`, `as` override compilers for C/C++/ASM
- `ar` overrides the archiver (used for `staticlib`)
- `ld` overrides the linker (used by GCC/Clang/NASM/GAS backends)
- `uic`, `moc`, `rcc` override Qt tools used in `build.steps`
Environment overrides (highest priority):
- `DCR_COMPILER` (all languages)
- `DCR_CC`, `DCR_CXX`, `DCR_AS`, `DCR_AR`, `DCR_LD`
- `DCR_DEBUG` enables verbose build logging
## 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.
For `kind = "sharedlib"`:
- Linux (GCC/Clang): `-shared` with output `.so`.
- macOS (Clang): `-dynamiclib` with output `.dylib`.
- Windows (MSVC): `/LD` with output `.dll`.

View File

@@ -1,203 +0,0 @@
# Cross-compilation and Targets
DCR supports cross-compilation to different platforms using the `--target` flag. This allows building your project for architectures and operating systems different from the host.
## Basic Usage
```bash
# Build for a specific target
dcr build --target x86_64-unknown-linux-gnu --release
# Short names for common platforms
dcr build --target linux --release # x86_64-unknown-linux-gnu
dcr build --target macos --release # x86_64-apple-darwin
dcr build --target windows --release # x86_64-pc-windows-msvc
# Run for a specific target
dcr run --target linux --release
```
## Supported Targets
### Short Names
- `linux` → `x86_64-unknown-linux-gnu`
- `macos` → `x86_64-apple-darwin`
- `windows` → `x86_64-pc-windows-msvc`
### Full Target Triples
DCR supports any valid target triple in the format `<arch>-<vendor>-<os>-<abi>`. Common examples:
- `x86_64-unknown-linux-gnu`
- `aarch64-linux-gnu`
- `x86_64-apple-darwin`
- `aarch64-apple-darwin`
- `x86_64-pc-windows-msvc`
- `i686-pc-windows-gnu`
## Configuration
### Multiple Targets
Configure multiple targets to build simultaneously:
```toml
[build.targets]
targets = ["linux", "macos", "windows"]
# Or per profile
[build.release.targets]
targets = ["linux", "macos"]
```
If no `--target` is specified, DCR builds for all targets in `build.targets` (or native if empty).
### Target-Specific Settings
Override settings for specific targets:
```toml
[build.linux]
compiler = "gcc"
cflags = ["-Wall", "-O2"]
[build.macos]
compiler = "clang"
cflags = ["-Wall", "-O2", "-arch", "x86_64"]
[build.windows]
compiler = "x86_64-w64-mingw32-gcc"
ldflags = ["-static"]
```
### Target-Specific Toolchain
Configure toolchain per target:
```toml
[toolchain.linux]
cc = "gcc"
ld = "ld"
[toolchain.macos]
cc = "clang"
ld = "ld"
[toolchain.windows]
cc = "x86_64-w64-mingw32-gcc"
ld = "x86_64-w64-mingw32-ld"
```
### Target-Specific Run Commands
Use custom run commands per target:
```toml
[run.linux]
cmd = "./target/linux/release/myapp"
[run.macos]
cmd = "open ./target/macos/release/myapp.app"
[run.windows]
cmd = "wine ./target/windows/release/myapp.exe"
```
## Workspace and Dependencies Inheritance
Workspace and dependencies sections also support target/profile inheritance:
```toml
[workspace.linux]
members = [
{ name = "lib1", path = "libs/lib1" },
]
[dependencies.linux]
sdl2 = { system = true, include = ["/usr/include/SDL2"] }
[dependencies.windows]
sdl2 = { system = true, include = ["C:/SDL2/include"] }
```
Order: `workspace.target.profile` → `workspace.profile.target` → `workspace.target` → `workspace.profile` → `workspace`.
Add `inherit = false` to disable inheritance in any section.
Settings are applied in order:
1. `[build.<target>]`
2. `[build.<profile>]`
3. `[build]`
### Toolchain Configuration
For cross-compilation, configure toolchains:
```toml
[toolchain]
cc = "aarch64-linux-gnu-gcc"
cxx = "aarch64-linux-gnu-g++"
ar = "aarch64-linux-gnu-ar"
ld = "aarch64-linux-gnu-ld"
```
## Output Structure
Build outputs are organized by target:
```
target/
├── native/
│ ├── debug/
│ └── release/
├── x86_64-unknown-linux-gnu/
│ ├── debug/
│ └── release/
└── aarch64-linux-gnu/
├── debug/
└── release/
```
## Requirements
- Cross-compilation requires appropriate toolchains installed (e.g., `aarch64-linux-gnu-gcc` on Arch Linux).
- For Windows targets on Linux, install MinGW: `pacman -S mingw-w64-gcc`.
- For macOS targets on Linux, use `osxcross` or similar.
## Examples
### ARM Linux Build
```bash
# Install toolchain (Arch Linux)
pacman -S aarch64-linux-gnu-gcc
# Configure
echo '[build.aarch64-linux-gnu]
compiler = "aarch64-linux-gnu-gcc"' >> dcr.toml
# Build
dcr build --target aarch64-linux-gnu --release
```
**Note:** If you set `target = "aarch64-linux-gnu"` (or any value) directly under `[build]`, DCR will automatically add `--target=...` to cflags when using clang. You usually don't need to repeat it manually.
### Windows Build on Linux
```bash
# Install toolchain (Arch Linux)
pacman -S mingw-w64-gcc
# Configure
echo '[build.windows]
compiler = "x86_64-w64-mingw32-gcc"' >> dcr.toml
# Build
dcr build --target windows --release
```
## Troubleshooting
- **Toolchain not found**: Ensure the compiler is installed and in PATH, or configure `[toolchain]` in `dcr.toml`. For Arch Linux: `pacman -S aarch64-linux-gnu-gcc` for ARM, `pacman -S mingw-w64-gcc` for Windows cross-compilation.
- **Linking errors**: Check `ldflags` and library paths for cross-compilation.
- **Header issues**: Include paths may differ; use target-specific `cflags`.
For more help, see [Troubleshooting map](troubleshooting-map.md).

View File

@@ -1,40 +0,0 @@
# Dependency format
Dependencies are defined in `dcr.toml` under `[dependencies]`.
## Full example (Path)
```toml
[dependencies]
fmt = { path = "./third_party/fmt", include = ["include"], lib = ["lib"], libs = ["fmt"] }
```
## Full example (Git)
```toml
[dependencies]
json = { git = "https://github.com/nlohmann/json", tag = "v3.11.2" }
```
## Field reference
- `path`: local path to dependency root.
- `git`: URL of Git repository.
- `branch`: Git branch name.
- `tag`: Git tag name.
- `rev`: Git commit SHA.
- `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 forms
```toml
[dependencies]
mylib = { path = "./libs/mylib" }
gitlib = { git = "https://github.com/user/repo" }
# Shortest form for path
simple = "./libs/simple"
```
In these forms DCR will try defaults for include/lib dirs and use the dependency name as the linker library name.

View File

@@ -1,24 +0,0 @@
# 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.
### Profile placeholders
`path`, `include`, and `lib` entries may use `{profile}` which expands to the active profile
(`debug` or `release`).
## 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,23 +0,0 @@
# Target directory
By default, DCR writes final artifacts to `target/<target>/<profile>/` (where `<target>` is `native` or target triple).
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/<target>/<profile>/...`.

View File

@@ -1,32 +0,0 @@
# 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.

66
docs/faq.mdx Normal file
View File

@@ -0,0 +1,66 @@
---
sidebar_label: FAQ
---
# FAQ
## Registry not found
```
error: registry not found
```
**Solution:** Make sure `~/.dcr/config.toml` exists:
```toml
[registry.default]
url = "https://index.dcr.pm"
priority = 1
```
And check `DCR_INDEX_PATH`:
```bash
echo $DCR_INDEX_PATH
```
## Compiler not found
```
error: compiler not found
```
**Solution:** Ensure a compiler is installed and available in PATH.
```bash
which gcc
which clang
```
Or specify explicitly via `[toolchain]` in `dcr.toml`.
## Ctrl+C during build
DCR handles SIGINT: interrupts the current compilation and exits with non-zero code.
## How to create a library?
See [Library Recipe](/docs/recipes/library-project).
## How to cross-compile to Windows?
See [Cross-Compile Recipe](/docs/recipes/cross-to-windows).
## How to create a multi-package project?
See [Workspace Recipe](/docs/recipes/multi-package-workspace).
## Bootloader / pure NASM OS image
Use `kind = "flat-bin"` (NASM `-f bin`) and optional `[archive]` for a FAT disk image.
See [OS-dev recipe](/docs/recipes/os-flat-bin-archive).
## Lock file
`dcr.lock` is created during builds (`dcr build`) when registry dependencies are present. To force an update — delete `dcr.lock` and run `dcr build`.

View File

@@ -1,57 +0,0 @@
# Build and run
## Build
Debug (default):
```sh
dcr build
# or
dcr build --debug
dcr build --target linux --debug
dcr build --debug --clean
```
Release:
```sh
dcr build --release
dcr build --target windows --release
```
## Run
```sh
dcr run
# or
dcr run --target macos
dcr run --release
dcr run --target linux --release
dcr run --release --force
```
`dcr run` first builds, then launches the produced binary.
## Clean artifacts
```sh
dcr clean
```
Profile-only cleanup:
```sh
dcr clean --debug
dcr clean --release
dcr clean --all
dcr clean --release --all
```
## Notes
- `run` is unavailable for `build.kind = "staticlib"`, `build.kind = "sharedlib"`, `build.kind = "efi"`, and `build.kind = "elf"`.
- Build profile flag (`--debug` / `--release`) can be passed in any argument position.
- Unknown profile flags produce an error.
- In workspace root, `clean --all` cleans all member projects.
- `--target` builds/runs for specified target (short names: `linux`, `macos`, `windows`).
- `--clean` for `build`/`run` removes `target/<target>/<profile>` and paths from `build.clean`.

View File

@@ -1,41 +0,0 @@
# 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

@@ -0,0 +1,78 @@
---
sidebar_label: First steps
---
# First Steps
## Create a project
```bash
dcr new my-app
cd my-app
```
Structure:
```
my-app/
├── dcr.toml
└── src/
└── main.c
```
`dcr.toml`:
```toml
[package]
name = "my-app"
version = "0.1.0"
type = "none"
[build]
language = "c"
standard = "c11"
compiler = "clang"
kind = "bin"
```
## Build
```bash
dcr build
```
Output — `target/<triple>/debug/my-app` (Linux) or `target/debug/my-app.exe` (Windows).
Build profiles:
```bash
dcr build --release # release build
dcr build --debug # debug (default)
```
## Run
```bash
dcr run
```
Builds (if needed) and runs the binary.
## First test
```bash
dcr test --init # create test template
dcr test # run tests
```
## Formatting
```bash
dcr fmt # clang-format with .clang-format
```
## Linting
```bash
dcr lint # clang-tidy checks
dcr lint --fix # apply fixes automatically
```

View File

@@ -1,56 +0,0 @@
# 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

@@ -0,0 +1,135 @@
---
sidebar_label: Installation
---
# Installation
## dcrup (recommended)
Install and switch DCR versions (stable / dev / night, pin `0.8.2`, optional build from source).
### Linux / macOS / BSD / Windows (bash)
```sh
curl -fsSL https://sh.dcr-tool.ru | sh -s -- self-install
export PATH="$HOME/.dcr/bin:$PATH"
dcrup install stable
```
Non-interactive install of DCR in one shot:
```sh
curl -fsSL https://sh.dcr-tool.ru | sh -s -- install stable
export PATH="$HOME/.dcr/bin:$PATH"
```
### Windows (PowerShell)
```powershell
irm https://ps1.dcr-tool.ru | iex
# or download then run:
# irm https://ps1.dcr-tool.ru -OutFile dcrup.ps1
# powershell -File .\dcrup.ps1 self-install
# $env:Path += ";$env:USERPROFILE\.dcr\bin"
dcrup install stable
```
Optional cmd bootstrap (if you prefer `curl` of the cmd shim):
```bat
curl -fsSL -o dcrup.cmd https://cmd.dcr-tool.ru
```
After `self-install`, the command is **`dcrup`** (no `.sh` / `.ps1`): shims live in `~/.dcr/bin` (Unix) or `%USERPROFILE%\.dcr\bin` (Windows `dcrup.cmd`).
### Common dcrup commands
```sh
dcrup install stable # latest stable prebuilt
dcrup install 0.8.2 # pin → 0.8.2@stable
dcrup install 0.8.2@dev
dcrup install stable --libc musl # Linux: musl asset (default: gnu)
dcrup install stable --build # cargo build --features archive
dcrup install night # always build from branch dev HEAD
dcrup default 0.8.2
dcrup update
dcrup list
dcrup show
dcrup which
```
Layout: `~/.dcr/toolchains/<id>/dcr` and `~/.dcr/bin/dcr` → active version.
---
## Arch Linux (AUR)
```sh
yay -S dcr
```
## macOS / Linux (Homebrew)
```sh
brew tap dexoron/dexoron
brew install dcr
```
## Snap (Linux)
```sh
sudo snap install dcrup
```
> If classic Snap Store publishing is unavailable, install the `.snap` from [GitHub Releases](https://github.com/dexoron/dcr/releases/latest) with `--dangerous`.
## Nix (flake)
```sh
nix run github:dexoron/dcr
nix profile install github:dexoron/dcr
```
## Cargo (crates.io)
```sh
cargo install dcr
```
Note: crates.io builds may omit optional features. For FAT disk images (`[archive]`), prefer release binaries or:
```sh
cargo install dcr --features archive
```
## From source
```sh
git clone https://github.com/dexoron/dcr.git
cd dcr
cargo build --release --features archive
ln -sf "$PWD/target/release/dcr" ~/.local/bin/dcr
# or manage versions with dcrup install night / --build
```
## Post-install
```bash
dcr --version
dcrup show # if installed via dcrup
```
Man pages (package installs / release assets):
```bash
man dcr
man dcr-build
```
Registry (optional) — `~/.dcr/config.toml`:
```toml
[registry.default]
url = "https://index.dcr.pm"
priority = 1
```

View File

@@ -1,40 +0,0 @@
# 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/<target>/<profile>/obj/`: cached object files for incremental rebuild (where `<target>` is `native` or target triple).
- `target/<target>/<profile>/deps/`: synchronized copies of path dependencies.
- `target/<target>/<profile>/<name>` (or `.exe` on Windows): output for `kind = "bin"`.
- `target/<target>/<profile>/lib<name>.a` (or `<name>.lib` on Windows): output for `kind = "staticlib"`.
- `target/<target>/<profile>/lib<name>.so` (or `.dylib` on macOS, `<name>.dll` on Windows): output for `kind = "sharedlib"`.
If `build.target` is set, the final artifact is written to that custom directory, while object cache still stays in `target/<target>/<profile>/obj`.

51
docs/ide-integration.mdx Normal file
View File

@@ -0,0 +1,51 @@
---
sidebar_label: IDE Integration
---
# IDE Integration
## VS Code
```bash
dcr gen vscode
```
Generates in `.vscode/`:
| File | Purpose |
|------|---------|
| `tasks.json` | `build` task (dcr build) |
| `launch.json` | Debug launch configuration |
| `settings.json` | clangd/IntelliSense: include paths, standard |
| `extensions.json` | Recommends vscode-clangd, vscode-lldb |
## CLion
```bash
dcr gen clion
```
Generates in `.idea/`:
| File | Purpose |
|------|---------|
| `externalTools.xml` | Build, Run, Clean, Test as external tools |
| `customTargets.xml` | Custom build targets |
| `misc.xml` | C/C++ project settings |
| `runConfigurations/<name>.xml` | Per-binary run configurations |
## compile_commands.json
```bash
dcr gen compile-commands
```
Generates `compile_commands.json` at project root. Standard format for clangd, C/C++ IntelliSense, static analyzers.
## project-info
```bash
dcr gen project-info
```
Outputs JSON array with project metadata (see [gen-commands](/docs/commands/gen-commands)).

33
docs/license.mdx Normal file
View File

@@ -0,0 +1,33 @@
---
sidebar_label: License
---
# License
## DCR
DCR itself is [GPL-3.0-or-later](https://spdx.org/licenses/GPL-3.0-or-later.html) licensed.
> **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.
## Rust dependencies
DCR is written in Rust. The following notable Rust crates are statically linked:
| Crate | License |
|---|---|
| [`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 |
| [`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 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
- DCR's CLI design and project model are inspired by [Cargo](https://doc.rust-lang.org/cargo/).

View File

@@ -0,0 +1,49 @@
---
sidebar_label: Cross-compile to Windows
---
# Cross-Compile to Windows from Linux
Building a Windows binary on Linux using mingw-w64.
## Install toolchain
```bash
# Ubuntu/Debian
sudo apt install mingw-w64
# Fedora
sudo dnf install mingw64-gcc mingw64-binutils
```
## Configuration
```toml
[package]
name = "my-app"
version = "0.1.0"
type = "none"
[build]
language = "c"
standard = "c11"
compiler = "clang"
kind = "bin"
target = "x86_64-pc-windows-gnu" # explicit mingw, not msvc
```
## Build
```bash
dcr build --target x86_64-pc-windows-gnu --release
```
Artifact: `target/x86_64-pc-windows-gnu/release/my-app.exe`.
## Custom toolchain
```toml
[toolchain]
cc = "x86_64-w64-mingw32-gcc"
cxx = "x86_64-w64-mingw32-g++"
```

View File

@@ -0,0 +1,65 @@
---
sidebar_label: Library project
---
# Library Project
Creating a static library and using it in another project.
## Step 1: Create the library
```bash
dcr new my-lib
cd my-lib
```
`dcr.toml`:
```toml
[package]
name = "my-lib"
version = "0.1.0"
type = "none"
[build]
language = "c"
standard = "c11"
kind = "staticlib"
```
`src/my_lib.h`:
```c
#ifndef MY_LIB_H
#define MY_LIB_H
int add(int a, int b);
#endif
```
`src/my_lib.c`:
```c
#include "my_lib.h"
int add(int a, int b) { return a + b; }
```
## Step 2: Build
```bash
dcr build --release
```
Artifacts:
- `target/<triple>/release/libmy-lib.a` (Linux)
- `target/release/my-lib.lib` (Windows)
- `target/include/` — header files
## Step 3: Use in another project
```bash
dcr new my-app
cd my-app
dcr add my-lib ../my-lib
```
Automatically:
- Adds include path to `target/include/` of the library
- Adds lib path to `target/<triple>/release/`
- Links `libmy-lib.a` / `my-lib.lib`

View File

@@ -0,0 +1,99 @@
---
sidebar_label: Multi-package workspace
---
# Multi-Package Workspace
A project with three packages: two libraries and a binary.
## Structure
```
workspace/
├── dcr.toml # root workspace
├── lib-core/
│ ├── dcr.toml
│ └── src/core.c
├── lib-utils/
│ ├── dcr.toml
│ └── src/utils.c
└── app/
├── dcr.toml
└── src/main.c
```
## Root dcr.toml
```toml
[package]
name = "my-workspace"
version = "0.1.0"
type = "none"
[build]
inherit = true
language = "c"
standard = "c11"
workspace_only = true
[workspace.lib-core]
path = "lib-core"
[workspace.lib-utils]
path = "lib-utils"
deps = ["lib-core"]
[workspace.app]
path = "app"
deps = ["lib-core", "lib-utils"]
main = true
```
## Packages
`lib-core/dcr.toml`:
```toml
[package]
name = "lib-core"
version = "0.1.0"
type = "none"
[build]
kind = "staticlib"
```
`lib-utils/dcr.toml`:
```toml
[package]
name = "lib-utils"
version = "0.1.0"
type = "none"
[build]
kind = "staticlib"
```
`app/dcr.toml`:
```toml
[package]
name = "app"
version = "0.1.0"
type = "none"
[build]
kind = "bin"
```
## Build
```bash
cd workspace
dcr build # builds everything in correct order
dcr build --workspace app # only app (lib-core and lib-utils built as deps)
dcr run # builds and runs main package
```
Build order (topological sort):
1. `lib-core`
2. `lib-utils` (depends on lib-core)
3. `app` (depends on lib-core, lib-utils)

View File

@@ -0,0 +1,89 @@
---
sidebar_label: OS-dev (flat-bin + archive)
---
# Pure ASM / boot image (flat-bin + archive)
Minimal OS-dev style pipeline: assemble raw binaries with NASM, then pack a FAT floppy/image with an optional boot sector.
## Project layout
```
myos/
dcr.toml
src/
boot.asm # boot sector (512 bytes)
kernel.asm # payload
```
For multiple flat artifacts, use a **workspace** (one member per binary) or separate packages; a single `flat-bin` package produces one binary per source stem.
## Boot package (`flat-bin`)
```toml
[package]
name = "boot"
version = "0.1.0"
[build]
language = "asm"
compiler = "nasm"
kind = "flat-bin"
extension = "bin"
roots = ["src/boot.asm"]
```
```bash
dcr build
# → target/<…>/debug/boot.bin (NASM -f bin, no link)
```
## Disk image after build
```toml
[archive]
output = "target/{profile}/disk.img"
format = "fat12"
size = "1440K"
label = "MYOS"
bootsector = "target/{profile}/boot.bin"
[[archive.layout]]
from = "target/{profile}/kernel.bin"
to = "KERNEL.BIN"
```
- `format`: `fat12`, `fat16`, or `fat32`
- `size`: bytes or `K`/`KB`/`M`/`MB`/`G`/`GB` (default ~1.44 MiB)
- `bootsector`: written only when `offset` is omitted or `0`
- `from` may be a glob; `{profile}` is substituted in paths
## C kernel → flat binary
```toml
[build]
language = "c"
compiler = "clang"
kind = "flat-bin"
freestanding = true
filename = "kernel"
extension = "bin"
ldflags = ["-T", "linker.ld"]
```
Pipeline: objects → temporary linked ELF → `objcopy -O binary` → `kernel.bin`. Requires `objcopy` / `llvm-objcopy` in PATH.
## Other assemblers
| Tool | Notes |
|------|--------|
| **FASM** | Write `format binary` in the source; DCR writes `<stem>.bin` directly |
| **GAS** | Assemble `.s` → obj → `objcopy -O binary` |
| **LLC** | `language = "llvm_ir"` → obj → objcopy |
| **MASM** | COFF obj → objcopy (needs binutils/LLVM objcopy) |
## Notes
- Single-file `roots` are supported: `roots = ["src/boot.asm"]`.
- `--force` re-runs `build.steps` / `build.post_steps` as well as recompilation.
- Prefer `kind = "elf"` if you need a relocatable ELF kernel without stripping to raw binary.

View File

@@ -1,34 +0,0 @@
# CLI reference
## Command list
```text
dcr new <name>
dcr init
dcr setup
dcr add <name> <source>(optional)
dcr build [--debug|--release] [--target <triple>]
dcr run [--debug|--release]
dcr clean [--debug|--release] [--all]
dcr tree
dcr test
dcr gen <subcommand>
dcr --help
dcr --version
dcr --update
```
## Notes on argument parsing
- `build`/`run` parse flags in any order (`--debug|--release`, `--force`, `--clean`, `--verbose`) and reject duplicates.
- `new` requires exactly one argument.
- `init` and `--update` do not accept extra arguments.
- `clean` accepts `--debug|--release` and optional `--all`.
- `gen` supports `project-info`, `compile-commands`, `vscode`, `clion`.
- `tree` shows a dependency tree (similar to `cargo tree`).
- `test` / `tests` runs the project's tests.
## Exit behavior overview
- Successful command execution returns `0`.
- Validation/build/runtime failures return non-zero status.

View File

@@ -1,149 +0,0 @@
# Config reference
## Full schema
```toml
[package]
name = "string" # required
version = "string" # required
type = "string" # optional: "app", "lib", "none"
description = "string" # optional
author = "string" # optional
authors = ["string", "..."] # optional
license = "string" # optional
homepage = "string" # optional
repository = "string" # optional
readme = "string" # optional
keywords = ["string", "..."] # optional
categories = ["string", "..."] # optional
[build]
language = "c|c++|cpp|cxx|asm" # required (string or array)
standard = "string" # required (e.g. "c11", "gnu11")
cxx_standard = "string" # optional (e.g. "c++17", "gnu++17")
compiler = "string" # required (e.g. "clang", "gcc")
kind = "bin|staticlib|sharedlib|efi|elf" # required
target = "string" # optional (cross-compilation target triple)
platform = "string" # optional (architecture hint, -march)
type = "string" # optional
cflags = ["string", "..."] # optional (supports {version} etc.)
ldflags = ["string", "..."] # optional (supports {version} etc.)
ldscript = "string" # optional (linker script path)
exclude = ["string", "..."] # optional (glob patterns)
include = ["string", "..."] # optional (allowlist + -I dirs)
roots = ["string", "..."] # optional (source roots)
src_disable = false # optional (disable default src/)
pkg_config = ["string", "..."] # optional (pkg-config packages)
generated = ["string", "..."] # optional (generated file patterns)
expect = ["string", "..."] # optional (expected artifact patterns)
clean = ["string", "..."] # optional (extra clean paths)
targets = ["string", "..."] # optional (build targets)
filename = "string" # optional (custom output name)
extension = "string" # optional (custom extension)
inherit = true # optional (inherit base settings)
[[build.steps]]
name = "string" # required
in = "glob" # required
out = "path" # required
cmd = "string" # required
# Inline steps (equivalent to [[build.steps]])
steps = [
{ name = "string", in = "glob", out = "path", cmd = "string" },
]
[[build.post_steps]]
name = "string" # required
in = "glob" # required (or "target/...")
out = "path" # required
cmd = "string" # required
# Inline post_steps (equivalent to [[build.post_steps]])
post_steps = [
{ name = "string", in = "glob", out = "path", cmd = "string" },
]
# Profile overrides (inherit all from [build])
[build.debug]
cflags = ["string", "..."] # optional
ldflags = ["string", "..."] # optional
[build.release]
cflags = ["string", "..."] # optional
ldflags = ["string", "..."] # optional
# Target-specific overrides
[build.linux]
compiler = "string"
cflags = ["string", "..."]
[build.windows]
compiler = "string"
# Target + profile override
[build.linux.release]
cflags = ["string", "..."]
[toolchain]
cc = "string" # optional (C compiler override)
cxx = "string" # optional (C++ compiler override)
as = "string" # optional (assembler override)
ar = "string" # optional (archiver override)
ld = "string" # optional (linker override)
uic = "string" # optional (Qt uic)
moc = "string" # optional (Qt moc)
rcc = "string" # optional (Qt rcc)
[run]
cmd = "string" # required for `dcr run`
# Debug run variant
[run.debug]
cmd = "string"
[workspace]
[workspace.member_name]
path = "string" # required
deps = ["string", "..."] # optional
[dependencies]
[dependencies.dep_name]
path = "string" # local path
# or
version = "string" # registry version
# or
git = "string" # git URL
branch = "string" # optional (git branch)
tag = "string" # optional (git tag)
rev = "string" # optional (git commit)
# common fields:
include = ["string", "..."] # optional (include dirs)
lib = ["string", "..."] # optional (lib dirs)
libs = ["string", "..."] # optional (link libs)
features = ["string", "..."] # optional (registry features)
```
## Validation rules
- `[package]`, `[build]`, `[dependencies]` must exist.
- Required string fields must be non-empty.
- `build.kind` must be `bin`, `staticlib`, `sharedlib`, `efi`, or `elf`.
- Dependency fields `include/lib/libs` must be string arrays when provided.
- `build.exclude`/`build.include` must be string arrays when provided.
- `build.roots` must be a string array when provided.
- `build.src_disable` must be boolean when provided.
- `build.clean`/`build.generated`/`build.pkg_config`/`build.expect` must be string arrays when provided.
- `build.debug`/`build.release` must be tables; their `cflags`/`ldflags` must be string arrays.
- `build.steps`/`build.post_steps` entries must include `name`, `in`, `out`, `cmd`.
- `build.language` may be a string or array (for example `["c", "c++", "asm"]`).
- `[build.<profile>]` tables inherit all base values and override any fields they specify.
Array fields (like `cflags`/`ldflags`) are appended to the base array.
## 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,34 +0,0 @@
# 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,35 +0,0 @@
# FAQ
## What commands are available?
`new`, `init`, `build`, `run`, `clean`, `gen`, `--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 dependencies are tracked too: if an included header changes (or disappears), rebuild is triggered.
## 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.

View File

@@ -1,48 +0,0 @@
# Flags & environment
This page summarizes runtime flags and environment variables that affect DCR behavior.
## Build/run flags
Used with `dcr build` and `dcr run`:
- `--debug`: select debug profile.
- `--release`: select release profile.
- `--force`: ignore incremental cache checks and rebuild.
- `--clean`: remove `target/<profile>` and `build.clean` paths before build.
Notes:
- Flags can be passed in any order.
- Duplicate profile flags are rejected.
## Clean flags
Used with `dcr clean`:
- `--debug` / `--release`: clean only selected profile directory.
- `--all`: in workspace root, also clean all members.
## Environment variables
Tool selection overrides:
- `DCR_COMPILER` (all languages)
- `DCR_CC`, `DCR_CXX`, `DCR_AS`, `DCR_AR`, `DCR_LD`
Diagnostics:
- `DCR_DEBUG=1` enables verbose build logging.
## Quick examples
```sh
# Force full release rebuild
dcr build --release --force
# Clean before debug run
dcr run --clean --debug
# Use custom compiler from env
DCR_CC=clang-18 dcr build --debug
```

View File

@@ -1,75 +0,0 @@
# Troubleshooting map
Fast mapping from symptom to likely cause and first action.
## `dcr.toml file not found`
Likely cause:
- you are outside project root (or member root).
First action:
```sh
pwd
ls
```
Run DCR from directory that contains `dcr.toml`.
## `Invalid config: missing [package]` / `missing [build]`
Likely cause:
- incomplete config in root project.
First action:
- ensure root `dcr.toml` includes `[package]`, `[build]`, and `[dependencies]`.
- for workspace setups, keep these sections in root and add `[workspace]` additionally.
## `Unknown build flag` or profile-flag errors
Likely cause:
- typo in flag or duplicate profile flag.
First action:
```sh
dcr --help
```
Use only supported flags and at most one of `--debug` / `--release`.
## Dependency include/lib path errors
Likely cause:
- path in `[dependencies]` does not exist.
First action:
- verify `path`, `include`, `lib` values.
- if using profile placeholders, confirm expanded paths exist for selected profile.
## `Cannot run library build`
Likely cause:
- `build.kind` is `staticlib` or `sharedlib`.
First action:
- switch `build.kind` to `bin`, or set `[run].cmd` if you intentionally need custom run command.
## Build succeeds but output is stale
Likely cause:
- stale artifacts or generated files from previous runs.
First action:
```sh
dcr clean --all
dcr build --force
```
## `dcr --update` suggests package manager update
Likely cause:
- DCR binary is managed by pacman/AUR.
First action:
```sh
yay -Syu dcr
# or
paru -Syu dcr
```

View File

@@ -1,53 +0,0 @@
# Workspace guide
`[workspace]` lets you build related DCR projects in dependency order from one root.
## Important rule
Workspace root still needs a valid root project config:
- `[package]`
- `[build]`
- `[dependencies]`
`[workspace]` augments that root config; it does not replace required root sections.
## Minimal example
```toml
[package]
name = "root-app"
version = "0.1.0"
[build]
language = "c"
standard = "c11"
compiler = "clang"
kind = "bin"
[dependencies]
[workspace]
core = { path = "./modules/core", deps = [] }
net = { path = "./modules/net", deps = ["core"] }
app = { path = "./modules/app", deps = ["core", "net"] }
```
Each member path must point to a directory containing its own `dcr.toml`.
## Build behavior
- Running `dcr build` in workspace root builds members in topological dependency order, then builds the root project.
- Running `dcr clean --all` in workspace root cleans all members too.
- `dcr gen` in workspace root includes root + members in generated outputs.
## Common errors
- `workspace.<name>.path does not contain dcr.toml`:
member path is wrong or config is missing.
- `workspace dependency '<name>' not found`:
`deps` references unknown member.
- `workspace dependency cycle at <name>`:
cyclic dependencies in member graph.

View File

@@ -0,0 +1,81 @@
---
sidebar_label: Build profiles
---
# Build Profiles
Profiles allow overriding `[build]` fields for specific build modes.
## Configuration
```toml
[build]
language = "c"
standard = "c17"
cflags = ["-Wall"]
[build.debug]
cflags = ["-O0", "-g"]
[build.release]
cflags = ["-O3", "-DNDEBUG"]
```
## Merge rules
Fields from `[build.<profile>]` are merged on top of `[build]`:
- **Scalar fields** (strings, numbers, bools) — replaced
- **Arrays** (`cflags`, `ldflags`, ...) — **appended** (extend the `[build]` array)
Set `inherit = false` to disable array inheritance (only profile's own arrays are used).
## Built-in profiles
The default flags for each profile are composed from three config fields:
| Field | debug default | release default |
|-------|--------------|----------------|
| `opt_level` | `"0"` | `"3"` |
| `debug` | `true` | `false` |
| `warnings` | `["all", "extra"]` | `[]` |
Which produce the equivalent compiler flags:
| Profile | Effective flags |
|---------|---------------|
| `debug` | `-O0 -g -Wall -Wextra -fno-omit-frame-pointer -DDCR_DEBUG` |
| `release` | `-O3 -DNDEBUG` |
Additional build options can be toggled per-profile:
```toml
[build.release]
opt_level = "z"
lto = true
strip = true
panic = "abort"
codegen-units = "1"
[build.debug]
opt_level = "1"
debug = false
warnings = ["all", "error"]
```
## Target-specific profiles
```toml
[build.linux]
cflags = ["-DLINUX"]
[build.windows.debug]
cflags = ["-DWIN32", "-O0", "-g"]
```
Application order (highest priority first):
1. `[build.<target>.<profile>]`
2. `[build.<profile>.<target>]`
3. `[build.<target>]`
4. `[build.<profile>]`
5. `[build]`

View File

@@ -0,0 +1,136 @@
---
sidebar_label: Build system
---
# Build System
## Compiler Backends
DCR supports 7 compilation backends. Selection is automatic based on file extension and `build.compiler` value.
| Backend | Files | When used |
|---------|-------|-----------|
| `unix_cc` | `.c`, `.cpp`, `.cxx`, `.cc`, `.S` | gcc/clang on Linux/macOS/BSD |
| `msvc` | `.c`, `.cpp`, `.cxx`, `.cc` | Windows (cl, clang-cl) |
| `gas` | `.s` | ARM/ARM64 assembler (no preprocessor) |
| `nasm` | `.asm`, `.s` | x86/x86_64 NASM assembler |
| `masm` | `.asm` | MASM (ml/ml64) on Windows |
| `fasm` | `.asm`, `.fasm` | Flat Assembler |
| `llvm_ir` | `.ll` | LLVM IR via `llc -filetype=obj` |
## Qt Support
DCR provides native Qt support for automatic meta-object handling (MOC, UIC, RCC).
Enable it by setting `build.qt = true` in `dcr.toml`. DCR will automatically detect Qt-related files (`.ui`, `.qrc`, `.h` with `Q_OBJECT`) and process them.
```toml
[build]
qt = true
```
*Note: Requires `qt6` modules (Core, Widgets, Gui, Svg) installed via `pkg-config`.*
Advanced customization is still possible via `build.steps` if special handling is needed:
```toml
[build.steps]
moc = "moc {in} -o {out}"
```
### Unix CC
- Compiler resolved via `resolve_compiler()`: `DCR_COMPILER` > `DCR_CC` > `[toolchain]` > `build.compiler` > `PATH`
- Supports `.d` files for header dependency tracking
- Flags: `-std=`, `-MMD -MF`, `-c -o`, `-I`, `-L`, `-l`
- Conditional flags based on config:
- `freestanding` or bare-metal target: `-ffreestanding` (compile), `-nostdlib -static` (link)
- `lto`: `-flto` (compile + link)
- `panic = "abort"`: `-fno-exceptions` (C++ only), `-fno-unwind-tables`, `-fno-asynchronous-unwind-tables`
### MSVC
- Supports cl.exe and clang-cl.exe
- Flags: `/std:`, `/Fo:`, `/Fe:`, `/I`, `/link`
### GAS / NASM / MASM / FASM / LLVM-IR
- GAS: `-I`, `-c -o`, `--defsym`
- NASM: `-I`, `-o`, `-D`, `-f` (format: win64/elf64/macho64/macho32/elf32; **`bin` when `kind = "flat-bin"`**)
- MASM: `/nologo /c /Fo<obj> <source>`
- FASM: `<source> <output>` (output path is the object file)
- LLVM IR: `-filetype=obj <source> -o <output>`
## Incremental Builds
Three levels of incrementality:
1. **mtime** — if output is newer than all inputs, skip
2. **`.d` files** — header change tracking (including transitive)
3. **SHA256 fingerprint** — recompile if compiler flags changed (stored in `.dcr_fingerprint`)
## Parallel Compilation
- `thread::scope` for thread pool
- Atomic task queue (`AtomicU64`)
- Mutex on stdout (`OUTPUT_MUTEX`)
- Thread count = `available_parallelism()`, capped by `build.codegen-units` if set
## Build Kinds
| Kind | Type | Path (Linux example) |
|------|------|---------------------|
| `bin` | Executable | `target/<triple>/<profile>/<name>` (.exe on Windows) |
| `staticlib` | Static library | `target/<triple>/<profile>/lib<name>.a` (.lib) |
| `sharedlib` | Dynamic library | `target/<triple>/<profile>/lib<name>.so` (.dll/.dylib) |
| `efi` | UEFI application | `target/<triple>/<profile>/<name>.efi` |
| `elf` | ELF without stdlib | `target/<triple>/<profile>/<name>` |
| `none` | Compile only, no link | — |
| `custom` | Full filename+extension control | `target/<triple>/<profile>/<filename>.<extension>` |
| `flat-bin` | Raw binary | ASM: `<stem>.bin` (NASM `-f bin` / FASM / GAS·MASM·LLC via objcopy); C/C++: `<name>.bin` (link + objcopy) |
## Disk images (`[archive]`)
After a successful build, if `[archive]` is present in `dcr.toml`, DCR formats a FAT volume and copies files from `layout` into the image. See [dcr.toml → archive](/docs/reference/dcr-toml#archive).
## Build Steps
DCR supports pre-build and post-build steps:
- `build.steps` — commands before compilation
- `build.post_steps` — commands after compilation
Substitutions: `{stem}`, `{in}`, `{out}`, `{profile}`, `{version}`, `{name}`.
Example Qt codegen via build steps:
```toml
[build.steps]
moc = "moc {in} -o {out}"
```
## pkg-config
Automatic lookup (read from raw config):
```toml
[build]
pkg_config = ["sdl2", "gl"]
```
DCR runs `pkg-config --cflags sdl2 gl` and `pkg-config --libs sdl2 gl` and adds results to compiler/linker flags.
## Variable Substitution
Supported variables:
| Variable | Description |
|----------|-------------|
| `{version}` | Package version |
| `{version_major}` | Major version part |
| `{version_minor}` | Minor version part |
| `{version_patch}` | Patch version |
| `{version_suffix}` | Suffix (e.g., `-rc1`) |
| `{version_suffix_dash}` | Suffix with dash |
| `{profile}` | Profile name (debug/release) |
| `{name}` | Package name |

View File

@@ -0,0 +1,64 @@
---
sidebar_label: Cross-compilation
---
# Cross-Compilation
## Short Names
DCR supports short platform names:
| Short Name | Full Triple |
|-----------|-------------|
| `linux` | `x86_64-unknown-linux-gnu` |
| `macos` | `x86_64-apple-darwin` |
| `windows` | `x86_64-pc-windows-msvc` |
```bash
dcr build --target windows
```
## Full Triples
```bash
dcr build --target aarch64-unknown-linux-gnu
dcr build --target x86_64-pc-windows-gnu # mingw
dcr build --target armv7-unknown-linux-gnueabihf
```
## clang --target
When using clang, DCR injects `--target=<triple>` into CFLAGS.
```toml
[build]
compiler = "clang"
target = "aarch64-unknown-linux-gnu"
# Auto: cflags += ["--target=aarch64-unknown-linux-gnu"]
```
## Bare-Metal / Freestanding
For targets containing `none`, `-elf`, `eabi`, or `baremetal`, DCR automatically:
1. **Disables default flags** — no system include paths, no `-l` libc
2. **Injects `-ffreestanding`** at compile time and `-nostdlib -static` at link time
You can also enable freestanding mode explicitly:
```toml
[build]
freestanding = true
```
```bash
dcr build --target aarch64-none-elf
```
## Target Directory
By default, the compilation output directories are structured as follows:
- **Linux and BSD**: Always output to `target/<triple>/<profile>/` (using host triple if no target is specified).
- **macOS and Windows (without target)**: Output to `target/<profile>/`.
- **macOS and Windows (with explicit target)**: Output to `target/<triple>/<profile>/`.

277
docs/reference/dcr-toml.mdx Normal file
View File

@@ -0,0 +1,277 @@
---
sidebar_label: dcr.toml overview
---
# dcr.toml
Main project configuration file. Located at the project root.
## Structure
```toml
[package]
# required fields
[build]
# build settings
[build.debug] # optional: debug override
[build.release] # optional: release override
[build.linux] # optional: Linux override
[build.windows] # optional: Windows override
[build.windows.debug] # target + profile combination
[toolchain]
# compiler/linker paths
[dependencies]
# project dependencies
[workspace]
# multi-package configuration
[run]
# run settings
[archive]
# optional: pack FAT disk image after build
```
## [package]
| Field | Required | Description |
|-------|----------|-------------|
| `name` | yes | Project name |
| `version` | yes | Semantic version of the **project** |
| `dcr-version` | no | Semver of the **dcr tool** this project targets. Written by `dcr new` / `dcr init` to the current tool version. |
| `type` | no | `app`, `lib`, `none` (defaults to `"none"`) |
| `license` | no | SPDX license identifier |
| `author` | no | Author |
```toml
[package]
name = "my-app"
version = "0.1.0"
dcr-version = "0.8.4"
type = "app"
license = "MIT"
author = "John Doe"
```
### `package.dcr-version`
Optional pin of the DCR CLI the project was written for. On every `dcr.toml` load:
| Situation | Behaviour |
|-----------|-----------|
| Field missing / empty | Warning: add `dcr-version` (set by `dcr new` / `dcr init`) |
| Running dcr **older** than pin | Warning: upgrade dcr (`dcr --update`) |
| Running dcr **newer** than pin | Warning: review changelog, bump the pin when ready |
| Equal | Silent |
| Invalid semver | Warning once, field ignored |
Never fails the command — warnings only. Pre-release suffixes (`1.0.0-dev`) are ignored for comparison (`1.0.0-dev` ≡ `1.0.0`).
## [build]
...
- `build.qt` — (bool) Enable automatic Qt meta-object handling (MOC, UIC, RCC). Requires `qt6` modules installed via `pkg-config`.
| Field | Default | Description |
|-------|---------|-------------|
| `language` | `"c"` | `"c"`, `"c++"`, `"cpp"`, `"cxx"`, `"asm"`, `"llvm_ir"`, `"llvm-ir"`, `"ll"` (optional, defaults to `"c"`) |
| `standard` | `"c11"` | C standard (`c11`, `c17`, `c23`) |
| `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`, `flat-bin` |
| `target` | host | Target triple for cross-compilation |
| `platform` | `"native"` | `native`, `efi` |
| `cflags` | `[]` | Additional C/C++/ASM flags |
| `ldflags` | `[]` | Additional linker flags |
| `filename` | `""` | Custom output file name |
| `extension` | `""` | Custom file extension (for `flat-bin`, default is `bin`) |
| `roots` | `["src"]` | Source roots: directories and/or individual source/header files |
| `exclude` | `[]` | Exclude patterns |
| `include` | `[]` | Additional include directories |
| `src_disable` | `false` | Disable auto source discovery |
| `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 (no `language`/`compiler` required) |
| `freestanding` | `false` | Compile in freestanding mode (`-ffreestanding` + `-nostdlib -static`) |
| `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` | `[]` | 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) |
Settings from raw config (not in typed struct):
- `pkg_config` — list of pkg-config packages
- `ldscript` — linker script path
- `build.steps` / `build.post_steps` — codegen steps
## Per-language overrides: `[build.c]`, `[build.cxx]`, `[build.asm]`, `[build.llvm_ir]`
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"]
[build.llvm_ir]
compiler = "llc"
```
The flat `[build]` acts as fallback; per-language tables take precedence for their language.
Example:
```toml
[build]
language = "c++"
standard = "c23"
cxx_standard = "c++23"
compiler = "clang"
kind = "sharedlib"
cflags = ["-Wall", "-Wextra"]
opt_level = "z"
lto = true
strip = true
panic = "abort"
codegen-units = "2"
```
## [toolchain]
```toml
[toolchain]
cc = "/usr/bin/clang"
cxx = "/usr/bin/clang++"
as = "/usr/bin/as"
ar = "/usr/bin/ar"
ld = "/usr/bin/ld.lld"
```
Raw config also supports `uic`, `moc`, `rcc` for Qt codegen.
## [dependencies]
See [dependencies](/docs/reference/dependencies).
## [run]
```toml
[run]
cmd = "./target/{profile}/{name}"
```
Substitutions:
- `{version}` — package version
- `{version_major}`, `{version_minor}`, `{version_patch}`, `{version_suffix}`, `{version_suffix_dash}` — version parts
- `{profile}` — debug / release
- `{name}` — package name
Default `cmd` = `./target/{profile}/{name}` (macOS/Windows) or `./target/<triple>/<profile>/<name>` (Linux).
## [workspace]
See [workspaces](/docs/reference/workspaces).
## [archive]
Optional post-build step: format a FAT volume and copy built artifacts into a disk image. Runs after a successful package build (and after workspace member builds that define `[archive]`).
Requires DCR built with the `archive` Cargo feature (`cargo build --features archive`). Release binaries include this feature.
| Field | Required | Description |
|-------|----------|-------------|
| `output` | yes | Image path relative to project root (`{profile}` allowed) |
| `format` | yes | `fat12`, `fat16`, or `fat32` |
| `size` | no | Image size: bytes or `K`/`KB`/`M`/`MB`/`G`/`GB` (default `1474560` ≈ 1.44 MiB) |
| `offset` | no | Byte offset of the FAT volume inside the image (default `0`) |
| `label` | no | Volume label (max 11 chars, default `VOLUME`) |
| `bootsector` | no | Path to a 512-byte boot sector written at offset 0 when `offset` is 0 (`{profile}` allowed) |
| `layout` | no | List of `{ from, to }` entries (files or globs → path inside the volume) |
```toml
[archive]
output = "target/{profile}/disk.img"
format = "fat12"
size = "1440K"
label = "MYOS"
bootsector = "target/{profile}/boot.bin"
[[archive.layout]]
from = "target/{profile}/kernel.bin"
to = "KERNEL.BIN"
[[archive.layout]]
from = "assets/*"
to = "/"
```
Typical pairing with `kind = "flat-bin"` (NASM `-f bin`) for bootloaders and pure-ASM OS images.
## `flat-bin` (kind)
Produces a raw binary (default extension `bin`) for boot sectors, kernels, and freestanding payloads.
### Assemblers
| Tool | Language / compiler | How flat-bin is produced |
|------|---------------------|--------------------------|
| NASM | `language = "asm"`, `compiler = "nasm"` | `-f bin` → `<stem>.bin` |
| FASM | `compiler = "fasm"` | direct write (use `format binary` in source) |
| GAS | `compiler = "as"` / `"gas"` | assemble → `objcopy -O binary` |
| MASM | `compiler = "ml"` / `"ml64"` | assemble → `objcopy -O binary` |
| LLC | `language = "llvm_ir"`, `compiler = "llc"` | `-filetype=obj` → `objcopy -O binary` |
```toml
[build]
language = "asm"
compiler = "nasm"
kind = "flat-bin"
extension = "bin"
roots = ["src/boot.asm"]
```
### C / C++
Compile all sources, link with `-nostdlib -static` (plus your `ldflags` / `ldscript`), then convert the intermediate ELF/PE with `objcopy -O binary` to `<filename|name>.bin`.
```toml
[build]
language = "c"
compiler = "clang"
kind = "flat-bin"
freestanding = true
filename = "kernel"
extension = "bin"
ldscript = "linker.ld"
ldflags = ["-T", "linker.ld"]
```
Notes:
- Multi-file **ASM** packages emit one `<stem>.bin` per source; **C/C++** emit a single project binary.
- `objcopy` tools tried in order: `llvm-objcopy`, `objcopy`, `gobjcopy`.
- Incompatible with `build.qt = true`.
- `dcr run` rejects `flat-bin` (not a host executable).

View File

@@ -0,0 +1,84 @@
---
sidebar_label: Dependencies
---
# Dependencies
## Formats
The `[dependencies]` section supports three formats:
### String (registry)
```toml
[dependencies]
fmt = "10.1.1"
spdlog = "1.12"
catch2 = "3.4.0"
```
The version string is used as-is for registry lookup.
### Table (git)
```toml
[dependencies]
fmt = { git = "https://github.com/fmtlib/fmt", tag = "10.1.1" }
```
Fields: `git`, `branch`, `tag`, `rev`.
### Table (path)
```toml
[dependencies]
mylib = { path = "../mylib" }
```
## Registry
DCR uses a package registry for dependency lookup by name.
```toml
# ~/.dcr/config.toml
[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
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)
## Path dependencies
Local paths. DCR automatically discovers include and lib directories from the neighbor's `dcr.toml`.
```toml
[dependencies]
mylib = { path = "/abs/path/to/lib" }
mylib = { path = "../relative/path" }
```
*Note: Header resolution automatically checks the packaged `target/include` directory of path dependencies, ensuring consumer packages can find headers from compiled static or dynamic libraries.*
## dcr.lock
Dependency lock file. Contains package names and sources.
Created during `dcr build` when registry dependencies are present. Not updated during `dcr add` — only on the next `dcr build`.
## Resolution process
1. Load all dependencies (registry → git → path)
2. For path deps: recursively read their `dcr.toml`
3. For registry deps: search `index.json`
4. For git deps: clone to cache
5. Collect `include_dirs`, `lib_dirs`, `libs` for the compiler

View File

@@ -0,0 +1,59 @@
---
sidebar_label: Environment variables
---
# Environment Variables
## DCR_COMPILER
Overrides the compiler for all languages. **Highest priority.**
```bash
export DCR_COMPILER=clang
dcr build
```
Compiler resolution priority:
1. `DCR_COMPILER` (env)
2. `DCR_CC` / `DCR_CXX` / `DCR_AS` (env)
3. `[toolchain]` (dcr.toml)
4. `build.compiler` (dcr.toml)
5. `PATH`
## DCR_CC / DCR_CXX / DCR_AS
Per-language override (lower priority than `DCR_COMPILER`, higher than `[toolchain]`).
```bash
export DCR_CC=gcc-14
export DCR_CXX=g++-14
export DCR_AS=arm-linux-gnueabihf-as
```
## DCR_LD / DCR_AR
Override linker and archiver.
```bash
export DCR_LD=ld.lld
export DCR_AR=llvm-ar
```
## DCR_DEBUG
Enables debug mode — prints all compilation commands to stderr before execution.
```bash
export DCR_DEBUG=1
dcr build
```
## DCR_INDEX_PATH
Overrides the path to the registry `index.json`.
```bash
export DCR_INDEX_PATH=/custom/path/index.json
```
Default: `~/.dcr/index.json`.

View File

@@ -0,0 +1,53 @@
---
sidebar_label: Platform support
---
# Platform Support
## Target Triples
DCR normalizes target triples. Short platform names are expanded to full triples.
### Linux
```
target/<arch>-unknown-linux-<env>/<profile>/
```
Architectures: `x86_64`, `aarch64`, `i686`, `armv7`, `riscv64` (host-detected).
Environments: `gnu` (default), `musl`.
Artifact type: ELF. Extensions: `.so` (sharedlib), `.a` (staticlib).
### macOS
```
target/<profile>/ (default) or target/<triple>/<profile>/ (with target)
```
Architectures: `x86_64`, `aarch64` (host-detected).
Extensions: `.dylib` (sharedlib), `.a` (staticlib).
### Windows
```
target/<profile>/ (default) or target/<triple>/<profile>/ (with target)
```
Architectures: `x86_64`, `aarch64`.
Environments: `msvc` (default), `gnu` (MinGW).
Extensions: `.exe` (bin), `.lib` (staticlib), `.dll` (sharedlib), `.efi` (UEFI).
### BSD
```
target/<arch>-unknown-<os>/<profile>/
```
Supported systems: `freebsd`, `openbsd`, `netbsd`, `dragonfly`.
## Host Detection
DCR uses `std::env::consts::ARCH` and `std::env::consts::OS` for host platform detection. Used as fallback when `target` is not specified.

View File

@@ -0,0 +1,87 @@
---
sidebar_label: Workspaces
---
# Workspaces
Workspaces allow managing multiple packages in a single repository.
## Configuration
```toml
[workspace.lib-core]
path = "lib-core"
[workspace.lib-utils]
path = "lib-utils"
deps = ["lib-core"]
[workspace.app]
path = "app"
deps = ["lib-core", "lib-utils"]
main = true
```
### Member fields
| Field | Description |
|-------|-------------|
| `path` | Path to the package (relative to workspace root) |
| `deps` | Dependencies on other members |
| `main` | Mark as the main package |
## Topological sort
DCR automatically sorts packages by dependencies: package A is built before B if B depends on A.
Cyclic dependencies are detected and cause an error.
## Build
```bash
dcr build # build all packages in dependency order
dcr build --workspace app # build only app (dependencies built automatically)
```
When building a workspace, DCR automatically injects include and library paths of dependent workspace members:
- **Include Paths**: Automatically resolves and injects header directories of dependencies, including the member's `src/` directory, local `include/` directory, and the packaged `target/include` directory.
- **Library Paths**: Injects compiled library search paths (`target/lib` as well as target-specific build folders) to allow automatic linking with member libraries.
## Clean
```bash
dcr clean # clean only root target/
dcr clean --all # clean target/ of all packages
```
## Inheritance
If a member has `inherit = true` in its `[build]` section, fields from the root `[build]` are merged into the member:
```toml
# root dcr.toml
[build]
inherit = true
language = "c"
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"] }
```

46
docs/self-update.mdx Normal file
View File

@@ -0,0 +1,46 @@
---
sidebar_label: Self Update
---
# Self Update
## dcr --update
Automatic update to the latest version. Downloads a binary (not an archive) from GitHub Releases and replaces the current executable.
```bash
dcr --update
```
## How it works
1. DCR detects the current platform and architecture
2. Fetches the latest release from `api.github.com/repos/dexoron/dcr/releases/latest`
3. Compares versions
4. Downloads the matching asset (direct binary URL, not archive)
5. Replaces the current executable via `self_replace`
## Asset naming
Pattern: `dcr-<triple>` or `dcr-<triple>.exe`
| Platform | Asset name |
|----------|-----------|
| Linux x86_64 | `dcr-x86_64-unknown-linux-gnu` |
| macOS x86_64 | `dcr-x86_64-apple-darwin` |
| macOS ARM64 | `dcr-aarch64-apple-darwin` |
| Windows x86_64 | `dcr-x86_64-pc-windows-msvc.exe` |
## AUR
If DCR was installed via AUR, `--update` shows a warning:
```
Update via package manager: yay/paru -Syu {package_name} or sudo pacman -Syu {package_name}
```
## Errors
- Cannot detect platform — error
- Cannot fetch release — error with URL
- No write permission — error (use `sudo` or manual install)

View File

@@ -0,0 +1,45 @@
---
sidebar_label: Running tests
---
# Running Tests
## Execution
```bash
dcr test
```
Builds the project, then compiles and runs test files from `tests/`.
## Profiles
```bash
dcr test # debug (default)
dcr test --release # release
dcr test --debug # explicit debug
```
## Output
```
=====================
Testsuite summary
=====================
TOTAL: 5
PASS: 3
SKIP: 1
FAIL: 1
=====================
```
## Exit code
- 0 — all tests passed (FAIL = 0)
- 1 — test failures or build error
## What gets built
- All `.c` files from `tests/` (`.cpp` not supported)
- Include path: `tests/` (for `dcr_test.h`)
- Linked with project if `package.type = "lib"` or `kind = "staticlib"`/`"sharedlib"`

View File

@@ -0,0 +1,68 @@
---
sidebar_label: Test framework (EXPECT, TEST, ...)
---
# Test Framework
DCR has a built-in minimal test framework for C.
## Macros
### `EXPECT(expr)`
Asserts that an expression is true.
```c
EXPECT(1 + 1 == 2);
EXPECT(ptr != NULL);
```
### `SKIP(reason)`
Skips a test with a message.
```c
SKIP("not implemented on Windows");
```
### `TEST(name)`
Defines a test.
```c
TEST(addition) {
EXPECT(1 + 1 == 2);
EXPECT(2 + 2 == 4);
}
```
### `TEST_CASE(name)`
Registers a test case.
```c
TEST_CASE(math) {
EXPECT(1 + 1 == 2);
}
```
## Initialization
```bash
dcr test --init
```
Creates:
- `tests/dcr_test.h` — framework header (do not edit)
- `tests/test.c` — template with example test
## Structure
```
tests/
├── dcr_test.h # framework (do not edit)
├── test.c # main tests
└── ... # additional .c test files
```
Only `.c` files are compiled (`.cpp` is not supported).

135
flake.lock generated Normal file
View File

@@ -0,0 +1,135 @@
{
"nodes": {
"fenix": {
"inputs": {
"nixpkgs": [
"nixpkgs"
],
"rust-analyzer-src": "rust-analyzer-src"
},
"locked": {
"lastModified": 1780218205,
"narHash": "sha256-c4MSlBQw5MIDRkad9UNUUnBaOHAHnhuCXrDt90FDVrg=",
"owner": "nix-community",
"repo": "fenix",
"rev": "96e0fc9f1a9b37f6477fa11c3fd48575354773ed",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "fenix",
"type": "github"
}
},
"flake-utils": {
"inputs": {
"systems": "systems"
},
"locked": {
"lastModified": 1731533236,
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1779560665,
"narHash": "sha256-tpyBcxPpcQb8ukyNF7DoCwfSY3VPsxHoYwj00Cayv5o=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "64c08a7ca051951c8eae34e3e3cb1e202fe36786",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1770107345,
"narHash": "sha256-tbS0Ebx2PiA1FRW8mt8oejR0qMXmziJmPaU1d4kYY9g=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "4533d9293756b63904b7238acb84ac8fe4c8c2c4",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"fenix": "fenix",
"flake-utils": "flake-utils",
"nixpkgs": "nixpkgs",
"treefmt-nix": "treefmt-nix"
}
},
"rust-analyzer-src": {
"flake": false,
"locked": {
"lastModified": 1780179631,
"narHash": "sha256-61A3gj4V1DyPP6lVHTdui4+dvG66pkMZSMd1Kke3Rz8=",
"owner": "rust-lang",
"repo": "rust-analyzer",
"rev": "cce33f2f1565958787bb763ae751a6a5f56b95e3",
"type": "github"
},
"original": {
"owner": "rust-lang",
"ref": "nightly",
"repo": "rust-analyzer",
"type": "github"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"treefmt-nix": {
"inputs": {
"nixpkgs": "nixpkgs_2"
},
"locked": {
"lastModified": 1780220602,
"narHash": "sha256-eynAfOmbmxJnkp7YewvCEbShNnnYJ9gLLqkzsYtBPeM=",
"owner": "numtide",
"repo": "treefmt-nix",
"rev": "db947814a175b7ca6ded66e21383d938df01c227",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "treefmt-nix",
"type": "github"
}
}
},
"root": "root",
"version": 7
}

115
flake.nix Normal file
View File

@@ -0,0 +1,115 @@
{
description = "DCR — Cargo-like utility for managing C/C++ projects";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
flake-utils.url = "github:numtide/flake-utils";
treefmt-nix.url = "github:numtide/treefmt-nix";
fenix = {
url = "github:nix-community/fenix";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs = {
self,
nixpkgs,
flake-utils,
treefmt-nix,
fenix,
}:
flake-utils.lib.eachDefaultSystem (system: let
pkgs = import nixpkgs {
inherit system;
};
cargoToml = builtins.fromTOML (builtins.readFile ./Cargo.toml);
packageName = cargoToml.package.name;
packageVersion = cargoToml.package.version;
rustToolchain = fenix.packages.${system}.stable.toolchain;
rustPlatform = pkgs.makeRustPlatform {
cargo = rustToolchain;
rustc = rustToolchain;
};
treefmtEval = treefmt-nix.lib.evalModule pkgs {
projectRootFile = "flake.nix";
programs.alejandra.enable = true;
programs.rustfmt.enable = true;
programs.taplo.enable = true;
};
app = rustPlatform.buildRustPackage {
pname = packageName;
version = packageVersion;
src = ./.;
cargoLock.lockFile = ./Cargo.lock;
nativeBuildInputs = [
pkgs.pkg-config
pkgs.cmake
pkgs.perl
];
buildInputs = pkgs.lib.optionals pkgs.stdenv.isDarwin [
pkgs.darwin.apple_sdk.frameworks.Security
pkgs.darwin.apple_sdk.frameworks.SystemConfiguration
];
postInstall = ''
install -Dm644 man/man1/*.1 -t $out/share/man/man1/
'';
# Tests require external services; run separately.
doCheck = false;
};
in {
packages = {
default = app;
dcr = app;
};
apps = let
defaultApp =
(flake-utils.lib.mkApp {
drv = app;
})
// {
meta.description = "Run ${packageName}";
};
in {
default = defaultApp;
dcr = defaultApp;
};
checks = {
dcr = app;
formatting = treefmtEval.config.build.check self;
};
formatter = treefmtEval.config.build.wrapper;
devShells.default = pkgs.mkShell {
inputsFrom = [app];
packages = [
rustToolchain
pkgs.rust-analyzer
treefmtEval.config.build.wrapper
];
shellHook = ''
export RUST_SRC_PATH="${rustToolchain}/lib/rustlib/src/rust/library"
'';
};
});
}

View File

@@ -47,10 +47,16 @@ function Select-Mode {
}
function Get-Target {
if ($env:PROCESSOR_ARCHITECTURE -ne 'AMD64') {
Fail "Only x86_64 Windows is supported, current architecture: $env:PROCESSOR_ARCHITECTURE"
$arch = $env:PROCESSOR_ARCHITECTURE
if ($env:PROCESSOR_ARCHITEW6432) {
$arch = $env:PROCESSOR_ARCHITEW6432
}
switch ($arch) {
'AMD64' { return 'x86_64-pc-windows-msvc' }
'ARM64' { return 'aarch64-pc-windows-msvc' }
'x86' { return 'i686-pc-windows-msvc' }
default { Fail "Unsupported Windows architecture: $arch" }
}
return 'x86_64-pc-windows-msvc'
}
function Fetch-ReleaseJson($channel) {

View File

@@ -4,6 +4,7 @@ set -Eeuo pipefail
TMPDIR="/tmp/dcr-install"
INSTALL_PATH="$HOME/.local/share/dcr"
BINPATH="$HOME/.local/bin"
MANPATH="${XDG_DATA_HOME:-$HOME/.local/share}/man"
LOGFILE="$HOME/.cache/dcr-install.log"
REPO_URL="https://github.com/dexoron/dcr"
GITHUB_API_LATEST="https://api.github.com/repos/dexoron/dcr/releases/latest"
@@ -30,8 +31,8 @@ CHANNEL=""
check_os() {
case "$(uname -s)" in
Linux|Darwin) ;;
*) error "Only Linux and macOS are supported"; exit 1 ;;
Linux|Darwin|FreeBSD|OpenBSD|NetBSD) ;;
*) error "Only Linux, macOS, and BSD systems are supported"; exit 1 ;;
esac
}
@@ -41,15 +42,35 @@ detect_target() {
arch="$(uname -m)"
case "$os:$arch" in
Linux:x86_64) TARGET_TRIPLE="x86_64-unknown-linux-gnu" ;;
Darwin:x86_64) TARGET_TRIPLE="x86_64-apple-darwin" ;;
Darwin:arm64|Darwin:aarch64) TARGET_TRIPLE="aarch64-apple-darwin" ;;
Linux:x86_64) TARGET_TRIPLE="x86_64-unknown-linux-gnu" ;;
Linux:aarch64|Linux:arm64) TARGET_TRIPLE="aarch64-unknown-linux-gnu" ;;
Linux:i686|Linux:i386) TARGET_TRIPLE="i686-unknown-linux-gnu" ;;
Linux:armv7l|Linux:armv7) TARGET_TRIPLE="armv7-unknown-linux-gnueabihf" ;;
Linux:riscv64) TARGET_TRIPLE="riscv64gc-unknown-linux-gnu" ;;
Darwin:x86_64) TARGET_TRIPLE="x86_64-apple-darwin" ;;
Darwin:arm64|Darwin:aarch64) TARGET_TRIPLE="aarch64-apple-darwin" ;;
FreeBSD:x86_64|FreeBSD:amd64) TARGET_TRIPLE="x86_64-unknown-freebsd" ;;
FreeBSD:aarch64|FreeBSD:arm64) TARGET_TRIPLE="aarch64-unknown-freebsd" ;;
FreeBSD:i686|FreeBSD:i386) TARGET_TRIPLE="i686-unknown-freebsd" ;;
OpenBSD:x86_64|OpenBSD:amd64) TARGET_TRIPLE="x86_64-unknown-openbsd" ;;
OpenBSD:aarch64|OpenBSD:arm64) TARGET_TRIPLE="aarch64-unknown-openbsd" ;;
OpenBSD:i686|OpenBSD:i386) TARGET_TRIPLE="i686-unknown-openbsd" ;;
NetBSD:x86_64|NetBSD:amd64) TARGET_TRIPLE="x86_64-unknown-netbsd" ;;
NetBSD:aarch64|NetBSD:arm64) TARGET_TRIPLE="aarch64-unknown-netbsd" ;;
NetBSD:i686|NetBSD:i386) TARGET_TRIPLE="i686-unknown-netbsd" ;;
*) error "Unsupported platform: $os/$arch"; exit 1 ;;
esac
}
check_common_dependencies() {
command -v curl >/dev/null 2>&1 || { error "curl is not installed"; exit 1; }
if [[ "$CHANNEL" == "dev" ]]; then
if ! command -v python3 >/dev/null 2>&1 && ! command -v jq >/dev/null 2>&1; then
error "For dev installations, either 'python3' or 'jq' must be installed to parse GitHub API response."
exit 1
fi
fi
}
check_build_dependencies() {
@@ -61,7 +82,7 @@ select_channel() {
echo "Choose channel:"
echo " 1) Latest stable release (default)"
echo " 2) Latest dev (pre-release)"
read -r -p "Enter 1 or 2 [1]: " choice
read -r -p "Enter 1 or 2 [1]: " choice < /dev/tty
case "${choice:-1}" in
1) CHANNEL="stable" ;;
@@ -74,7 +95,7 @@ select_install_mode() {
echo "Choose installation mode:"
echo " 1) Download prebuilt binary from GitHub Release (recommended)"
echo " 2) Build from git"
read -r -p "Enter 1 or 2 [1]: " choice
read -r -p "Enter 1 or 2 [1]: " choice < /dev/tty
case "${choice:-1}" in
1) INSTALL_MODE="release" ;;
@@ -83,15 +104,16 @@ select_install_mode() {
esac
}
# Возвращает JSON нужного релиза в stdout
# Returns JSON of the requested release to stdout
fetch_release_json() {
if [[ "$CHANNEL" == "dev" ]]; then
log "Looking for latest dev (pre-release)..."
local json
local json result
json="$(curl -fsSL "$GITHUB_API_ALL")"
# Первый pre-release в списке
local result
result="$(printf '%s' "$json" | python3 - <<'EOF'
if command -v jq >/dev/null 2>&1; then
result="$(printf '%s' "$json" | jq -e -c 'map(select(.prerelease == true))[0]')"
else
result="$(printf '%s' "$json" | python3 - <<'EOF'
import sys, json
releases = json.load(sys.stdin)
pre = [r for r in releases if r.get("prerelease", False)]
@@ -101,7 +123,9 @@ else:
print(json.dumps(pre[0]), end="")
EOF
)"
if [[ -z "$result" || "$result" == "{}" ]]; then
fi
if [[ -z "$result" || "$result" == "{}" || "$result" == "null" ]]; then
error "No dev (pre-release) found on GitHub"
exit 1
fi
@@ -123,9 +147,9 @@ download_binary() {
exit 1
fi
# Версия без ведущего 'v'
# Version without leading 'v'
version="${tag#v}"
# Имя бинарника: dcr-<triple>-<version>
# Binary name: dcr-<triple>-<version>
asset_name="dcr-${TARGET_TRIPLE}-${version}"
log "Fetching release ${tag} (channel: ${CHANNEL})..."
@@ -149,7 +173,7 @@ prepare_sources() {
rm -rf "$TMPDIR"
git clone --depth 1 "$REPO_URL" "$TMPDIR"
if [[ "$CHANNEL" == "dev" ]]; then
# Клонируем dev ветку, если она есть
# Clone dev branch if it exists
git clone --depth 1 --branch dev "$REPO_URL" "$TMPDIR" 2>/dev/null || \
git clone --depth 1 "$REPO_URL" "$TMPDIR"
fi
@@ -176,6 +200,16 @@ install_link() {
success "Command 'dcr' added to $BINPATH"
}
install_man() {
log "Installing man pages..."
local man_src="$TMPDIR/man/man1"
if [[ -d "$man_src" ]]; then
mkdir -p "$MANPATH/man1"
cp "$man_src"/*.1 "$MANPATH/man1/"
success "Man pages installed to $MANPATH/man1"
fi
}
check_path() {
if ! echo "$PATH" | grep -q "$BINPATH"; then
warn "Directory $BINPATH not found in PATH"
@@ -193,8 +227,8 @@ main() {
check_os
detect_target
check_common_dependencies
select_channel
check_common_dependencies
select_install_mode
cleanup
@@ -208,6 +242,7 @@ main() {
fi
install_link
install_man
check_path
cleanup
@@ -215,4 +250,4 @@ main() {
log "Log saved to $LOGFILE"
}
main "$@"
main "$@"

241
install_bsd.sh Executable file
View File

@@ -0,0 +1,241 @@
#!/bin/sh
set -eu
TMPDIR="/tmp/dcr-install"
INSTALL_PATH="$HOME/.local/share/dcr"
BINPATH="$HOME/.local/bin"
MANPATH="${XDG_DATA_HOME:-$HOME/.local/share}/man"
LOGFILE="$HOME/.cache/dcr-install.log"
REPO_URL="https://github.com/dexoron/dcr"
GITHUB_API_LATEST="https://api.github.com/repos/dexoron/dcr/releases/latest"
GITHUB_API_ALL="https://api.github.com/repos/dexoron/dcr/releases"
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
mkdir -p "$(dirname "$LOGFILE")"
log() { printf "${BLUE}[%s]${NC} %s\n" "$(date '+%Y-%m-%d %H:%M:%S')" "$1" | tee -a "$LOGFILE"; }
success() { printf "${GREEN}✔ %s${NC}\n" "$1" | tee -a "$LOGFILE"; }
warn() { printf "${YELLOW}⚠ %s${NC}\n" "$1" | tee -a "$LOGFILE"; }
error() { printf "${RED}✖ %s${NC}\n" "$1" | tee -a "$LOGFILE" >&2; }
INSTALL_MODE=""
CHANNEL=""
check_os() {
case "$(uname -s)" in
FreeBSD|OpenBSD|NetBSD|DragonFly) ;;
*) error "Only BSD systems (FreeBSD, OpenBSD, NetBSD, DragonFly) are supported by this script"; exit 1 ;;
esac
}
detect_target() {
local os arch
os="$(uname -s)"
arch="$(uname -m)"
case "$os:$arch" in
FreeBSD:x86_64|FreeBSD:amd64) TARGET_TRIPLE="x86_64-unknown-freebsd" ;;
FreeBSD:aarch64|FreeBSD:arm64) TARGET_TRIPLE="aarch64-unknown-freebsd" ;;
FreeBSD:i686|FreeBSD:i386) TARGET_TRIPLE="i686-unknown-freebsd" ;;
OpenBSD:x86_64|OpenBSD:amd64) TARGET_TRIPLE="x86_64-unknown-openbsd" ;;
OpenBSD:aarch64|OpenBSD:arm64) TARGET_TRIPLE="aarch64-unknown-openbsd" ;;
OpenBSD:i686|OpenBSD:i386) TARGET_TRIPLE="i686-unknown-openbsd" ;;
NetBSD:x86_64|NetBSD:amd64) TARGET_TRIPLE="x86_64-unknown-netbsd" ;;
NetBSD:aarch64|NetBSD:arm64) TARGET_TRIPLE="aarch64-unknown-netbsd" ;;
NetBSD:i686|NetBSD:i386) TARGET_TRIPLE="i686-unknown-netbsd" ;;
DragonFly:x86_64|DragonFly:amd64) TARGET_TRIPLE="x86_64-unknown-dragonfly" ;;
*) error "Unsupported BSD platform: $os/$arch"; exit 1 ;;
esac
}
check_common_dependencies() {
command -v curl >/dev/null 2>&1 || { error "curl is not installed"; exit 1; }
if [ "$CHANNEL" = "dev" ]; then
if ! command -v python3 >/dev/null 2>&1 && ! command -v jq >/dev/null 2>&1; then
error "For dev installations, either 'python3' or 'jq' must be installed to parse GitHub API response."
exit 1
fi
fi
}
check_build_dependencies() {
command -v git >/dev/null 2>&1 || { error "git is not installed"; exit 1; }
command -v cargo >/dev/null 2>&1 || { error "cargo is not installed"; exit 1; }
}
select_channel() {
echo "Choose channel:"
echo " 1) Latest stable release (default)"
echo " 2) Latest dev (pre-release)"
printf "Enter 1 or 2 [1]: "
read -r choice
case "${choice:-1}" in
1) CHANNEL="stable" ;;
2) CHANNEL="dev" ;;
*) error "Unknown option"; exit 1 ;;
esac
}
select_install_mode() {
echo "Choose installation mode:"
echo " 1) Download prebuilt binary from GitHub Release (recommended)"
echo " 2) Build from git"
printf "Enter 1 or 2 [1]: "
read -r choice
case "${choice:-1}" in
1) INSTALL_MODE="release" ;;
2) INSTALL_MODE="build" ;;
*) error "Unknown option"; exit 1 ;;
esac
}
fetch_release_json() {
if [ "$CHANNEL" = "dev" ]; then
log "Looking for latest dev (pre-release)..."
local json result
json="$(curl -fsSL "$GITHUB_API_ALL")"
if command -v jq >/dev/null 2>&1; then
result="$(printf '%s' "$json" | jq -e -c 'map(select(.prerelease == true))[0]')"
else
result="$(printf '%s' "$json" | python3 - <<'EOF'
import sys, json
releases = json.load(sys.stdin)
pre = [r for r in releases if r.get("prerelease", False)]
if not pre:
print("{}", end="")
else:
print(json.dumps(pre[0]), end="")
EOF
)"
fi
if [ -z "$result" ] || [ "$result" = "{}" ] || [ "$result" = "null" ]; then
error "No dev (pre-release) found on GitHub"
exit 1
fi
printf '%s' "$result"
else
curl -fsSL "$GITHUB_API_LATEST"
fi
}
download_binary() {
local release_json tag version asset_name download_url
release_json="$(fetch_release_json)"
tag="$(printf '%s\n' "$release_json" | \
sed -n 's/.*"tag_name": "\([^"]*\)".*/\1/p' | head -n1)"
if [ -z "$tag" ]; then
error "Failed to determine release version"
exit 1
fi
version="${tag#v}"
asset_name="dcr-${TARGET_TRIPLE}-${version}"
log "Fetching release ${tag} (channel: ${CHANNEL})..."
download_url="$(printf '%s\n' "$release_json" | \
sed -n "s#.*\"browser_download_url\": \"\([^\"]*/${asset_name}\)\".*#\1#p" | head -n1)"
if [ -z "$download_url" ]; then
error "Asset ${asset_name} not found in release ${tag}"
exit 1
fi
mkdir -p "$INSTALL_PATH"
curl -fL "$download_url" -o "$INSTALL_PATH/dcr"
chmod +x "$INSTALL_PATH/dcr"
success "Binary ${asset_name} downloaded (${tag})"
}
prepare_sources() {
log "Fetching sources..."
rm -rf "$TMPDIR"
git clone --depth 1 "$REPO_URL" "$TMPDIR"
if [ "$CHANNEL" = "dev" ]; then
git clone --depth 1 --branch dev "$REPO_URL" "$TMPDIR" 2>/dev/null || \
git clone --depth 1 "$REPO_URL" "$TMPDIR"
fi
success "Sources fetched"
}
build_binary() {
log "Building release binary..."
(cd "$TMPDIR" && cargo build --release)
success "Build completed"
}
install_built_binary() {
mkdir -p "$INSTALL_PATH"
cp "$TMPDIR/target/release/dcr" "$INSTALL_PATH/dcr"
chmod +x "$INSTALL_PATH/dcr"
success "Binary installed from source"
}
install_link() {
log "Creating symlink..."
mkdir -p "$BINPATH"
ln -sf "$INSTALL_PATH/dcr" "$BINPATH/dcr"
success "Command 'dcr' added to $BINPATH"
}
install_man() {
log "Installing man pages..."
man_src="$TMPDIR/man/man1"
if [ -d "$man_src" ]; then
mkdir -p "$MANPATH/man1"
cp "$man_src"/*.1 "$MANPATH/man1/"
success "Man pages installed to $MANPATH/man1"
fi
}
check_path() {
if ! echo "$PATH" | grep -q "$BINPATH"; then
warn "Directory $BINPATH not found in PATH"
echo "Add this to ~/.bashrc, ~/.zshrc or ~/.profile:"
echo "export PATH=\"$BINPATH:\$PATH\""
fi
}
cleanup() {
rm -rf "$TMPDIR" 2>/dev/null || true
}
main() {
log "Starting DCR installation for BSD"
check_os
select_channel
check_common_dependencies
detect_target
select_install_mode
cleanup
if [ "$INSTALL_MODE" = "build" ]; then
check_build_dependencies
prepare_sources
build_binary
install_built_binary
else
download_binary
fi
install_link
install_man
check_path
cleanup
success "Installation completed successfully"
log "Log saved to $LOGFILE"
}
main "$@"

42
man/man1/dcr-add.1 Normal file
View File

@@ -0,0 +1,42 @@
.TH DCR-ADD 1 "2026-06-02" "dcr 0.7.0" "DCR Manual"
.SH NAME
dcr-add \- Add a dependency to a DCR project
.SH SYNOPSIS
.B dcr add \fI<name>\fR \fI<source>\fR
[\fB\-\-branch\fR \fI<b>\fR]
[\fB\-\-tag\fR \fI<t>\fR]
[\fB\-\-rev\fR \fI<r>\fR]
.SH DESCRIPTION
Adds a dependency to the project.
.SH SOURCES
.TP
.B user/repo
GitHub shorthand.
.TP
.B github:user/repo
Full GitHub repository.
.TP
.B gitlab:user/repo
GitLab repository.
.TP
.B git:host.com/user/repo
Generic git repository.
.TP
.B path:./path/to/lib
Local path dependency.
.TP
.B <version>
Version from registry.
.SH OPTIONS
.TP
.B \-\-branch \fI<name>\fR
Use a specific branch.
.TP
.B \-\-tag \fI<name>\fR
Use a specific tag.
.TP
.B \-\-rev \fI<hash>\fR
Use a specific commit hash.
.SH SEE ALSO
.BR dcr (1),
.BR dcr-tree (1)

48
man/man1/dcr-build.1 Normal file
View File

@@ -0,0 +1,48 @@
.TH DCR-BUILD 1 "2026-08-04" "dcr 0.8.4" "DCR Manual"
.SH NAME
dcr-build \- Compile a DCR project
.SH SYNOPSIS
.B dcr build
[\fB\-\-debug\fR | \fB\-\-release\fR]
[\fB\-\-target\fR \fI<triple>\fR]
[\fB\-\-force\fR]
[\fB\-\-clean\fR]
[\fB\-\-verbose\fR]
[\fB\-\-workspace\fR \fI<name>\fR]
[\fB\-\-print\-artifact\-path\fR]
.SH DESCRIPTION
Compiles the project. Default profile is
.B \-\-debug .
On success, updates
.B .dcr/build-info.json
and
.B .dcr/toolchain.json
when applicable.
.SH OPTIONS
.TP
.B \-\-debug
Build with debug profile (default). Enables debug symbols.
.TP
.B \-\-release
Build with release profile. Enables full optimization.
.TP
.B \-\-target \fI<triple>\fR
Cross-compile for the given target.
.TP
.B \-\-force
Force a full rebuild, ignoring cached artifacts.
.TP
.B \-\-clean
Clean before building.
.TP
.B \-\-verbose
Print detailed build output including compiler commands.
.TP
.B \-\-workspace \fI<name>\fR
Build a specific workspace member.
.TP
.B \-\-print\-artifact\-path
After a successful build, print the absolute path of the main artifact as a single line on stdout.
.SH SEE ALSO
.BR dcr (1),
.BR dcr-gen (1)

26
man/man1/dcr-clean.1 Normal file
View File

@@ -0,0 +1,26 @@
.TH DCR-CLEAN 1 "2026-06-02" "dcr 0.7.0" "DCR Manual"
.SH NAME
dcr-clean \- Remove build artifacts
.SH SYNOPSIS
.B dcr clean
[\fB\-\-debug\fR | \fB\-\-release\fR]
[\fB\-\-target\fR \fI<triple>\fR]
[\fB\-\-all\fR]
.SH DESCRIPTION
Removes build artifacts from the target directory.
.SH OPTIONS
.TP
.B \-\-debug
Clean debug artifacts (default).
.TP
.B \-\-release
Clean release artifacts.
.TP
.B \-\-target \fI<triple>\fR
Clean artifacts for a specific target.
.TP
.B \-\-all
Clean all workspace members.
.SH SEE ALSO
.BR dcr (1),
.BR dcr-build (1)

10
man/man1/dcr-fmt.1 Normal file
View File

@@ -0,0 +1,10 @@
.TH DCR-FMT 1 "2026-06-02" "dcr 0.7.0" "DCR Manual"
.SH NAME
dcr-fmt \- Format C/C++ source files
.SH SYNOPSIS
.B dcr fmt
.SH DESCRIPTION
Formats all C/C++ source files using clang-format. Scans \fBsrc/\fR
and \fBtests/\fR directories recursively.
.SH SEE ALSO
.BR dcr (1)

67
man/man1/dcr-gen.1 Normal file
View File

@@ -0,0 +1,67 @@
.TH DCR-GEN 1 "2026-08-04" "dcr 0.8.4" "DCR Manual"
.SH NAME
dcr-gen \- Generate IDE and tooling integration files
.SH SYNOPSIS
.B dcr gen \fI<subcommand>\fR
[\fB\-\-debug\fR | \fB\-\-release\fR]
[\fB\-\-quiet\fR | \fB\-q\fR]
.SH DESCRIPTION
Generates IDE and tooling integration files for DCR projects.
Machine-readable build facts are written under
.B .dcr/
(compile database, build-info, toolchain).
.SH SUBCOMMANDS
.TP
.B project-info
Print project metadata as JSON to stdout (absolute paths, artifact_path, target_dir).
Also updates
.B .dcr/build-info.json
and
.B .dcr/toolchain.json .
.TP
.B compile-commands
Generate
.B .dcr/compile_commands.json
(atomic write) and ensure
.B .clangd
points at
.B .dcr
as CompilationDatabase.
.TP
.B vscode
Generate
.B .vscode/
integration files (tasks, launch configurations) and compile commands under
.B .dcr/ .
.TP
.B clion
Generate
.B .idea/
integration files for CLion and compile commands under
.B .dcr/ .
.SH OPTIONS
.TP
.B \-\-debug
Use debug profile (default).
.TP
.B \-\-release
Use release profile.
.TP
.B \-\-quiet\fR, \fB\-q
Suppress human-readable success messages on stdout.
.SH FILES
.TP
.B .dcr/compile_commands.json
JSON Compilation Database (moved from project root; breaking change in 0.8.4).
.TP
.B .dcr/build-info.json
Last known artifact path, profile, compiler.
.TP
.B .dcr/toolchain.json
Resolved compiler/debugger (and Qt tools if configured).
.TP
.B .clangd
Created once with CompilationDatabase: .dcr; not overwritten if customized.
.SH SEE ALSO
.BR dcr (1),
.BR dcr-build (1)

11
man/man1/dcr-init.1 Normal file
View File

@@ -0,0 +1,11 @@
.TH DCR-INIT 1 "2026-06-02" "dcr 0.7.0" "DCR Manual"
.SH NAME
dcr-init \- Initialize a directory as a DCR project
.SH SYNOPSIS
.B dcr init
.SH DESCRIPTION
Initializes the current directory as a DCR project. The directory must
be empty.
.SH SEE ALSO
.BR dcr (1),
.BR dcr-new (1)

13
man/man1/dcr-new.1 Normal file
View File

@@ -0,0 +1,13 @@
.TH DCR-NEW 1 "2026-06-02" "dcr 0.7.0" "DCR Manual"
.SH NAME
dcr-new \- Create a new DCR project
.SH SYNOPSIS
.B dcr new \fI<name>\fR
.SH DESCRIPTION
Creates a new C/C++ project with the given name. The name may only
contain ASCII letters, digits, underscores and hyphens.
.SH EXAMPLE
.B dcr new my-project
.SH SEE ALSO
.BR dcr (1),
.BR dcr-init (1)

47
man/man1/dcr-run.1 Normal file
View File

@@ -0,0 +1,47 @@
.TH DCR-RUN 1 "2026-06-02" "dcr 0.7.0" "DCR Manual"
.SH NAME
dcr-run \- Build and run a DCR project
.SH SYNOPSIS
.B dcr run
[\fB\-\-debug\fR | \fB\-\-release\fR]
[\fB\-\-target\fR \fI<triple>\fR]
[\fB\-\-force\fR]
[\fB\-\-clean\fR]
[\fB\-\-verbose\fR]
[\fB\-\-\fR \fI<args>...\fR]
.SH DESCRIPTION
Builds and runs the project. Only available for projects with
\fBkind = "bin"\fR.
Arguments after a bare
.B \-\-
are forwarded to the built binary (cargo-style).
.SH OPTIONS
.TP
.B \-\-debug
Run with debug profile (default).
.TP
.B \-\-release
Run with release profile.
.TP
.B \-\-target \fI<triple>\fR
Cross-compile for the given target.
.TP
.B \-\-force
Force a full rebuild.
.TP
.B \-\-clean
Clean before building.
.TP
.B \-\-verbose
Print detailed build output.
.TP
.B \-\- \fI<args>...\fR
Arguments passed to the built binary.
.SH EXAMPLES
.nf
dcr run --release -- --test_help
dcr run -- --foo bar
.fi
.SH SEE ALSO
.BR dcr (1),
.BR dcr-build (1)

11
man/man1/dcr-setup.1 Normal file
View File

@@ -0,0 +1,11 @@
.TH DCR-SETUP 1 "2026-06-02" "dcr 0.7.0" "DCR Manual"
.SH NAME
dcr-setup \- Set up DCR registries
.SH SYNOPSIS
.B dcr setup
.SH DESCRIPTION
Sets up DCR registries. Downloads and indexes package registries
for dependency resolution.
.SH SEE ALSO
.BR dcr (1),
.BR dcr-add (1)

24
man/man1/dcr-test.1 Normal file
View File

@@ -0,0 +1,24 @@
.TH DCR-TEST 1 "2026-06-02" "dcr 0.7.0" "DCR Manual"
.SH NAME
dcr-test \- Run project tests
.SH SYNOPSIS
.B dcr test
[\fB\-\-init\fR]
[\fB\-\-debug\fR | \fB\-\-release\fR]
.SH ALIASES
.B dcr tests
.SH DESCRIPTION
Runs project tests and prints a unified testsuite report.
.SH OPTIONS
.TP
.B \-\-init
Create \fBtests/dcr_test.h\fR in the current project.
.TP
.B \-\-debug
Build and run tests with debug profile (default).
.TP
.B \-\-release
Build and run tests with release profile.
.SH SEE ALSO
.BR dcr (1),
.BR dcr-build (1)

11
man/man1/dcr-tree.1 Normal file
View File

@@ -0,0 +1,11 @@
.TH DCR-TREE 1 "2026-06-02" "dcr 0.7.0" "DCR Manual"
.SH NAME
dcr-tree \- Display the dependency tree
.SH SYNOPSIS
.B dcr tree
.SH DESCRIPTION
Displays the dependency tree of the current project, showing all
transitive dependencies and their versions.
.SH SEE ALSO
.BR dcr (1),
.BR dcr-add (1)

212
man/man1/dcr.1 Normal file
View File

@@ -0,0 +1,212 @@
.TH DCR 1 "2026-06-02" "dcr 0.7.0" "DCR Manual"
.SH NAME
dcr \- Cargo\-like build tool and package manager for C/C++ projects
.SH SYNOPSIS
.B dcr
[\fIcommand\fR] [\fIoptions\fR]
.SH DESCRIPTION
DCR is a comprehensive build tool and package manager for C and C++ projects,
inspired by Cargo from the Rust ecosystem. It handles project creation,
building, dependency management, testing, formatting, and IDE integration.
.SH COMMANDS
.TP
.B new \fI<name>\fR
Create a new C/C++ project with the given name. Only ASCII letters, digits,
underscores and hyphens are allowed.
.TP
.B init
Initialize the current (empty) directory as a DCR project.
.TP
.B build [\fIoptions\fR]
Compile the project. Default profile is \fB\-\-debug\fR.
.TP
.B run [\fIoptions\fR]
Build and run the project. Only available for binary projects.
.TP
.B clean [\fIoptions\fR]
Remove build artifacts from the target directory.
.TP
.B test [\fI\-\-init\fR] [\fI\-\-debug\fR|\fI\-\-release\fR]
Run project tests (alias: \fBdcr tests\fR).
.TP
.B add \fI<name>\fR \fI<source>\fR [\fIoptions\fR]
Add a dependency to the project.
.TP
.B tree
Display the dependency tree of the current project.
.TP
.B fmt
Format all C/C++ source files using clang-format.
.TP
.B lint [\fI\-\-fix\fR]
Run clang-tidy static analysis on C/C++ sources.
.TP
.B gen \fI<subcommand>\fR
Generate IDE integration files (vscode, clion, compile-commands, project-info).
.TP
.B setup
Show configured package registries.
.SH GLOBAL FLAGS
.TP
.B \-\-help
Show this help message and exit.
.TP
.B \-\-version
Print version information and exit.
.TP
.B \-\-update
Update DCR to the latest version from GitHub Releases.
.SH BUILD OPTIONS
The following options apply to \fBbuild\fR and \fBrun\fR commands:
.TP
.B \-\-debug
Build with debug profile (default). Enables debug symbols and minimal optimization.
.TP
.B \-\-release
Build with release profile. Enables full optimization without debug symbols.
.TP
.B \-\-target \fI<triple>\fR
Cross-compile for the given target (e.g. \fBaarch64-linux-gnu\fR, \fBx86_64-w64-mingw32\fR).
Short names like \fBlinux\fR, \fBmacos\fR, \fBwindows\fR are also supported.
.TP
.B \-\-force
Force a full rebuild, ignoring cached build artifacts.
.TP
.B \-\-clean
Clean build artifacts before building.
.TP
.B \-\-verbose
Print detailed build output including compiler commands.
.TP
.B \-\-workspace \fI<name>\fR
Build a specific workspace member.
.SH CLEAN OPTIONS
.TP
.B \-\-debug
Clean debug artifacts (default).
.TP
.B \-\-release
Clean release artifacts.
.TP
.B \-\-target \fI<triple>\fR
Clean artifacts for a specific target.
.TP
.B \-\-all
Clean all workspace members.
.SH ADD OPTIONS
.TP
.B \-\-branch \fI<name>\fR
Use a specific branch when adding a git dependency.
.TP
.B \-\-tag \fI<name>\fR
Use a specific tag when adding a git dependency.
.TP
.B \-\-rev \fI<hash>\fR
Use a specific commit hash when adding a git dependency.
.SH DEPENDENCY SOURCES
.TP
.B user/repo
GitHub shorthand (e.g. \fBuser/repo\fR).
.TP
.B github:user/repo
Full GitHub repository URL shorthand.
.TP
.B gitlab:user/repo
GitLab repository URL shorthand.
.TP
.B git:host.com/user/repo
Generic git repository.
.TP
.B path:./path/to/lib
Local path dependency.
.TP
.B \fI<version>\fR
Version from registry (e.g. \fB1.2.3\fR).
.SH GEN SUBCOMMANDS
.TP
.B project-info
Print project metadata as JSON to stdout.
.TP
.B compile-commands
Generate \fB.dcr/compile_commands.json\fR for IDE tooling.
.TP
.B vscode
Generate \fB.vscode/\fR integration files (tasks, launch configurations).
.TP
.B clion
Generate \fB.idea/\fR integration files for CLion.
.SH TEST OPTIONS
.TP
.B \-\-init
Create \fBtests/dcr_test.h\fR in the current project.
.TP
.B \-\-debug
Build and run tests with debug profile (default).
.TP
.B \-\-release
Build and run tests with release profile.
.SH PROJECT CONFIGURATION
DCR uses \fBdcr.toml\fR for project configuration. Key settings include:
.TP
.B package.name
Project name (required).
.TP
.B package.version
Project version (default: \fB0.1.0\fR).
.TP
.B package.dcr\-version
Semver of the DCR tool this project targets. Set automatically by
\fBdcr new\fR / \fBdcr init\fR. Missing pin, or an installed \fBdcr\fR older/newer
than the pin, prints a warning (commands still run).
.TP
.B build.language
Programming language: \fBc\fR or \fBc++\fR (default: \fBc\fR).
.TP
.B build.standard
Language standard (e.g. \fBc11\fR, \fBc17\fR, \fBc++20\fR; default: \fBc11\fR).
.TP
.B build.compiler
Compiler to use: \fBclang\fR, \fBgcc\fR, \fBcl\fR, \fBclang-cl\fR (default: \fBclang\fR).
.TP
.B build.kind
Output type: \fBbin\fR, \fBlib\fR (static or dynamic), \fBstaticlib\fR, \fBsharedlib\fR (default: \fBbin\fR).
.SH FILES
.TP
.I dcr.toml
Project manifest file.
.TP
.I ~/.dcr/config.toml
User-level DCR configuration.
.TP
.I ~/.dcr/index.json
Local registry index.
.SH ENVIRONMENT
.TP
.B DCR_COMPILER
Override the compiler used for building.
.TP
.B DCR_CC
Alternative way to override the compiler.
.SH EXAMPLES
.TP
Create a new project:
.B dcr new hello
.TP
Initialize from current directory:
.B dcr init
.TP
Build with release profile:
.B dcr build \-\-release
.TP
Cross-compile for Windows:
.B dcr build \-\-target windows
.TP
Add a dependency:
.BR "dcr add curl git:https://github.com/curl/curl" .
.TP
Generate VS Code integration:
.B dcr gen vscode
.SH SEE ALSO
.IR https://dcr.dexoron.su ", " https://github.com/dexoron/dcr
.SH AUTHORS
Dexoron (Bezotechestvo Vladimir) <main@dexoron.su>

Submodule packaging/aur/dcr-dev-git added at 93bdce858b

Submodule packaging/aur/dcr-git updated: 12038a613e...2c5743a456

View File

@@ -27,4 +27,7 @@ package() {
cd "$srcdir/$pkgname-$pkgver"
install -Dm755 "target/release/dcr" "$pkgdir/usr/bin/dcr"
install -Dm644 LICENSE "$pkgdir/usr/share/licenses/$pkgname/LICENSE"
for manpage in man/man1/*.1; do
install -Dm644 "$manpage" "$pkgdir/usr/share/man/man1/$(basename "$manpage")"
done
}

Some files were not shown because too many files have changed in this diff Show More