Redub v1.36.4: Incremental compilation, automation on EMSDK, WASI-SDK, Android-SDK, LDC-Addon and much more
Hipreme
msnmancini at hotmail.com
Thu Nov 5 04:19:14 UTC 2026
Hello guys, I've come to announce big changes in redub:
I'm posting a full changelog on the golden version below, but if
you want to know one of the main highlights:
- Redub has got a manual D parser which is able to get imports of
most projects, with basic template, string mixin, mixin template
evaluation, so it can parse structures such as `template t(string
mod){mixin("import ",mod,";");}` or even in structures such as
variadic string[]... arguments being used in the import context.
Think of a powered libdparse but it's main focus is on detecting
`import`.
- Hashing became 2x faster, competitive with Makefile (I've
adopted fixed a bug where a reparse would happen needlessly)
- Cache is now using only 20% of the space it needed from before,
I've adopted a binary format (faster load and write too)
- You can now build and test directly to multiple platforms, such
as wasm or android, no extra work needed, this is as minimal as
it gets:
```d
redub install ldc 1.43.0 --addon=android
redub init --android android-hello
cd android-hello
redub install android-sdk
redub install android-ndk
redub --target=android --bundle=android
```
> This is as minimal as it gets, and will have your app running
> on your smartphone
- [**Cross Compilation Targets**](#redub-cross-compile) - Adds
support to build targets, selecting a compiler, architecture and
other configuration by just calling `redub --target=PSVita`
- [**LDC Addon**](#redub-ldc-addon) - Since `v1.35.2`: Adds
support to installing LDC addon, together with target presets
- **Auto PATH setup** - Since `v1.32.0`: Adds a way to auto setup
redub paths in your system. Call `redub setup` and it will
install redub, redub's ldc and redub's dmd in the PATH.
- **Cache Sharing** - Since `v1.33.2`: Whenever you build a
library which has the same versions and flags between parallel
projects, the built library will be reused.
- [**Incremental Compilation**](#redub-incremental-compilation) -
Since `v1.34.0`: Redub is able to parse your root project and
detect whether it is better to use a single compilation unit vs
per module in parallel
- **Build Time Regression Warn** - Since `v1.35.0`: Redub now
also warns you if you've done some change that done a big
regression in the build time, allowing you to be aware of your
own changes.
- [**Built-in Cross Runner**](#built-in-targets) - Since
`v1.36.1`: It is now possible to use redub to run D on android
and web without any modification: `redub --target=android
--bundle=android`|`redub --target=wasm` - builds and runs a
server loading your executable
## Redub Cross Compile
- **1.30.0**: Added cross compilation definition support via the
`--target` flag.
Ever wanted to configure a default compiler/arch based on the
configuration? Now you can (mostly). This is an example on how a
`target` will look in your recipe JSON:
```json
{
"name": "my-project",
"targets": {
"wasm": {
"compiler": "ldc2",
"arch": "wasm32-unknown-unknown-wasm"
},
"PSVita": {
"compiler": "ldc2",
"arch": "armv7a-unknown-unknown-eabi",
"dflags": [
"--revert=dtorfields",
"-mcpu=cortex-a9",
"-mattr=+neon,+neonfp,+thumb-mode",
"-fvisibility=hidden",
"-gcc=$VITASDK/bin/arm-vita-eabi-gcc",
"--relocation-model=static"
],
"versions": ["PSVita"],
"dependencies": {
"custom-rt": {"path": "my/custom/runtime"}
},
"runCommand": ["nxlink", "${DUB_ROOT_PACKAGE}.nro"] //New
addition to redub. If you're cross-compiling, you can define a
specific run command that will be used instead of just launching
from shell the executable.
}
}
}
```
Now you can just call `redub --target=wasm` or `redub
--target=PSVita` and every dependency will inherit this
configuration.
### Built-in targets
Since `v1.36.1`: use `redub --target=<name>`; a recipe target
with the same name overrides the preset. Addons require LDC 1.43+
(`redub install ldc --addon=<group>`).
| Target | Addon | SDK | Environment | Run |
| --- | --- | --- | --- | --- |
| `windows`, `windows-i686`, `windows-arm64` | `windows` | N/A |
N/A | native |
| `macos`, `macos-arm64` | N/A | Apple tooling to link | N/A |
native |
| `android`, `android-armv7a`, `android-x86_64`, `android-i686` |
`android` | NDK + SDK build-tools/platform | `ANDROID_NDK_HOME`,
`CC`, `PATH` | `adb` push/run; APK via `--bundle=android` |
| `wasi`, `wasi-p2` | `wasi` | WASI SDK | `WASI_SDK_PATH`, `CC`,
`PATH` | `redub serve` (p2 needs `jco`) |
| `emscripten` | `emscripten` | Emscripten SDK | `EMSDK`, `PATH`,
`EMSDK_NODE`, `EMSDK_PYTHON` | `redub serve` with its `.js` glue |
| `wasm`, `web` | N/A | N/A | N/A | `redub serve` |
**Remarks**
**Remarks**
- **macOS:** compiles everywhere; linking needs Apple tooling.
Use `--build=syntax` for a pure syntax check.
- **Android – setup:** redub finds the NDK via env/Android Studio
paths or `redub install android-ndk`. For APK packaging, `redub
install android-sdk` installs platform-tools, build-tools, a
platform and a JDK 17 when none is found (all in the workspace
and found automatically). `adb` (platform-tools) is
auto-downloaded and `ANDROID_SERIAL` selects a device.
- **Android – run on a device:** `redub run --target=android`
pushes and runs the `.so`; with `--bundle=android` it builds the
APK, installs it, starts the launcher activity and streams
`logcat`.
- **Android – build an APK:** `redub build --target=android
--bundle=android` requires `extern(C) void
android_d_main(void*)`; the APK uses the redub icon and
permissions go in `"bundleConfiguration": { "permissions":
["INTERNET"] }`.
- **Android – start a project:** `redub init --android <dir>`
creates an OpenGL ES + touch template
(`bundleConfiguration.opengl = true`, callbacks
`redub_android_init/draw/touch/destroy`).
- **Android – customize the glue:** the selected bridge lives in
`android/glue/source/redub_{minimal,opengl}_bridge.c`; the glue C
project is created in `android/glue` (edit its `dub.json` flags
or add sources under `source/`); redub builds it only for Android
bundles and caches the result.
- **Android – example:** see `tests/android`.
- **WASI:** install the SDK with `redub install wasi-sdk`; p1
runs in the browser via `redub serve`; p2 outputs are components,
transpile with `jco`.
- **Emscripten:** install with `redub install emsdk`; no system
Python needed.
- **wasm/web:** no SDK; links with `--no-entry` and
`--allow-undefined`, so use `-betterC` or provide an entry
point/runtime. `env.js` can provide JS imports for `extern(C)`;
builds create a template in the project root.
- **serve:** `redub serve [<artifact|dir>] [--port=8080]
[--host=127.0.0.1] [--no-open]` serves the build directory, opens
the browser (unless `--no-open`), and generates
`index.html`/`redub.js` when missing.
## Redub Incremental Compilation
Depending on the project size, it may be more useful to build it
in parallel per module vs in a single command how it is done by
default. Note that this is only valid for the root project.
The `auto` option will parse your D source and identify whether
it is cheaper to use incremental-prallel or full-once, which is
the default behavior. It is also possible to override that in 2
ways:
`auto` also execute multiple compilation strategies and collect
in its cache the build timings to get which strategy is faster
and better decide.
- **Project Configuration**:
```json
"redub": {
"buildStrategy": "incremental-parallel",
"buildStats": false, //Do not collect build stats. Since we're
not using auto, there's not much gain by doing that.
"trustedNoImportMixins": [ //Mixins that can't be resolved but
you guarantee they do not import anything.
"my.NoImportMixin"
]
}
```
- **Command Line**:
```
--build-strategy Root build strategy:
|auto|full-once|incremental-once|incremental-parallel|full-parallel|. Overrides the project's redub config.
strategy incremental processes
link
full-once no 1 compiler
same invocation
incremental-once yes 1 compiler + 1 linker
separate
incremental-parallel yes N compilers (1 per module) +
link separate
full-parallel no N compilers (1 per module) +
link separate
auto(default) picks full-once or incremental-parallel
from module count/weight;
fewer than 4 cores picks
incremental-once.
link is separate whenever per-module objects are reused
```
More information about the Digitalmars-d-announce
mailing list