summaryrefslogtreecommitdiff
path: root/archived/projt-launcher/docs/BUILD_SYSTEM.md
diff options
context:
space:
mode:
Diffstat (limited to 'archived/projt-launcher/docs/BUILD_SYSTEM.md')
-rw-r--r--archived/projt-launcher/docs/BUILD_SYSTEM.md996
1 files changed, 996 insertions, 0 deletions
diff --git a/archived/projt-launcher/docs/BUILD_SYSTEM.md b/archived/projt-launcher/docs/BUILD_SYSTEM.md
new file mode 100644
index 0000000000..7003e272ab
--- /dev/null
+++ b/archived/projt-launcher/docs/BUILD_SYSTEM.md
@@ -0,0 +1,996 @@
+# ProjT Launcher — Build System Documentation
+
+> **Version:** 0.0.5-1
+> **Build System:** GNU Make + Kconfig
+> **Last Updated:** 2026-02-07
+
+---
+
+## Table of Contents
+
+1. [Architecture Overview](#1-architecture-overview)
+2. [Quick Start](#2-quick-start)
+3. [Directory Layout](#3-directory-layout)
+4. [Makefile Include Graph](#4-makefile-include-graph)
+5. [Build Phases](#5-build-phases)
+6. [Configuration System (Kconfig)](#6-configuration-system-kconfig)
+7. [Toolchain Selection](#7-toolchain-selection)
+8. [mk/ File Reference](#8-mk-file-reference)
+9. [Module System](#9-module-system)
+10. [Qt Integration](#10-qt-integration)
+11. [Test Infrastructure](#11-test-infrastructure)
+12. [Packaging](#12-packaging)
+13. [Cross-Compilation](#13-cross-compilation)
+14. [CI/CD Integration](#14-cicd-integration)
+15. [Make Targets Reference](#15-make-targets-reference)
+16. [Variables Reference](#16-variables-reference)
+17. [Troubleshooting](#17-troubleshooting)
+18. [Design Decisions](#18-design-decisions)
+
+---
+
+## 1. Architecture Overview
+
+The build system uses **GNU Make** as the build driver with **Kconfig** (the Linux kernel
+configuration system) for build-time configuration. There is no CMake dependency for the
+main build (CMake files exist only for Nix builds and cmark's internal build).
+
+### Key Design Principles
+
+- **Single entry point:** The top-level `Makefile` is the only user-facing interface
+- **Kconfig for config:** All build options live in `Kconfig` and are set via `menuconfig`/`defconfig`
+- **Modular mk/ files:** Build logic is split into focused `.mk` files under `mk/`
+- **Per-module Makefiles:** Each library/component has its own `Makefile` invoked as a sub-make
+- **Jobserver passthrough:** Parallel builds work across all sub-makes via GNU Make's jobserver
+- **No recursive include hell:** Clear include chains with include guards where needed
+
+### Build Flow Summary
+
+```
+./configure → .config → make defconfig → syncconfig → make build
+ │
+ ┌─────────┴─────────┐
+ │ scripts/ │
+ │ syncconfig.sh │
+ │ │
+ ▼ ▼
+ auto.conf autoconf.h
+ (Make vars) (C #defines)
+ │
+ ┌───────────────┼───────────────┐
+ ▼ ▼ ▼
+ mk/targets.mk mk/tests.mk mk/package.mk
+ │
+ ┌───────────┼───────────┬────────────┐
+ ▼ ▼ ▼ ▼
+ configure subtrees libs launcher
+ (.in→gen) (zlib,etc) (bzip2, (main app)
+ cmark,etc)
+```
+
+---
+
+## 2. Quick Start
+
+### Linux (Native Build)
+
+```bash
+# Install dependencies
+sudo apt install build-essential qt6-base-dev qt6-5compat-dev \
+ libssl-dev flex bison libncurses-dev
+
+# Configure
+./configure # or: make defconfig
+make menuconfig # optional: tweak settings
+
+# Build
+make -j$(nproc)
+
+# Test
+make test
+
+# Install
+sudo make install PREFIX=/usr/local
+```
+
+### Windows (MSVC — from VS Developer Command Prompt)
+
+```cmd
+configure.bat
+make defconfig
+make -j%NUMBER_OF_PROCESSORS%
+```
+
+### Windows (MinGW Cross-Compile from Linux)
+
+```bash
+./configure --platform windows --cross-compile x86_64-w64-mingw32-
+make defconfig && make -j$(nproc)
+```
+
+### macOS
+
+```bash
+./configure
+make defconfig && make -j$(sysctl -n hw.ncpu)
+```
+
+---
+
+## 3. Directory Layout
+
+```
+ProjT-Launcher/
+├── Makefile # Top-level entry point (961 lines)
+├── Kconfig # Configuration menu definitions
+├── defconfig # Default configuration
+├── configure # Unix configure script → generates .config
+├── configure.bat # Windows configure script
+├── scripts/
+│ └── syncconfig.sh # Generates auto.conf + autoconf.h from .config
+│
+├── mk/ # Build system modules (16 active files)
+│ ├── config.mk # Foundational: paths, auto.conf include, helpers
+│ ├── host.mk # Host tool detection
+│ ├── flags.mk # Compiler flag definitions
+│ ├── toolchain.mk # Toolchain selection from Kconfig values
+│ ├── rules.mk # Common compile/link pattern rules
+│ ├── qt.mk # Qt framework integration
+│ ├── qt-tools.mk # Qt tool paths (MOC, UIC, RCC)
+│ ├── module.mk # Shared build rules for simple modules
+│ ├── configure.mk # Template .in file processing
+│ ├── targets.mk # Build orchestration (6 phases)
+│ ├── subtrees.mk # Subtree library wrappers (zlib, tomlplusplus)
+│ ├── tests.mk # Test build & execution
+│ ├── package.mk # Packaging (DEB, RPM, AppImage, DMG, NSIS)
+│ ├── platform.mk # Platform detection utilities
+│ ├── toolchain-gcc.mk # Standalone GCC build
+│ ├── toolchain-llvm.mk # Standalone LLVM/Clang build
+│ └── unused/ # Dead code (preserved for reference)
+│ ├── bootstrap.mk # Self-hosted toolchain bootstrap (unused)
+│ ├── modules.mk # Central module definitions (unused)
+│ ├── rules-full.mk # Extended build rules (unused)
+│ ├── toolchain-full.mk # Advanced toolchain detection (unused)
+│ ├── buildconfig.mk # Python-based config gen (unused)
+│ ├── qt-gen.mk # Qt generation rules (unused)
+│ ├── vars.mk # Version/branding vars (unused)
+│ └── java.mk # Java build rules (unused)
+│
+├── kconfig/ # Kconfig source (conf, mconf, nconf, qconf, gconf)
+├── build/ # Build output directory (default O=build)
+│ ├── .config # Active configuration
+│ ├── include/
+│ │ ├── config/auto.conf # Make-includable config variables
+│ │ └── generated/autoconf.h # C-includable config defines
+│ ├── obj/ # Object files per module
+│ ├── lib/ # Static/shared libraries
+│ ├── bin/ # Final executables
+│ ├── jars/ # Java JARs
+│ └── tests/ # Test executables
+│
+├── launcher/ # Main launcher source (993-line Makefile)
+│ ├── Makefile
+│ ├── console/
+│ ├── icons/
+│ ├── java/
+│ ├── launch/
+│ ├── logs/
+│ ├── meta/
+│ ├── minecraft/
+│ ├── modplatform/
+│ ├── net/
+│ ├── news/
+│ ├── screenshots/
+│ ├── settings/
+│ ├── tasks/
+│ ├── tools/
+│ ├── translations/
+│ ├── ui/
+│ └── updater/
+│
+├── bzip2/ # libbz2 (simple module)
+├── murmur2/ # MurmurHash2 (simple module)
+├── rainbow/ # Color library (Qt dep, simple module)
+├── qdcss/ # Qt CSS parser (Qt dep, simple module)
+├── systeminfo/ # System info (simple module)
+├── libnbtplusplus/ # NBT parser (simple module)
+├── gamemode/ # Linux GameMode (header-only)
+├── libpng/ # PNG library (custom Makefile)
+├── libqrencode/ # QR code library (custom Makefile)
+├── cmark/ # CommonMark parser (uses internal CMake)
+├── quazip/ # Qt ZIP library (Qt MOC module)
+├── LocalPeer/ # IPC library (Qt MOC module)
+├── buildconfig/ # Generated BuildConfig.cpp
+├── javacheck/ # Java version checker
+├── launcherjava/ # Java launcher wrappers
+├── zlib/ # zlib source (built by subtrees.mk)
+├── tomlplusplus/ # TOML parser (header-only)
+├── json/ # nlohmann JSON (header-only)
+├── tests/ # Test sources
+└── fuzz/ # Fuzzing test sources
+```
+
+---
+
+## 4. Makefile Include Graph
+
+### Main Makefile (entry point)
+
+```
+Makefile
+├── include kconfig/Makefile (Kconfig tool build rules)
+├── -include auto.conf (CONFIG_* variables)
+├── $(MAKE) -f mk/targets.mk (build, libs, launcher, etc.)
+├── $(MAKE) -f mk/tests.mk (test, tests-build)
+├── $(MAKE) -f mk/package.mk (package-deb, package-rpm, etc.)
+├── $(MAKE) -f mk/toolchain-gcc.mk (toolchain-gcc)
+└── $(MAKE) -f mk/toolchain-llvm.mk (toolchain-llvm)
+```
+
+### mk/ Include Dependencies
+
+```
+config.mk ← foundational, included by 8+ files
+├── host.mk ← included by config.mk (indirectly via toolchain.mk)
+├── toolchain.mk ← includes config.mk + host.mk
+│ └── flags.mk ← includes toolchain.mk
+│ └── qt-tools.mk ← includes flags.mk
+│ └── rules.mk ← includes qt-tools.mk
+│ └── module.mk ← includes rules.mk (used by ~27 modules)
+├── configure.mk ← includes config.mk
+├── qt.mk ← includes config.mk
+├── subtrees.mk ← includes config.mk
+├── tests.mk ← standalone (receives vars via export)
+├── package.mk ← includes config.mk + platform.mk
+├── platform.mk ← includes config.mk
+├── toolchain-gcc.mk ← standalone
+└── toolchain-llvm.mk ← standalone
+```
+
+### Module Makefile Pattern
+
+All simple modules follow this pattern:
+```makefile
+# In bzip2/Makefile, murmur2/Makefile, etc.
+lib := bz2 # Library name → libXXX.a
+lib-y := blocksort.c ... # Source files
+includes-y := bzip2 # Include paths
+ccflags-y := -DFOO # Extra C flags (optional)
+qt-modules-y := Core # Qt modules needed (optional)
+include $(srctree)/mk/module.mk
+```
+
+---
+
+## 5. Build Phases
+
+The build executes in 6 sequential phases (defined in `mk/targets.mk`):
+
+### Phase 1: Configure
+- Processes `.in` template files → generates C/C++ source files
+- `BuildConfig.cpp.in` → `build/obj/generated/BuildConfig.cpp`
+- `Launcher.in` → `build/obj/bin/LauncherScript`
+- `pnglibconf.h.prebuilt` → `build/obj/generated/include/pnglibconf.h`
+- `nbt_export.h`, `cmark_config.h`, `cmark_export.h`, `cmark_version.h`
+
+### Phase 2: Subtrees
+- Builds vendored libraries from source subtrees
+- **zlib:** Compiled from `zlib/` → `build/lib/libz.a`
+- **tomlplusplus:** Header-only, stamp file only
+- **json:** Header-only, stamp file only
+- **Qt (if bundled):** Built from `qt/` subtree
+
+### Phase 3: Qt Build
+- If `CONFIG_QT_BUNDLED=y`: builds Qt from source
+- If system Qt: skipped (uses pkg-config)
+
+### Phase 4: Libraries (3 tiers)
+- **Tier 0:** No dependencies → bzip2, murmur2
+- **Tier 1:** zlib dependencies → (currently empty, reserved)
+- **Tier 2:** General deps → libpng, cmark, libnbtplusplus, libqrencode
+- **Tier 3:** Qt dependencies → rainbow, qdcss, LocalPeer, quazip
+
+### Phase 5: Java
+- **javacheck:** Java version detection utility
+- **launcherjava:** Java launcher wrappers (ProjTLaunch.jar, ProjTLaunchLegacy.jar)
+
+### Phase 6: Launcher
+- Builds all launcher submodules (console, icons, java, launch, etc.)
+- Links everything into `build/bin/projtlauncher`
+- Uses `--whole-archive` to ensure all symbols are included
+
+---
+
+## 6. Configuration System (Kconfig)
+
+### How It Works
+
+1. **`Kconfig`** (root file) defines all configuration options with types, defaults, help text
+2. **`./configure`** (or `configure.bat`) creates initial `.config` in the build directory
+3. **`make menuconfig`** opens the interactive ncurses-based configuration editor
+4. **`scripts/syncconfig.sh`** converts `.config` → `auto.conf` (Make) + `autoconf.h` (C)
+
+### Configuration Files
+
+| File | Format | Purpose |
+|------|--------|---------|
+| `Kconfig` | Kconfig DSL | Option definitions |
+| `defconfig` | key=value | Default values |
+| `build/.config` | key=value | Active configuration |
+| `build/include/config/auto.conf` | Make include | `CONFIG_*` variables for Make |
+| `build/include/generated/autoconf.h` | C header | `#define CONFIG_*` for C/C++ |
+
+### Key Configuration Variables
+
+| Variable | Type | Default | Description |
+|----------|------|---------|-------------|
+| `CONFIG_CC` | string | `"gcc"` | C compiler |
+| `CONFIG_CXX` | string | `"g++"` | C++ compiler |
+| `CONFIG_BUILD_TYPE` | string | `"Debug"` | Build type (Debug/Release/RelWithDebInfo) |
+| `CONFIG_BUILD_TESTS` | bool | `y` | Enable test building |
+| `CONFIG_BUILD_FUZZERS` | bool | `n` | Enable fuzzer building |
+| `CONFIG_ENABLE_LTO` | bool | `n` | Link-time optimization |
+| `CONFIG_QT_VERSION_MAJOR` | string | `"6"` | Qt major version |
+| `CONFIG_QT_PREFIX` | string | `""` | Qt installation prefix |
+| `CONFIG_USE_BUNDLED_QT` | bool | `n` | Build Qt from source |
+| `CONFIG_TARGET_LINUX` | bool | auto | Target Linux |
+| `CONFIG_TARGET_WINDOWS` | bool | auto | Target Windows |
+| `CONFIG_TARGET_MACOS` | bool | auto | Target macOS |
+
+### syncconfig.sh
+
+The `scripts/syncconfig.sh` script is a lightweight replacement for the kernel's `syncconfig`
+mechanism. It:
+
+1. Reads `build/.config`
+2. Extracts `CONFIG_*=value` lines
+3. Generates `auto.conf` (for Make inclusion)
+4. Generates `autoconf.h` (with `#define` for C/C++)
+5. Uses `LC_ALL=C` to avoid locale-dependent regex issues
+
+**Critical:** The `LC_ALL=C` export at the top of `syncconfig.sh` is essential. Without it,
+Turkish locale (`tr_TR`) breaks `[A-Za-z]` regex patterns, causing CONFIG variables with
+uppercase `I` to be silently dropped.
+
+---
+
+## 7. Toolchain Selection
+
+### Selection Priority (highest to lowest)
+
+1. **Command line:** `make CC=clang CXX=clang++`
+2. **Kconfig config:** `CONFIG_CC="clang"` in `.config`
+3. **Platform default:** Set in main Makefile per platform
+4. **ccache/sccache wrapping:** Applied automatically if available
+
+### Platform Defaults
+
+| Platform | CC | CXX | LD |
+|----------|----|----|-----|
+| Linux | `gcc` | `g++` | `g++` |
+| macOS | `clang` | `clang++` | `clang++` |
+| Windows (MSVC) | `cl.exe` | `cl.exe` | `link.exe` |
+| Windows (MinGW) | `$(CROSS_COMPILE)gcc` | `$(CROSS_COMPILE)g++` | `$(CROSS_COMPILE)g++` |
+
+### Kconfig Override Flow
+
+```
+Makefile: CC = gcc (platform default)
+ ↓
+-include auto.conf (loads CONFIG_CC="clang")
+ ↓
+cfg-unquote strips quotes (_CC_CFG = clang)
+ ↓
+CC := clang (override applied)
+ ↓
+CC := ccache clang (ccache wrapper, if available)
+```
+
+### ccache/sccache
+
+Detected automatically. Disable with `NO_CCACHE=1`:
+```bash
+make NO_CCACHE=1 build
+```
+
+---
+
+## 8. mk/ File Reference
+
+### Active Files (16)
+
+#### `mk/config.mk` — Foundational Configuration
+- **Lines:** 41
+- **Included by:** 8+ other mk/ files
+- **Purpose:** Defines `OBJDIR`, `LIBDIR`, `BINDIR`, includes `auto.conf` and `.config`,
+ provides `cfg-yes`, `cfg-on`, `cfg-unquote` helper functions
+- **Exports:** `CC`, `CXX`, `AR`, `RANLIB`, `OBJDIR`, `LIBDIR`, `BINDIR`
+
+#### `mk/host.mk` — Host Tool Detection
+- **Lines:** 10
+- **Purpose:** Detects host tools (`HOSTCC`, `INSTALL`, `MKDIR`, etc.)
+
+#### `mk/toolchain.mk` — Toolchain Selection
+- **Lines:** 46
+- **Includes:** `config.mk`, `host.mk`
+- **Purpose:** Reads `CONFIG_CC`, `CONFIG_CXX`, `CONFIG_CROSS_COMPILE`, `CONFIG_SYSROOT`
+ from Kconfig and overrides `CC`/`CXX`/`AR`/`STRIP`/etc.
+- **Also applies:** `CONFIG_CFLAGS_EXTRA`, `CONFIG_CXXFLAGS_EXTRA`, `CONFIG_LDFLAGS_EXTRA`
+
+#### `mk/flags.mk` — Compiler Flags
+- **Lines:** 19
+- **Includes:** `toolchain.mk`
+- **Purpose:** Sets up `CFLAGS`, `CXXFLAGS`, `LDFLAGS` with platform-appropriate values
+
+#### `mk/qt-tools.mk` — Qt Tool Paths
+- **Lines:** 79
+- **Includes:** `flags.mk`
+- **Purpose:** Locates `MOC`, `UIC`, `RCC`, `LRELEASE` tools via pkg-config or
+ `CONFIG_QT_HOST_BINS` prefix
+
+#### `mk/rules.mk` — Common Build Rules
+- **Lines:** 63
+- **Includes:** `qt-tools.mk`
+- **Purpose:** Defines `src-to-obj`, `build-static-lib`, `build-exe` macros and common
+ pattern rules for `.c` → `.o`, `.cpp` → `.o` compilation
+
+#### `mk/module.mk` — Module Build Template
+- **Lines:** 151
+- **Included by:** ~27 module Makefiles
+- **Purpose:** Standard build rules for simple modules. Expects `lib`, `lib-y`, `includes-y`
+ variables from the including Makefile. Handles MSVC vs GCC differences.
+
+#### `mk/configure.mk` — Template Processing
+- **Lines:** 352
+- **Includes:** `config.mk`
+- **Include guard:** `_MK_CONFIGURE_INCLUDED`
+- **Purpose:** Processes `.in` template files with `@VAR@` → value substitutions.
+ Generates `BuildConfig.cpp`, `LauncherScript`, `pnglibconf.h`, `nbt_export.h`,
+ `cmark_config.h`, `cmark_export.h`, `cmark_version.h`
+- **Key macro:** `SED_SUBST` — massive sed expression with all substitution variables
+
+#### `mk/qt.mk` — Qt Framework Integration
+- **Lines:** 487
+- **Includes:** `config.mk`
+- **Include guard:** `_MK_QT_INCLUDED`
+- **Purpose:** Detects system Qt or builds bundled Qt. Provides `QT_MODULE_template` macro,
+ MOC/UIC/RCC rule templates, Qt CFLAGS/LIBS setup
+- **Exports:** `QT_CFLAGS`, `QT_LIBS`, `QT_PREFIX`, `QT_HOST_BINS`, `MOC`, `UIC`, `RCC`
+
+#### `mk/targets.mk` — Build Orchestration
+- **Lines:** 521
+- **Includes:** `configure.mk`, `qt.mk`
+- **Purpose:** Defines the 6-phase build sequence. Contains `build_local` and `clean_local`
+ macros for consistent module building. Handles launcher linking with `--whole-archive`.
+- **Key targets:** `build`, `configure`, `subtrees`, `qt-build`, `libs`, `launcher-all`,
+ `java-modules`, `tests`, `list-modules`
+
+#### `mk/subtrees.mk` — Subtree Library Wrappers
+- **Lines:** 318
+- **Includes:** `config.mk`
+- **Purpose:** Build wrappers for vendored subtree libraries:
+ - **zlib:** Full C build → `libz.a` + `libprojtZ.so` (renamed shared lib for tests)
+ - **tomlplusplus:** Header-only (stamp file)
+ - **json:** Header-only (stamp file)
+ - **Qt (bundled):** Conditional Qt build from `qt/` subtree
+
+#### `mk/tests.mk` — Test Infrastructure
+- **Lines:** 312
+- **Standalone:** Invoked via `$(MAKE) -f mk/tests.mk`
+- **Purpose:** Builds and runs 23 test executables. Links against all launcher libraries
+ with `--start-group`/`--end-group`. Uses `libprojtZ.so` (renamed shared zlib) to avoid
+ symbol conflicts with system Qt's zlib.
+- **Key targets:** `test`, `check`, `tests-build`, `tests-run`, `tests-clean`
+
+#### `mk/package.mk` — Packaging
+- **Lines:** 508
+- **Includes:** `config.mk`, `platform.mk`
+- **Purpose:** Creates distribution packages:
+ - **DEB:** Debian/Ubuntu `.deb` packages
+ - **RPM:** Fedora/RHEL `.rpm` packages
+ - **AppImage:** Linux portable AppImage
+ - **DMG:** macOS disk image
+ - **NSIS:** Windows installer
+ - **TAR:** Source/binary tarballs
+
+#### `mk/platform.mk` — Platform Detection
+- **Lines:** 279
+- **Includes:** `config.mk`
+- **Purpose:** Comprehensive OS/architecture detection. Used by `package.mk` and
+ toolchain files.
+
+#### `mk/toolchain-gcc.mk` — GCC Build
+- **Lines:** 181
+- **Standalone:** Invoked via `$(MAKE) -f mk/toolchain-gcc.mk`
+- **Purpose:** Downloads and builds GCC from source or subtree for self-hosted builds
+
+#### `mk/toolchain-llvm.mk` — LLVM Build
+- **Lines:** 189
+- **Standalone:** Invoked via `$(MAKE) -f mk/toolchain-llvm.mk`
+- **Purpose:** Downloads and builds LLVM/Clang from source or subtree
+
+### Unused Files (8, in `mk/unused/`)
+
+These files were developed for planned features but are not referenced by any active
+build path. Preserved for reference:
+
+| File | Reason Unused |
+|------|---------------|
+| `bootstrap.mk` | Self-hosted bootstrap — never integrated |
+| `modules.mk` | Central module definitions — modules use per-directory Makefiles instead |
+| `rules-full.mk` | Extended build rules (MSVC, Obj-C, shared libs) — not needed |
+| `toolchain-full.mk` | Advanced toolchain auto-detection — simplified version used instead |
+| `buildconfig.mk` | Python-based config generation — configure.mk handles this |
+| `qt-gen.mk` | Qt generation rules — qt.mk handles this |
+| `vars.mk` | Version/branding variables — main Makefile defines these |
+| `java.mk` | Java build rules — targets.mk handles Java directly |
+
+---
+
+## 9. Module System
+
+### Module Types
+
+#### Type 1: Simple Module (uses `mk/module.mk`)
+
+Modules that compile C/C++ sources into a static library:
+
+```makefile
+# bzip2/Makefile
+lib := bz2
+lib-y := blocksort.c huffman.c crctable.c randtable.c \
+ compress.c decompress.c bzlib.c
+includes-y := bzip2
+include $(srctree)/mk/module.mk
+```
+
+**Variables accepted by module.mk:**
+| Variable | Required | Description |
+|----------|----------|-------------|
+| `lib` | Yes | Library name (output: `lib$(lib).a`) |
+| `lib-y` | Yes | Source files (`.c` and/or `.cpp`) |
+| `includes-y` | No | Include directories (relative to `srctree`) |
+| `ccflags-y` | No | Extra C flags |
+| `cxxflags-y` | No | Extra C++ flags |
+| `qt-modules-y` | No | Qt modules needed (e.g., `Core Gui Widgets`) |
+
+**Modules using this pattern:** bzip2, murmur2, rainbow, qdcss, systeminfo,
+libnbtplusplus, gamemode
+
+#### Type 2: Qt MOC Module
+
+Modules that need Qt's Meta-Object Compiler:
+
+```makefile
+# LocalPeer/Makefile
+lib := localpeer
+lib-y := LocalPeer.cpp LockedFile.cpp LockedFile_unix.cpp
+MOC_HEADERS := include/LocalPeer.h
+EXTRA_OBJS := $(MOC_OBJS)
+CUSTOM_STATIC_LIB_RULE := 1
+includes-y := LocalPeer/include LocalPeer
+qt-modules-y := Core Network
+include $(srctree)/mk/module.mk
+```
+
+**Modules using this pattern:** quazip, LocalPeer
+
+#### Type 3: Custom Makefile
+
+Modules with complex build logic:
+
+- **libpng:** Standalone C build with custom flags
+- **libqrencode:** Standalone C build with own CFLAGS
+- **buildconfig:** Compiles generated `BuildConfig.cpp`
+- **cmark:** Uses its **own internal CMake** build system
+- **launcher/:** Complex build with MOC, RCC, multiple submodules
+
+#### Type 4: Java Module
+
+```makefile
+# javacheck/Makefile — compiles .java → .jar
+```
+
+---
+
+## 10. Qt Integration
+
+### System Qt (Default)
+
+Qt is detected via `pkg-config` or the `CONFIG_QT_PREFIX` path:
+
+```bash
+# Auto-detect via pkg-config
+./configure
+
+# Specify prefix manually
+./configure --qt-prefix /opt/qt6
+```
+
+### Bundled Qt
+
+When `CONFIG_USE_BUNDLED_QT=y`, Qt is built from the `qt/` subtree:
+
+```bash
+make menuconfig # Enable "Use Bundled Qt"
+make qt-build # Build Qt from source
+make build # Build the project
+```
+
+### Qt Tool Discovery
+
+The `mk/qt-tools.mk` file locates Qt tools in this order:
+
+1. `CONFIG_QT_HOST_BINS` (explicit path from Kconfig)
+2. pkg-config `Qt6Core` `host_bins` variable
+3. Common system paths (`/usr/lib/qt6/libexec/`, etc.)
+
+### Qt Modules Used
+
+| Qt Module | Used By |
+|-----------|---------|
+| Core | All Qt-dependent modules |
+| Gui | launcher/ui |
+| Widgets | launcher/ui |
+| Network | launcher/net, LocalPeer |
+| Xml | launcher/meta |
+| Concurrent | launcher/tasks |
+| Core5Compat | Various |
+
+---
+
+## 11. Test Infrastructure
+
+### Overview
+
+- **23 test executables**, each testing a specific component
+- Built by `mk/tests.mk`, run sequentially
+- Each test links against ALL launcher libraries (to resolve dependencies)
+- Uses `libprojtZ.so` (renamed shared zlib) to avoid symbol conflicts with system Qt
+
+### Why libprojtZ.so?
+
+System Qt links against system zlib. Our static `libz.a` has identical symbols, causing
+`Z_VERSION_ERROR` at runtime. Solution: build zlib as a shared library with a unique name
+(`libprojtZ.so.1`) and link tests against it instead.
+
+### Running Tests
+
+```bash
+make test # Build + run all tests
+make check # Same as test
+make tests-build # Build only (no run)
+make TEST_VERBOSE=1 test # Verbose output
+make TEST_FILTER=Version test # Run only matching tests
+```
+
+### Test List
+
+| Test | Component |
+|------|-----------|
+| `Version_test` | Version parsing |
+| `GradleSpecifier_test` | Gradle dependency specifiers |
+| `RuntimeVersion_test` | Java runtime version parsing |
+| `GZip_test` | GZip compression |
+| `ParseUtils_test` | General parsing utilities |
+| `JavaVersion_test` | Java version detection |
+| `INIFile_test` | INI file parsing |
+| `Library_test` | Library management |
+| `MojangVersionFormat_test` | Mojang version format |
+| `Packwiz_test` | Packwiz modpack format |
+| `Index_test` | Index management |
+| `MetaComponentParse_test` | Meta component parsing |
+| `DataPackParse_test` | Data pack parsing |
+| `ResourcePackParse_test` | Resource pack parsing |
+| `TexturePackParse_test` | Texture pack parsing |
+| `ShaderPackParse_test` | Shader pack parsing |
+| `WorldSaveParse_test` | World save parsing |
+| `ResourceFolderModel_test` | Resource folder model |
+| `Task_test` | Task system |
+| `CatPack_test` | Cat pack handling |
+| `XmlLogs_test` | XML log parsing |
+| `LogEventParser_test` | Log event parsing |
+| `ProjTExternalUpdater_test` | External updater (non-macOS only) |
+
+---
+
+## 12. Packaging
+
+Packaging is handled by `mk/package.mk`. All package targets are invoked via:
+
+```bash
+make package-deb # Debian/Ubuntu package
+make package-rpm # RPM package
+make package-appimage # Linux AppImage
+make package-dmg # macOS disk image
+make package-nsis # Windows NSIS installer
+make package # Build all configured packages
+```
+
+### Package Output
+
+All packages are created in `build/packages/`.
+
+---
+
+## 13. Cross-Compilation
+
+### Linux → Windows (MinGW)
+
+```bash
+./configure --platform windows --cross-compile x86_64-w64-mingw32-
+make defconfig && make -j$(nproc)
+```
+
+### Linux → macOS (requires osxcross)
+
+```bash
+./configure --platform macos --cross-compile x86_64-apple-darwin-
+make defconfig && make -j$(nproc)
+```
+
+### Linux x86_64 → Linux aarch64
+
+```bash
+./configure --arch aarch64 --cross-compile aarch64-linux-gnu-
+make defconfig && make -j$(nproc)
+```
+
+### Key Variables
+
+| Variable | Example | Description |
+|----------|---------|-------------|
+| `TARGET_PLATFORM` | `linux`, `windows`, `macos` | Target OS |
+| `TARGET_ARCH` | `x86_64`, `aarch64`, `i686` | Target architecture |
+| `CROSS_COMPILE` | `x86_64-w64-mingw32-` | Toolchain prefix |
+| `WINDOWS_TOOLCHAIN` | `mingw`, `msvc` | Windows toolchain choice |
+
+---
+
+## 14. CI/CD Integration
+
+### CI Targets
+
+```bash
+make ci-prepare # Prepare CI environment
+make ci-lint # Run linting checks
+make ci-release # Build + create release artifacts
+```
+
+### GitHub Actions Matrix
+
+The CI runs ~20 build configurations:
+- Linux x86_64 (GCC, Clang)
+- Linux aarch64 (cross-compile)
+- Windows MSVC (x86_64)
+- Windows MinGW (x86_64)
+- macOS 14, 15, 26 (arm64)
+
+---
+
+## 15. Make Targets Reference
+
+### Configuration
+
+| Target | Description |
+|--------|-------------|
+| `defconfig` | Load default configuration |
+| `menuconfig` | Interactive ncurses configuration |
+| `nconfig` | Alternative ncurses configuration |
+| `xconfig` | Qt-based graphical configuration |
+| `gconfig` | GTK-based graphical configuration |
+| `oldconfig` | Update config, prompt for new options |
+| `olddefconfig` | Update config, use defaults for new options |
+| `savedefconfig` | Save minimal config to `defconfig` |
+| `listnewconfig` | List new, unconfigured options |
+
+### Build
+
+| Target | Description |
+|--------|-------------|
+| `all` (default) | Build everything |
+| `build` | Build the project |
+| `configure` | Generate headers from `.in` files |
+| `subtrees` | Build subtree dependencies |
+| `qt-build` | Build Qt (if bundled) |
+| `libs` | Build all libraries |
+| `launcher-all` | Build launcher and submodules |
+| `java-modules` | Build Java modules |
+
+### Install
+
+| Target | Description |
+|--------|-------------|
+| `install` | Install to `PREFIX` (default: `/usr/local`) |
+| `install-bin` | Install binary only |
+| `install-data` | Install data files only |
+| `uninstall` | Remove installed files |
+
+### Testing
+
+| Target | Description |
+|--------|-------------|
+| `test` / `check` | Build and run all tests |
+| `tests-build` | Build tests without running |
+| `fuzz` | Run fuzzers (requires `CONFIG_BUILD_FUZZERS=y`) |
+
+### Packaging
+
+| Target | Description |
+|--------|-------------|
+| `package` | Build all configured packages |
+| `package-deb` | Build `.deb` package |
+| `package-rpm` | Build `.rpm` package |
+| `package-appimage` | Build AppImage |
+| `package-dmg` | Build macOS DMG |
+| `package-nsis` | Build Windows NSIS installer |
+
+### Toolchain
+
+| Target | Description |
+|--------|-------------|
+| `toolchain-gcc` | Build GCC from source |
+| `toolchain-llvm` | Build LLVM/Clang from source |
+| `toolchain-all` | Build both |
+| `toolchain-clean` | Clean toolchain builds |
+| `toolchain-distclean` | Remove all toolchain files |
+| `toolchain-help` | Show toolchain options |
+
+### Utility
+
+| Target | Description |
+|--------|-------------|
+| `info` | Show project and build information |
+| `version` | Show version string |
+| `listconfig` | Show configuration summary |
+| `list-modules` | List all available modules |
+| `clean` | Remove build artifacts (obj, lib, bin) |
+| `distclean` | Remove everything including `.config` |
+| `mrproper` | Alias for `distclean` |
+| `help` | Show help text |
+
+---
+
+## 16. Variables Reference
+
+### User-Settable Variables
+
+| Variable | Default | Description |
+|----------|---------|-------------|
+| `V` | `0` | Verbose build (`V=1` for full commands) |
+| `O` | `build` | Output directory |
+| `PREFIX` | `/usr/local` | Installation prefix |
+| `DESTDIR` | (empty) | Staging directory for packages |
+| `JOBS` | `$(nproc)` | Parallel job count |
+| `NO_CCACHE` | (unset) | Set to `1` to disable ccache |
+| `CC` | (auto) | C compiler |
+| `CXX` | (auto) | C++ compiler |
+| `CROSS_COMPILE` | (empty) | Toolchain prefix |
+| `TARGET_PLATFORM` | (auto) | Target OS |
+| `TARGET_ARCH` | (auto) | Target architecture |
+| `WINDOWS_TOOLCHAIN` | `mingw` | Windows toolchain (`mingw`/`msvc`) |
+
+### Internal Variables (read-only)
+
+| Variable | Description |
+|----------|-------------|
+| `srctree` | Source tree root (always `$(CURDIR)`) |
+| `KBUILD_OUTPUT` | Absolute path to build output |
+| `KCONFIG_CONFIG` | Path to `.config` file |
+| `KCONFIG_AUTOCONFIG` | Path to `auto.conf` |
+| `HOST_PLATFORM` | Host OS (`linux`/`macos`/`windows`) |
+| `HOST_ARCH` | Host architecture |
+| `OBJDIR` | Object file directory (`build/obj`) |
+| `LIBDIR` | Library directory (`build/lib`) |
+| `BINDIR` | Binary directory (`build/bin`) |
+
+---
+
+## 17. Troubleshooting
+
+### Build fails with "CONFIG not found" or missing CONFIG variables
+
+**Cause:** Locale-dependent regex in `syncconfig.sh`.
+**Fix:** Ensure `LC_ALL=C` is set in `scripts/syncconfig.sh` (already applied).
+
+```bash
+# Verify: should show 70 CONFIG entries
+grep -c '^CONFIG_' build/include/config/auto.conf
+```
+
+### CC/CXX empty in `make info`
+
+**Cause:** `MAKEFLAGS += -r -R` disables built-in variables, breaking `CC ?=` assignments.
+**Fix:** Main Makefile now uses unconditional `CC =` and applies CONFIG_CC override after
+auto.conf include (already fixed).
+
+### Tests fail with "libprojtZ not found"
+
+**Cause:** The shared zlib (`libprojtZ.so`) wasn't being built before test linking.
+**Fix:** `mk/tests.mk` now includes `zlib-shared` as a prerequisite of `tests-build`
+(already fixed).
+
+### "Tests not enabled" even though BUILD_TESTS=y in .config
+
+**Cause:** syncconfig.sh failed to generate `auto.conf` correctly (locale bug).
+**Fix:** See "CONFIG not found" above.
+
+### ccache wrapping an empty CC
+
+**Cause:** ccache section ran before CONFIG_CC override.
+**Fix:** ccache/sccache wrapping now happens after auto.conf values are applied.
+
+### Out-of-tree build
+
+```bash
+make O=../build-release defconfig
+make O=../build-release -j$(nproc)
+```
+
+### Windows: "make is not recognized"
+
+Install make via:
+- **MSYS2:** `pacman -S make`
+- **Chocolatey:** `choco install make`
+- **Visual Studio:** Use `nmake` or install GNU Make
+
+### Nix builds
+
+Nix builds use `CMakeLists.txt` (not the Make build system). The CMake files are
+maintained separately for Nix compatibility.
+
+---
+
+## 18. Design Decisions
+
+### Why Make instead of CMake?
+
+1. **Simpler:** 961-line Makefile + 16 mk/ files vs. 50+ CMakeLists.txt files
+2. **Faster:** No generation step, direct compilation
+3. **Kconfig:** Native integration with Linux kernel's proven configuration system
+4. **Transparent:** Easy to debug with `make V=1` and `make -p`
+5. **Cross-platform:** Works on Linux, macOS, Windows (MSVC, MinGW, MSYS2)
+
+### Why Kconfig?
+
+1. **Battle-tested:** Used by the Linux kernel for 20+ years
+2. **Dependency tracking:** Options can depend on other options
+3. **Multiple UIs:** `menuconfig` (ncurses), `xconfig` (Qt), `gconfig` (GTK)
+4. **Minimal footprint:** Pure C, builds as part of the project
+
+### Why libprojtZ.so for tests?
+
+System Qt links against system zlib. Our static `libz.a` has the same symbols.
+When both are linked into the same binary, the zlib version check fails
+(`Z_VERSION_ERROR`). Using a renamed shared library (`libprojtZ.so`) with `-rpath`
+avoids this conflict.
+
+### Why `-r -R` in MAKEFLAGS?
+
+`-r` disables built-in implicit rules (like `.c.o:`) and `-R` disables built-in
+variable definitions (like `CC=cc`). This eliminates ~150 implicit rules and variables
+that would otherwise slow down Make's pattern matching. The speed improvement is
+significant for large projects.
+
+**Trade-off:** All variables must be explicitly set (no fallback to `CC=cc`).
+The Makefile uses unconditional `CC = gcc` (not `CC ?= gcc`) to handle this.
+
+### Why `SHELL := /bin/bash`?
+
+The build system uses bash-specific features:
+- `PIPESTATUS` array for checking exit codes in pipelines
+- `set -o pipefail` for proper error propagation
+- Process substitution `<()` in some scripts
+
+---
+
+## Appendix: File Statistics
+
+| Component | Files | Lines |
+|-----------|-------|-------|
+| Main Makefile | 1 | 977 |
+| Active mk/ files | 16 | ~3,200 |
+| Module Makefiles | ~27 | ~2,500 |
+| Launcher Makefile | 1 | 993 |
+| Launcher sub-Makefiles | 18 | ~3,000 |
+| Total build system | ~63 | ~10,700 |