Files
nextcloud-share/docker

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

The easiest way to use these containers is with the provided helper scripts:

1. Build the container:

./scripts/build-container.sh 3ds

2. Open interactive shell:

# Current directory
./scripts/container-shell.sh

# Specific project
./scripts/container-shell.sh ~/my-3ds-game

# With additional volumes or environment
./scripts/container-shell.sh ~/my-game -v /data:/data:z -e DEBUG=1

Manual Container Usage

If you prefer to use podman/docker commands directly:

Building the Container:

# 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):

podman run --rm -v ./your-project:/project:z tomusan/devkitarm-3ds:latest make

With CIA file creation:

# Most 3DS projects with proper Makefile configuration
podman run --rm -v ./your-project:/project:z tomusan/devkitarm-3ds:latest make

Clean and rebuild:

podman run --rm -v ./your-project:/project:z tomusan/devkitarm-3ds:latest bash -c "make clean && make"

Interactive Shell:

For debugging or manual builds:

podman run -it --rm -v ./your-project:/project:z tomusan/devkitarm-3ds:latest bash

Helper Scripts

build-container.sh

Builds and tags development containers with automatic runtime detection (podman/docker).

Usage:

./scripts/build-container.sh <platform> [version]

Examples:

# Build with default version (0.1.0)
./scripts/build-container.sh 3ds

# Build with custom version
./scripts/build-container.sh 3ds 0.2.0

# Show help
./scripts/build-container.sh --help

Features:

  • Auto-detects podman/docker runtime
  • Validates semantic versioning (X.Y.Z format)
  • Tags both version and latest
  • Colored output with build status
  • Shows usage examples after successful build

Environment Variables:

  • CONTAINER_RUNTIME - Override runtime (podman or docker)

container-shell.sh

Opens an interactive bash shell in the development container with your project mounted.

Usage:

./scripts/container-shell.sh [project-path] [podman-args...]

Examples:

# Shell in current directory
./scripts/container-shell.sh

# Shell in specific project
./scripts/container-shell.sh ~/my-3ds-game

# With additional volume mount
./scripts/container-shell.sh ~/my-game -v /data:/data:z

# With environment variable
./scripts/container-shell.sh ~/my-game -e DEBUG=1

# Multiple extra arguments
./scripts/container-shell.sh ~/my-game -v /data:/data:z -e DEBUG=1 --network=host

Features:

  • First argument = project path (defaults to current directory)
  • All additional arguments passed to podman/docker run
  • Auto-detects podman/docker runtime
  • Colored output with container information
  • Project mounted at /project with working directory set

Environment Variables:

  • CONTAINER_RUNTIME - Override runtime (podman or docker)

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:

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

# 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

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:

-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/:

# 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

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