This is the "scripts to control compilation and installation" record the
LGPL relink obligation depends on (docs/LICENSING.md). Each step says
whether it has been re-executed from a clean checkout. A fresh recursive
clone of the repository at commit 8a8cabe was tested on 2026-09-16 (with
the submodule URLs redirected to the local forks, since nothing is pushed):
the app target does NOT build from the clone alone, because the inputs
marked "not in the repository" below are absent. Two further findings:
app/Madeira/x86_64-vcruntime is required by the project but ignored, and
the submodule commits (FEX, its nested rpmalloc fork, wine branch
madeira-lgpl, dxmt) exist only locally: the forks named in .gitmodules
(all under github.com/willfaust) do not yet carry them, so a recipient's
recursive clone fails at the first submodule until every fork is pushed. This document is the
remediation; steps marked UNVERIFIED have not yet been re-run from scratch.
A build without app/Madeira/x86_64-vcruntime still gets the Visual C++ runtime
on the device: setup and Settings take the DLLs out of Microsoft's own installers
there, for 64-bit and 32-bit games (app/Madeira/VCRedist.swift, docs/LIBRARY.md).
| Input | Why absent | How to obtain | Verified from clean |
|---|---|---|---|
toolchains/llvm-mingw-20260421-ucrt-macos-universal/ |
122 MB third-party toolchain | llvm-mingw-20260421-ucrt-macos-universal.tar.xz from https://github.com/mstorsjo/llvm-mingw/releases/tag/20260421, SHA-256 bd85a3975723815cef28dbbd2ca2cb0c926f6b348a12a0453f39f7af273cb3f7, extracted under toolchains/ |
tarball hash recorded; download UNVERIFIED |
toolchains/llvm-project/ + toolchains/llvm-ios-build/ + toolchains/llvm-host-build/ |
LLVM built for iOS | upstream llvm-project at commit 8dfdcc7b7; configure llvm-ios-build with -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_SYSTEM_PROCESSOR=arm64 -DCMAKE_OSX_ARCHITECTURES=arm64 -DCMAKE_OSX_SYSROOT=iphoneos -DCMAKE_OSX_DEPLOYMENT_TARGET=17.0 -DCMAKE_MACOSX_BUNDLE=OFF -DCMAKE_BUILD_TYPE=Release -DLLVM_HOST_TRIPLE=arm64-apple-ios17.0 -DLLVM_DEFAULT_TARGET_TRIPLE=arm64-apple-ios17.0 -DLLVM_TARGET_ARCH=host -DLLVM_TARGETS_TO_BUILD= -DLLVM_ENABLE_PROJECTS= -DLLVM_BUILD_TOOLS=OFF -DLLVM_INCLUDE_TESTS=OFF -DLLVM_INCLUDE_BENCHMARKS=OFF -DLLVM_ENABLE_ZLIB=OFF -DLLVM_ENABLE_ZSTD=OFF -DLLVM_ENABLE_TERMINFO=OFF -DLLVM_TABLEGEN=<absolute path to llvm-host-build/bin/llvm-tblgen>. First build the host llvm-tblgen target; then build iOS targets LLVMPasses LLVMBitWriter. |
these targets built with Xcode 26.6 on 2026-10-17 |
research/GPTK/Metal Shader Converter 4.0 beta 2.pkg |
Apple installer, 30 MB, licence-bound | Apple developer downloads; SHA-256 1acc33c87ea663933df89721a998d066106685473020bcbe007cee7a16155734 (pinned in build/madeira-d3d12/deps.sh). Only needed to REBUILD the converter fetch; the library itself is tracked |
n/a |
app/Madeira/x86_64-vcruntime/ |
Microsoft Visual C++ 2015-2022 x64 runtime DLLs (concrt140, msvcp140*, vcamp140, vccorlib140, vcruntime140*), redistributable under Microsoft's terms, not under this repository's licence | extract from Microsoft's vc_redist.x64.exe (or copy from C:\Windows\System32 of a licensed Windows install) into that folder |
UNVERIFIED |
build/wine-mono/wine-mono-11.0.0/ (optional) |
Wine Mono, the .NET Framework runtime Wine's mscoree loads (not Microsoft code; licences in build/wine-mono/COPYING and THIRD-PARTY-NOTICES.md), 41.6 MB download, 228 MB unpacked |
bash build/wine-mono/fetch.sh downloads wine-mono-11.0.0-x86.tar.xz from https://dl.winehq.org/wine/wine-mono/11.0.0/ and checks its SHA-256; --source also fetches the matching source tarball. Version and hashes are pinned in build/wine-mono/pin.sh, which does not follow WINE_MONO_VERSION in wine/dlls/mscoree/mscoree_private.h. The Xcode phase "Bundle Wine Mono" runs build/wine-mono/bundle.sh, which copies it into Madeira.app/wine-mono without the lib/mono/*-api reference assemblies and patches the bundled mscorlib.dll: a dirty hack (4 IL bytes: GC.Collect with GCCollectionMode.Optimized returns, for Terraria), pinned to the exact file by SHA-256 so the build stops on any other mscorlib; TODO: replace it with a Wine Mono built from source or an upstream fix (see the TODO in bundle.sh). Without the folder the app builds without Mono, and .NET Framework programs fail with "Wine Mono is not installed". Release builds leave Wine Mono out (2026-10-06): the packaging step deletes Madeira.app/wine-mono, and the app downloads it from WineHQ on first use (setup or Settings › .NET Framework, app/Madeira/WineMono.swift) |
fetch + bundle run on the development machine 2026-10-05; not from a clean checkout |
toolchains/mesa-d3d12/ (OpenGL, optional) |
Mesa 26.2.4 source, the DirectXShaderCompiler release for dxil.dll, and zlib for Meson |
downloaded by build/mesa-d3d12/build.sh and checked against the SHA-256 values in it: mesa-26.2.4.tar.xz bce5f7fb…832e9 from archive.mesa3d.org, dxc_2026_09_29.zip ad31b1fc…7e7f1 (DirectXShaderCompiler v1.9.2609), zlib 1.3.1 and its wrap patch; DirectX-Headers at commit 9e393d6d (v1.619.1) |
Verified 2026-10-06 |
| A free Apple ID; StikDebug or a pairing file plus LocalDevVPN | signing and JIT runtime requirements | see docs/JIT.md |
n/a |
Run in this order after the inputs above are in place. Outputs are git-ignored and consumed by the app project.
build/gnutls-ios/build.sh: GMP 6.3.0, Nettle 3.10.1, GnuTLS 3.8.9 from the tracked tarballs inbuild/gnutls-ios/src(SHA256SUMS there) ->app/Madeira/lib{gmp,nettle,hogweed,gnutls}.a(these four outputs are also tracked). Verified: built on the development machine; not re-run from a clean checkout.build/ffmpeg/build.sh: FFmpeg 7.1.1 in an LGPL-only configuration (WMA, MPEG audio and PCM decoders; mp3/wav/mov demuxers; no H.264/HEVC/AAC), built from the tracked, unmodified release tarball inbuild/ffmpeg/srcafter verifying it againstbuild/ffmpeg/src/SHA256SUMS-> headers intoolchains/ffmpeg-ios/include(read bybuild/ntdll-unix/build.shfor winegstreamer's unix side) andapp/Madeira/lib{avformat,avcodec,swresample,avutil}.a(ignored; the app target links them together with VideoToolbox, CoreMedia, CoreVideo, AudioToolbox and CoreFoundation). The configure arguments are the ones the port was built and device-tested with on the WSL toolchain; the macOS form of the script is UNVERIFIED.- FEX (submodule, branch ios-port-2607):
FEX/build-ios:build/fex-ios/build.sh(same options as the development CMakeCache) ->FEX/build-ios/FEXCore/Source/lib{FEXCore,FEXCore_Base,JemallocLibs}.aand theExternal/{cephes,fmt,SoftFloat-3e,xxhash}archives. UNVERIFIED from clean.FEX/build-arm64ec:build/fex-arm64ec/build.sh(configures withFEX/Data/CMake/toolchain_mingw.cmakeand the recorded options on first run, builds targetarm64ecfex, copiesBin/libarm64ecfex.dlltoapp/Madeira/arm64ec-windows/xtajit64.dll). The build step was verified this session. The first-run configure uses Ninja,MINGW_TRIPLE=arm64ec-w64-mingw32,TUNE_CPU=cortex-a78,FEX_IOS_HOST_BUILD=ON,FEX_IOS_HOST=1for the C, C++ and assembler flags, and LTO off: the options the madeira-bcd fork's macOS CI has built xtajit64.dll with since 2026-09-26 (the module every 64-bit game ran on from its build 231). A tree configured before keeps its cached options and generator (removeFEX/build-arm64ecto configure it again).
- Wine (submodule, branch madeira-lgpl):
- unix side:
build/ntdll-unix/build.sh,build/wineserver/build.sh,build/win32u-unix/build.sh->app/Madeira/lib{ntdll_unix,wineserver,win32u_unix}.a. Verified on the development machine. The ntdll build probes the selected iPhoneOS SDK for the optionalrusage_info_v6.ri_page_wait_time_machdiagnostic member. When absent,[xp] pgw=-1.0means unavailable, not zero page-wait time. SDKs that expose the member keep the measured delta. This does not remove other SDK/toolchain requirements. Runpython3 tests/host/check-rusage-sdk.pyto check both header layouts and, on macOS, the installed iPhoneOS SDK. - PE side:
build/wine-pe/build-ntdll.sh(configureswine/build-arm64ecwith--enable-archs=arm64ec --without-x --disable-tests --enable-winegstreameron first run, buildsdlls/ntdll, strips, pads to SizeOfImage + 0x50000, copies to the app). Other PE modules:build/wine-pe/build-modules.sh <name>...(same tree; it builds each module's DLL targetdlls/<name>/arm64ec-windows/<name>.dll, strips it with--strip-debuglike every shipped builtin and installs it intoapp/Madeira/arm64ec-windows/, or into$DEST). Building the DLL target rather thanmake -C dlls/<name>is also what winegstreamer needs (enabled by--enable-winegstreameralthough GStreamer is absent, since its unix side isbuild/ntdll-unix/winegstreamer_unixlib_ios.c). Without arguments the script rebuilds the stock builtins added for games:cryptsp,d3dx11_43,faultrep,msvcp110,msvcr110andxaudio2_7, and the builtins games and their installers import that the farm did not have (GAME_MODULESin the script: older VC++ runtimes, D3DX and d3dcompiler versions, XAudio2/X3DAudio/XAPOFX,d3d10,avifil32,d2d1,wmvcorewithwinegstreamer,netprofm), all committed inapp/Madeira/arm64ec-windows/like every other builtin. Every module the script builds links its delay imports as plain imports (UNDELAY=0keeps them; the script says why), andtools/check-wine-media-dlls.pythen checks the Windows Media Format reader's exports and imports in the farm. It needs bison 3 fortools/wrc(macOS ships 2.3; Homebrew's is used when installed). The strip/pad step was verified this session; the configure step is UNVERIFIED from clean; build-modules.sh reproduced the five default DLLs at their shipped sizes on the development machine (2026-10-03). app/Madeira/arm64ec-windows/is the DLL farm: every file in it is linked into the prefix (system32for x64 sessions, andsysx64), so a Wine module is only available if it was built and copied there. The native D3D12 path needs two stock modules in addition to the existing ones:dcomp.dll(make -C dlls/dcomp; a 64-bit Godot 4 engine loads it before it creates its D3D12 device, and gives up on D3D12 without it) andktmw32.dll(make -C dlls/ktmw32; an optional import the same engine probes).- TaskbarList COM: the prefix registers
explorerframe.dll, which must be in the ARM64EC farm. It is in the default module list; rebuild it explicitly withbash build/wine-pe/build-modules.sh explorerframe. Seedocs/TASKBARLIST.mdfor the package check and Windows x64 COM fixture. - Stand-ins for DLLs Wine cannot provide here but games import:
python3 tools/build-stub-dlls.py wine build/stub-dlls toolchains/llvm-mingw-20260421-ucrt-macos-universal/bin/arm64ec-w64-mingw32-clang toolchains/llvm-mingw-20260421-ucrt-macos-universal/bin/llvm-readobj app/Madeira/arm64ec-windowsbuildsvulkan-1.dll(answers like a PC without a Vulkan driver, so a game falls back to D3D) and, when the farm has no Wine build of them,d3d10.dllandavifil32.dll; each exports exactly its Wine.spec. Crysis Remastered imports all three.
- unix side:
- DXMT (submodule, branch ios-port):
- unix side:
build/dxmt-ios/build.sh(needstoolchains/llvm-ios-build) ->app/Madeira/libdxmt_combined.a(ignored; the app links it). Verified this session. - PE side:
meson setup dxmt/build-arm64ec dxmt -Dbuildtype=release -Dwine_build_path=../../wine/build-arm64ec --cross-file=dxmt/build-arm64ec-win.txtthenninja -C dxmt/build-arm64ec src/winemetal/winemetal.dll(and d3d11.dll) -> copied toapp/Madeira/arm64ec-windows/. Verified this session (winemetal.dll). 4b. In-app pairing (Built-in StikJIT on iOS 27):build/rppairing-ios/build.sh(Rust with theaarch64-apple-iostarget; crates from crates.io at the versions inbuild/rppairing-ios/Cargo.lock) ->app/Madeira/libmadeira_rppairing.a(ignored; the app links it) and the bundled crate noticesapp/Madeira/legal/LICENSES-rppairing-crates.txt(tracked).cargo testin that folder runs its host tests. Verified on the development machine.
- unix side:
- Native D3D12 runtime:
build/madeira-d3d12/build-pe.sh->d3d12.dll,madeira_d3d12.dlland the test executables inapp/Madeira/arm64ec-windows/(tracked). Verified this session.build/madeira-d3d12/fetch-converter.shre-verifies the converter library;build/stage-licenses.shrefreshes the bundled licence copies (the Xcode build fails if they are stale).faultrep.dll(Windows Error Reporting stubs; Wine's faultrep lacksWerReportHang, and Ghost of Tsushima imports it):build/faultrep/build.sh->app/Madeira/arm64ec-windows/faultrep.dll(tracked like the other builtins). 5b. OpenGL (optional):build/mesa-d3d12/build.shbuilds Mesa's Windows x64 D3D12 driver from the pinned tarball withbuild/mesa-d3d12/patches/and writesopengl32.dll,libgallium_wgl.dlland the fetcheddxil.dll(withLICENSE-dxil.txt) toapp/Madeira/x86_64-opengl/(ignored). Needs bison 3, ninja, and uv orpython3 -m venvfor Meson and Mako. Meson cannot download (--wrap-mode=nodownload), and two clean builds give the same bytes.tests/host/check-mesa-fence-fallback.pychecks the fence patch against the built tree. At session start WineProcessBridge.m links these DLLs over Wine's opengl32 stub for x64 games (env.MADEIRA_OPENGL = 0selects the native WGL route; set env.MADEIRA_OPENGL = 1 for Mesa on D3D12). Without the DLLs nothing changes. Verified on the development machine 2026-10-06. - App:
xcodebuild -project app/Madeira.xcodeproj -scheme Madeira -destination 'generic/platform=iOS' -allowProvisioningUpdates build(Debug is the configuration that runs the games; Release builds have crashed the guest), then zipPayload/Madeira.appinto an IPA and sideload. Verified this session on the development machine. - WoW64 (32-bit programs, optional):
build/wine-i386/build.sh(i386 Wine farm - OpenGL and LOVE games:
- Before step 3, apply the Wine patch:
git -C wine apply ../patches/wine-opengl-winios.patch. Then rebuild the trackedopengl32.dllwithbuild/wine-pe/build-modules.sh opengl32. build/luajit-x64/build.sh->app/Madeira/compat/love/lua51.dll, needed for LOVE games.build/moltenvk-ios/build.sh, thenbuild/mesa-ios/build.sh->app/Madeira/gl/, the desktop OpenGL backend. Optional: without it the app uses OpenGL ES. The script applies every file inbuild/mesa-ios/patchesonce (a.madeira-applied-*marker in the Mesa source records it), so an existing Mesa tree picks up a new patch on the next run.- 32-bit OpenGL games (id Tech 3: Jedi Academy, Jedi Outcast, Quake III) need all of: the regenerated wow64 thunks in
wine-opengl-winios.patch(fromdlls/opengl32/make_opengl; to regenerate, runperl make_openglinwine/dlls/opengl32, which downloads the pinned Khronos registry files into~/.cache/wine),build/ntdll-unixrebuilt, and Mesa patch0004(Zink on MoltenVK: fragment inputs Metal can link, and no crash when a pipeline fails). They need the desktop OpenGL (Zink) backend; fixed-function OpenGL does not exist in OpenGL ES. A 32-bit process getsGL_EXTENSIONScut to 3072 bytes, because these engines copy it into a fixed buffer;env.MADEIRA_GL_EXTENSIONS_MAXin madeira.cfg sets another limit (0 = none). - Each script says what source to download if it is missing. Verified on the development machine.
faultrep.dll(Windows Error Reporting stubs; Wine's faultrep lacksWerReportHang, and Ghost of Tsushima imports it):build/faultrep/build.sh.
- Before step 3, apply the Wine patch:
- OpenGL games:
- Before step 3, apply the Wine patch:
git -C wine apply ../patches/wine-opengl-winios.patch. Then rebuild the trackedopengl32.dllwithbuild/wine-pe/build-modules.sh opengl32. build/moltenvk-ios/build.sh, thenbuild/mesa-ios/build.sh->app/Madeira/gl/, the desktop OpenGL backend. Optional: without it the app uses OpenGL ES. The script applies every file inbuild/mesa-ios/patchesonce (a.madeira-applied-*marker in the Mesa source records it), so an existing Mesa tree picks up a new patch on the next run.- 32-bit OpenGL games (id Tech 3: Jedi Academy, Jedi Outcast, Quake III) need all of: the regenerated wow64 thunks in
wine-opengl-winios.patch(fromdlls/opengl32/make_opengl; to regenerate, runperl make_openglinwine/dlls/opengl32, which downloads the pinned Khronos registry files into~/.cache/wine),build/ntdll-unixrebuilt, and Mesa patch0004(Zink on MoltenVK: fragment inputs Metal can link, and no crash when a pipeline fails). They need the desktop OpenGL (Zink) backend; fixed-function OpenGL does not exist in OpenGL ES. A 32-bit process getsGL_EXTENSIONScut to 3072 bytes, because these engines copy it into a fixed buffer;env.MADEIRA_GL_EXTENSIONS_MAXin madeira.cfg sets another limit (0 = none). - Each script says what source to download if it is missing. Verified on the development machine. 6b. wined3d (Direct3D 8/9 and DirectDraw on OpenGL), the second Direct3D 9 route (2026-10-12):
- Wine's
d3d9.dll,wined3d.dll,d3d8.dllandddraw.dllare stock modules built from the same trees as every other builtin, after the OpenGL patch of step 6 (wined3d importsopengl32.dlland draws through it, i.e. through the winios WGL driver and Zink on MoltenVK). wined3d has no unix side; nothing else is needed. - ARM64EC:
build/wine-pe/build-modules.sh wined3d d3d9-wined3d d3d8 ddraw, which ismake -C wine/build-arm64ec dlls/<m>/arm64ec-windows/<m>.dllfor the four modules andarm64ec-w64-mingw32-strip --strip-debug. The named3d9-wined3dbuildsdlls/d3d9and installs it asapp/Madeira/arm64ec-windows/d3d9-wined3d.dll, becaused3d9.dllthere is DXMT's frontend (the script refusesd3d9).wined3d.dll,d3d8.dllandddraw.dllgo in under their own names (no DXMT or native file uses them; d3d8 and ddraw always drew through wined3d). All four are tracked. - i386:
build/wine-i386/build.sh d3d9-wined3d wined3d d3d8 ddraw(on this PC:make -C wine/build-i386 dlls/<m>/i386-windows/<m>.dll,i686-w64-mingw32-strip --strip-debug), installing Wine's d3d9 asapp/Madeira/i386-windows/d3d9-wined3d.dllbeside the DXMT shim (d3d9.dll) andd3d9-emulated.dll. The i386 farm is not tracked. - The farms link every file into the prefix as before.
d3d9 = wined3din madeira.cfg (or a game's own lines) makesWineProcessBridge.mre-point that session'ssystem32/sysx64(ARM64EC) andsyswow64(i386)d3d9.dlllinks tod3d9-wined3d.dll; the next session without it gets DXMT's again. It needs the desktop OpenGL backend (gl-backend = zink, the default whenapp/Madeira/gl/is bundled). - Added size:
d3d9-wined3d.dll896 KiB (ARM64EC) + 276 KiB (i386); the ARM64ECwined3d.dllrebuilt from the current wine tree grew from 3.5 to 4.8 MiB (the previous one dates from 2026-08-25, older than the wine pin that builtd3d8.dll/ddraw.dll, which call into it; the export names match, the structures they pass are only guaranteed to within one tree). Unverified on a device. 6c. winevulkan and vkd3d-proton: Vulkan for x64 programs and the second Direct3D 12 route (2026-10-12, not device-tested): - Unix side (linked into the app):
build/ntdll-unix/build.shcompileswine/dlls/winevulkan/vulkan.candvulkan_thunks.cintolibntdll_unix.a(tablewinevulkan_unix_call_funcs, bound by export name invirtual_ios.c'sload_builtin_unixlib; 64-bit callers only, its wow64 thunks lack the 32-bit window base).build/win32u-unix/build.shcompilesvulkan_ios.cin place ofdlls/win32u/vulkan.c: upstream's file, with the Vulkan library opened from$MADEIRA_VULKAN_LIBRARY(unset = Vulkan off, exactly as before) and the winios Vulkan driver (VK_KHR_win32_surfaceonVK_EXT_metal_surface, the window's CAMetalLayer frommadeira_vulkan_layer_for_hwndinIOSDisplayShim.m);d3dkmt_ios.cskips D3DKMT's Vulkan instance on a thread inside Vulkan's own set-up (Apple'spthread_oncetraps on the re-entry). Rebuild both libraries (rebuild-native.sh ntdll win32uin the WSL loop). - PE side, ARM64EC:
make -C wine/build-arm64ec dlls/winevulkan/arm64ec-windows/winevulkan.dll dlls/vulkan-1/arm64ec-windows/vulkan-1.dll,arm64ec-w64-mingw32-strip --strip-debug, intoapp/Madeira/vulkan/arm64ec-windows/(a bundle folder of its own: thearm64ec-windows/farm is linked into every prefix, and a program probing forvulkan-1.dllmust keep finding none by default). No i386 build. - vkd3d-proton:
build/vkd3d-proton/build.sh(upstream750061ae2be846d19d6364628eaf5ea4beb8e619with submodules, cloned intotoolchains/vkd3d-protonwhen absent; the three patches inbuild/vkd3d-proton/patches, from another iOS port, seePATCHES.mdthere; meson cross build forarm64ec-w64-mingw32with-static; strip) ->app/Madeira/vulkan/arm64ec-windows/d3d12.dllandd3d12core.dll(git-ignored) and three licence texts inapp/Madeira/licenses/. Host tools: meson, ninja, glslangValidator. On this PC:VKD3D_SRC=/home/hero/.cache/vkd3d-proton-src VKD3D_WORK=/home/hero/.cache/vkd3d-proton-build LLVM_MINGW=/home/hero/.cache/madeira-tall6/toolchains/llvm-mingw bash build/vkd3d-proton/build.sh(about a minute). It is built with the toolchain's ownwinnt.h: itsNtCurrentTeb()and implicit-TLS reads of x18 are rewritten at load time by the same x18 patcher as every other ARM64EC DLL (Madeira's TEB slot is found at run time, so a compile-time slot does not fit); the script lists any x18 instruction the patcher would not rewrite (none in this build: 8 + 31ldr xN, [x18, #imm]). - Selection (
WineProcessBridge.m,madeira_setup_vulkan): madeira.cfgvulkan = moltenvk|kosmickrisp|off|<path>.dylibpicks the library (gl/libMoltenVK.dylib,gl/libvulkan_kosmickrisp.dylib);d3d12 = vkd3dturns Vulkan on (MoltenVK unlessvulkansays otherwise) and re-points the session'ssystem32/sysx64d3d12.dllandd3d12core.dllto vkd3d-proton's. madeira-d3d12 stays the default. Both keys also work from a game's own lines. - Presenting: DXMT's
dxgi.dll(submodule commit 03baeb58,src/dxgi/dxgi_swapchain_vk.cpp) wraps vkd3d-proton's swapchain (IDXGIVkSwapChainFactory, surfaces throughvkCreateWin32SurfaceKHRin winevulkan) as anIDXGISwapChain4, windowed only;env.MADEIRA_DXGI_VK_SWAPCHAIN = 0restores the old "Unsupported device type" refusal. Rebuild:ninja -C build-pe-arm64ec src/dxgi/dxgi.dllin the dxmt tree. - Added size: 7.7 MiB in the bundle (d3d12core.dll 6.0 MiB, winevulkan.dll 0.9, vulkan-1.dll 0.6, d3d12.dll 0.2), about 2.3 MiB compressed in the IPA, plus the winevulkan thunks in the app binary (an 0.86 MB object); no in-app download needed. 6d. DXVK: Direct3D 10/11 and DXGI on Vulkan for x64 programs, opt-in (2026-10-13, not device-tested; docs/DXVK.md):
build/dxvk/build.sh(upstream DXVKv3.1.1,b1a1c99ab52b687cf950d62c88bc2fa316b41663, with submodules, cloned intotoolchains/dxvk-srcwhen absent; the patch inbuild/dxvk/patches, seePATCHES.mdthere; meson cross build forarm64ec-w64-mingw32, D3D8/D3D9 off; strip; the same x18 check as vkd3d-proton's script) ->app/Madeira/vulkan/arm64ec-windows/dxvk-d3d11.dll,dxvk-d3d10core.dllanddxvk-dxgi.dll(git-ignored) andlicenses/DXVK-zlib.txt+licenses/libdisplay-info-MIT.txt. Host tools: meson, ninja, glslangValidator. On this PC:DXVK_SRC=/home/hero/.cache/dxvk-src DXVK_WORK=/home/hero/.cache/dxvk-build LLVM_MINGW=/home/hero/.cache/madeira-tall6/toolchains/llvm-mingw bash build/dxvk/build.sh(about 4 minutes).- Selection (
WineProcessBridge.m,madeira_setup_vulkan):d3d11 = dxvkturns Vulkan on and re-points the session'ssystem32/sysx64d3d11.dll,d3d10core.dllanddxgi.dllto thedxvk-*files; withd3d12unset it also impliesd3d12 = vkd3d(DXVK's DXGI presents only Vulkan devices). DXMT stays the default. - Added size: 14.1 MiB in the bundle, about 4.5 MiB compressed in the IPA; no in-app download needed.
- Before step 3, apply the Wine patch:
- App:
xcodebuild -project app/Madeira.xcodeproj -scheme Madeira -destination 'generic/platform=iOS' -allowProvisioningUpdates build(Debug is the configuration that runs the games; Release builds have crashed the guest), then zipPayload/Madeira.appinto an IPA and sideload. Verified this session on the development machine. - WoW64 (32-bit programs, optional):
build/wine-i386/build.sh(i386 Wine farm ->app/Madeira/i386-windows/),build/fex-wow64/build.sh(FEX WOW64 module ->app/Madeira/aarch64-windows/xtajit.dll) and the aarch64wow64.dll/wow64win.dll; see docs/WOW64.md, "Building". UNVERIFIED on macOS.
The app's Debug target linked successfully with Xcode 26.6 (iPhoneOS 26.5 SDK)
after building FEX's native FEXCore, FEXCore_Base and JemallocLibs, the
three Wine unix archives, FreeType, FFmpeg, rppairing and DXMT plus the LLVM
targets above. Wine's macOS configuration needs the llvm-mingw and bison 3
directories on PATH; make -j6 include/all generates the IDL headers the unix
builds consume. Clone FreeType as described in build/freetype-ios/build.sh.
Run build/stage-licenses.sh before the app build.
The scripts now bootstrap the wineserver archive from Wine's unchanged server
sources, generate airconv's three shader headers, and create the combined
DXMT/LLVM archive on first use. FEX explicitly selects arm64 and cortex-a78
instead of probing Linux's /proc/cpuinfo. The optional page-wait diagnostic
counter is compile-probed; SDKs without that field report pgw=-1.
The clean-build work from PR #261 is combined here. Run
bash build/wine-macos/configure.sh to configure the host Wine headers, and
bash build/llvm-ios/build.sh to build host llvm-tblgen and the iOS LLVM
archives. The latter disables app bundles, terminfo, zlib, and zstd for the
libraries the app links. FreeType's build script fetches its pinned release
when absent and refuses to replace an existing incomplete source directory.
The FEX build includes the external archives the app links. The wineserver
build selects unchanged sources from Wine's Makefile and excludes this fork's
replacement objects. It does not need a separate fixed-list base builder.
These combined changes have host script checks. A new full native-library or IPA build has not been run for the consolidation.
This run reused the release's i386 PE farm and the tracked PE resources, with
separately rebuilt ARM64EC ntdll and aarch64 wow64win. It did not rebuild every
PE module or the Windows FEX modules, so it does not establish a complete
clean-machine release build. The Microsoft x64 runtime resources came from
Microsoft's vc_redist.x64.exe, as described above. Device installation and
game compatibility are separate checks from successful native compilation.
Development signing also needs a provisioning profile authorizing both
com.apple.developer.kernel.increased-memory-limit and
com.apple.developer.kernel.extended-virtual-addressing. An existing wildcard
profile without those capabilities can sign an app which installs but cannot
reserve the WoW64 guest window. Use an explicit app identifier and regenerate
its profile through Xcode's normal signing workflow; retain those entitlements
in the app signature. On the tested M1 iPad this changed the observed task map
from 17 GB to 63 GB. This removes that reservation limit; it is not proof that
every 32-bit child process starts successfully.
A recipient of a built package can obtain the complete corresponding source of every LGPL library (Wine fork, GnuTLS, Nettle, GMP, FFmpeg) from the repository, and the application source and build scripts above. Whether they can actually relink depends on assembling the "not in the repository" inputs and re-executing the UNVERIFIED steps; that end-to-end clean-machine rebuild, signing and installation has NOT been performed. Until it is, docs/LICENSING.md keeps the relink capability marked unverified. The alternative the LGPL offers, shipping the application's object files, is not currently done.
See build/vulkan-ios/README.md for the pinned MoltenVK input, explicit
MADEIRA_MOLTENVK=1 native builds and optional app link flag, Wine DLL builds,
and Windows-side enumerate/readback/presentation fixtures. The normal native
build and app link do not require MoltenVK. Existing prerequisites above still
apply; this route is not a replacement bootstrap or complete Vulkan support.
The combined graphics source selects native WGL with OpenGL ES or Zink by
default. env.MADEIRA_OPENGL = 1 selects the separate Mesa-on-D3D12 Windows
overlay when its DLLs are built. vulkan = static selects the optional static
MoltenVK backend; the app requires that backend to be linked. The dynamic
MoltenVK and KosmicKrisp choices share the same retained-layer surface adapter.
tools/build-ipa.sh builds Dock, the 64-bit Windows runtime, and the optional
OpenGL/Vulkan backends before packaging. Wine Mono still downloads on first use.
The default graphics settings remain unchanged.
CI keeps seven separate runtime caches. Each cache uses its own source recipes, submodule pins, and the actual SDK/compiler identity. An app-only or validation-only change reuses those binaries. A failed or missing transfer rebuilds the affected component. Successful components remain cached if another component fails.
tools/build/runtime-components.py verify all checks the staged files before
Xcode builds the app. Packaging then writes runtime-build.json with the source
keys and final bundle hashes. tools/build/runtime-components.py ipa dist/Madeira.ipa
checks a completed IPA, including Dock, the graphics drivers, and their notices.
Run this command from the matching checkout and build environment. CI calls the
same check before it uploads a fresh or cached IPA.