-
Notifications
You must be signed in to change notification settings - Fork 88
Defoogi Demystified
Source-verified against defoogi v1.4.6 (Makefile TAG = 1.4.6) and versions.env as of June 2026.
- What defoogi Is, and the Problem It Solves
- How defoogi Is Built (Architecture)
- How defoogi Runs (The Runtime Model)
- The Complete Toolchain Inventory
- Installing Each Tool Yourself (The Hard Way)
- Why defoogi Is the More Complete Option
- Using defoogi Day-to-Day
- Appendix A — Version Pin Reference
- Appendix B — The Generated Dockerfile
- Appendix C — Sources & References
defoogi (created by Chris Osborn, @fozztexx) is a single Docker container that bundles every compiler, assembler, li brary, and disk-image utility needed to build FujiNet firmware, libraries, and applications — acro ss every retro platform FujiNet supports — plus the modern embedded toolchains (PlatformIO/ESP32, Pico SDK) the FujiNet hard ware itself is built with.
You use it as a command prefix. Instead of installing a dozen cross-compilers on your machine, you run:
defoogi make
defoogi cc65 hello.c
defoogi cmoc program.c…and the build happens inside the container, but the artifacts land in your working directory owned by you, not by root .
Building software for 8-bit and 16-bit machines means assembling a zoo of toolchains that were each written by a different p erson, in a different decade, with a different build system, and with wildly different packaging stories:
- Some are in
apt/Homebrew (cc65, nasm, cpmtools, mtools). - Some are Java jars that need a JDK (AppleCommander).
- Some only build from source under autotools and won't compile natively on Windows (CMOC needs Cygwin).
- Some are Free Pascal programs that need
fpcjust to bootstrap (MADS, Mad Pascal). - Some are two-phase self-hosting builds that "take forever" (Open Watcom v2 — the Dockerfile comment literally says so).
- Some need a specific pre-release commit with non-default build flags (z88dk, built
-zfor special MSX options).
Getting all of these onto one machine — at mutually compatible, reproducible versions — and then getting the same set
onto a teammate's macOS laptop and a Windows box and a CI runner, is the actual problem. defoogi turns that problem into do cker pull.
Unlike many Docker build environments, defoogi preserves file ownership and permissions, so your build artifacts stay usable on the host without extra
chown. —README.md
This is not cosmetic. The usual Docker-build complaint is that everything the container writes to a bind-mounted directory c
omes out root:root, and you spend your life running sudo chown -R. defoogi solves this at the entrypoint (see [§3](#3-ho
w-defoogi-runs-the-runtime-model)).
defoogi is not one monolithic Dockerfile. It is a set of independent build stages that are assembled at build time by th
e Makefile. Understanding this explains both its reproducibility and why each tool is cleanly separable.
Dockerfiles/
├── head.docker ← CORE: defines the `tooling` base image
├── final.docker ← CORE: the final image preamble (PlatformIO, etc.)
├── tail.docker ← CORE: installs all .debs, runtime tools, entrypoint
│
├── cc65.docker ┐
├── cmoc.docker │
├── z88dk.docker │
├── open-watcom-v2.docker│
├── mads.docker │
├── nasm.docker ├─ COMPONENT stages: each builds ONE tool
├── applecommander.docker│ and packages it as a .deb
├── atari-tools.docker │
├── dir2atr.docker │
├── cc1541.docker │
├── cpmtools.docker │
└── pico-sdk.docker ┘
The Makefile classifies them:
CORE = head final tail
COMPONENTS = $(filter-out $(CORE),$(notdir $(DOCKERFILES:.docker=)))Everything starts from Debian 13.0 (ARG BASE=debian:13.0), plus a minimal toolchain that every component shares:
FROM ${BASE} AS tooling
RUN apt-get install -y --no-install-recommends build-essential ca-certificates gitEvery component stage begins FROM tooling AS <name>, so they all inherit the same compiler base.
Each component builds its tool from source (or downloads it), installs it into a clean prefix, then wraps that prefix in a
Debian package inside the build stage. The pattern, taken verbatim from cc65.docker:
FROM tooling AS cc65
RUN git clone .../cc65.git && cd cc65 && git checkout ${CC65_VERSION} \
&& PREFIX=/usr/local make && PREFIX=/opt/cc65 make install
# …then turn /opt/cc65 into /tmp/cc65.deb via dpkg-deb --buildSo each stage's output artifact is a single file: /tmp/<name>.deb.
This is the trick that ties it together. The docker-build target literally streams the core + component Dockerfiles in
to docker build -f - (read from stdin), injecting generated COPY --from= lines that pull each component's .deb out of
its build stage:
docker-build:
printf "%s\n" $(COMPONENTS) | \
sed 's,.*,COPY --from=& /tmp/&.deb /tmp/packages/,' | \
cat head.docker <component stages> final.docker - tail.docker | \
docker build -f - $(shell sed 's/^\([^=]*\)=/--build-arg \1_VERSION=/' versions.env) ...The result, written to /tmp/defoogi.dockerfile, is one big multi-stage Dockerfile where:
-
headbuildstooling. - Every component stage builds its tool as a
.deb— these run in parallel under BuildKit, each isolated. -
final(a freshFROM tooling) installs the no-compile-needed pieces — PlatformIO andabimapviapipx, pluscm ake/libmbedtls/libexpat. - The generated
COPY --from=<component> /tmp/<component>.deb /tmp/packages/lines copy every built.debinto the final image. -
tailinstalls them all in one shot (apt-get install -y ./tmp/packages/*.deb), adds runtime utilities, sets environmen t variables, creates the unprivilegedwariouser, and installs the entrypoint.
Every tool version is pinned in versions.env, and the Makefile turns each line into a --build-arg <NAME>_VERSION=…
. The intent is stated in the Makefile:
Package versions are pinned intentionally. This ensures a stable, reproducible toolchain that can be matched to specific F ujiNet firmware/software releases. In the future, older defoogi versions can still be rebuilt against the exact tool version s they were originally developed with.
This is the single most important architectural property: defoogi version 1.4.6 is a fixed point — a known-good constell ation of ~19 tool versions that are known to build FujiNet together. (See Appendix A.)
make multi-arch NAMESPACE=fozztexx/ builds and pushes per-architecture tags (-amd64, -arm64), and make manifest stit
ches them into a single multi-arch manifest with docker buildx imagetools create. That's why the published image runs nati
vely on both Intel and Apple-Silicon/ARM hosts.
Three scripts implement the "just prefix your command" experience: start (installed as defoogi), cntnr-init (the in-co
ntainer entrypoint), and defoogi-make (a make convenience wrapper).
You copy start into your PATH renamed to defoogi (make install does cp start /usr/local/bin/defoogi). Because the
script keys off its own name (IMAGE=$(basename $0):latest), the executable name is the image name.
When you run defoogi make, start issues roughly:
docker run --privileged -v /dev:/dev --cap-add=SYS_ADMIN --cap-add SYS_PTRACE \
-e DISPLAY -v ${HOME}/.Xauthority:/home/wario/.Xauthority --net=host \
--rm -e HOSTDIR="${PWD}" -v "${PWD}":/workspace \
fozztexx/defoogi:latest makeNotable bits:
-
-v "${PWD}":/workspace— your current directory becomes/workspacein the container. -
-e HOSTDIR="${PWD}"— tells the container the real host path, so it can recreate it (see §3.2). -
X11 passthrough (
DISPLAY,.Xauthority,--net=host) — so GUI tools (e.g. AppleCommander's GUI) can display. -
--privileged+SYS_ADMIN— needed because the entrypoint performs amount --bind. -
--rmfor one-shot runs;--daemonkeeps it running;--shell/--super-shellgive you an interactive shell as the workspace user / root.
This is the entrypoint, and it's where the "no root-owned artifacts" promise is kept. On startup it:
- Reads the owner uid:gid of
/workspace(your mounted directory). - If that owner is a normal user (uid ≥ 1000), it
usermod/groupmods the in-containerwariouser to match your uid:g id. So whenwariowrites files, they're written as you. -
Bind-mounts
/workspaceback onto the original host path (HOSTDIR) inside the container, thencds there — so rel ative paths,realpath, and anything that records absolute paths match the host. (This is why--privileged/SYS_ADMINar e required.) - Drops privileges and runs your command as
warioviasudo -u wario -E --preserve-env=PATH -H env "$@".
That uid/gid remapping is the whole trick: artifacts come out owned by you, on Linux, with zero chown. (On Docker Desktop
for macOS/Windows the file-sharing layer already remaps ownership, so the benefit is most visible on native Linux Docker.)
A thin wrapper so make -C some/subdir works through the container: it extracts the -C/--directory argument, mounts the
parent directory, and re-invokes defoogi --directory <parent> make -C <target>. Useful when your build references files
one level up from the makefile.
Everything defoogi contains, grouped by job. Versions are the pinned values from versions.env.
| Tool | Pinned version | CPU / target | What it is |
|---|---|---|---|
| cc65 | 6efe447 |
6502/65C02/65816 | C compiler + ca65 assembler + ld65 linker + ar65 + da65. Targets C64, Apple |
| II, Atari 8-bit, NES, VIC-20, Oric, and more. The backbone of FujiNet's 6502-family apps. | |||
| CMOC | 0.1.97 |
6809/6309 | C-like compiler for Motorola 6809. Targets Tandy CoCo, Dragon 32/64, OS-9. **Requires lw |
| tools** (below). | |||
| lwtools | 4.24 |
6809/6309 |
lwasm assembler + lwlink linker + lwar. CMOC emits assembly that lwasm/lwlink tur |
| n into binaries. | |||
| z88dk |
4c74585 (pre-release) |
Z80/Z180/8080/8085 | C compiler (zcc driving sccz80 and a bundled SDCC), |
| assembler, linker, and a huge library covering 100+ Z80 machines: MSX, ZX Spectrum, CP/M, Amstrad CPC, Coleco/ADAM, etc. Bu | |||
ilt with ./build.sh -z for special MSX options (per git log). |
|||
| Open Watcom v2 | 2025-08-02-Build |
8086/80286/80386 (x86) | Full C/C++ compiler + linker (wcc, wcl, wlink) fo |
| r DOS, 16-bit Windows, OS/2, CP/M-86. This is the FujiNet MS-DOS / PC toolchain. Self-hosting two-phase build. | |||
| Mad Pascal | 23e4c5f |
6502 (Atari 8-bit) | Turbo-Pascal-compatible compiler for Atari 8-bit, paired with MADS as it |
s backend. Ships with FujiNet Pascal libraries (fn_cookies, fn_tcp) — defoogi even patches them at build time. |
FujiNet-specific Z80 libraries added into z88dk:
| Library | Pinned version | Purpose |
|---|---|---|
| eoslib | 70d476b |
Coleco ADAM EOS (operating system) C library — eos.lib + eos.h. (tschak909) |
| smartkeyslib | 1.1 |
ADAM SmartKeys function-key library. (tschak909) |
| Tool | Pinned version | CPU / target | Notes |
|---|---|---|---|
| ca65 | (part of cc65 6efe447) |
6502 family | cc65's macro assembler. |
| lwasm | (part of lwtools 4.24) |
6809 | lwtools' assembler. |
| MADS (Mad-Assembler) | 2370bf0 |
6502 / Atari | Powerful Atari-centric 6502 macro assembler; the Atari-8-bit communi |
ty standard. Built from Pascal via fpc. |
|||
| atasm | V1.30 |
6502 / Atari | MAC/65-compatible Atari assembler (built inside dir2atr.docker). |
| nasm | e9fac2f |
x86 | The Netwide Assembler — modern x86/x86-64 assembly. |
This is the part most "just install a compiler" guides forget: a compiled binary is useless until it's inside a disk image t he target machine (or FujiNet) can mount. defoogi bundles a tool for every disk format FujiNet platforms use:
| Tool | Pinned version | Disk/file format | Platform |
|---|---|---|---|
atari-tools (atr) |
835d5a6 |
.ATR (read/write/extract) |
Atari 8-bit |
| dir2atr (from AtariSIO) | bbccb15 |
builds .ATR from a directory tree |
Atari 8-bit |
| cc1541 | 4.2 |
.D64 (1541 floppy image) |
Commodore 64 / VIC-20 |
AppleCommander (ac, acx) |
12.0 |
.dsk, .do, .po, .2mg, ShrinkIt |
Apple II |
cpmtools (cpmcp, cpmls, mkfs.cpm) |
2.23 |
CP/M filesystems | CP/M machines + Coleco ADAM (custom `diskdef |
| s`) | |||
mtools (mcopy, mformat, …) |
(Debian apt) | FAT12/16 floppy & disk images | MS-DOS / PC |
| decb (from Toolshed) | v2_4_2 |
Disk Extended Color BASIC .dsk
|
Tandy CoCo |
ADAM detail worth knowing:
cpmtools.dockerwrites a custom/usr/local/share/diskdefsdefiningcoleco-adam(5.25″ , 40 tracks) andcoleco-adam-3.5(3.5″, 160 tracks) geometries — so you can build ADAM media that stock cpmtools doesn't k now about out of the box.
| Tool | Pinned version | Target | Role |
|---|---|---|---|
| PlatformIO | latest (via pipx) |
ESP32 (ESP-IDF / Arduino) | The FujiNet firmware build system itself. This is h |
| ow the FujiNet device firmware is compiled and flashed. | |||
| abimap | latest (via pipx) |
— | ABI/symbol-version map helper used in some build flows. |
| Pico SDK | 2.2.0 |
RP2040 (Raspberry Pi Pico) | SDK at /usr/local/share/pico-sdk (PICO_SDK_PATH is preset) for R |
| P2040-based FujiNet peripherals/variants. | |||
| picotool | (built w/ pico-sdk) | RP2040 | Inspect/flash RP2040 binaries. |
These come from head, final, and tail, and from being pulled in as dependencies. They're "free" inside defoogi but eac
h is a thing you'd otherwise have to provide:
- Debian 13.0 userland + build-essential (gcc/g++/make), git, ca-certificates, cmake.
-
Free Pascal Compiler (
fpc) — required to build MADS / Mad Pascal. -
default-jdk (Java) — pulled in as a dependency of AppleCommander; required to run
ac/acx. -
SDCC — built as part of z88dk (
BUILD_SDCC=1). - A large pile of Perl modules (Capture::Tiny, Clone, Path::Tiny, YAML, Modern::Perl, …) plus
bison,flex,ragel,re2c,m4,ccache,texinfo— all required just to build z88dk. - Runtime utilities in
tail:mtools,curl,wget,file,jq,xxd,zip/unzip,less,bsdmainutils,libz-d ev,sudo. - Preset environment:
WATCOM=/opt/watcom,PATH+=${WATCOM}/binl,PLATFORMIO_CORE_DIR=/workspace/.platformio,PICO_SDK_ PATH=/usr/local/share/pico-sdk.
Two entries are referenced but not currently produced by any Dockerfile in this revision:
-
versions.envpinsVASM=2_0c, but there is novasm.docker. -
tail.dockerexportsVBCC=/opt/vbccand adds${VBCC}/bintoPATH, but novbcc.dockerbuilds it and there's noVBCCversion pin.
These look like scaffolding for a planned vasm/vbcc (Amiga/68k-style) toolchain. They're harmless today (the PATH entr
y just points at a non-existent dir) but worth flagging so you don't go looking for vasmm68k and wonder why it's missing.
This section answers "what if I didn't use defoogi?" — what it actually takes to stand up each tool on Linux, Window s, and macOS. The pattern that emerges: a few tools are well-packaged everywhere, but the majority are source-only, several do not build natively on Windows (Cygwin/MSYS required), and none of the platform combinations gets you a pinn ed, mutually-compatible set without manual version juggling.
Legend: ✅ packaged/easy ·
| Method | |
|---|---|
| Linux | ✅ apt install cc65 (Debian/Ubuntu); also openSUSE Build Service RPM/DEB. |
| macOS | ✅ brew install cc65. |
| Windows | ✅ Official .exe snapshot installer (sets env vars) or unzip the Windows binary snapshot. |
cc65 is the easy one. Caveat: distro packages can lag the upstream git HEAD that FujiNet may rely on, so you may still e
nd up doing git clone && make to match versions.env's 6efe447.
Sources: Homebrew, [cc65 getting-started](https://cc65.github.io/getting-started.ht
ml), NESdev: Installing CC65.
| Method | |
|---|---|
| Linux | lwtools: download tarball, make && make install. CMOC: `./configure && make && |
make install(needsflex/yacc). lwasm/lwlink must be on PATH`. |
|
| macOS | |
| Windows | ❌ Per the CMOC author, it cannot be compiled as a native Windows app — you must use Cygwin (lwtools |
likewise). A third-party WinCMOC bundle exists on SourceForge but lags far behind (≈v0.5) and isn't the pinned 0.1.97
|
|
| . |
defoogi additionally builds decb from Toolshed here (CoCo .dsk handling) — another from-source step you'd have to re
plicate.
Sources: CMOC homepage, [CMOC manual](https://perso.b2b2c.ca/~sarrazip/dev
/cmoc-manual.html), [LWTOOLS on Windows via Cygwin](https://subethasoftware.com/2022/06/16/installing-lwtools-on-windows-usi
ng-cygwin/).
| Method | |
|---|---|
| Linux | git clone --recursive + ./build.sh; a snap exists for some distros but won |
't be the pinned commit or carry the -z MSX flags. |
|
| macOS | z88dk-osx-latest.zip exists, but to match defoogi's pinned pre-release commit with MSX options you |
| build from source. | |
| Windows | ❌/✅ Nightly z88dk-win32-latest.zip is available, **but building the classic libs from source requires MS |
| YS or Cygwin**. |
Then you'd still have to clone & build eoslib and smartkeyslib and drop them into z88dk's lib tree — exactly what
z88dk.docker does. And z88dk's build pulls in a long list of Perl modules + bison/flex/ragel/re2c.
Sources: z88dk installation wiki, [nightly builds](http://nightly.z88dk.
org/).
| Method | |
|---|---|
| Linux | ✅/ow_portable_v2_stable.zip) and set WATCOM/PATH/INCLUDE; or bu |
| ild from source (two-phase, slow). | |
| macOS | |
| Windows | ✅ Official installer from the snapshot builds. |
Workable, but you must pick a build and wire up three environment variables (WATCOM, INCLUDE, PATH) yourself — defoogi
presets them. The source build "takes forever" (Dockerfile's own words).
Sources: Open Watcom v2 install.txt,
openwatcom.org.
| Method | |
|---|---|
| Linux | fpc, then fpc -Mdelphi mads.pas and fpc src/mp.pas from the Mad-Assembler / Mad-Pascal git rep |
| os. | |
| macOS | |
| Windows | ✅/ |
You'd also need to replicate defoogi's library staging (copying base/lib/blibs/dlibs, creating upper-case symlinks) *and
- the FujiNet
fn_cookies/fn_tcpsource patch to build current FujiNet Pascal code.
| Method | |
|---|---|
| Linux | atasm: clone & make. dir2atr: clone AtariSIO (make tools && make tools-install); needs `libncurs |
| es-dev`. | |
| macOS | |
| rtability fixes. | |
| Windows |
| Method | |
|---|---|
| Linux / macOS | git clone jhallen/atari-tools && make. No package. |
| Windows |
| Method | |
|---|---|
| Linux | make && make install. (Some community AUR/Homebrew packages exist but versions vary. |
| ) | |
| macOS | |
| Windows |
| Method | |
|---|---|
| All three | ✅/ |
and you'll want to write ac/acx shell-script wrappers (java -jar …) yourself. defoogi does both (and pulls `default-j |
|
| dk` automatically). |
Source: AppleCommander releases, [install guide](https://applec ommander.github.io/install/) (Java 11 required).
| Method | |
|---|---|
| Linux | ✅ apt install cpmtools mtools. |
| macOS | ✅ brew install cpmtools mtools. |
| Windows |
Even here, you'd have to add defoogi's custom Coleco ADAM diskdefs by hand to make ADAM media.
Sources: cpmtools Homebrew, GNU mtools.
| Method | |
|---|---|
| Linux | ✅ apt install nasm. |
| macOS | ✅ brew install nasm. |
| Windows | ✅ Official installer/binaries. |
Source: nasm Homebrew.
| Method | |
|---|---|
| All three | ✅ PlatformIO: pipx install platformio (cross-platform). |
| Pico SDK | pico-sdk + submodules, set PICO_SDK_PATH, and install the gcc-arm-none-eabi cross toolcha |
in + newlib; build picotool from source (needs libusb, cmake, pkg-config). |
PlatformIO is genuinely easy everywhere; the Pico SDK is the usual "clone + submodules + ARM toolchain + env var" dance, whi ch defoogi has already done and wired up.
| Tool | Linux | Windows | macOS | Packaged anywhere? |
|---|---|---|---|---|
| cc65 | ✅ | ✅ | ✅ | apt, brew, .exe |
| nasm | ✅ | ✅ | ✅ | apt, brew, .exe |
| cpmtools / mtools | ✅ | ✅ | apt, brew | |
| Open Watcom v2 | ✅ | snapshot/installer | ||
| AppleCommander | jar (needs JDK 11) | |||
| PlatformIO | ✅ | ✅ | ✅ | pipx |
| z88dk (+eoslib/smartkeys) | ❌ | nightly/snap (not pinned) | ||
| CMOC + lwtools | ❌ | source only | ||
| MADS / Mad Pascal | ✅* | source (Win binaries) | ||
| atasm / dir2atr / atari-tools | source only | |||
| cc1541 | source (mostly) | |||
| Pico SDK + picotool | source + ARM toolchain |
* Windows binaries published by upstream author, version may differ from the pin.
Tally: of ~13 tool groups, only 3 (cc65, nasm, PlatformIO) are genuinely one-command everywhere. Two won't build nativ ely on Windows at all. And none of this gives you version pins matched to a FujiNet release.
The DIY matrix above shows the breadth problem. Here's why the container wins on the dimensions that actually matter for F ujiNet development:
-
One install, not thirteen.
docker pull fozztexx/defoogi(or build once) replaces a multi-day setup involving apt, H omebrew, pipx, Java, Free Pascal, Cygwin/MSYS, and a half-dozengit clone && makebuilds — per developer, per machine. -
Reproducibility pinned to FujiNet releases.
versions.envfreezes ~19 components at exact commits/tags. A given defo ogi tag (1.4.6) is a known-good constellation that builds the matching FujiNet sources. With DIY installs, every machine d rifts to slightly different upstream versions and "works on my machine" bugs follow. defoogi can be rebuilt from an old ta g to reproduce a historical build exactly. -
True cross-platform parity. The container is byte-for-byte identical on Linux, Windows (Docker Desktop/WSL2), and mac OS (incl. Apple Silicon via the multi-arch manifest). The DIY path is different on every OS — and on Windows, several tool s require Cygwin/MSYS that subtly change behavior.
-
The disk-image tools are included and pre-configured. Compilers are only half the job; you need
atr,dir2atr,cc 1541,ac/acx,cpmtools(with ADAM diskdefs),mtools, anddecbto produce mountable media. defoogi ships all o f them, wired up — including custom config a fresh install wouldn't have. -
All the build glue is solved. Java for AppleCommander, FPC for MADS, SDCC inside z88dk, the Perl-module wall z88dk ne eds, the FujiNet
fn_cookies/fn_tcppatches, the eoslib/smartkeyslib staging,WATCOM/PICO_SDK_PATHenv vars — all pre -resolved. -
Ownership preservation. Build artifacts come out owned by you (uid/gid remap + bind-mount), so there's no
sudo chownritual and no root-owned junk in your repo. -
Local and CI are the same environment. The exact image used on your laptop runs in GitHub Actions, enabling the edi t → push → CI build → mount over HTTP via FujiNet → boot workflow the README describes. DIY means maintaining two parallel setups (your machine and the CI image) and keeping them in sync.
-
FujiNet firmware and apps in one place. It's the only environment that covers both the device firmware (Platfor mIO/ESP32, Pico SDK) and every client-platform app toolchain — so firmware devs and app devs share one tool.
The honest counterpoint: defoogi requires Docker, the first build/pull is large, --privileged is needed for the bind-mount
trick, and GUI/serial-flashing workflows need the X11//dev passthrough the start script sets up. For the FujiNet use ca
se, those costs are small next to maintaining a dozen hand-built cross toolchains across three operating systems.
# 1. Get Docker (the repo even ships get-docker.py for Debian-family Linux)
./get-docker.py # adds Docker's apt repo + installs docker-ce; adds you to the docker group
# 2. Put the launcher on your PATH, named `defoogi`
sudo make install # cp start /usr/local/bin/defoogi
# or manually: cp start ~/bin/defoogi && chmod +x ~/bin/defoogi
# 3. (first run pulls fozztexx/defoogi:latest automatically)To build the image yourself (reproducible from pins):
make # assembles + builds defoogi:1.4.6 and defoogi:latest
make rebuild # --no-cache --pull, full clean buildcd ~/my-fujinet-app
defoogi make # run the project's Makefile in-container
defoogi cc65 hello.c # invoke a single tool
defoogi cmoc program.c # 6809
defoogi zcc +cpm program.c # z88dk for CP/M
defoogi wcl -bcl=dos prog.c # Open Watcom for DOS
# Disk images:
defoogi atr disk.atr format ; defoogi atr disk.atr write prog.xex
defoogi cc1541 -f prog -w prog.prg disk.d64
defoogi ac -as disk.dsk PROG < prog.bin
# Interactive shells:
defoogi --shell # shell as `wario` (you), in your workspace
defoogi --super-shell # root shell (for poking at the image)Use the same image as a container step so CI builds bit-identically to local, then publish the artifact as a downloadable as set that FujiNet can mount over HTTP. The README's promised loop: edit → push → CI builds with defoogi → boot retro machin e → mount the build directly via FujiNet → run. No floppies, no SD-card sneakernet.
-
No /workspace directory foundwarning → you ran the raw container without thestart/defoogiwrapper; usedefoog i …(it sets-v $PWD:/workspaceandHOSTDIR). -
Artifacts owned by a system user → if
/workspaceis owned by a uid < 1000,cntnr-initdeliberately skips the remap and warns; run from a normally-owned directory. -
GUI tool won't display → ensure
$DISPLAYis set and~/.Xauthorityexists;startforwards both with--net=host. -
vasm/vbccnot found → expected; they're declared inversions.env/tailbut not built in this revision (see §4. 6).
Every pin in versions.env, with what it controls. defoogi tag at time of writing: 1.4.6.
versions.env key |
Value | Controls | Built by |
|---|---|---|---|
AC |
12.0 |
AppleCommander jars | applecommander.docker |
ATARISIO |
bbccb15 |
dir2atr (AtariSIO tools) | dir2atr.docker |
ATARITOOLS |
835d5a6 |
atr (atari-tools) |
atari-tools.docker |
ATASM |
V1.30 |
atasm assembler | dir2atr.docker |
CC1541 |
4.2 |
cc1541 (D64) | cc1541.docker |
CC65 |
6efe447 |
cc65 suite | cc65.docker |
CMOC |
0.1.97 |
CMOC 6809 compiler | cmoc.docker |
CPMTOOLS |
2.23 |
cpmtools (+ADAM diskdefs) | cpmtools.docker |
EOSLIB |
70d476b |
ADAM EOS lib (in z88dk) | z88dk.docker |
LWTOOLS |
4.24 |
lwasm/lwlink (for CMOC) | cmoc.docker |
MADSASM |
2370bf0 |
Mad-Assembler | mads.docker |
MADSPAS |
23e4c5f |
Mad-Pascal | mads.docker |
OW2 |
2025-08-02-Build |
Open Watcom v2 | open-watcom-v2.docker |
PICOSDK |
2.2.0 |
Pico SDK + picotool | pico-sdk.docker |
SMARTKEYS |
1.1 |
ADAM SmartKeys lib (in z88dk) | z88dk.docker |
TOOLSHED |
v2_4_2 |
decb (CoCo .dsk) |
cmoc.docker |
VASM |
2_0c |
(declared, not built) | — |
Z88DK |
4c74585 |
z88dk + SDCC | z88dk.docker |
NASM |
e9fac2f |
nasm | nasm.docker |
Not in versions.env (installed at latest): PlatformIO, abimap, mtools, default-jdk (Java), fpc, **SDCC
** (built within z88dk), cmake.
What the Makefile actually feeds to docker build (written to /tmp/defoogi.dockerfile), conceptually:
[ head.docker ] # FROM debian:13.0 AS tooling
[ cc65.docker ] # FROM tooling AS cc65 → /tmp/cc65.deb
[ cmoc.docker ] # FROM tooling AS cmoc → /tmp/cmoc.deb
[ z88dk.docker ] # …one stage per component, built in parallel
[ … every other component … ]
[ final.docker ] # FROM tooling (the final image; installs PlatformIO)
COPY --from=cc65 /tmp/cc65.deb /tmp/packages/ ← generated by sed
COPY --from=cmoc /tmp/cmoc.deb /tmp/packages/
COPY --from=… … (one COPY per component)
[ tail.docker ] # apt-get install /tmp/packages/*.deb; runtime tools;
# env vars; create `wario`; ENTRYPOINT cntnr-init
Build-args are injected from versions.env (AC=12.0 → --build-arg AC_VERSION=12.0), plus MAINTAINER and WSUSER.
defoogi itself
- defoogi repository:
github.com/tschak909/defoogi(analyzed locally at~/Workspace/defoogi, tag 1.4.6) - Docker Hub: https://hub.docker.com/repository/docker/fozztexx/defoogi
- FujiNet: https://fujinet.online
Toolchains
- cc65: https://cc65.github.io/ · Homebrew formula · [NESdev install guide](https:/ /www.nesdev.org/wiki/Installing_CC65)
- CMOC: https://perso.b2b2c.ca/~sarrazip/dev/cmoc.html · manual · lwtools on Windows/Cygwin
- lwtools: http://www.lwtools.ca/
- z88dk: https://www.z88dk.org/ · installation wiki · [nightly builds](h ttp://nightly.z88dk.org/)
- Open Watcom v2: https://www.openwatcom.org/ · [install.txt](https://github.com/open-watcom/open-watcom-v2/blob/master/buil d/server/install.txt) · https://open-watcom.github.io/
- MADS / Mad-Pascal: https://github.com/tebe6502/Mad-Assembler · https://github.com/tebe6502/Mad-Pascal
- atasm: https://github.com/CycoPH/atasm
- AtariSIO (dir2atr): https://github.com/HiassofT/AtariSIO
- atari-tools: https://github.com/jhallen/atari-tools
- cc1541: https://bitbucket.org/ptv_claus/cc1541
- AppleCommander: https://applecommander.github.io/ · releases · install (Java 11)
- cpmtools: https://www.moria.de/~michael/cpmtools/ · Homebrew
- mtools: https://www.gnu.org/software/mtools/
- nasm: https://www.nasm.us/ · Homebrew
- Toolshed (decb): https://github.com/nitros9project/toolshed
- eoslib / smartkeyslib: https://github.com/tschak909/eoslib · https://github.com/tschak909/smartkeyslib
- PlatformIO: https://platformio.org/
- Pico SDK / picotool: https://github.com/raspberrypi/pico-sdk · https://github.com/raspberrypi/picotool
Document generated for the FujiNet manuals project. Verified against defoogi v1.4.6 source. Where this manual lists upstrea m packaging behavior it reflects the state at June 2026; individual upstreams may change.
Copyright 2026 Contributors to the FujiNetWIFI project.
Join us on Discord: https://discord.gg/7MfFTvD
- Home
- What is FujiNet?
- The Definition of Done
- Board bring up for FujiNet Platform.IO code
- The Complete Linux CLI Guide
- The Complete macOS CLI Guide
- Development Env for Apps
- FujiNet-Development-Guidelines
- System Quickstarts
- FujiNet Flasher
- Setting up a TNFS Server
- FujiNet Configuration File: fnconfig.ini
- AppKey Registry - SIO Command $DC Open App Key
- CP-M Support
- BBS
- Official Hardware Versions
- Prototype Board Revisions
- FujiNet Development Guidelines
- Atari Programming
- Apple Programming
- C64 Programming
- ADAM Programming
- Testing Plan
- Hacker List
- FujiNet VirtualMachine