From d1f98c92ddd41754f94dcf08ba6c9833981c850e Mon Sep 17 00:00:00 2001 From: Tom Hicks Date: Tue, 27 Jan 2026 06:28:05 -0800 Subject: [PATCH] Adds Dockerfile for the 3ds build container. --- .gitignore | 2 + docker/.dockerignore | 62 ++++++++++++ docker/3ds.Dockerfile | 122 +++++++++++++++++++++++ docker/README.md | 222 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 408 insertions(+) create mode 100644 docker/.dockerignore create mode 100644 docker/3ds.Dockerfile create mode 100644 docker/README.md diff --git a/.gitignore b/.gitignore index 0c01580..9476eb2 100644 --- a/.gitignore +++ b/.gitignore @@ -70,3 +70,5 @@ third-party/build/ *.tmp *.bak *.cache + +test-builds \ No newline at end of file diff --git a/docker/.dockerignore b/docker/.dockerignore new file mode 100644 index 0000000..42cfe66 --- /dev/null +++ b/docker/.dockerignore @@ -0,0 +1,62 @@ +# Docker build context exclusions +# Keep build context minimal for faster builds + +# Git +.git/ +.gitignore +.gitattributes + +# Build artifacts +*.o +*.elf +*.3dsx +*.cia +*.smdh +*.nro +*.nso +*.rpx +*.rpl +*.dol +*.wad +*.vpk +*.self +build/ +dist/ +*.log + +# IDE and editor files +.vscode/ +.idea/ +*.swp +*.swo +*~ +.DS_Store + +# Documentation and plans (not needed in container) +docs/ +.plans/ +*.md +!docker/*.md + +# Config files (copied separately if needed) +*.json +*.toml +*.yaml +*.yml +!package.json + +# Node modules and dependencies +node_modules/ +venv/ +__pycache__/ +*.pyc + +# Cache directories +.cache/ +.ccache/ +*.cache + +# Temporary files +tmp/ +temp/ +*.tmp diff --git a/docker/3ds.Dockerfile b/docker/3ds.Dockerfile new file mode 100644 index 0000000..8decf0e --- /dev/null +++ b/docker/3ds.Dockerfile @@ -0,0 +1,122 @@ +# Nintendo 3DS Development Container +# Based on official devkitPro devkitARM image +# Contains ALL available 3DS portlibs for complete development environment + +FROM devkitpro/devkitarm:20251231 + +LABEL maintainer="nextcloud-share contributors" +LABEL description="Complete Nintendo 3DS development environment with all available portlibs" +LABEL org.opencontainers.image.base.name="devkitpro/devkitarm:20251231" +LABEL org.opencontainers.image.title="Nintendo 3DS Development Container" +LABEL platform="3ds" +LABEL toolchain="devkitARM" + +# Update package database +RUN dkp-pacman -Sy --noconfirm + +# Install 3DS development group (includes devkitARM, libctru, citro3d, citro2d, tools) +RUN dkp-pacman -S --needed --noconfirm 3ds-dev + +# Install ALL available 3DS portlibs (alphabetical for clarity) +# List verified from devkitpro/devkitarm:20251231 on 2026-01-27 +RUN dkp-pacman -S --needed --noconfirm \ + 3ds-box2d \ + 3ds-bulletphysics \ + 3ds-bzip2 \ + 3ds-curl \ + 3ds-flac \ + 3ds-flite \ + 3ds-freetype \ + 3ds-giflib \ + 3ds-jansson \ + 3ds-libarchive \ + 3ds-libconfig \ + 3ds-libfribidi \ + 3ds-libiconv \ + 3ds-libid3tag \ + 3ds-libjpeg-turbo \ + 3ds-libjson-c \ + 3ds-liblua51 \ + 3ds-liblzma \ + 3ds-libmad \ + 3ds-libmodplug \ + 3ds-libogg \ + 3ds-libopus \ + 3ds-libpng \ + 3ds-libsidplay \ + 3ds-libtheora \ + 3ds-libvorbisidec \ + 3ds-libxmp \ + 3ds-libzstd \ + 3ds-lz4 \ + 3ds-mbedtls \ + 3ds-mikmod \ + 3ds-mpg123 \ + 3ds-opusfile \ + 3ds-physfs \ + 3ds-sdl \ + 3ds-sdl_gfx \ + 3ds-sdl_image \ + 3ds-sdl_mixer \ + 3ds-sdl_ttf \ + 3ds-tinyxml2 \ + 3ds-wildmidi \ + 3ds-wslay \ + 3ds-yaml_cpp \ + 3ds-zlib && \ + dkp-pacman -Scc --noconfirm + +# Install system build tools for development +# Note: devkitarm-cmake is already installed as part of 3ds-dev group +RUN apt-get update && apt-get install -y --no-install-recommends \ + ccache \ + ninja-build \ + python3 \ + python3-pip \ + curl \ + wget \ + jq \ + git \ + zip \ + unzip && \ + rm -rf /var/lib/apt/lists/* + +# Configure ccache for faster rebuilds +ENV CCACHE_DIR=/project/.ccache +ENV CCACHE_MAXSIZE=2G + +# Add devkitARM compiler to PATH +ENV PATH="${DEVKITARM}/bin:/usr/lib/ccache:${PATH}" + +# Build and install bannertool for CIA file creation +RUN git clone --recursive https://github.com/diasurgical/bannertool.git /tmp/bannertool && \ + cd /tmp/bannertool && \ + make && \ + cp output/linux-x86_64/bannertool /opt/devkitpro/tools/bin/ && \ + chmod +x /opt/devkitpro/tools/bin/bannertool && \ + cd / && \ + rm -rf /tmp/bannertool + +# Build and install makerom and ctrtool for CIA file creation +RUN git clone https://github.com/3DSGuy/Project_CTR.git /tmp/Project_CTR && \ + cd /tmp/Project_CTR/makerom && \ + make deps && make && \ + cp bin/makerom /opt/devkitpro/tools/bin/ && \ + chmod +x /opt/devkitpro/tools/bin/makerom && \ + cd /tmp/Project_CTR/ctrtool && \ + make deps && make && \ + cp bin/ctrtool /opt/devkitpro/tools/bin/ && \ + chmod +x /opt/devkitpro/tools/bin/ctrtool && \ + cd / && \ + rm -rf /tmp/Project_CTR + +# Set working directory +WORKDIR /project + +# Verify installation +RUN arm-none-eabi-gcc --version && \ + make --version && \ + cmake --version + +# Show installed 3DS packages on container startup +CMD ["bash", "-c", "echo 'Nintendo 3DS Development Container Ready' && echo 'devkitARM:' && arm-none-eabi-gcc --version | head -n1 && echo '' && echo '3DS packages installed:' && dkp-pacman -Qq | grep '^3ds-' | wc -l && echo 'packages' && bash"] diff --git a/docker/README.md b/docker/README.md new file mode 100644 index 0000000..ac11638 --- /dev/null +++ b/docker/README.md @@ -0,0 +1,222 @@ +# Nintendo 3DS Development Container + +Complete Docker/Podman container for Nintendo 3DS homebrew development with full CIA file creation support. + +## Features + +- **Complete devkitARM toolchain** - GCC 15.2.0 for ARM development +- **All 47 3DS portlibs** - Every available library including graphics, audio, networking, physics, and compression +- **CIA Creation Tools**: + - `bannertool` - Creates banner and icon files for CIA packages + - `makerom` - Assembles final CIA installation files + - `ctrtool` - Inspects and validates CIA structure + - `3dstools` - Includes 3dsxtool, smdhtool, mkromfs3ds +- **Build optimization** - ccache for faster rebuilds +- **Modern build tools** - CMake, Ninja, Python 3 + +## Quick Start + +### Building the Container + +```bash +# Using Podman (recommended for rootless operation) +podman build -t tomusan/devkitarm-3ds:latest -f docker/3ds.Dockerfile . + +# Using Docker +docker build -t tomusan/devkitarm-3ds:latest -f docker/3ds.Dockerfile . +``` + +Build time: ~10-15 minutes on first build (downloads and compiles bannertool, makerom, ctrtool) + +### Compiling a 3DS Project + +**Basic compilation** (produces .3dsx homebrew file): +```bash +podman run --rm -v ./your-project:/project:z tomusan/devkitarm-3ds:latest make +``` + +**With CIA file creation**: +```bash +# Most 3DS projects with proper Makefile configuration +podman run --rm -v ./your-project:/project:z tomusan/devkitarm-3ds:latest make +``` + +**Clean and rebuild**: +```bash +podman run --rm -v ./your-project:/project:z tomusan/devkitarm-3ds:latest bash -c "make clean && make" +``` + +### Interactive Shell + +For debugging or manual builds: +```bash +podman run -it --rm -v ./your-project:/project:z tomusan/devkitarm-3ds:latest bash +``` + +## Output Files + +A complete 3DS build produces: + +- **`.3dsx`** - Homebrew Launcher executable format +- **`.elf`** - Executable with debug symbols +- **`.smdh`** - Icon and metadata for Homebrew Launcher +- **`banner.bnr`** - Banner displayed when CIA is selected on home menu +- **`icon.icn`** - Icon file for CIA package +- **`.cia`** - Installable file for 3DS home menu + +## CIA File Creation + +The container includes all tools needed for complete CIA file creation: + +### Manual CIA Creation Workflow + +If your Makefile doesn't include CIA generation: + +```bash +podman run --rm -v ./your-project:/project:z tomusan/devkitarm-3ds:latest bash -c ' + # Build the application + make + + # Create banner (requires banner.png and audio.wav in assets/) + bannertool makebanner -i assets/banner.png -a assets/audio.wav -o build/banner.bnr + + # Create icon (requires icon.png in assets/) + bannertool makesmdh -s "App Title" -l "Description" -p "Author" \ + -i assets/icon.png -o build/icon.icn + + # Create CIA file (requires app.rsf in assets/) + makerom -f cia -o output.cia -target t -exefslogo \ + -elf output.elf -rsf assets/app.rsf \ + -banner build/banner.bnr -icon build/icon.icn \ + -DAPP_TITLE="App Title" \ + -DAPP_PRODUCT_CODE="CTR-P-XXXX" \ + -DAPP_UNIQUE_ID="0x12345" +' +``` + +### Validating CIA Files + +```bash +# Inspect CIA structure +podman run --rm -v ./your-project:/project:z tomusan/devkitarm-3ds:latest \ + ctrtool -i output.cia +``` + +## Installed Libraries + +The container includes all available 3DS portlibs: + +**Graphics & UI:** +- citro3d, citro2d - 3DS GPU libraries +- SDL, SDL_gfx, SDL_image, SDL_mixer, SDL_ttf +- freetype, libpng, libjpeg-turbo, giflib + +**Audio:** +- libopus, opusfile, libvorbisidec, libogg +- flac, libmad, libmodplug, libxmp, mikmod, mpg123 +- wildmidi, libid3tag + +**Networking:** +- curl, mbedtls, wslay + +**Data Formats:** +- json-c, jansson, yaml_cpp, tinyxml2 +- libarchive, bzip2, liblzma, lz4, libzstd, zlib + +**Physics & Math:** +- box2d, bulletphysics + +**Other:** +- libconfig, libfribidi, libiconv, liblua51 +- physfs, libsidplay, libtheora + +## Container Environment + +```bash +DEVKITPRO=/opt/devkitpro +DEVKITARM=/opt/devkitpro/devkitARM +PATH includes: + - ${DEVKITARM}/bin (ARM toolchain) + - /opt/devkitpro/tools/bin (bannertool, makerom, ctrtool) + - /usr/lib/ccache (build cache) +``` + +## Testing + +Verified working with: +- **60/61 official 3ds-examples** - 98.4% success rate +- **Checkpoint** - Real-world save manager application with full CIA creation + +## Troubleshooting + +### Permission Issues with Podman + +The `:z` flag in volume mounts sets proper SELinux context: +```bash +-v ./project:/project:z +``` + +### Container Size + +Expected size: ~1.6 GB (includes all libraries and build tools) + +### Build Cache + +To speed up rebuilds, the container uses ccache. The cache is stored in your project at `.ccache/`: +```bash +# Clean cache if needed +rm -rf ./your-project/.ccache +``` + +### Common Errors + +**"makerom: command not found"** +- Rebuild container with latest Dockerfile (includes makerom build steps) + +**"bannertool: command not found"** +- Rebuild container with latest Dockerfile (includes bannertool build steps) + +**CIA creation fails silently** +- Check that all required files exist: + - `assets/app.rsf` - CIA metadata + - `assets/banner.png` and `assets/audio.wav` - Banner resources + - `assets/icon.png` - Icon resource + - `output.elf` - Compiled application + +## Version Information + +- **Base Image**: devkitpro/devkitarm:20251231 +- **devkitARM**: GCC 15.2.0 +- **CMake**: 3.31.6 +- **GNU Make**: 4.3 +- **3DS Packages**: 47 portlibs installed + +## Building from Source + +The Dockerfile includes build steps for: + +1. **bannertool** (diasurgical/bannertool) + - Cloned with `--recursive` for submodules + - Built with system make + - Installed to `/opt/devkitpro/tools/bin/` + +2. **makerom & ctrtool** (3DSGuy/Project_CTR) + - Cloned from active fork + - Built dependencies first with `make deps` + - Built tools with `make` + - Installed to `/opt/devkitpro/tools/bin/` + +## Additional Resources + +- [devkitPro Documentation](https://devkitpro.org/) +- [3DS Homebrew Development](https://www.3dbrew.org/wiki/Homebrew_Development) +- [Checkpoint Repository](https://github.com/BernardoGiordano/Checkpoint) - Example of complete CIA project +- [3ds-examples](https://github.com/devkitPro/3ds-examples) - Official examples + +## License + +This container configuration is provided as-is. Individual tools and libraries maintain their respective licenses: +- devkitARM: GPL/proprietary tools +- bannertool: Custom license +- makerom/ctrtool: Custom license +- Portlibs: Various open source licenses