Building the oracles¶
The parity suite compares against C-built oracle binaries. They live in
References/ (git-ignored, GPL-3.0 — built from GPL reference material,
used only as local test oracles, never shipped).
Credits
The RAHasher CLI we test against is written by LeXofLeviafan (RALibretro lineage). His project is the reference oracle for this suite — byte-identical output between our port and his binaries is asserted on every run.
Which oracle is used¶
The harness resolves, in order:
RASHARP_ORACLEenv var;References\rcheevos-12.4.0\bin64\RAHasher.exe— built from rcheevos 12.4.0 (the Part II source of truth);References\RAHasher-1.8.3\bin64\RAHasher.exe— built from the pinned 1.8.3 sources;References\RAHasher.exe— any other 1.8.3 binary (a legacy build that only accepts numeric console ids; the harness adapts).
Prerequisites (Windows)¶
- MSYS2 (
/c/msys64) withmake,sh, and the MinGW-w64 toolchain (gcc/g++16.x). - miniz and libchdr sources under
References/RAHasher-1.8.3/src/(cloned; libchdr pinned to v0.3.0 with its vendored deps lzma-25.01/zstd-1.5.7/miniz-3.1.1).
The TMP problem (why the wrapper scripts exist)¶
The MSYS2 sh clears TMP/TEMP for child processes, so MinGW gcc falls
back to C:\WINDOWS and fails with "Cannot create temporary file". The
ccw-gcc.sh / ccw-g++.sh wrappers set TMP=C:\msys64\tmp before
exec-ing the real compiler:
#!/bin/sh
export TMP='C:\msys64\tmp'
export TEMP='C:\msys64\tmp'
exec /c/msys64/mingw64/bin/gcc.exe "$@"
Building the 1.8.3 oracle¶
cd References/RAHasher-1.8.3
export PATH="/c/msys64/usr/bin:/c/msys64/mingw64/bin:$PATH"
make -f Makefile.RAHasher HAVE_CHD=1 CC=./ccw-gcc.sh CXX=./ccw-g++.sh
# → bin64/RAHasher.exe
Notes on the reference-tree adaptations (build-only, never shipped):
src/rcheevos/is the 40d916d snapshot;src/minizis 3.1.0 (master's API drifted — 3.1.0 restoresmz_alloc_func/tinfl_decompressor);src/Util.cppincludes<miniz.h>before<miniz_zip.h>(the header split);Makefile.common'sCHD_OBJSwere adapted to libchdr v0.3.0's dep layout (lzma-25.01/src/LzmaDec.c,zstd-1.5.7/zstddeclib.c, codec files split per-module) andcodec_zlib's miniz include is shimmed to the CLI's miniz to avoid duplicate symbols;src/RA_BuildVer.his a handwritten1.8.3header (the git-generated one needs the RAInterface submodule).
Building the 12.4.0 oracle¶
cd References/rcheevos-12.4.0
export PATH="/c/msys64/usr/bin:/c/msys64/mingw64/bin:$PATH"
make -f Makefile.oracle CC=./ccw-gcc.sh CXX=./ccw-g++.sh
# → bin64/RAHasher.exe
Makefile.oracle compiles the RAHasher 1.8.3 CLI stack
(RAHasher.cpp, Util.cpp, Hash3DS.cpp, HashCHD.cpp, Logger.cpp,
sha256.c) against rcheevos 12.4.0's src/rhash, reusing the same
miniz 3.1.0 and libchdr v0.3.0 trees for zip pre-load and CHD support.
Why CHD needs libchdr¶
rc_hash's default cdreader has no CHD support — the CHD track reader is
HashCHD.cpp (from the RAHasher tree, GPL reference), which plugs into
rc_hash_cdreader_t and reads hunks via libchdr. Both oracles therefore
link libchdr v0.3.0 + vendored deps (zstd single-file decoder, LZMA
decoder, miniz for the zlib codec).
Verification¶
After building, smoke-test:
bin64/RAHasher.exe GB <any-file> # hash + exit 0
bin64/RAHasher.exe '?' <any-file> # iterate mode
bin64/RAHasher.exe PS1 <game>.cue # disc
bin64/RAHasher.exe 12 <game>.chd # CHD (numeric id also works)
bin64/RAHasher.exe -s <sysdir> 62 <file>.cia # 3DS
Then run dotnet test --filter FullyQualifiedName~Parity — all 90 cases
must pass byte-identically.