Publish portable Darling runtime patch snapshot and testing tools

This commit is contained in:
lucannez64 committed 2026-10-12 20:15:55 +02:00
commit a96cdc62b1
186 files changed
+45822

No files matched your search

+11
View File
@@ -0,0 +1,11 @@
#!/bin/sh
set -eu
repo=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)
cd "$repo"
python3 scripts/configure.py
if [ -d build/venv/bin ]; then PATH="$repo/build/venv/bin:$PATH"; export PATH; fi
python3 scripts/prepare.py
cmake -S build/darling-src -B build/darling-src/build -G 'Unix Makefiles' \
-DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local -DENABLE_METAL=ON
cmake --build build/darling-src/build --parallel "${JOBS:-$(nproc)}"
echo 'Build complete. Install the base runtime with: sudo cmake --install build/darling-src/build'
+15
View File
@@ -0,0 +1,15 @@
from pathlib import Path
import getpass,json,os
ROOT=Path(__file__).resolve().parent.parent
def configuration():
file=ROOT/'build/config.json'
if file.exists():return json.loads(file.read_text())
username=getpass.getuser()
return {'project_root':str(ROOT),'host_home':str(Path.home()),'prefix':str(Path.home()/'.darling'),'guest_user':username,'guest_home':'/Users/'+username,'sdk':'/usr/local/libexec/darling'}
def render(text,config=None):
c=config or configuration()
for token,key in [('PROJECT_ROOT','project_root'),('HOST_HOME','host_home'),('DPREFIX','prefix'),('GUEST_USER','guest_user'),('GUEST_HOME','guest_home'),('DARLING_SDK','sdk')]:
text=text.replace('@'+token+'@',c[key])
return text
+23
View File
@@ -0,0 +1,23 @@
#!/usr/bin/env python3
"""Render local paths into ignored runtime tools; never alter the source snapshot."""
import argparse,json,os,shutil
from pathlib import Path
from common import ROOT,configuration,render
p=argparse.ArgumentParser(description=__doc__)
p.add_argument('--guest-user');p.add_argument('--prefix',type=Path);p.add_argument('--sdk',type=Path)
a=p.parse_args();c=configuration()
if a.guest_user:
if not a.guest_user.replace('_','').replace('-','').isalnum():p.error('guest user must be a simple account name')
c['guest_user']=a.guest_user;c['guest_home']='/Users/'+a.guest_user
if a.prefix:c['prefix']=str(a.prefix.expanduser().resolve())
if a.sdk:c['sdk']=str(a.sdk.expanduser().resolve())
c['project_root']=str(ROOT);c['host_home']=str(Path.home())
build=ROOT/'build';build.mkdir(exist_ok=True)
(build/'config.json').write_text(json.dumps(c,indent=2)+'\n')
folder=build/'runtime/tools';folder.mkdir(parents=True,exist_ok=True)
for source in (ROOT/'tools').iterdir():
if not source.is_file():continue
target=folder/source.name;target.write_text(render(source.read_text(),c));os.chmod(target,source.stat().st_mode & 0o777)
link=folder.parent/'build'
if not link.exists():link.symlink_to(build,target_is_directory=True)
print('Configured',len(list(folder.iterdir())),'runtime sources for',c['guest_home'])
+14
View File
@@ -0,0 +1,14 @@
#!/bin/sh
# Builds and installs the paired per-user runtime; does not copy game files.
set -eu
repo=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)
cd "$repo"
python3 scripts/configure.py
if [ -d build/venv/bin ]; then PATH="$repo/build/venv/bin:$PATH"; export PATH; fi
# Initialize the normal user-owned prefix before installing overrides.
darling shell /usr/bin/true
python3 build/runtime/tools/stop-darling-runtime.py
sh build/runtime/tools/install-riot-presentation-runtime.sh
sh build/runtime/tools/install-riot-gpu-runtime.sh
python3 build/runtime/tools/install-darling-system-profiler.py
python3 scripts/install-shim.py
+9
View File
@@ -0,0 +1,9 @@
#!/usr/bin/env python3
import os,subprocess
from pathlib import Path
from common import ROOT,configuration
c=configuration();guest=Path(c['prefix'])/c['guest_home'].lstrip('/')
guest.mkdir(parents=True,exist_ok=True)
source=ROOT/'build/runtime/tools/m58f101-logdir-shim.c';out=guest/'zzlogdir.dylib'
subprocess.run(['clang','-target','x86_64-apple-macosx11.0','-fuse-ld=lld','-dynamiclib','-nostdlib','-nodefaultlibs','-undefined','dynamic_lookup','-O2',str(source),'-Wl,-install_name,'+c['guest_home']+'/zzlogdir.dylib','-o',str(out)],check=True)
print('Installed launch argument shim')
+13
View File
@@ -0,0 +1,13 @@
#!/bin/sh
set -eu
repo=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)
cd "$repo"
region=${1:-euw}
case "$region" in euw|eune|na|br|kr|jp|lan|las|oce|ru|tr) ;; *) echo 'Use a Riot installer region code' >&2; exit 1;; esac
python3 scripts/configure.py >/dev/null
sh build/runtime/tools/fetch-installer.sh "$region" build/installer
unzip -q -o "build/installer/live.$region.zip" -d build/installer
RIOT_LAUNCHER_HOST="$repo/build/installer/Install League of Legends $region.app/Contents/MacOS/RiotClientServices"
RCLOL_REGION=$(printf '%s' "$region" | tr '[:lower:]' '[:upper:]')
export RIOT_LAUNCHER_HOST RCLOL_REGION
exec sh scripts/run.sh
+34
View File
@@ -0,0 +1,34 @@
#!/usr/bin/env python3
"""Fetch pinned Darling sources and apply each patch to its owning repository."""
import argparse,json,os,subprocess,tempfile
from pathlib import Path
from common import ROOT,render
p=argparse.ArgumentParser(description=__doc__)
p.add_argument('--source',type=Path,default=ROOT/'build/darling-src')
p.add_argument('--check-only',action='store_true',help='validate against temporary base indexes, without changing existing source')
a=p.parse_args();source=a.source.resolve();manifest=json.loads((ROOT/'upstream/manifest.json').read_text())
def run(args,**kwargs):return subprocess.run(args,check=True,**kwargs)
if not (source/'.git').exists():
if a.check_only:p.error('check-only requires an existing pinned source checkout')
source.parent.mkdir(parents=True,exist_ok=True)
run(['git','clone',manifest['upstream'],str(source)])
run(['git','-C',str(source),'checkout','--detach',manifest['revision']])
run(['git','-C',str(source),'submodule','update','--init','--recursive'])
# Never reset someone else's checkout to make a patch apply.
for component in manifest['components']:
repo=source/component['path']
actual=subprocess.check_output(['git','-C',str(repo),'rev-parse','HEAD'],text=True).strip()
if actual!=component['revision']:raise SystemExit(f"Wrong revision for {component['path']}: expected {component['revision']}, got {actual}")
patch=render((ROOT/component['patch']).read_text())
if a.check_only:
with tempfile.TemporaryDirectory(prefix='darling-patch-index-') as tmp:
env=dict(os.environ,GIT_INDEX_FILE=str(Path(tmp)/'index'))
run(['git','-C',str(repo),'read-tree',component['revision']],env=env)
run(['git','-C',str(repo),'apply','--cached','--check','--whitespace=nowarn','-'],input=patch,text=True,env=env)
else:
already=subprocess.run(['git','-C',str(repo),'apply','--reverse','--check','-'],input=patch,text=True,stdout=subprocess.DEVNULL,stderr=subprocess.DEVNULL).returncode==0
if not already:
run(['git','-C',str(repo),'apply','--check','-'],input=patch,text=True)
run(['git','-C',str(repo),'apply','--whitespace=nowarn','-'],input=patch,text=True)
print(('Checked ' if a.check_only else 'Prepared ')+component['path'],flush=True)
print('All',len(manifest['components']),'component patches validated' if a.check_only else 'component patches ready')
Executable
+7
View File
@@ -0,0 +1,7 @@
#!/bin/sh
set -eu
repo=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)
cd "$repo"
python3 scripts/configure.py >/dev/null
if [ -d build/venv/bin ]; then PATH="$repo/build/venv/bin:$PATH"; export PATH; fi
exec sh build/runtime/tools/run-riot-ux-with-logdir-shim.sh
+33
View File
@@ -0,0 +1,33 @@
#!/usr/bin/env python3
"""Validate the public source package without launching apps or installing anything."""
import ast,json,re,subprocess,sys
from pathlib import Path
from common import ROOT
subprocess.run([sys.executable,str(ROOT/'scripts/configure.py')],check=True)
files=subprocess.check_output(['git','-C',str(ROOT),'ls-files','-z']).decode().split('\0')
errors=[]
secret_patterns=[r'gh[pousr]_[A-Za-z0-9]{30,}',r'AKIA[0-9A-Z]{16}',r'eyJ[A-Za-z0-9_-]{20,}\.[A-Za-z0-9_-]{20,}\.[A-Za-z0-9_-]{20,}',r'-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----']
for name in filter(None,files):
p=ROOT/name;data=p.read_bytes()
if data.startswith((b'\x7fELF',b'MZ',b'\xcf\xfa\xed\xfe',b'\xca\xfe\xba\xbe')) or b'\0' in data:
errors.append(name+': binary content is not part of this source package');continue
try:text=data.decode()
except UnicodeDecodeError:errors.append(name+': non-UTF8 content');continue
if re.search(r'/(?:home|Users)/' + 'hi' + 'rew' + r'(?:/|\b)',text):
errors.append(name+': development-machine path')
if any(re.search(pattern,text) for pattern in secret_patterns):errors.append(name+': possible credential; review before publishing')
if name.split('/')[0] in ['build','logs','Config','Library'] or p.suffix in ['.dylib','.so','.asar','.perf','.zip']:
errors.append(name+': local artifact')
for p in list((ROOT/'scripts').glob('*.py'))+list((ROOT/'build/runtime/tools').glob('*.py')):
try:ast.parse(p.read_text(),filename=str(p))
except SyntaxError as e:errors.append(p.name+': '+str(e))
for p in list((ROOT/'scripts').glob('*.sh'))+list((ROOT/'build/runtime/tools').glob('*.sh')):
result=subprocess.run(['bash','-n',str(p)],capture_output=True,text=True)
if result.returncode:errors.append(p.name+': shell syntax error')
manifest=json.loads((ROOT/'upstream/manifest.json').read_text())
for c in manifest['components']:
if not re.fullmatch('[0-9a-f]{40}',c['revision']):errors.append(c['path']+': invalid pinned revision')
if not (ROOT/c['patch']).is_file():errors.append(c['path']+': patch missing')
if errors:
print('\n'.join(errors));raise SystemExit(1)
print('PASS: tracked source audit, rendered Python/shell syntax and',len(manifest['components']),'pinned patch entries')