mirror of
https://github.com/dexoron/dcr.git
synced 2026-10-21 08:48:30 +00:00
feat: add cross-compilation support with --target flag
- Updated build and run commands to accept a --target option for specifying target platforms. - Enhanced documentation to include cross-compilation usage and supported targets. - Modified configuration to allow target-specific settings and toolchains. - Introduced a new test command to run project tests with specified profiles and targets. - Improved handling of target directories and output structure for different platforms. - Added support for multiple targets in the configuration file. - Implemented inheritance for workspace and dependencies based on target and profile.
This commit is contained in:
@@ -25,6 +25,7 @@
|
||||
* [dcr run](commands/dcr-run.md)
|
||||
* [dcr clean](commands/dcr-clean.md)
|
||||
* [dcr gen](commands/dcr-gen.md)
|
||||
* [dcr test](commands/dcr-test.md)
|
||||
|
||||
## Dependencies & Build
|
||||
|
||||
@@ -32,6 +33,7 @@
|
||||
* [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
|
||||
|
||||
@@ -8,6 +8,7 @@ Builds the project in `debug` or `release` profile.
|
||||
dcr build
|
||||
dcr build --debug
|
||||
dcr build --release
|
||||
dcr build --target linux --release
|
||||
dcr build --release --force
|
||||
dcr build --debug --clean
|
||||
```
|
||||
@@ -54,6 +55,8 @@ dcr build --debug --clean
|
||||
|
||||
- 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`).
|
||||
- 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.
|
||||
|
||||
@@ -8,6 +8,7 @@ Builds the project and runs the resulting binary.
|
||||
dcr run
|
||||
dcr run --debug
|
||||
dcr run --release
|
||||
dcr run --target linux --release
|
||||
dcr run --release --force
|
||||
dcr run --debug --clean
|
||||
```
|
||||
@@ -24,6 +25,7 @@ dcr run --debug --clean
|
||||
|
||||
- If `build.kind = "staticlib"` or `build.kind = "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.
|
||||
|
||||
|
||||
44
docs/commands/dcr-test.md
Normal file
44
docs/commands/dcr-test.md
Normal file
@@ -0,0 +1,44 @@
|
||||
# dcr test
|
||||
|
||||
Runs the project's test suite.
|
||||
|
||||
## Usage
|
||||
|
||||
```sh
|
||||
dcr test
|
||||
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 release mode by default for performance.
|
||||
- Custom test logic can be added by editing `tests/test.c`.
|
||||
- Fails if no `tests/test.c` exists (run `dcr test --init` first).
|
||||
@@ -9,6 +9,8 @@ standard = "c11"
|
||||
compiler = "clang"
|
||||
kind = "bin"
|
||||
# optional:
|
||||
# inherit = true # Inherit from base (default true)
|
||||
# targets = ["linux", "macos"] # Multiple targets to build
|
||||
# target = "./dist"
|
||||
# platform = "x86_64"
|
||||
# cflags = ["-Wall"]
|
||||
@@ -30,6 +32,8 @@ kind = "bin"
|
||||
- `standard` (string, required): language standard passed to compiler.
|
||||
- `compiler` (string, required): compiler command (for example `clang`, `gcc`, `cl`).
|
||||
- `kind` (string, required): `bin`, `staticlib`, or `sharedlib`.
|
||||
- `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.
|
||||
- `platform` (string, optional): architecture hint for compiler (used for `-march` or `/arch`).
|
||||
- `cflags` (string array, optional): extra compile flags.
|
||||
@@ -82,6 +86,15 @@ Step notes:
|
||||
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"]
|
||||
@@ -89,6 +102,29 @@ 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
|
||||
|
||||
@@ -43,7 +43,10 @@ Workspace-only root:
|
||||
|
||||
## Optional keys
|
||||
|
||||
- `build.inherit`
|
||||
- `build.targets`
|
||||
- `build.target`
|
||||
- `build.platform`
|
||||
- `build.cflags`
|
||||
- `build.ldflags`
|
||||
- `build.exclude`
|
||||
@@ -58,7 +61,11 @@ Workspace-only root:
|
||||
- `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)
|
||||
|
||||
@@ -17,7 +17,7 @@ DCR picks a backend from `build.compiler`:
|
||||
- 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/<profile>/obj/<relative-path>.o` (`.obj` on MSVC).
|
||||
- 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`.
|
||||
|
||||
@@ -35,6 +35,8 @@ 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:
|
||||
|
||||
201
docs/dependencies-and-build/cross-compilation.md
Normal file
201
docs/dependencies-and-build/cross-compilation.md
Normal file
@@ -0,0 +1,201 @@
|
||||
# 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
|
||||
```
|
||||
|
||||
### 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).
|
||||
@@ -1,6 +1,6 @@
|
||||
# Target directory
|
||||
|
||||
By default, DCR writes final artifacts to `target/<profile>/`.
|
||||
By default, DCR writes final artifacts to `target/<target>/<profile>/` (where `<target>` is `native` or target triple).
|
||||
|
||||
You can override this with `build.target`:
|
||||
|
||||
@@ -20,4 +20,4 @@ target = "./dist"
|
||||
|
||||
## Important detail
|
||||
|
||||
`build.target` changes only the final artifact location. Object cache and dependency sync directories still use `target/<profile>/...`.
|
||||
`build.target` changes only the final artifact location. Object cache and dependency sync directories still use `target/<target>/<profile>/...`.
|
||||
|
||||
@@ -8,6 +8,7 @@ Debug (default):
|
||||
dcr build
|
||||
# or
|
||||
dcr build --debug
|
||||
dcr build --target linux --debug
|
||||
dcr build --debug --clean
|
||||
```
|
||||
|
||||
@@ -15,6 +16,7 @@ Release:
|
||||
|
||||
```sh
|
||||
dcr build --release
|
||||
dcr build --target windows --release
|
||||
```
|
||||
|
||||
## Run
|
||||
@@ -22,7 +24,9 @@ dcr build --release
|
||||
```sh
|
||||
dcr run
|
||||
# or
|
||||
dcr run --target macos
|
||||
dcr run --release
|
||||
dcr run --target linux --release
|
||||
dcr run --release --force
|
||||
```
|
||||
|
||||
@@ -49,4 +53,5 @@ dcr clean --release --all
|
||||
- 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.
|
||||
- `--clean` for `build`/`run` removes `target/<profile>` and paths from `build.clean`.
|
||||
- `--target` builds/runs for specified target (short names: `linux`, `macos`, `windows`).
|
||||
- `--clean` for `build`/`run` removes `target/<target>/<profile>` and paths from `build.clean`.
|
||||
|
||||
@@ -31,10 +31,10 @@ project/
|
||||
- `dcr.toml`: main project configuration.
|
||||
- `dcr.lock`: generated lock file for resolved path dependencies.
|
||||
- `src/`: recursively scanned source directory.
|
||||
- `target/<profile>/obj/`: cached object files for incremental rebuild.
|
||||
- `target/<profile>/deps/`: synchronized copies of path dependencies.
|
||||
- `target/<profile>/<name>` (or `.exe` on Windows): output for `kind = "bin"`.
|
||||
- `target/<profile>/lib<name>.a` (or `<name>.lib` on Windows): output for `kind = "staticlib"`.
|
||||
- `target/<profile>/lib<name>.so` (or `.dylib` on macOS, `<name>.dll` on Windows): output for `kind = "sharedlib"`.
|
||||
- `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/<profile>/obj`.
|
||||
If `build.target` is set, the final artifact is written to that custom directory, while object cache still stays in `target/<target>/<profile>/obj`.
|
||||
|
||||
Reference in New Issue
Block a user