Skip to content

Commit 852ccd8

Browse files
committed
Initial public release: x86-32 to C static recompiler and macOS ARM64 runtime
0 parents  commit 852ccd8

108 files changed

Lines changed: 24823 additions & 0 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.gitignore‎

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# --- Oyunun kendisi ve ondan tureyen her sey: ASLA repoya girmez ---
2+
# Oyun verisi + SPEED2.EXE (EA'nin telifli icerigi)
3+
/Need for Speed Underground 2*/
4+
# Lift edilmis C kaynagi: SPEED2.EXE'nin makine kodunun cevirisi (turev eser).
5+
# tools/reloc2.py + tools/genall.py + tools/argcount.py ile birebir yeniden uretilir.
6+
/gen/
7+
# Derlenmis ikililer, .app paketleri, dagitim zip'i, gomulu oyun verisi
8+
/out/
9+
10+
# --- Kisisel / oturum kayitlari ---
11+
/session.jsonl
12+
/Claude outputs/
13+
# Ham oturum ekran goruntuleri (secme/ ve rapor/ haric)
14+
/sunum_ss/*
15+
!/sunum_ss/secme/
16+
!/sunum_ss/rapor/
17+
18+
# --- Ortam / gecici ---
19+
/.venv/
20+
__pycache__/
21+
*.pyc
22+
.DS_Store
23+
*.o
24+
*.log

‎D3DX_HLE.md‎

Lines changed: 360 additions & 0 deletions
Large diffs are not rendered by default.

‎GRAFIK_ARASTIRMA.md‎

Lines changed: 667 additions & 0 deletions
Large diffs are not rendered by default.

‎LICENSE‎

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
Copyright (c) 2026 Talha Müderrisoğlu. All rights reserved.
2+
3+
This software and its source code, documentation, tools, images and other
4+
files in this repository (the "Software") are proprietary.
5+
6+
1. Personal use. You may download, build, run and modify the Software on
7+
your own computers, for your own personal, non-commercial use only, with
8+
your own legally obtained copy of the game.
9+
10+
2. Everything else requires permission. You may not publish, distribute,
11+
share, upload, host, sell, sublicense or otherwise make available the
12+
Software, any modified version of it, or any work derived from it, in
13+
whole or in part, in source or binary form, and you may not use it for
14+
any commercial purpose, without the prior written permission of the
15+
copyright holder. This includes forks, ports, mirrors and builds made from
16+
the Software.
17+
18+
3. Requesting permission. Open an issue at
19+
https://github.com/TalhaMudo/NFSU2Recomp to ask for permission. Any
20+
permission given applies only to what it explicitly states.
21+
22+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25+
AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
26+
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28+
29+
Earlier copies: earlier versions of this project that were distributed under
30+
other license terms remain subject to those terms only for those exact copies.
31+
This license applies to this version and all later versions.

‎PROJECT.md‎

Lines changed: 1450 additions & 0 deletions
Large diffs are not rendered by default.

‎README.md‎

Lines changed: 232 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,232 @@
1+
# NFSU2 on Apple Silicon — static recompilation of a Win32/x86 game to native ARM64
2+
3+
This repository contains the tools and runtime that turn the original Windows
4+
executable of *Need for Speed: Underground 2* (2004, 32-bit x86, Direct3D 9)
5+
into a **native ARM64 macOS binary**. The game's x86 machine code is lifted to
6+
C ahead of time and compiled with clang. There is no Wine, no emulator, no JIT
7+
and no Windows involved at run time.
8+
9+
> **This repository contains no game code and no game assets.** It contains the
10+
> recompiler and the runtime only. You need your own copy of the game; the C
11+
> code generated from its executable and the resulting binaries are derived
12+
> from the game and are not, and must not be, distributed here.
13+
14+
![Race, native ARM64 build](sunum_ss/secme/27_20260924_guncel-yaris.jpg)
15+
16+
## Status
17+
18+
The game boots, reaches the menus, and races are playable with sound.
19+
20+
| Area | State |
21+
|---|---|
22+
| x86-32 → C lifter (integer, x87, MMX, SSE/SSE2, 3DNow!, string ops) | 23,278 functions, 132.5 MB of generated C |
23+
| Win32 layer (CRT startup, heap, TLS, threads, files, registry, window) | working |
24+
| Direct3D 9 → Metal, shader bytecode (vs/ps 1.x–2.x) → MSL | working |
25+
| DirectSound → CoreAudio, DirectInput (keyboard, mouse) | working |
26+
| Windowed, fullscreen, Retina-native and 1080p widescreen | working |
27+
| Double-clickable `.app` (`./pack.sh`) | working |
28+
| Optional "HD" build: 4× MSAA, SSR, ray-traced reflections | working, see `GRAFIK_ARASTIRMA.md` |
29+
30+
### Known limitations
31+
32+
- **Exactly one build of `SPEED2.EXE` is supported** (see [Requirements](#requirements)).
33+
Game addresses are hard-coded in the runtime, and the pipeline relies on a
34+
property of that particular file (below).
35+
- Videos are skipped: there is no VP6 decoder.
36+
- Keyboard and mouse only; no gamepad or wheel support. No network play.
37+
- Structured exception handling is not implemented (`RtlUnwind` /
38+
`RaiseException` are stubs).
39+
- x87 is modelled with 64-bit doubles, not 80-bit extended precision.
40+
- One workaround with an unknown root cause remains: the front end's
41+
world-view-projection matrix arrives broken and an identity matrix is injected
42+
instead (`FIXMAT`, see `run.sh`).
43+
- 400 instructions in rarely used opcodes are still emitted as traps. None are
44+
hit in the measured race scene.
45+
- Some visuals are unverified against a Windows reference (crowds / skinned
46+
meshes, HUD seams). See "Kalan grafik maddeleri" in `PROJECT.md`.
47+
48+
## How it works
49+
50+
```
51+
SPEED2.EXE (PE32, x86)
52+
│ tools/reloc2.py recover the relocation table → out/relocs.txt
53+
│ tools/genall.py recursive-descent discovery + tools/lift.py
54+
▼ x86 → C, one C function per guest function
55+
gen/all/shard_*.c (128 files) + fntab.c (guest address → native function)
56+
│ build.sh clang -O3, in parallel
57+
▼
58+
runtime/ (hand-written) CPU state, guest memory, Win32, D3D9→Metal, audio
59+
│ link.sh
60+
▼
61+
out/nfsu2_boot 46 MB arm64 Mach-O
62+
```
63+
64+
- **Pointers vs. constants.** The hard problem of x86 static recompilation is
65+
telling a 4-byte address from a 4-byte number. This executable has its
66+
relocation *directory entry* zeroed, but the relocation *data* is still
67+
physically present in an unnamed section. `tools/reloc2.py` parses it by hand:
68+
91,106 absolute addresses, all of which point into the image. Function
69+
discovery and jump-table recovery are seeded from it.
70+
- **Guest memory.** The 32-bit guest address space is reserved with `mmap`;
71+
guest→host translation is a single ARM64 addressing mode
72+
(`ldr w8, [x_base, w_addr, uxtw]`).
73+
- **Indirect calls** go through an O(1) table indexed by guest address.
74+
- **Code generated at run time.** The game writes small x86 thunks to its stack
75+
and calls them. `runtime/genexec.c` detects these and runs them in a small
76+
interpreter, handing calls back to lifted functions.
77+
- **D3DX effects.** The statically linked D3DX9 effect framework took ~47% of
78+
guest time when executed as lifted code; `runtime/d3dx_hle.c` short-circuits
79+
parts of it (`D3DX_HLE.md`).
80+
81+
| Path | What it is |
82+
|---|---|
83+
| `tools/lift.py` | x86-32 → C lifter, with lazy EFLAGS (flag liveness) |
84+
| `tools/genall.py` | function discovery, parallel generation, sharding |
85+
| `tools/reloc2.py` | relocation table recovery |
86+
| `tools/argcount.py` | stdcall argument counts for imports |
87+
| `tools/isatest.py`, `tools/fuzzisa.py` | instruction-semantics tests and differential fuzzer |
88+
| `runtime/cpu.h`, `mem.c`, `dispatch.c`, `genexec.c` | CPU state, guest memory, dispatch, run-time code |
89+
| `runtime/win32.c`, `win32_ext.c`, `fileio.c`, `res.c` | Win32 API layer |
90+
| `runtime/com.c`, `metal.m`, `vsemu.c` | Direct3D 9 / DirectInput / DirectSound COM layer, Metal renderer, shader translation |
91+
| `runtime/audio.m` | CoreAudio output |
92+
| `runtime/overrides.c`, `d3dx_hle.c` | hand-written replacements for specific game functions |
93+
| `runtime/enhance.c` | HD build only (`-DNFS_ENHANCED=1`) |
94+
| `runtime/bundle.m`, `pack.sh` | `.app` behaviour and packaging |
95+
| `tests/boot.c` | program entry point (runs the game from its PE entry point) |
96+
97+
## Verification
98+
99+
- **Instruction semantics:** 169 hand-written tests, 439 checks
100+
(`tools/isatest.py` → `out/isatest`).
101+
- **Differential fuzzing against real x86:** `tools/fuzzisa.py` assembles random
102+
instruction sequences, runs them as real x86-64 code under Rosetta 2 and as
103+
lifted C on ARM64, and compares registers, flags and memory.
104+
- **Function-level tests:** 15 checks against lifted game functions
105+
(`out/nfsu2_all`).
106+
- **Reproducible generation:** the generated C is a pure function of the
107+
executable and the tools; regenerating gives byte-identical output.
108+
109+
`./run.sh test` runs the first and third.
110+
111+
## Performance
112+
113+
Measured on an M1 Pro at 1280×960, same scene and settings, alternating runs
114+
(method, raw numbers and caveats in `WINE_KIYAS.md`):
115+
116+
| | This port | Wine 11.18 (wined3d, Rosetta 2) |
117+
|---|---|---|
118+
| Race | 119 fps (capped by the 120 Hz display) | 10–15 fps |
119+
| 3D menus | 119 fps | 45 fps |
120+
| CPU time per frame | ~12.6 ms | ~105 ms |
121+
122+
## Requirements
123+
124+
- Apple Silicon Mac, macOS 11 or later. Developed on an M1 Pro, macOS 27.
125+
- Xcode Command Line Tools (`clang`).
126+
- Python 3 with `capstone` 5.x and `pefile` (`requirements.txt`).
127+
- Rosetta 2, only for `tools/fuzzisa.py`.
128+
- Your own installation of the game, with this exact executable:
129+
130+
| | |
131+
|---|---|
132+
| File | `SPEED2.EXE`, 4,788,224 bytes |
133+
| SHA-256 | `8f6a9ae2c4cfa01181d2fd755d99c6f4b7103f60273908ea1de1e719dfe2a297` |
134+
135+
Other builds have not been tested and will not work without changes.
136+
137+
## Build and run
138+
139+
Run everything from the repository root.
140+
141+
```bash
142+
export NFSU2_DATA="/path/to/Need for Speed Underground 2" # folder containing SPEED2.EXE
143+
EXE="$NFSU2_DATA/SPEED2.EXE"
144+
145+
python3 -m venv .venv && .venv/bin/pip install -r requirements.txt
146+
147+
# 1) relocation table -> out/relocs.txt
148+
.venv/bin/python tools/reloc2.py "$EXE"
149+
150+
# 2) lift every function to C -> gen/all/ (~20 s)
151+
# OVERRIDE lists the functions that runtime/overrides.c and
152+
# runtime/d3dx_hle.c wrap; it must match them or the link fails.
153+
OVERRIDE=60fab0,61e390,61f130,5c7ed0,50d510,65ae35,6623ea,66aa3f,66ace2,6691b1,669296,664a2f,663a42,688e89,663275,662edc,660a52,668e0d,664792,66ac27,65addb,65acf5,66d13a,66d303,66d7e9,66e8a9,66f501,66ca38,65ab24 \
154+
.venv/bin/python tools/genall.py "$EXE" 128
155+
156+
# 3) import argument table -> gen/all/impargs.c
157+
.venv/bin/python tools/argcount.py "$EXE"
158+
159+
# 4) compile the shards, then build the runtime and link
160+
./build.sh && ./link.sh
161+
162+
./run.sh test # ISA + function tests
163+
./run.sh # windowed
164+
./run.sh 1080p # 1920x1080, widescreen-corrected
165+
./run.sh hd # HD build
166+
./pack.sh # out/NFSU2.app
167+
```
168+
169+
`run.sh` documents the environment switches; most are diagnostics.
170+
171+
## Related work
172+
173+
Static recompilation of x86 is not new, and this is not the first project to do
174+
it:
175+
176+
- [M-HT/SR](https://github.com/M-HT/SR) statically recompiles DOS and Windows
177+
game executables (Septerra Core, Battle Isle 3 and others) at assembly level,
178+
for targets including macOS arm64.
179+
- [sp00nznet/xboxrecomp](https://github.com/sp00nznet/xboxrecomp) lifts original
180+
Xbox (x86) games to C with a Python + Capstone pipeline very similar to this
181+
one.
182+
- [N64: Recompiled](https://github.com/N64Recomp/N64Recomp) and
183+
[XenonRecomp](https://github.com/hedge-dev/XenonRecomp) established the
184+
approach for MIPS and PowerPC consoles, and are where the method here comes
185+
from.
186+
- McSema, rev.ng, RetDec and BinRec are IR-based binary lifters from the research
187+
side.
188+
189+
What this project adds is narrower: recovering a relocation table whose
190+
directory entry was zeroed and using it to separate pointers from constants; a
191+
differential instruction fuzzer that uses Rosetta 2 as the oracle; a hybrid
192+
interpreter for x86 code the game generates at run time; and an end-to-end,
193+
playable Win32 + Direct3D 9 → macOS ARM64 + Metal port of a 23,000-function 3D
194+
game.
195+
196+
## Documentation
197+
198+
The engineering notes are in Turkish, as are the code comments.
199+
200+
- `PROJECT.md` — chronological engineering log: findings, bugs and root causes,
201+
measurements.
202+
- `D3DX_HLE.md` — high-level emulation of the D3DX effect framework.
203+
- `GRAFIK_ARASTIRMA.md` — graphics research and the HD build.
204+
- `WINE_KIYAS.md` — comparison against Wine.
205+
- `sunum_ss/rapor/nfsu2-rapor.html` — illustrated project report.
206+
207+
## How this was built
208+
209+
Development was carried out with an AI coding assistant (Claude Code) under the
210+
direction of the project owner. Goals, constraints and priorities, observations
211+
from playing the game, Windows reference material and direction decisions came
212+
from the project owner; implementation, measurement and debugging were done
213+
together with the assistant.
214+
215+
## Legal
216+
217+
Copyright (c) 2026 Talha Müderrisoğlu. All rights reserved.
218+
219+
This repository is **not open source**. You may download, build, run and
220+
modify it for your own personal, non-commercial use with your own copy of the
221+
game. Publishing, distributing or sharing it — or any modified version, port,
222+
fork or build of it — and any commercial use require prior written
223+
permission. See `LICENSE`.
224+
225+
**Permission:** to publish, share or build on this code, ask first by opening
226+
an issue in this repository.
227+
228+
This project is not affiliated with or endorsed by Electronic Arts. *Need for
229+
Speed* and *Need for Speed: Underground 2* are trademarks of Electronic Arts
230+
Inc. The repository contains none of the game's code or data. Screenshots show
231+
the game running through this port and are included for documentation; the
232+
game content in them belongs to its owners.

‎WINE_KIYAS.md‎

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# Wine kıyas ölçümü (2026-10-03)
2+
3+
Projenin çıkış noktası olan "oyunu Wine ile çalıştırma" yoluna karşı native
4+
portun ölçümü. Aynı makine (M1 Pro, macOS 27.0.1, 120 Hz ekran), aynı ayarlar
5+
(`~/.nfsu2_registry`: yarış çözünürlüğü indeks 3 = 1280x960, tüm efektler açık),
6+
aynı sahne (Quick Race → Circuit → Resort Loop, `TRACKS/STREAML4RA.BUN`), ses
7+
iki tarafta da kapalı. Native ve Wine **dönüşümlü** iki tur koşuldu
8+
(N → W → N → W) ki ısıl sürükleme iki tarafa eşit dağılsın.
9+
10+
## Sonuç
11+
12+
| | Native port | Wine 11.18 (wined3d, Rosetta) | oran |
13+
|---|---|---|---|
14+
| Yarış, +10..60 s | **119.3 / 119.0 fps** (8.34 ms medyan) | **11.3 / 10.0 fps** (~88–100 ms) | ~11x |
15+
| Yarış, +60..140 s | 119.8 / 119.3 fps | 14.6 / 12.8 fps (~68–78 ms) | ~8.7x |
16+
| Kare süresi p99 (yarış) | 9.4–10.6 ms | 10 sn'lik pencerelerde 4–5 fps'e düşüşler | |
17+
| 3D menüler | 119.5 / 118.7 fps | 45.4 / 45.9 fps | ~2.6x |
18+
| Oyun süreci CPU (yarış ortası) | %151 / %148 | %142 / %144 (tüm Wine süreçleri %147–151) | |
19+
| **Kare başına CPU zamanı** | **~12.6 ms** | **~105 ms** | **~8x** |
20+
| Enerji etkisi (`top` POWER) | 123 / 121 | 116 / 117 | kare başına ~8x |
21+
| RSS (oyun süreci) | ~575 MB | ~345 MB (+ wineserver) | |
22+
| Açılış güvenilirliği | 4/4 | 11 açılışın 7'si 15 sn içinde kare üretmedi (otomatik yeniden denendi) | |
23+
24+
**Native yarışta 120 Hz vsync tavanına dayalı** (`NOVSYNC=1` ile de 119–120);
25+
gerçek tavan payı bu tablodan yüksek, yani oran **en az** 8–11x.
26+
27+
Wine tarafında hiçbir thread doymuş değil: oyun thread'i ~%70–77 meşgul,
28+
`wined3d_cs` (komut thread'i) ~%44–48. Toplam CPU ~1.5 çekirdek iken kare
29+
başına 8x daha fazla CPU harcanıyor; geri kalan zaman muhtemelen thread'ler
30+
arası senkronizasyon ve GL→Metal sürücü beklemesi. Bu bir çıkarım: Rosetta
31+
altındaki kod `sample` ile sembollenmedi.
32+
33+
## Wine tarafında karşılaşılanlar (Wine yolunun gerçek maliyeti)
34+
35+
1. Homebrew'ün `wine-stable`/`wine@devel` cask'ları 2026-09-01'de kapatıldı;
36+
macOS 27 güncellemesi Rosetta 2'yi kaldırmıştı (elle yeniden kuruldu).
37+
2. Tam ekran 1280x960 macdrv'de reddediliyor (`ChangeDisplaySettings -2`) →
38+
`CreateDevice` başarısız → oyun `0x5D2790`'da null okumasıyla çöküyor.
39+
Yalnızca Wine sanal masaüstüyle açılıyor.
40+
3. Pencere Mac'te öne geçemezse (ekran kilitliyken ya da kullanıcı başka
41+
uygulamadayken) tam ekran D3D cihazı "kayıp" durumunda kalıyor, oyun
42+
donuyor. macOS 14+ kooperatif aktivasyonu ve kilitli ekran yüzünden
43+
programla öne alınamıyor.
44+
4. Açılışta aralıklı çökme (`7BF21239`, Wine DLL'i) ve sessiz kapanmalar.
45+
46+
## Yöntem ve sapmalar (dürüstlük notu)
47+
48+
- Kilitli ekran yüzünden Wine koşuları **pencereli modda** yapıldı. Bunun için
49+
oyunla gelen ThirteenAG widescreen fix ASI'si (`dinput8=n,b`) yüklendi ama
50+
`WindowedMode=2` dışındaki tüm müdahaleler kapatıldı (FixHUD/FOV, FPSLimit,
51+
SingleCoreAffinity, ConsoleGamma, SkipIntro vb. = 0). Native taraf ASI'siz.
52+
- Wine'da menü girişi zamanlamalı `keybd_event` enjektörüyle yapıldı
53+
(`~/wine-olcum/tools/mkinject.py`, clang + elle PE32), native'de `AUTOSEQ`.
54+
Pist her iki tarafta da L4RA; Wine'da araba koşudan koşuya değişti
55+
(206 / 106), native'de hep Peugeot 206.
56+
- Native fps: `FPSCSV`, yarış başı = çizimi 1000'i aşan ilk sürekli kare,
57+
`cizim > 400` kareleri. Wine fps: `WINEDEBUG=+timestamp,+fps` (~1.5 sn'lik
58+
ortalamalar, kare ağırlıklı birleştirildi), yarış başı = menülerden sonraki
59+
ilk <20 fps raporu.
60+
- CPU/RSS `ps` ile 1 sn'de bir, enerji `top -stats power` ile 5 sn'de bir.
61+
- Ham veriler ve betikler: `~/wine-olcum/` (`ab.sh`, `run_wine.sh`,
62+
`run_native.sh`, `tools/nstat.py`, `tools/wstat.py`, `tools/summary.py`,
63+
`n_ab*.csv`, `w_ab*.log`).

‎build.sh‎

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#!/bin/bash
2+
# 23k lift edilmis fonksiyonu paralel derle
3+
set -e
4+
ROOT="$(cd "$(dirname "$0")" && pwd)"
5+
# -O3 + -mcpu=native olculdu: yaris karesi ortanca 18.7 -> 15.7 ms
6+
# (53.5 -> 63.9 fps). Lifted kod cok sayida kucuk temel bloktan olusuyor,
7+
# daha agresif inline/sadelestirme dogrudan geri donuyor.
8+
# DAGITIM tabani:
9+
# -mcpu=apple-m1 : M1 tum Apple Silicon'un ortak paydasi. "native" ile
10+
# derlenirse yeni bir Mac'te uretilen ikili M1'de gecersiz
11+
# komutla coker. M1'de olculen fark sifir.
12+
# -mmacosx-version-min=11.0 : bayrak verilmezse ikili derleyen makinenin OS
13+
# surumuyle damgalanir (minos 26.0) ve eski macOS'ta
14+
# "daha yeni surum gerekiyor" diyerek hic acilmaz.
15+
MCPU="${MCPU:-apple-m1}"
16+
MINOS="${MINOS:-11.0}"
17+
OPT="${OPT:--O3 -mcpu=$MCPU -mmacosx-version-min=$MINOS}"
18+
J="${J:-$(sysctl -n hw.ncpu)}"
19+
mkdir -p "$ROOT/out/obj"
20+
cd "$ROOT/gen/all"
21+
# $OPT'u xargs komut satirina GOMME: -I{} ile kurulan satirin uzunlugu
22+
# sinirli ("command line cannot be assembled, too long"). Disaridan
23+
# ortamla gecir, ic kabuk genisletsin.
24+
#
25+
# Derleyici ciktisini DOGRUDAN "| head -5"e BAGLAMA: head 5 satirdan sonra
26+
# kapaninca clang bir sonraki uyariyi yazarken SIGPIPE ile oluyor ve nesne
27+
# dosyasi HIC yazilmiyordu (shard_0006/0019: 3 denemede 3 kez), ustelik
28+
# build.sh yine 0 donuyordu -> link "symbol(s) not found" ile kiriliyordu.
29+
# Cikti once degiskene alinir, sonra kisaltilir; clang'in cikis kodu korunur
30+
# (herhangi bir shard derlenemezse xargs, dolayisiyla build.sh hata doner).
31+
export OPT ROOT
32+
ls shard_*.c fntab.c stubs.c 2>/dev/null | \
33+
xargs -P "$J" -n 1 sh -c '
34+
o=$(clang $OPT -c -I"$ROOT/runtime" -I. -Wno-unused-label -Wno-parentheses-equality \
35+
-o "$ROOT/out/obj/$(basename "$1" .c).o" "$1" 2>&1); r=$?
36+
[ -z "$o" ] || printf "%s\n" "$o" | head -5
37+
[ $r -eq 0 ] || echo "DERLENEMEDI: $1" >&2
38+
exit $r' sh

0 commit comments

Comments
 (0)