Skip to content

Refactor build system to use out-of-tree builds #115

@nchapman

Description

@nchapman

Problem

The current build system violates best practices by building components in-place within source directories. This causes several issues:

  1. Toolchain changes leave stale artifacts - When switching GCC versions (e.g., GCC 13→10 for TG5050), old .o files persist and cause linking errors
  2. make clean is fragile - Must enumerate every possible build artifact location (currently 615+ .o files across platform directories)
  3. Source pollution - Build artifacts mixed with source files in workspace/*/other/, workspace/*/lib*/
  4. Cross-platform conflicts - Different platforms building in same directories

Current Anti-pattern

workspace/tg5050/other/DinguxCommander-sdl2/
├── src/
│   ├── dialog.cpp
│   ├── dialog.o          ❌ Build artifact in source
│   └── main.o            ❌ Pollutes source tree
└── DinguxCommander       ❌ Binary in source directory

Impact

  • Had to manually delete 615+ .o files when implementing TG5050 GCC 10.3 toolchain
  • make clean was ineffective, requiring find commands to locate artifacts
  • Easy to miss artifacts when adding new platforms/components

Proposed Solution

Implement out-of-tree builds where all build artifacts go into separate build/ tree:

build/
├── tg5050/
│   ├── intermediate/              # All .o files, temp builds
│   │   ├── launcher/
│   │   ├── player/
│   │   ├── DinguxCommander/
│   │   └── libmsettings/
│   └── SYSTEM/                    # Final outputs
│       └── bin/
└── miyoomini/
    └── intermediate/

Benefits:

  • make clean becomes: rm -rf ./build
  • Source directories stay clean
  • No toolchain artifact conflicts
  • Standard practice for build systems

Implementation Options

Option 1: Fix Platform Component Makefiles

Modify DinguxCommander, libmsettings, etc. makefiles to use BUILD_DIR variable and output to separate directories.

Pros: Proper solution, follows best practices
Cons: Requires maintaining patches for third-party components

Option 2: Docker Ephemeral Builds

Use Docker container filesystem as build scratch space, only copy final outputs to host.

Pros: Automatic cleanup, leverages existing Docker infrastructure
Cons: Requires refactoring build scripts

Option 3: Wrapper Makefiles

Create wrapper makefiles that intercept build and redirect outputs.

Pros: Minimal changes to third-party code
Cons: Additional complexity layer

Current Workaround

Temporary fix applied: Enhanced make clean to aggressively find/delete all .o, .elf files in workspace.

This is a band-aid solution that works but doesn't address root cause.

Acceptance Criteria

  • All build artifacts go into build/ directory tree
  • make clean is a single rm -rf ./build command
  • Source directories contain zero build artifacts
  • Works for all platforms (miyoomini, tg5050, etc.)
  • Documented in build system docs

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions