# Docker Build Environment Plan for devkitARM **Issue**: #5 - Create Docker build environment for devkitARM **Branch**: `docker-for-devkitarm` **Status**: Planning **Last Updated**: 2026-01-27 --- ## Overview We need containerized build environments for multiple game console platforms (3DS, Switch, Wii U, etc.). Each container will extend the official devkitPro base image and install **ALL available platform-specific libraries and tools** from dkp-pacman. This ensures developers have a complete, batteries-included build environment without local toolchain installation. **Container Philosophy**: Install everything available for a platform (e.g., all `3ds-*` packages), not just what we need right now. This makes containers useful for other projects and ensures we don't need to rebuild when we need a new library. **Repository Strategy**: 1. **Phase 1 (This PR - Issue #5)**: Dockerfiles live in this repo, build locally only - No DockerHub account needed - No credentials to manage - Build containers once, use many times - Fast, reproducible local development 2. **Phase 2 (Before CI/Releases)**: Extract to separate repo, publish to DockerHub - After containers are tested and stable - Before setting up Gitea CI - Before first release and merge to main 3. **Phase 3 (Production)**: CI uses published images, local dev can use either - CI pulls pre-built images (fast) - Developers can pull OR build locally - Separate repo allows community contributions **Local Container Building**: Containers are built separately from project builds. Build once, use many times: ```bash # Build the 3DS container locally (one-time, or when Dockerfile changes) podman build -f docker/3ds.Dockerfile -t tomusan/devkitarm-3ds:20251231 . # Now use it for all project builds (fast) podman run --rm -v .:/project:z tomusan/devkitarm-3ds:20251231 make -C 3ds ``` The build scripts will check for local images first, then try DockerHub (Phase 2). This means: - Early development: Everyone builds containers locally - After publishing: New contributors can pull pre-built images - No DockerHub account needed until we're ready to publish **Why Delay Publishing?**: - ✅ Test containers thoroughly before making public - ✅ No rush to manage DockerHub accounts/credentials - ✅ Can iterate freely without versioning concerns - ✅ Extract to separate repo when containers are mature - ✅ Easier to set up CI with pre-published containers --- ## Goals 1. **Developer Convenience**: Zero local toolchain installation required 2. **Build Consistency**: Same environment everywhere (dev, CI, production) 3. **Maintainability**: Easy to update dependencies and toolchain versions 4. **Documentation**: Clear usage instructions for both podman and docker 5. **CI Integration**: Container works seamlessly in Gitea Actions --- ## Requirements ### Must Have - devkitARM toolchain (arm-none-eabi-gcc) - libctru (3DS system library) - citro3d and citro2d (3DS graphics libraries) - makerom (CIA package generation) - tex3ds (texture conversion) - bannertool (banner/icon creation) - CMake 3.15+ (for shared library builds) - git (for version control operations) ### Nice to Have - ccache (for faster rebuilds) - ninja (faster build system than make) - pkg-config (for library discovery) - Python 3 (for build scripts) - Debugging tools (gdb-multiarch) ### Build Outputs - `.3dsx` files (Homebrew Launcher format) - `.cia` files (installable format) - `.elf` files (debugging symbols) --- ## Approach Options ### Option 1: Use Official devkitPro Containers As-Is **Description**: Use `devkitpro/devkitarm:latest` directly without modification. **Pros**: - ✅ Officially maintained by devkitPro team - ✅ Always up-to-date with latest toolchain releases - ✅ Pre-configured with correct environment variables - ✅ Includes all standard libraries (libctru, citro3d, citro2d) - ✅ Zero maintenance burden on our part - ✅ Community support and documentation - ✅ Guaranteed compatibility with devkitARM ecosystem **Cons**: - ❌ Less control over installed packages - ❌ May include unnecessary tools (slight bloat) - ❌ Potential breaking changes with `:latest` tag - ❌ Limited customization options **When to Use**: - When you want the simplest, most maintainable solution - When you trust the devkitPro team's container decisions - For quick prototyping and initial development - When you don't need special tools or configurations **Implementation**: ```bash # In build scripts or CI podman run --rm \ -v $PWD:/project:z \ devkitpro/devkitarm:latest \ make -C /project/3ds ``` **Docker Commands**: ```bash # No Dockerfile needed - just pull and use podman pull devkitpro/devkitarm:latest # Build 3DS app podman run --rm -v ./:/project:z devkitpro/devkitarm:latest \ make -C /project/3ds # Interactive shell podman run --rm -it -v ./:/project:z devkitpro/devkitarm:latest bash ``` --- ### Option 2: Extend Official Container with `FROM` ⭐ CHOSEN **Description**: Create our own Dockerfile that extends `devkitpro/devkitarm` with additional tools and configuration. **Pros**: - ✅ Inherits all benefits of official image - ✅ Can add project-specific tools (ccache, ninja, etc.) - ✅ Can pre-install dependencies (curl, python, etc.) - ✅ Can set custom environment variables - ✅ Can create helper scripts and aliases - ✅ Version-controllable configuration - ✅ Still receives upstream updates (if we rebuild regularly) **Cons**: - ❌ Requires maintaining a Dockerfile - ❌ Needs periodic rebuilds to get upstream updates - ❌ Slightly slower CI (build time for our layer) - ❌ Can break if devkitPro changes base image significantly **When to Use**: - When you need additional tools beyond what devkitPro provides - When you want to optimize build times (ccache, pre-downloaded deps) - When you need custom scripts or configuration - When you want more control but still leverage official base **Implementation**: ```dockerfile # docker/devkitarm.Dockerfile FROM devkitpro/devkitarm:20240202 # Install additional build tools RUN dkp-pacman -Syu --noconfirm && \ dkp-pacman -S --needed --noconfirm \ devkitARM-cmake \ general-tools \ 3ds-dev && \ dkp-pacman -Scc --noconfirm # Install system tools RUN apt-get update && apt-get install -y --no-install-recommends \ ccache \ ninja-build \ python3 \ curl \ jq \ && rm -rf /var/lib/apt/lists/* # Configure ccache ENV CCACHE_DIR=/project/.ccache ENV PATH="/usr/lib/ccache:${PATH}" # Add helper scripts COPY scripts/container-helpers.sh /usr/local/bin/ WORKDIR /project ``` **Usage**: ```bash # Build our custom image podman build -f docker/devkitarm.Dockerfile -t nextcloud-share-3ds:latest . # Use it podman run --rm -v ./:/project:z nextcloud-share-3ds:latest \ make -C /project/3ds ``` --- ### Option 3: Build From Scratch **Description**: Create a completely custom Dockerfile starting from a base Linux image (Debian/Ubuntu) and manually install devkitARM. **Pros**: - ✅ Complete control over everything - ✅ Minimal image size (only what we need) - ✅ Deep understanding of all dependencies - ✅ Can optimize for CI performance - ✅ No surprises from upstream changes **Cons**: - ❌ **EXTREMELY HIGH MAINTENANCE** - we own all toolchain issues - ❌ Must manually track devkitARM releases and updates - ❌ Complex installation procedure (dkp-pacman setup) - ❌ Need to debug toolchain issues ourselves - ❌ Risk of misconfiguration breaking builds - ❌ Time-consuming initial setup - ❌ No community support for custom setup **When to Use**: - When you have very specific requirements the official image can't meet - When image size is absolutely critical - When you have deep expertise with devkitARM setup - **RARELY RECOMMENDED** - too much work for minimal benefit **Implementation Sketch**: ```dockerfile FROM debian:bookworm-slim # Install prerequisites RUN apt-get update && apt-get install -y \ wget curl gnupg2 bzip2 xz-utils make # Add devkitPro repository RUN wget https://apt.devkitpro.org/install-devkitpro-pacman && \ chmod +x install-devkitpro-pacman && \ ./install-devkitpro-pacman # Install devkitARM and libraries RUN dkp-pacman -Syu --noconfirm && \ dkp-pacman -S --needed --noconfirm \ devkitARM general-tools 3ds-dev # Set environment variables ENV DEVKITPRO=/opt/devkitpro ENV DEVKITARM=/opt/devkitpro/devkitARM # ... many more env vars needed ... # This approach is NOT RECOMMENDED unless you have very specific needs ``` --- ### Option 4: Fork Official Dockerfile Repository **Description**: Fork the devkitPro Docker repository and maintain our own version of their Dockerfiles. **Pros**: - ✅ Full source control - ✅ Can submit improvements upstream - ✅ Can cherry-pick updates from upstream - ✅ Complete flexibility **Cons**: - ❌ **HIGHEST MAINTENANCE BURDEN** - must track and merge upstream changes - ❌ Need to rebuild entire image on updates - ❌ Can diverge significantly from official builds - ❌ Requires git submodule or regular sync process - ❌ CI needs to build base image first (very slow) - ❌ Other developers need to understand fork workflow **When to Use**: - When you plan to contribute major improvements back to devkitPro - When you need significant changes that won't be accepted upstream - When you're building a commercial product needing LTS support - **NOT RECOMMENDED** for typical open-source homebrew projects **Implementation**: ```bash # Fork https://github.com/devkitPro/docker to our repo git clone https://github.com/devkitPro/docker.git devkitpro-docker cd devkitpro-docker # Make our changes vim devkitarm/Dockerfile # Build our forked version podman build -f devkitarm/Dockerfile -t nextcloud-share-devkitarm:latest . # Need to periodically merge upstream: git remote add upstream https://github.com/devkitPro/docker.git git fetch upstream git merge upstream/main ``` --- ## Comparison Matrix | Criteria | Option 1: Use Official | Option 2: Extend Official | Option 3: From Scratch | Option 4: Fork Official | |----------|----------------------|--------------------------|----------------------|------------------------| | **Setup Time** | ⭐⭐⭐⭐⭐ Instant | ⭐⭐⭐⭐ Minutes | ⭐ Hours | ⭐⭐ Days | | **Maintenance** | ⭐⭐⭐⭐⭐ None | ⭐⭐⭐⭐ Low | ⭐ Very High | ⭐ Very High | | **Customization** | ⭐⭐ Limited | ⭐⭐⭐⭐ High | ⭐⭐⭐⭐⭐ Complete | ⭐⭐⭐⭐⭐ Complete | | **Reliability** | ⭐⭐⭐⭐⭐ Official | ⭐⭐⭐⭐ Excellent | ⭐⭐ Self-support | ⭐⭐⭐ Self-support | | **CI Build Time** | ⭐⭐⭐⭐⭐ Fast (pull) | ⭐⭐⭐⭐ Fast (cache) | ⭐⭐ Slow (build all) | ⭐ Very Slow | | **Community Support** | ⭐⭐⭐⭐⭐ Full | ⭐⭐⭐⭐ Good | ⭐ None | ⭐⭐ Limited | | **Update Frequency** | ⭐⭐⭐⭐⭐ Automatic | ⭐⭐⭐⭐ Manual rebuild | ⭐⭐ Manual upgrade | ⭐⭐ Manual merge | --- ## Recommendation ### 🏆 Option 2: Extend Official Containers (Multi-Platform Strategy) **Decision**: We will use Option 2 (extend official containers) from the start because: 1. **Required 3rd Party Libraries**: We need libraries like libpng that are NOT included in the base devkitPro containers 2. **Multi-Platform Support**: We'll build containers for multiple platforms (3DS, Switch, Wii U, etc.) that other projects can reuse 3. **DockerHub Publishing**: We'll publish our containers to DockerHub for easy consumption 4. **Optimization Opportunities**: Can add ccache, build tools, and platform-specific dependencies 5. **Version Control**: Maintain Dockerfiles in our repo for reproducibility **Options 3 & 4 Rejected**: Both "from scratch" and "fork official" are too much work for too little benefit. We inherit upstream goodness with Option 2. **Version Pinning Strategy**: Pin to specific devkitPro image tags for stability: ```bash # Use date-based tags, not :latest devkitpro/devkitarm:20251231 # Latest stable as of Jan 2026 devkitpro/devkita64:20251231 # For Switch devkitpro/devkitppc:20251231 # For Wii/Wii U/GameCube ``` **Available Official Tags** (as of January 2026): - `devkitpro/devkitarm`: 20251231, 20251117, 20250728, 20250527, 20250512 (GBA/NDS/3DS) - `devkitpro/devkita64`: Available with similar date tags (Switch) - `devkitpro/devkitppc`: Available with similar date tags (Cube/Wii/Wii U) - All images support both linux/amd64 and linux/arm64 architectures --- ## Implementation Plan ### Phase 1: Local Container Development (This PR) **Goal**: Build and use containers locally for reproducible development. No DockerHub publishing yet. **Timeline**: Immediate - part of Issue #5 **Deliverables**: - Dockerfile for 3DS with ALL portlibs - Build scripts for container management - Build scripts for project compilation - Documentation for local workflow **Steps**: 1. **Create Dockerfile**: `docker/3ds.Dockerfile` ```dockerfile FROM devkitpro/devkitarm:20251231 LABEL maintainer="Tom Hicks" LABEL description="Complete Nintendo 3DS development environment with all available portlibs" LABEL base-image="devkitpro/devkitarm:20251231" # 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 CMake support for devkitARM RUN dkp-pacman -S --needed --noconfirm devkitARM-cmake # Install system build tools for development 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 ENV PATH="/usr/lib/ccache:${PATH}" # Set working directory WORKDIR /project # Verify installation RUN arm-none-eabi-gcc --version && \ make --version && \ cmake --version ``` **Note**: This installs EVERYTHING available for 3DS. Remove packages as needed if image size becomes an issue, but aim for completeness. The list above may need updating as devkitPro adds new portlibs. 2. **Verify package list**: Query official container for complete list ```bash # Test with official container to see all available 3ds packages podman run --rm devkitpro/devkitarm:20251231 \ dkp-pacman -Sl dkp-libs | grep '^dkp-libs 3ds-' ``` 3. **Create container build script**: `scripts/build-container.sh` - Accepts platform argument (3ds, switch, wiiu, etc.) - Builds container with appropriate tag - Shows success message with usage instructions 4. **Create project build wrapper**: `scripts/build-3ds.sh` - Checks if container exists locally - Shows helpful error if not built yet - Runs make inside container with volume mounts - Handles SELinux (`:z` flag) for Fedora/RHEL 5. **Create interactive shell script**: `scripts/container-shell.sh` - Launches bash inside container for debugging - Same volume mounts as build script 6. **Document workflow**: `docker/README.md` - Building containers locally - Using containers for development - Container contents and architecture - Troubleshooting common issues 7. **Update main README**: Add "Quick Start" section - Step 1: Build container (one-time) - Step 2: Build project (fast, repeatable) - Note about build times 8. **Test complete workflow**: - Build 3DS container locally (~10-15 min first time) - Verify all portlibs installed - Create minimal 3DS project structure - Test compilation works - Test incremental builds are fast **Key Benefits of Phase 1**: - ✅ No DockerHub account needed - ✅ No credentials to manage - ✅ Reproducible builds immediately - ✅ Fast iteration after initial build - ✅ Can test containers thoroughly before publishing --- ### Phase 2: Extract and Publish (Before CI/Release) **Goal**: Separate containers into independent repo and publish to DockerHub. **Timeline**: Before setting up CI and before first release/merge to main **Prerequisites**: - Containers tested and working locally - At least 3DS container fully functional - Documentation complete and accurate **Steps**: 1. **Create new repository**: `tomusan/homebrew-devkit-containers` - Move entire `docker/` directory - Move container-related scripts - Add README for the containers project - Add LICENSE (MIT, same as this project) 2. **Set up DockerHub repositories**: - Create `tomusan/devkitarm-3ds` - Create repos for other platforms as they're ready - Configure automated builds (optional) 3. **Add CI to containers repo**: - GitHub Actions or Gitea Actions - Build on Dockerfile changes - Tag with base image date and semver - Push to DockerHub on tags 4. **Update this project**: - Update build scripts to try DockerHub first - Fallback to local build if pull fails - Update documentation to reference published images - Add note about building locally as alternative 5. **Publish initial versions**: - Tag containers as `20251231-v1.0.0` - Push to DockerHub - Verify pulls work **Updated Build Script Logic** (Phase 2): ```bash # Try to use existing local image if $CONTAINER_RUNTIME image exists "$CONTAINER_IMAGE"; then echo "Using local container image" # Try to pull from DockerHub elif $CONTAINER_RUNTIME pull "$CONTAINER_IMAGE" 2>/dev/null; then echo "✅ Pulled container from DockerHub" # Give helpful error else echo "❌ Container not found locally or on DockerHub" echo "Build it locally: ./scripts/build-container.sh 3ds" exit 1 fi ``` **Migration Path**: - Old workflow (Phase 1): Works exactly as before with local builds - New workflow (Phase 2): Pull pre-built images or build locally - CI: Always pulls from DockerHub for speed --- ### Phase 3: Additional Platforms (Parallel to Phase 2) **Goal**: Create containers for all planned platforms. **Timeline**: Can be done alongside Phase 2, per-platform as needed Create similar Dockerfiles for other platforms. Each installs ALL available portlibs for that platform: 1. **`docker/switch.Dockerfile`** - Based on `devkitpro/devkita64:20251231` - Install `switch-dev` group - Install ALL `switch-*` portlibs (switch-libpng, switch-curl, etc.) - Build locally, optionally publish to: `tomusan/devkita64-switch` 2. **`docker/wiiu.Dockerfile`** - Based on `devkitpro/devkitppc:20251231` - Install `wiiu-dev` group - Install ALL `wiiu-*` and `wut-*` portlibs - Build locally, optionally publish to: `tomusan/devkitppc-wiiu` 3. **`docker/wii.Dockerfile`** - Based on `devkitpro/devkitppc:20251231` - Install `wii-dev` group - Install ALL `wii-*` and `ppc-*` portlibs - Build locally, optionally publish to: `tomusan/devkitppc-wii` 4. **`docker/nds.Dockerfile`** - Based on `devkitpro/devkitarm:20251231` - Install `nds-dev` group - Install ALL `nds-*` portlibs - Build locally, optionally publish to: `tomusan/devkitarm-nds` 5. **`docker/gba.Dockerfile`** - Based on `devkitpro/devkitarm:20251231` - Install `gba-dev` group - Install ALL `gba-*` portlibs - Build locally, optionally publish to: `tomusan/devkitarm-gba` **Note**: Other projects can use these Dockerfiles even before publishing to DockerHub. Just copy the Dockerfile and build locally! --- ## Testing Strategy ### Local Testing Checklist - [ ] Pull/build container successfully - [ ] Create minimal 3DS project structure - [ ] Compile a "Hello World" 3DS app - [ ] Generate `.3dsx` file - [ ] Generate `.cia` file - [ ] Verify files work on hardware/emulator - [ ] Test volume mounting (source accessible inside container) - [ ] Test with both podman and docker - [ ] Verify on Linux (primary development platform) - [ ] Test on macOS (if available) - [ ] Document any platform-specific quirks ### CI Testing Checklist - [ ] Container pulls successfully in Gitea Actions - [ ] Builds complete without errors - [ ] Build artifacts uploaded correctly - [ ] Build time is reasonable (< 5 minutes for clean build) - [ ] Cached builds are faster (< 1 minute for incremental) --- ## Environment Variables The devkitPro official container sets these automatically: ```bash DEVKITPRO=/opt/devkitpro DEVKITARM=/opt/devkitpro/devkitARM PATH=$DEVKITARM/bin:$DEVKITPRO/tools/bin:$PATH ``` Our scripts should **not** override these unless necessary. --- ## File Structure ``` nextcloud-share/ ├── docker/ │ ├── README.md # Container usage and publishing docs │ ├── 3ds.Dockerfile # 3DS build container (devkitARM) │ ├── switch.Dockerfile # (Phase 2) Switch container (devkitA64) │ ├── wiiu.Dockerfile # (Phase 2) Wii U container (devkitPPC) │ ├── wii.Dockerfile # (Phase 2) Wii container (devkitPPC) │ ├── nds.Dockerfile # (Phase 2) NDS container (devkitARM) │ ├── gba.Dockerfile # (Phase 2) GBA container (devkitARM) │ └── .dockerignore # Files to exclude from build context ├── scripts/ │ ├── build-3ds.sh # Wrapper for 3DS builds │ ├── build-image.sh # Build and optionally push container │ ├── container-shell.sh # Launch interactive dev shell │ └── publish-images.sh # Push containers to DockerHub └── 3ds/ ├── Makefile # devkitARM build configuration └── src/ # 3DS source code ``` --- --- ## DockerHub Naming Strategy ### Option A: Generic Platform Names (RECOMMENDED) Name containers after the platform, not the project: - `tomusan/devkitarm-3ds` - Nintendo 3DS - `tomusan/devkita64-switch` - Nintendo Switch - `tomusan/devkitppc-wiiu` - Wii U - `tomusan/devkitppc-wii` - Wii - `tomusan/devkitarm-nds` - Nintendo DS - `tomusan/devkitarm-gba` - Game Boy Advance **Pros**: - ✅ Reusable by other projects - ✅ Clear what toolchain and platform - ✅ Easy to migrate to separate repo later - ✅ Follows naming pattern: `/-` ### Option B: Project-Specific Names - `tomusan/nextcloud-share-3ds` - `tomusan/nextcloud-share-switch` **Pros**: - ✅ Clear ownership - ✅ Can add project-specific customization **Cons**: - ❌ Less discoverable for other projects - ❌ Suggests containers are project-specific ### Option C: Organization Account - `homebrew-containers/3ds` - `homebrew-containers/switch` **Pros**: - ✅ Professional appearance - ✅ Shared ownership - ✅ Best for community adoption **Cons**: - ❌ Requires creating organization - ❌ Overkill for initial version **DECISION: Start with Option A** (`tomusan/devkitarm-3ds`), migrate to Option C when we extract to separate repo. --- ## Image Tagging Strategy Use semantic versioning with base image date for traceability: ### Tag Format: `` and `-v` **Primary Tags**: - `20251231` - Based on devkitpro/devkitarm:20251231, latest rebuild - `20251231-v1.0.0` - Specific container version with that base - `latest` - Always points to newest base with latest rebuild **Examples**: ```bash # User wants latest everything podman pull tomusan/devkitarm-3ds:latest # User wants specific base for reproducibility podman pull tomusan/devkitarm-3ds:20251231 # User wants exact container version (most reproducible) podman pull tomusan/devkitarm-3ds:20251231-v1.0.0 ``` **Version Bumping**: - **Patch** (v1.0.1): Add/update documentation, minor script fixes - **Minor** (v1.1.0): Add new packages, optimization improvements - **Major** (v2.0.0): Change base image date, breaking changes **When Base Image Updates**: ```bash # Old stable version remains available tomusan/devkitarm-3ds:20251231-v1.2.0 # New major version with updated base tomusan/devkitarm-3ds:20260315-v2.0.0 tomusan/devkitarm-3ds:20260315 # Points to v2.0.0 tomusan/devkitarm-3ds:latest # Points to v2.0.0 ``` --- ## Open Questions 1. **Container Runtime**: Prefer podman or docker in documentation? - **Recommendation**: Document podman first (rootless), mention docker compatibility - **Decision**: Detect with `${CONTAINER_RUNTIME:-podman}` in scripts 2. **Separate Repo Name**: What to call the extracted containers repo? - **Options**: `homebrew-devkit-containers`, `devkitpro-extended`, `console-dev-containers` - **Recommendation**: `homebrew-devkit-containers` - clear and descriptive 3. **DockerHub Organization**: Create organization or use personal account? - **Phase 1**: Use personal account (`tomusan/devkitarm-3ds`) - **Phase 2**: Optionally migrate to organization (`homebrew-containers/3ds`) - **Decision**: Start personal, evaluate if organization needed later 4. **CI Platform for Containers Repo**: GitHub Actions or Gitea Actions? - **Recommendation**: GitHub Actions (better DockerHub integration, free for public repos) - **Alternative**: Gitea Actions if staying fully self-hosted 5. **Windows Support**: Should we test with Docker Desktop on Windows? - **Recommendation**: Best-effort support, primarily target Linux/macOS - **Recommendation**: Yes, on release tags. Manual push for development builds. 6. **Windows Support**: Should we test with Docker Desktop on Windows? - **Recommendation**: Best-effort support, primarily target Linux --- ## Success Criteria ### Phase 1 Complete (Issue #5) When: - ✅ `docker/3ds.Dockerfile` created with ALL 3DS portlibs - ✅ `scripts/build-container.sh` can build containers locally - ✅ `scripts/build-3ds.sh` builds project using container - ✅ `scripts/container-shell.sh` provides interactive debugging - ✅ `docker/README.md` documents local workflow - ✅ Main README has "Quick Start" section - ✅ Can build 3DS apps without local devkitARM install - ✅ Works with both podman and docker - ✅ SELinux volume mounting (`:z`) handled correctly - ✅ Build artifacts (`.3dsx`, `.cia`) generate correctly - ✅ Incremental builds are fast (< 2 minutes) ### Phase 2 Complete When: - ✅ Separate `homebrew-devkit-containers` repository created - ✅ Containers published to DockerHub - ✅ CI in containers repo builds and publishes automatically - ✅ This project's build scripts try DockerHub first - ✅ Documentation updated with published image references - ✅ Version tags follow semver + base image date ### Phase 3 Complete When: - ✅ All planned platform containers created (Switch, Wii U, Wii, NDS, GBA) - ✅ Each platform has comprehensive portlib installation - ✅ Build scripts support all platforms - ✅ Documentation covers all platforms --- ## DevkitPro Portlibs Research The devkitPro ecosystem uses **pacman** to distribute "portlibs" - pre-compiled libraries for each platform. **Available via `dkp-pacman`**: - Search packages: `dkp-pacman -Ss ` - List all packages: `dkp-pacman -Sl dkp-libs` - Install package: `dkp-pacman -S 3ds-libpng` --- ### Nintendo 3DS Portlibs (devkitARM) **Total: 46 portlibs** (verified from devkitpro/devkitarm:20251231) **3DS Portlibs** (Verified list from devkitpro/devkitarm:20251231): - `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` **Notable packages**: - `3ds-cmake` - CMake toolchain files (installed separately with devkitARM-cmake) - `3ds-examples` - Example projects (optional, not installed in container) - `3ds-pkg-config` - pkg-config tool (optional) **For Our Project**: - ✅ `3ds-curl` - HTTP/HTTPS client for WebDAV - ✅ `3ds-mbedtls` - TLS/SSL support - ✅ `3ds-tinyxml2` - XML parsing for PROPFIND responses - ✅ `3ds-libpng` - Image support (icons, UI) - ✅ `3ds-zlib` - Compression (dependency of many libs) - ✅ `3ds-libjson-c` or `3ds-jansson` - JSON parsing (alternative to nlohmann header-only) - ❓ nlohmann/json - Can still use header-only version if preferred **Note**: We install ALL available portlibs (46 packages), not just what we need. This makes the container useful for any 3DS project. --- ### Nintendo Switch Portlibs (devkitA64) **Total: 77 portlibs** (verified from devkitpro/devkita64:20251231) **Complete list**: - `switch-box2d`, `switch-bulletphysics`, `switch-bzip2`, `switch-curl` - `switch-dav1d`, `switch-enet`, `switch-ffmpeg`, `switch-flac` - `switch-freetype`, `switch-giflib`, `switch-glad`, `switch-glfw` - `switch-glm`, `switch-harfbuzz`, `switch-jansson`, `switch-libarchive` - `switch-libass`, `switch-libavif`, `switch-libconfig`, `switch-libdrm_nouveau` - `switch-libexpat`, `switch-libfribidi`, `switch-libgd`, `switch-libjpeg-turbo` - `switch-libjson-c`, `switch-liblua51`, `switch-liblzma`, `switch-liblzo2` - `switch-libmad`, `switch-libmikmod`, `switch-libmodplug`, `switch-libmpv` - `switch-libogg`, `switch-libopus`, `switch-libpcre2`, `switch-libplacebo` - `switch-libpng`, `switch-libsamplerate`, `switch-libsodium`, `switch-libssh2` - `switch-libtheora`, `switch-libtimidity`, `switch-libvorbis`, `switch-libvorbisidec` - `switch-libvpx`, `switch-libwebp`, `switch-libxml2`, `switch-libzstd` - `switch-lwext4`, `switch-lz4`, `switch-mbedtls`, `switch-mesa` - `switch-miniupnpc`, `switch-mpg123`, `switch-mupdf`, `switch-ntfs-3g` - `switch-ode`, `switch-oniguruma`, `switch-openal-soft`, `switch-opusfile` - `switch-physfs`, `switch-sdl2`, `switch-sdl2_gfx`, `switch-sdl2_image` - `switch-sdl2_mixer`, `switch-sdl2_net`, `switch-sdl2_ttf`, `switch-smpeg2` - `switch-tinyxml2`, `switch-wslay`, `switch-xxhash`, `switch-zlib`, `switch-zziplib` **Notable packages**: - `switch-cmake` - CMake toolchain files (installed separately) - `switch-examples` - Example projects (optional) - `switch-pkg-config` - pkg-config tool - `switch-mesa` - OpenGL/graphics (Switch has better GPU support than 3DS) - `switch-ffmpeg` - Full video codec support - `switch-glfw`, `switch-glad` - Modern OpenGL support - `switch-ntfs-3g` - NTFS filesystem support **For Our Project**: - ✅ `switch-curl` - HTTP/HTTPS client - ✅ `switch-mbedtls` - TLS/SSL - ✅ `switch-tinyxml2` or `switch-libxml2` - XML parsing - ✅ `switch-libpng` - Image support - ✅ `switch-zlib` - Compression - ✅ `switch-libjson-c` or `switch-jansson` - JSON parsing --- ### Wii U Portlibs (devkitPPC) **Total: 10 portlibs** (verified from devkitpro/devkitppc:20251231) **Complete list**: - `wiiu-curl` - HTTP/HTTPS client - `wiiu-mbedtls` - TLS/SSL support - `wiiu-physfs` - Filesystem abstraction - `wiiu-sdl2` - SDL2 library - `wiiu-sdl2_gfx` - SDL2 graphics primitives - `wiiu-sdl2_image` - SDL2 image loading - `wiiu-sdl2_mixer` - SDL2 audio mixing - `wiiu-sdl2_ttf` - SDL2 TrueType fonts **Notable packages**: - `wiiu-cmake` - CMake toolchain files - `wiiu-pkg-config` - pkg-config tool **For Our Project**: - ✅ `wiiu-curl` - HTTP/HTTPS client - ✅ `wiiu-mbedtls` - TLS/SSL - ⚠️ `wiiu-sdl2_image` - Can load PNG via SDL2 - ❌ No XML library available (need to investigate alternatives) - ❌ No JSON library (need to add or use header-only) **Note**: Wii U has significantly fewer portlibs than 3DS or Switch. May need to add more libraries to our container or use alternatives. --- ### Wii Portlibs (devkitPPC) **Total: 17 portlibs** (verified from devkitpro/devkitppc:20251231) **Complete list**: - `wii-freeglut` - OpenGL utility toolkit - `wii-glu` - OpenGL utility library - `wii-opengx` - OpenGL implementation for Wii - `wii-physfs` - Filesystem abstraction - `wii-sdl` - SDL 1.2 library - `wii-sdl2` - SDL2 library - `wii-sdl2_gfx` - SDL2 graphics primitives - `wii-sdl2_image` - SDL2 image loading - `wii-sdl2_mixer` - SDL2 audio mixing - `wii-sdl2_ttf` - SDL2 TrueType fonts - `wii-sdl_gfx` - SDL 1.2 graphics primitives - `wii-sdl_image` - SDL 1.2 image loading - `wii-sdl_mixer` - SDL 1.2 audio mixing - `wii-sdl_ttf` - SDL 1.2 TrueType fonts **Notable packages**: - `wii-cmake` - CMake toolchain files - `wii-examples` - Example projects - `wii-pkg-config` - pkg-config tool **For Our Project**: - ❌ No curl or HTTP library - ❌ No mbedtls or TLS support - ⚠️ `wii-sdl2_image` - Can load PNG via SDL2 - ❌ No XML library - ❌ No JSON library **Note**: Wii has even fewer networking/utility libraries than Wii U. Will likely need significant additional library building for network functionality. --- ### GameCube Portlibs (devkitPPC) **Total: 17 portlibs** (verified from devkitpro/devkitppc:20251231) **Complete list**: - `gamecube-freeglut` - OpenGL utility toolkit - `gamecube-glu` - OpenGL utility library - `gamecube-opengx` - OpenGL implementation for GameCube - `gamecube-physfs` - Filesystem abstraction - `gamecube-sdl` - SDL 1.2 library - `gamecube-sdl2` - SDL2 library - `gamecube-sdl2_gfx` - SDL2 graphics primitives - `gamecube-sdl2_image` - SDL2 image loading - `gamecube-sdl2_mixer` - SDL2 audio mixing - `gamecube-sdl2_ttf` - SDL2 TrueType fonts - `gamecube-sdl_gfx` - SDL 1.2 graphics primitives - `gamecube-sdl_image` - SDL 1.2 image loading - `gamecube-sdl_mixer` - SDL 1.2 audio mixing - `gamecube-sdl_ttf` - SDL 1.2 TrueType fonts **Notable packages**: - `gamecube-cmake` - CMake toolchain files - `gamecube-examples` - Example projects - `gamecube-pkg-config` - pkg-config tool - `ogc-cmake` - Legacy OGC (libogc) CMake support **For Our Project**: - ❌ No curl or HTTP library (no network adapter support in most GameCubes) - ❌ No mbedtls or TLS support - ⚠️ `gamecube-sdl2_image` - Can load PNG via SDL2 - ❌ No XML library - ❌ No JSON library **Note**: GameCube has identical library support to Wii (both use libogc). Networking was rare on GameCube (broadband adapter required), so no network libraries. --- ### NDS (Nintendo DS) Portlibs (devkitARM) **Total: 9 portlibs** (verified from devkitpro/devkitarm:20251231) **Complete list**: - `nds-bzip2` - Compression library - `nds-freetype` - TrueType font rendering - `nds-libexpat` - XML parser - `nds-libmad` - MP3 audio decoder - `nds-libpng` - PNG image support - `nds-zlib` - Compression library **Notable packages**: - `nds-cmake` - CMake toolchain files - `nds-examples` - Example projects - `nds-pkg-config` - pkg-config tool **For Our Project**: - ❌ No curl or HTTP library - ❌ No mbedtls or TLS support - ✅ `nds-libexpat` - XML parsing - ✅ `nds-libpng` - Image support - ✅ `nds-zlib` - Compression - ❌ No JSON library (need to add or use header-only) **Note**: NDS has basic library support. No networking libraries (Wi-Fi support was limited on original DS hardware). --- ### GBA (Game Boy Advance) Portlibs (devkitARM) **Total: 0 portlibs** (verified from devkitpro/devkitarm:20251231) **Notable packages**: - `gba-cmake` - CMake toolchain files - `gba-examples` - Example projects - `gba-pkg-config` - pkg-config tool **For Our Project**: - ❌ No portlibs available at all - ❌ Will need to compile all libraries from source **Note**: GBA has NO portlibs. This is expected - GBA has very limited hardware (16 MHz ARM7TDMI, 256 KB RAM). Most GBA projects use custom/embedded libraries optimized for the hardware constraints. --- ## Platform Summary | Platform | Toolchain | Container | Portlibs | Network | Graphics | Priority | |----------|-----------|-----------|----------|---------|----------|----------| | **3DS** | devkitARM | devkitpro/devkitarm | 46 | ✅ curl, mbedtls | SDL, citro3d | **HIGH** | | **Switch** | devkitA64 | devkitpro/devkita64 | 77 | ✅ curl, mbedtls | SDL2, OpenGL | **HIGH** | | **Wii U** | devkitPPC | devkitpro/devkitppc | 10 | ✅ curl, mbedtls | SDL2 | **HIGH** | | **Wii** | devkitPPC | devkitpro/devkitppc | 17 | ❌ None | SDL 1.2/2.0, OpenGL | **MEDIUM** | | **GameCube** | devkitPPC | devkitpro/devkitppc | 17 | ❌ None | SDL 1.2/2.0, OpenGL | **LOW** | | **NDS** | devkitARM | devkitpro/devkitarm | 9 | ⚠️ Wi-Fi only | Basic 2D/3D | **UNSUPPORTED** | | **GBA** | devkitARM | devkitpro/devkitarm | 0 | ❌ None | Basic 2D | **UNSUPPORTED** | **Notes**: - **Wii U**: Has plugins available for screenshots and camera photos. Priority platform for this project. - **NDS/NDSi**: Could theoretically upload photos or files from SD card (NDSi has cameras), but no native screenshot support. Containers will be built for potential future use, but not supported in this project. - **GBA**: No network connectivity and no screenshot capability. Container will be built for completeness, but not supported in this project. - **Wii/GameCube**: No networking capabilities in most units. May consider for local file transfer in future. **Recommendations**: - **Phase 1 (Issue #5)**: Focus on **3DS** only (our current project target - has networking and screenshot capability) - **Phase 3a**: Add **Switch** (best library ecosystem, modern platform, network + screenshots) - **Phase 3b**: Add **Wii U** (has plugins for screenshots and camera, network capable) - **Unsupported in this project**: NDS/NDSi (could upload SD card files/photos but no game screenshots), GBA (no network) - **Future consideration**: Wii/GameCube (no networking, but may support local file transfer later) **Container Build Strategy**: - All platforms will have Dockerfiles and build scripts in the extracted repo - This allows community members to use containers for any devkitPro platform - This project (nextcloud-share) only officially supports 3DS, Switch, and Wii U --- ## References - [devkitPro Docker Hub](https://hub.docker.com/u/devkitpro) - Official container images - [devkitPro Docker Images (GitHub)](https://github.com/devkitPro/docker) - Dockerfile source - [devkitPro Getting Started](https://devkitpro.org/wiki/Getting_Started) - [devkitPro pacman](https://devkitpro.org/wiki/devkitPro_pacman) - Package management - [3DS Development Guide](https://devkitpro.org/wiki/3DS_Development) - [libctru Documentation](https://libctru.devkitpro.org/) - 3DS system library API --- ## Notes - SELinux systems (like Fedora) require `:z` flag on volume mounts: `-v ./:/project:z` - Container runs as root by default, but files are created with host UID due to volume mount - podman is rootless by default, docker typically requires sudo (unless in docker group) - Official containers are multi-arch (amd64, arm64) - works on both x86 and ARM host