Skip to content

Build Instructions

digdat0 edited this page Nov 1, 2026 · 4 revisions

Build MKDD-NX.nro from your own disc image of Mario Kart: Double Dash!! (USA, GM4E01). Paths such as tools/ and switch/ are in the repository.

tools/build_from_iso.py does the whole build from your disc image in one command. Everything it makes from the disc goes to a work folder outside the repository (default ../mkdd-nx-work).

Requirements (one-time setup)

What Notes
devkitPro packages switch-dev deko3d switch-sdl2 switch-tools
Python 3.8+ on Windows run scripts with py -3 (Git Bash's python may be devkitPro's msys2 Python); for an .rvz disc image also py -3 -m pip install zstandard
Git on Windows, Git for Windows (its bash runs the Switch build)
Java 21 (JDK) for Ghidra, e.g. Temurin 21
Ghidra 12.1.4 unzip anywhere
GameCubeLoader for Ghidra 12.1 in Ghidra: File > Install Extensions, or unzip into <Ghidra>/Ghidra/Extensions

The script also fetches MKDD-Recomp at a pinned commit: its function list, metadata and Ghidra export scripts.

One command

py -3 tools/build_from_iso.py "D:/Games/Mario Kart Double Dash (USA).iso" --ghidra C:/tools/ghidra_12.1.4_PUBLIC

.iso, .gcm, .ciso and .rvz all work. It:

  1. checks the disc is GM4E01 and extracts main.dol (its SHA-1 must match the supported build),
  2. clones MKDD-Recomp (pinned),
  3. runs Ghidra headless on main.dol (about 10-20 minutes): import, auto-analysis, CreateGapFunctions.java, ExportPcode.java (expected: 740,738 instructions),
  4. assembles the sheets and generates the C with tools/gen_c.py (a few minutes),
  5. builds the .nro with switch/build.sh (30-60 minutes the first time).

Output: build-switch/sdcard/switch/MKDD-NX/MKDD-NX.nro. Re-running skips the steps already done (the Ghidra export is reused); --force redoes everything. Other options: --work DIR, --recomp DIR (use an existing MKDD-Recomp checkout), --bash PATH, --no-build (stop after generating the C). GHIDRA_INSTALL_DIR can replace --ghidra.

By hand

  1. Extract main.dol from the disc and export it with Ghidra:
    analyzeHeadless <project dir> MKDD -import main.dol -loader GameCubeLoader        -loader-autoloadMaps false -scriptPath <MKDD-Recomp>/tools        -postScript CreateGapFunctions.java -postScript ExportPcode.java <export dir>
    
    Expected: 13,490 functions, 740,738 instructions, 55,822 memory rows.
  2. Put MKDD-Recomp's sheets/functions.csv, meta.csv, hle.csv and the exported instructions.csv, memory.csv, registers.csv into one folder (outside this repository).
  3. py -3 tools/gen_c.py <sheets folder> <gen folder>
  4. switch/build.sh <gen folder> (Git Bash on Windows)

Updating

After pulling new commits, regenerate the C before building: the generated code calls the port's native functions (runtime/native.h) directly, so C generated by an older version doesn't match a newer runtime (the link fails, or a new feature such as the field-of-view setting does nothing).

py -3 tools/gen_c.py <sheets folder> <gen folder>
switch/build.sh <gen folder>

gen_c.py takes a few minutes, and the build then recompiles everything (30-60 minutes). The one-command build_from_iso.py always regenerates the C (only the Ghidra export is reused), so re-running it is enough. Always pass the gen folder to switch/build.sh: without it, it uses a default path that may hold an old generation.

Headless PC test build (MSYS2 UCRT64 gcc): pc/build_pc.sh <gen folder>, then pc/build/mkdd_pc.exe <disc image> [seconds] [pad script].

Clone this wiki locally