Modernization Plan
The first modernization goal is a reproducible build interface that behaves the same way on Linux, macOS, and Windows. Docker is the practical compatibility boundary: developers install Docker, clone the repository, and use the same wrapper commands regardless of the host operating system.
This page is a proposed implementation plan. The Docker build environment does not exist yet, and no target should be marked restored until its image builds a binary and passes an emulator or hardware smoke test.
Goals
- Build without installing historical SDKs directly on the host.
- Pin compiler, SDK, and packaging-tool versions.
- Keep generated files in the repository workspace.
- Use the same commands locally and in CI.
- Restore targets incrementally without blocking work on the PC baseline.
Proposed Developer Interface
Add one repository-native wrapper, for example:
./run.sh build pc
./run.sh clean pc
./run.sh test pc
./run.sh shell pc
./run.sh build gba
On Windows, these commands should run from WSL 2 or Git Bash with Docker Desktop configured for Linux containers. PowerShell users can call:
wsl ./run.sh build pc
The wrapper should:
- Validate the requested target.
- Build or pull the corresponding pinned toolchain image.
- Mount the repository at a stable in-container path such as
/src/bricks-os. - Set
BRICKS_ROOT=/src/bricks-os. - Run the existing target makefile.
- Preserve host ownership of generated artifacts where the Docker runtime supports user mapping.
The initial implementation should wrap the existing makefiles rather than rewrite the build system at the same time.
Docker Layout
A maintainable layout would separate the shared wrapper from target-specific images:
run.sh
docker/
pc/
Dockerfile
devkitpro/
Dockerfile
ps2/
Dockerfile
psp/
Dockerfile
dc/
Dockerfile
ps1/
Dockerfile
Use immutable image tags or digests in CI. Each image should contain only the toolchains needed by its target family.
Target Images
| Image | Targets | Required tools | Status |
|---|---|---|---|
bricks-os-pc |
pc |
i386 ELF GCC/binutils, make, QEMU, ISO tooling |
First restoration target |
bricks-os-devkitpro |
gba, nds, ngc, wii |
ARM and PowerPC devkitPro toolchains, libogc, packaging tools | Version compatibility unverified |
bricks-os-ps2 |
ps2-ee, ps2-iop |
ps2dev toolchains, PS2 SDK, DVP tools, OpenVCL toolchain | Version compatibility unverified |
bricks-os-psp |
psp |
PSP SDK and packaging tools | Version compatibility unverified |
bricks-os-dc |
dc |
sh-elf-*, scramble, optional Dreamcast loader tools |
Version compatibility unverified |
bricks-os-ps1 |
ps1 |
PSX MIPS toolchain and libraries | Requires build-rule cleanup first |
The historical build prefixes are encoded in include/makeinclude/:
- PC currently uses the host
gcc,g++, and binutils. - GBA and NDS expect
arm-eabi-*. - GameCube and Wii expect
powerpc-gekko-*. - Dreamcast expects
sh-elf-*. - PS2 expects
ee-*andiop-*. - PSP expects
psp-*.
The PS1 rules require special attention: they contain /D/dev/env/devkitPSX
paths and a mips prefix without a separator. Convert these to configurable
environment variables before claiming Docker support.
PC Baseline
Start with pc. It is the shortest path to an automated feedback loop and can
run under QEMU without physical console hardware.
The PC image should provide a Linux i386 cross-toolchain explicitly. Do not
depend on the host architecture or on whichever compiler happens to be named
gcc. This matters on ARM64 macOS and Windows hosts, and it also makes Linux
CI deterministic.
The first PC milestones are:
- Produce
bin/pc/Bricks.elfin Docker. - Replace loop-mounted floppy updates with an unprivileged image-generation step.
- Replace the legacy
qemu -soundhw sb16command with currentqemu-system-i386syntax. - Capture serial output from QEMU.
- Add a smoke test that boots the kernel and asserts a stable startup marker.
Cross-Platform Constraints
Docker removes most host-toolchain differences, but it does not remove all platform concerns:
| Concern | Approach |
|---|---|
| Apple Silicon hosts | Publish or build multi-architecture images where feasible. Use --platform linux/amd64 only for SDKs that cannot run natively on ARM64. |
| Windows filesystem semantics | Use WSL 2 for the repository checkout and Docker invocation. Avoid case-insensitive-path assumptions. |
| Generated-file ownership | Run containers with the host UID and GID on Linux. Document Docker Desktop behavior separately. |
| Hardware loaders | Keep run-hardware commands optional and outside required CI. They may need USB, serial, or local-network access. |
| Emulator UI | Keep the first smoke test headless and serial-driven. Interactive emulator launches can remain convenience commands. |
CI Strategy
After the PC container works locally, add a build workflow:
.github/workflows/build.yml
The first CI job should:
- Build the PC toolchain image or pull its pinned published form.
- Run
./run.sh build pc. - Run
./run.sh test pc. - Upload
bin/pc/Bricks.elf, boot media, maps, and serial logs as artifacts.
Console jobs should initially be opt-in or allowed to fail while their SDK compatibility is being restored. Promote a target to a required CI check only after its build is reproducible.
Build-System Cleanup
Once Docker establishes a known-good baseline, make the existing build rules less dependent on ambient environment:
- Allow compiler prefixes to be overridden instead of hard-coded.
- Replace hard-coded SDK paths with documented variables.
- Separate
build,package,emulate, andrun-hardwareconcerns. - Remove privileged
sudo mountsteps from ordinary builds. - Make packaging output deterministic.
- Add
cleancoverage for generated map files and packaged images.
Avoid combining this cleanup with broad kernel refactors. A reproducible build should come first so later source changes have a reliable verification path.
Definition Of Done
A target is restored only when:
- A fresh clone builds through
./run.sh build <target>. - The required Docker image is pinned and documented.
- Output files are produced at documented paths.
- CI runs the same build command.
- An emulator or hardware smoke test has recorded observable output.