mirror of
https://github.com/lucannez64/darling-lol.git
synced 2026-10-26 19:47:42 +00:00
fix(setup): use consistent runtime paths and reject incomplete installs
This commit is contained in:
1 parent
057f0f06d1
commit
9adfaf010f
18 files changed
+439
-48
No files matched your search
+16
-1
@@ -12,7 +12,22 @@ python3 scripts/configure.py --guest-user my-linux-user
|
||||
python3 scripts/configure.py --sdk /usr/local/libexec/darling
|
||||
```
|
||||
|
||||
The normal wrappers currently support the default `~/.darling` prefix and `/usr/local` base installation. The configurator exposes a custom prefix for developers, but several archived tools assume the default layout. Custom prefixes/install locations have not been tested end to end.
|
||||
The runtime installation wrappers resolve `DPREFIX` first, otherwise the saved
|
||||
`configure.py --prefix` setting. The configured guest account supplies the
|
||||
default guest home. `RIOT_GUEST_HOME`, when set, is an absolute **host** path
|
||||
inside the selected prefix, not a guest `/Users/...` path. Installers, runtime
|
||||
validation and the Riot launcher's guest library paths use that selection.
|
||||
Paths containing spaces are supported by isolated regression fixtures. Explicit
|
||||
environment overrides win over saved configuration; clear stale values before
|
||||
selecting a different installation.
|
||||
|
||||
A complete real installation using a custom prefix has not been verified.
|
||||
Archived tools may still assume the default layout. Runtime validation fails on
|
||||
missing expected binaries, unreadable/missing directories or checker errors;
|
||||
an empty input set is not a successful validation.
|
||||
|
||||
Runtime installation requires the selected runtime to stop before overlay
|
||||
replacement. Failed shutdown blocks replacement.
|
||||
|
||||
The build uses Unix Makefiles because the incremental runtime helpers read CMake `flags.make` and `link.txt`. Ninja is not a drop-in replacement for those helpers.
|
||||
|
||||
|
||||
@@ -17,7 +17,12 @@ build=ROOT/'build';build.mkdir(exist_ok=True)
|
||||
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)
|
||||
target=folder/source.name
|
||||
# Unlink the directory entry, including dangling symlinks. Any other error
|
||||
# must abort rather than following a leftover link or writing through it.
|
||||
target.unlink(missing_ok=True)
|
||||
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'])
|
||||
@@ -4,6 +4,7 @@ set -eu
|
||||
repo=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)
|
||||
cd "$repo"
|
||||
python3 scripts/configure.py
|
||||
. build/runtime/tools/runtime-paths.sh
|
||||
if [ -d build/venv/bin ]; then PATH="$repo/build/venv/bin:$PATH"; export PATH; fi
|
||||
# A server killed by the base install leaves a stale .init.pid that makes darling shell fail.
|
||||
python3 build/runtime/tools/ensure-darling-runtime.py
|
||||
@@ -11,8 +12,9 @@ python3 build/runtime/tools/ensure-darling-runtime.py
|
||||
darling shell /usr/bin/true
|
||||
# The prefix has no /private/tmp of its own, so the guest falls through to the root-owned
|
||||
# installed layer and every write there (the Riot installer's temp files) fails with EACCES.
|
||||
mkdir -p "$HOME/.darling/private/tmp"
|
||||
chmod 1777 "$HOME/.darling/private/tmp"
|
||||
prefix=$prefix_dir
|
||||
mkdir -p "$prefix/private/tmp"
|
||||
chmod 1777 "$prefix/private/tmp"
|
||||
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
|
||||
@@ -23,6 +25,4 @@ if [ -f build/runtime/tools/build-riot-libs-runtime.sh ]; then
|
||||
fi
|
||||
python3 build/runtime/tools/install-darling-system-profiler.py
|
||||
# Every guest process loads these overlays; refuse a set the compiler broke (check-darwin-tlv-calls.py).
|
||||
find "$HOME/.darling/Users/$(id -un)/RuntimeLibraries" "$HOME/.darling/Users/$(id -un)/RuntimeFrameworks" \
|
||||
-type f ! -name '*.before-*' ! -name '*.rt-*' ! -name '*.llvm*' -size +4k -print0 |
|
||||
xargs -0 python3 build/runtime/tools/check-darwin-tlv-calls.py
|
||||
python3 build/runtime/tools/validate-riot-runtime.py
|
||||
@@ -0,0 +1,222 @@
|
||||
"""Filesystem/subprocess fixtures: never invoke a host runtime or compiler."""
|
||||
import importlib.util
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import unittest
|
||||
from unittest.mock import patch
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
|
||||
|
||||
VALIDATION_INPUTS = (
|
||||
'RuntimeFrameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libvDSP.dylib',
|
||||
'libDarlingXShm.dylib',
|
||||
*(f'RuntimeLibraries/{name}.dylib' for name in (
|
||||
'libsystem_kernel', 'libsystem_c', 'libsystem_platform', 'libsystem_malloc',
|
||||
'libsystem_pthread', 'libobjc.A', 'libc++abi', 'libc++.1',
|
||||
'libGL', 'libindium', 'libiridium')),
|
||||
*(f'RuntimeFrameworks/{name}.framework/Versions/{version}/{name}' for name, version in (
|
||||
('AppKit', 'C'), ('QuartzCore', 'A'), ('CoreFoundation', 'A'),
|
||||
('SystemConfiguration', 'A'), ('CFNetwork', 'A'), ('IOSurface', 'A'),
|
||||
('OpenGL', 'A'), ('CoreVideo', 'A'), ('CoreAudio', 'A'), ('AudioToolbox', 'A'),
|
||||
('CoreGraphics', 'A'), ('CoreText', 'A'), ('Metal', 'A'), ('CarbonCore', 'A'),
|
||||
('LaunchServices', 'A'))),
|
||||
'RuntimeFrameworks/AppKit.framework/Versions/C/Resources/Backends/X11.backend/Contents/MacOS/X11',
|
||||
'RuntimeFrameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib',
|
||||
'Library/Audio/Plug-Ins/Components/DarlingRiotAudio.component/Contents/MacOS/CoreAudio',
|
||||
)
|
||||
|
||||
|
||||
class SetupFixture(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.tmp = tempfile.TemporaryDirectory(prefix='setup fixture ', dir=os.environ.get('TMPDIR'))
|
||||
self.addCleanup(self.tmp.cleanup)
|
||||
self.root = Path(self.tmp.name) / 'project space'
|
||||
self.root.mkdir()
|
||||
for name in ('scripts', 'tools'):
|
||||
shutil.copytree(ROOT / name, self.root / name)
|
||||
self.home = Path(self.tmp.name) / 'host home'
|
||||
self.home.mkdir()
|
||||
self.prefix = Path(self.tmp.name) / 'custom prefix'
|
||||
self.guest = self.prefix / 'Users/Guest Account'
|
||||
self.bin = Path(self.tmp.name) / 'bin'
|
||||
self.bin.mkdir()
|
||||
self.env = dict(os.environ, HOME=str(self.home), TMPDIR=self.tmp.name,
|
||||
DPREFIX=str(self.prefix), PYTHONDONTWRITEBYTECODE='1',
|
||||
PATH=str(self.bin) + ':' + os.environ['PATH'])
|
||||
self.config = dict(project_root=str(self.root), host_home=str(self.home),
|
||||
prefix=str(self.prefix), guest_user='Guest Account',
|
||||
guest_home='/Users/Guest Account', sdk=str(self.root / 'sdk'), jobs=1)
|
||||
(self.root / 'build').mkdir()
|
||||
(self.root / 'build/config.json').write_text(json.dumps(self.config))
|
||||
self.log = Path(self.tmp.name) / 'events'
|
||||
self.env['FIXTURE_LOG'] = str(self.log)
|
||||
|
||||
|
||||
def run_script(self, path, *args):
|
||||
return subprocess.run([sys.executable if path.endswith('.py') else 'sh',
|
||||
str(self.root / path), *args], env=self.env,
|
||||
text=True, capture_output=True, timeout=20)
|
||||
|
||||
|
||||
def configure(self):
|
||||
result = self.run_script('scripts/configure.py')
|
||||
self.assertEqual(result.returncode, 0, result.stderr)
|
||||
|
||||
|
||||
def stub(self, name, body):
|
||||
path = self.bin / name
|
||||
path.write_text('#!/bin/sh\nset -eu\n' + body + '\n')
|
||||
path.chmod(0o755)
|
||||
|
||||
|
||||
def runtime_stubs(self):
|
||||
# Nested Python is a strict allowlist: no accidental live helper execution.
|
||||
self.stub('python3', '''printf 'python %s\\n' "$*" >> "$FIXTURE_LOG"
|
||||
case "$1" in
|
||||
-|*runtime_paths.py) exec REAL_PYTHON "$@";;
|
||||
*stop-darling-runtime.py) [ "${STOP_FAIL:-0}" = 0 ] || exit 9; printf stopped\\n >> "$FIXTURE_LOG";;
|
||||
*build-*.py|*ensure-darling-runtime.py|*install-darling-system-profiler.py|*install-riot-*.py) :;;
|
||||
*) exit 90;;
|
||||
esac'''.replace('REAL_PYTHON', sys.executable))
|
||||
self.stub('darling', '''printf 'darling %s\\n' "$*" >> "$FIXTURE_LOG"
|
||||
if [ "$1" = shutdown ]; then sleep "${SHUTDOWN_DELAY:-0}"; exit "${SHUTDOWN_FAIL:-0}"; fi''')
|
||||
self.stub('clang', '''last=; for arg do if [ "$last" = -o ]; then printf binary > "$arg"; fi; last=$arg; done''')
|
||||
self.stub('sudo', 'exit 1')
|
||||
self.stub('make', ':')
|
||||
self.stub('cc', 'exec clang "$@"')
|
||||
self.stub('pkg-config', ':')
|
||||
self.stub('install', '''case "$(cat "$FIXTURE_LOG")" in *stopped*) :;; *) exit 88;; esac
|
||||
exec REAL_INSTALL "$@"'''.replace('REAL_INSTALL', shutil.which('install')))
|
||||
|
||||
|
||||
def test_configure_replaces_readonly_and_repeats(self):
|
||||
self.configure()
|
||||
generated = self.root / 'build/runtime/tools/run-riot-client.sh'
|
||||
generated.chmod(0o444)
|
||||
self.configure()
|
||||
self.configure()
|
||||
self.assertTrue(generated.stat().st_mode & 0o200)
|
||||
|
||||
|
||||
def test_configure_unlinks_dangling_symlink_without_writing_victim(self):
|
||||
self.configure()
|
||||
target = self.root / 'build/runtime/tools/run-riot-client.sh'
|
||||
target.unlink()
|
||||
victim = self.home / 'must not be created'
|
||||
target.symlink_to(victim)
|
||||
self.configure()
|
||||
self.assertFalse(victim.exists(), 'configure followed the dangling generated-file symlink')
|
||||
self.assertFalse(target.is_symlink())
|
||||
|
||||
|
||||
def test_presentation_creates_prerequisites_and_repeat_install(self):
|
||||
self.configure()
|
||||
self.runtime_stubs()
|
||||
self.presentation_inputs()
|
||||
for _ in range(2):
|
||||
result = self.run_script('build/runtime/tools/install-riot-presentation-runtime.sh')
|
||||
self.assertEqual(result.returncode, 0, result.stderr)
|
||||
self.assertTrue((self.guest / 'libDarlingXShm.dylib').is_file())
|
||||
self.assertTrue((self.guest / 'RuntimeLibraries/libsystem_kernel.dylib').is_file())
|
||||
self.assertIn('stopped', self.log.read_text())
|
||||
|
||||
|
||||
def presentation_inputs(self):
|
||||
for name in ('external/cocotron/AppKit/AppKit', 'external/cocotron/AppKit/X11',
|
||||
'external/cocotron/QuartzCore/QuartzCore',
|
||||
'external/corefoundation/CoreFoundation',
|
||||
'external/configd/SystemConfiguration.fproj/SystemConfiguration',
|
||||
'external/cfnetwork/src/CFNetwork',
|
||||
'external/libplatform/libsystem_platform.dylib',
|
||||
'external/xnu/darling/src/libsystem_kernel/libsystem_kernel.dylib'):
|
||||
path = self.root / 'build/darling-src/build/src' / name
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
path.write_text('library')
|
||||
for framework, version in (('AppKit', 'C'), ('QuartzCore', 'A'),
|
||||
('CoreFoundation', 'A'), ('SystemConfiguration', 'A'),
|
||||
('CFNetwork', 'A')):
|
||||
path = self.root / 'sdk/System/Library/Frameworks' / (framework + '.framework')
|
||||
binary = path / 'Versions' / version / framework
|
||||
binary.parent.mkdir(parents=True)
|
||||
binary.write_text('sdk binary')
|
||||
binary.chmod(0o555)
|
||||
(path / 'Versions/Current').symlink_to(version)
|
||||
(path / framework).symlink_to('Versions/Current/' + framework)
|
||||
if framework == 'AppKit':
|
||||
backend = binary.parent / 'Resources/Backends/X11.backend/Contents/MacOS/X11'
|
||||
backend.parent.mkdir(parents=True)
|
||||
backend.write_text('sdk backend')
|
||||
p = self.root / 'build/libcxx-install/lib'
|
||||
p.mkdir(parents=True)
|
||||
(p / 'libc++.1.0.dylib').write_text('library')
|
||||
|
||||
|
||||
def prepare_validation(self):
|
||||
self.configure()
|
||||
for relative in VALIDATION_INPUTS:
|
||||
path = self.guest / relative
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
path.write_bytes(b'\xcf\xfa\xed\xfe' + b'\0' * 5000)
|
||||
self.stub('llvm-objdump', '''printf '%s\\n' "$*" >> "$FIXTURE_LOG"
|
||||
exit "${CHECK_FAIL:-0}"''')
|
||||
|
||||
|
||||
def test_launcher_selects_paths_before_prefix_helpers(self):
|
||||
source = (ROOT / 'tools/run-riot-client.sh').read_text()
|
||||
self.assertLess(source.index('runtime-paths.sh'), source.index('ensure-darling-runtime.py'))
|
||||
|
||||
def test_paths_reject_symlink_escape(self):
|
||||
self.configure()
|
||||
outside = self.home / 'outside'
|
||||
outside.mkdir()
|
||||
self.prefix.mkdir(parents=True, exist_ok=True)
|
||||
(self.prefix / 'escape').symlink_to(outside, target_is_directory=True)
|
||||
self.env['RIOT_GUEST_HOME'] = str(self.prefix / 'escape/new-user')
|
||||
result = self.run_script('build/runtime/tools/validate-riot-runtime.py')
|
||||
self.assertNotEqual(result.returncode, 0)
|
||||
self.assertIn('inside DPREFIX', result.stderr)
|
||||
result = self.run_script('build/runtime/tools/runtime-paths.sh')
|
||||
self.assertNotEqual(result.returncode, 0)
|
||||
|
||||
def test_validation_missing_empty_and_checker_failure(self):
|
||||
self.prepare_validation()
|
||||
self.env['CHECK_FAIL'] = '1'
|
||||
self.assertNotEqual(self.run_script('build/runtime/tools/validate-riot-runtime.py').returncode, 0)
|
||||
self.env.pop('CHECK_FAIL')
|
||||
vdsp = self.guest / 'RuntimeFrameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libvDSP.dylib'
|
||||
vdsp.unlink(missing_ok=True)
|
||||
self.assertNotEqual(self.run_script('build/runtime/tools/validate-riot-runtime.py').returncode, 0)
|
||||
shutil.rmtree(self.guest)
|
||||
self.assertNotEqual(self.run_script('build/runtime/tools/validate-riot-runtime.py').returncode, 0)
|
||||
|
||||
def test_validation_uses_host_guest_override(self):
|
||||
self.prepare_validation()
|
||||
override = self.prefix / 'Users/Override Guest'
|
||||
self.guest.rename(override)
|
||||
self.env['RIOT_GUEST_HOME'] = str(override)
|
||||
result = self.run_script('build/runtime/tools/validate-riot-runtime.py')
|
||||
self.assertEqual(result.returncode, 0, result.stderr)
|
||||
self.assertIn(str(override), self.log.read_text())
|
||||
|
||||
|
||||
def test_failed_stop_with_all_compile_outputs_available(self):
|
||||
self.configure()
|
||||
self.runtime_stubs()
|
||||
self.presentation_inputs()
|
||||
self.guest.mkdir(parents=True)
|
||||
self.env['RIOT_GUEST_HOME'] = str(self.guest)
|
||||
self.env.update(STOP_FAIL='1', SHUTDOWN_FAIL='1')
|
||||
result = self.run_script('build/runtime/tools/install-riot-presentation-runtime.sh')
|
||||
self.assertNotEqual(result.returncode, 0)
|
||||
self.assertIn('stop-darling-runtime.py', self.log.read_text())
|
||||
self.assertFalse((self.guest / 'libDarlingXShm.dylib').exists())
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
@@ -51,6 +51,9 @@ def bad_accesses(path):
|
||||
return found
|
||||
|
||||
|
||||
if len(sys.argv) < 2:
|
||||
sys.exit('No runtime binaries supplied for validation')
|
||||
|
||||
status = 0
|
||||
for binary in sys.argv[1:]:
|
||||
problems = bad_accesses(binary)
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Install the host-backed system_profiler into the Darling prefix (no sudo)."""
|
||||
import os
|
||||
import json
|
||||
from pathlib import Path
|
||||
import shutil
|
||||
|
||||
from runtime_paths import runtime_paths
|
||||
|
||||
root = Path(__file__).resolve().parent
|
||||
prefix = Path(os.environ.get("DPREFIX", str(Path.home() / ".darling")))
|
||||
prefix, _ = runtime_paths(json.loads((root.parent / "build/config.json").read_text()))
|
||||
target = prefix / "usr/sbin/system_profiler"
|
||||
target.parent.mkdir(parents=True, exist_ok=True)
|
||||
staged = target.with_name(target.name + ".new")
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Manually exit the game and both clients, then shut down Darling before use.
|
||||
set -eu
|
||||
project_dir=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)
|
||||
guest_home=${RIOT_GUEST_HOME:-$HOME/.darling@GUEST_HOME@}
|
||||
. "$project_dir/tools/runtime-paths.sh"
|
||||
framework="$guest_home/RuntimeFrameworks/AppKit.framework/Versions/C"
|
||||
backup_dir=${RIOT_APPKIT_BACKUP_DIR:-$project_dir/build/appkit-runtime-backups}
|
||||
# Preflight both artifacts and destinations before replacing either binary.
|
||||
|
||||
@@ -3,8 +3,7 @@
|
||||
# Exit the game and both clients, then run darling shutdown before this script.
|
||||
set -eu
|
||||
project_dir=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)
|
||||
prefix_dir=${DPREFIX:-@DPREFIX@}
|
||||
guest_home=${RIOT_GUEST_HOME:-$prefix_dir@GUEST_HOME@}
|
||||
. "$project_dir/tools/runtime-paths.sh"
|
||||
artifact=${RIOT_CARBONCORE_ARTIFACT:-$project_dir/build/riot-CarbonCore}
|
||||
backup_dir=${RIOT_CARBONCORE_BACKUP_DIR:-$project_dir/build/carboncore-runtime-backups}
|
||||
sdk_framework="@DARLING_SDK@/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/CarbonCore.framework"
|
||||
@@ -12,6 +11,7 @@ framework="$guest_home/RuntimeFrameworks/CarbonCore.framework"
|
||||
prefix_binary="$prefix_dir/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/CarbonCore.framework/Versions/A/CarbonCore"
|
||||
[ -f "$artifact" ] || { echo "Build CarbonCore first: $artifact" >&2; exit 1; }
|
||||
[ -f "$sdk_framework/Versions/A/CarbonCore" ] || { echo "Missing SDK CarbonCore framework" >&2; exit 1; }
|
||||
python3 "$project_dir/tools/stop-darling-runtime.py"
|
||||
mkdir -p "$guest_home/RuntimeFrameworks" "$backup_dir"
|
||||
if [ ! -d "$framework" ]; then
|
||||
cp -a "$sdk_framework" "$framework"
|
||||
|
||||
@@ -17,7 +17,9 @@ import shutil
|
||||
import stat
|
||||
import tempfile
|
||||
|
||||
ROOT = Path(__file__).resolve().parent.parent
|
||||
from runtime_paths import runtime_paths
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
DEFAULT_ARTIFACT = ROOT / "build/riot-Foundation"
|
||||
|
||||
|
||||
@@ -110,9 +112,8 @@ def main():
|
||||
parser.exit(1, "The library to install does not exist: " + str(args.binary) + "; build it first: "
|
||||
"python3 build/runtime/tools/build-riot-foundation-runtime.py\n")
|
||||
config = json.loads((ROOT / "build/config.json").read_text())
|
||||
prefix = Path(config["prefix"])
|
||||
guest_home = config["guest_home"].lstrip("/")
|
||||
framework = prefix / guest_home / "RuntimeFrameworks/Foundation.framework"
|
||||
_, guest_home = runtime_paths(config)
|
||||
framework = guest_home / "RuntimeFrameworks/Foundation.framework"
|
||||
sdk_framework = Path(config["sdk"]) / "System/Library/Frameworks/Foundation.framework"
|
||||
if not sdk_framework.exists():
|
||||
parser.exit(1, "The SDK framework does not exist: " + str(sdk_framework) + "\n")
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
# Build/install the paired GPU, NV12 and display-clock runtime overrides.
|
||||
set -eu
|
||||
project_dir=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)
|
||||
guest_home=${RIOT_GUEST_HOME:-$HOME/.darling@GUEST_HOME@}
|
||||
. "$project_dir/tools/runtime-paths.sh"
|
||||
cd "$project_dir"
|
||||
mkdir -p build
|
||||
python3 tools/build-m58f333-iosurface.py
|
||||
# Rebuild the native wrapper with floating-point-safe symbol resolvers.
|
||||
make -C build/darling-src/build/src/native GL -j4
|
||||
@@ -31,6 +32,7 @@ python3 tools/build-riot-server-runtime.py
|
||||
build/riot-host-message-check
|
||||
cc -shared -fPIC -O2 -Wall -Wextra -Wl,-soname,"$project_dir/build/libdarling-xshm.so" tools/m58f299-xshm.c -o build/libdarling-xshm.so.next -pthread $(pkg-config --cflags --libs x11 x11-xcb xcb-shm xext)
|
||||
python3 tools/stop-darling-runtime.py
|
||||
mkdir -p "$guest_home/RuntimeFrameworks"
|
||||
# Host fileports own SCM_RIGHTS descriptors and must die with their last sender.
|
||||
if sudo -n true 2>/dev/null; then
|
||||
sudo make -C "$project_dir/build/darling-src/build/src/external/darlingserver" install -j12
|
||||
@@ -70,7 +72,7 @@ mkdir -p "$guest_home/RuntimeLibraries"
|
||||
gl_wrapper="$guest_home/RuntimeLibraries/libGL.dylib"
|
||||
if [ ! -f "$gl_wrapper.before-float-resolver" ]; then
|
||||
if [ -f "$gl_wrapper" ]; then cp -p "$gl_wrapper" "$gl_wrapper.before-float-resolver"
|
||||
else cp -p @DARLING_SDK@/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib "$gl_wrapper.before-float-resolver"; fi
|
||||
else cp -p "@DARLING_SDK@"/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib "$gl_wrapper.before-float-resolver"; fi
|
||||
fi
|
||||
install -m755 build/darling-src/build/src/native/libGL.dylib "$gl_wrapper.next"
|
||||
mv "$gl_wrapper.next" "$gl_wrapper"
|
||||
@@ -78,7 +80,7 @@ install -m755 build/darling-src/build/src/native/libGL.dylib "$guest_home/Runtim
|
||||
mv "$guest_home/RuntimeFrameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib.next" "$guest_home/RuntimeFrameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib"
|
||||
launchservices="$guest_home/RuntimeFrameworks/LaunchServices.framework"
|
||||
if [ ! -d "$launchservices" ]; then
|
||||
cp -a @DARLING_SDK@/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework "$launchservices"
|
||||
cp -a "@DARLING_SDK@"/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework "$launchservices"
|
||||
fi
|
||||
launchservices_binary="$launchservices/Versions/A/LaunchServices"
|
||||
if [ ! -f "$launchservices_binary.before-null-error" ]; then cp -p "$launchservices_binary" "$launchservices_binary.before-null-error"; fi
|
||||
@@ -86,12 +88,11 @@ install -m755 build/darling-src/build/src/frameworks/CoreServices/src/LaunchServ
|
||||
mv "$launchservices_binary.next" "$launchservices_binary"
|
||||
# Electron opens this subframework by its absolute path, bypassing the
|
||||
# framework search override. Replace the same binary in the stopped prefix.
|
||||
prefix_dir="${DPREFIX:-$HOME/.darling}"
|
||||
launchservices_prefix="$prefix_dir/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/LaunchServices"
|
||||
mkdir -p "$(dirname "$launchservices_prefix")"
|
||||
if [ ! -f "$launchservices_prefix.before-null-error" ]; then
|
||||
if [ -f "$launchservices_prefix" ]; then cp -p "$launchservices_prefix" "$launchservices_prefix.before-null-error"
|
||||
else cp -p @DARLING_SDK@/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/LaunchServices "$launchservices_prefix.before-null-error"; fi
|
||||
else cp -p "@DARLING_SDK@"/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/LaunchServices "$launchservices_prefix.before-null-error"; fi
|
||||
fi
|
||||
install -m755 build/darling-src/build/src/frameworks/CoreServices/src/LaunchServices/LaunchServices "$launchservices_prefix.next"
|
||||
mv "$launchservices_prefix.next" "$launchservices_prefix"
|
||||
@@ -100,7 +101,7 @@ vdsp_prefix="$prefix_dir/System/Library/Frameworks/Accelerate.framework/Versions
|
||||
mkdir -p "$(dirname "$vdsp_prefix")"
|
||||
if [ ! -f "$vdsp_prefix.before-vdsp" ]; then
|
||||
if [ -f "$vdsp_prefix" ]; then cp -p "$vdsp_prefix" "$vdsp_prefix.before-vdsp"
|
||||
else cp -p @DARLING_SDK@/System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libvDSP.dylib "$vdsp_prefix.before-vdsp"; fi
|
||||
else cp -p "@DARLING_SDK@"/System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libvDSP.dylib "$vdsp_prefix.before-vdsp"; fi
|
||||
fi
|
||||
install -m755 build/darling-src/build/src/frameworks/Accelerate/vecLib/vDSP/libvDSP.dylib "$vdsp_prefix.next"
|
||||
mv "$vdsp_prefix.next" "$vdsp_prefix"
|
||||
@@ -108,7 +109,7 @@ mv "$vdsp_prefix.next" "$vdsp_prefix"
|
||||
component="$guest_home/Library/Audio/Plug-Ins/Components/DarlingRiotAudio.component"
|
||||
if [ ! -d "$component" ]; then
|
||||
mkdir -p "$(dirname "$component")"
|
||||
cp -a @DARLING_SDK@/System/Library/Components/CoreAudio.component "$component"
|
||||
cp -a "@DARLING_SDK@"/System/Library/Components/CoreAudio.component "$component"
|
||||
fi
|
||||
component_binary="$component/Contents/MacOS/CoreAudio"
|
||||
if [ ! -f "$component_binary.before-gpu-direct" ]; then cp -p "$component_binary" "$component_binary.before-gpu-direct"; fi
|
||||
@@ -139,7 +140,7 @@ mv "$kernel.next" "$kernel"
|
||||
allocator="$guest_home/RuntimeLibraries/libsystem_malloc.dylib"
|
||||
if [ ! -f "$allocator.before-gpu-direct" ]; then
|
||||
if [ -f "$allocator" ]; then cp -p "$allocator" "$allocator.before-gpu-direct"
|
||||
else cp -p @DARLING_SDK@/usr/lib/system/libsystem_malloc.dylib "$allocator.before-gpu-direct"; fi
|
||||
else cp -p "@DARLING_SDK@"/usr/lib/system/libsystem_malloc.dylib "$allocator.before-gpu-direct"; fi
|
||||
fi
|
||||
install -m755 build/riot-libsystem_malloc.dylib "$allocator.next"
|
||||
mv "$allocator.next" "$allocator"
|
||||
@@ -149,7 +150,7 @@ mv build/libdarling-xshm.so.next build/libdarling-xshm.so
|
||||
objc_library="$guest_home/RuntimeLibraries/libobjc.A.dylib"
|
||||
if [ ! -f "$objc_library.before-m761" ]; then
|
||||
if [ -f "$objc_library" ]; then cp -p "$objc_library" "$objc_library.before-m761"
|
||||
else cp -p @DARLING_SDK@/usr/lib/libobjc.A.dylib "$objc_library.before-m761"; fi
|
||||
else cp -p "@DARLING_SDK@"/usr/lib/libobjc.A.dylib "$objc_library.before-m761"; fi
|
||||
fi
|
||||
install -m755 build/riot-libobjc.A.dylib "$objc_library.next"
|
||||
mv "$objc_library.next" "$objc_library"
|
||||
@@ -157,7 +158,7 @@ mv "$objc_library.next" "$objc_library"
|
||||
cxxabi_library="$guest_home/RuntimeLibraries/libc++abi.dylib"
|
||||
if [ ! -f "$cxxabi_library.before-m765" ]; then
|
||||
if [ -f "$cxxabi_library" ]; then cp -p "$cxxabi_library" "$cxxabi_library.before-m765"
|
||||
else cp -p @DARLING_SDK@/usr/lib/libc++abi.dylib "$cxxabi_library.before-m765"; fi
|
||||
else cp -p "@DARLING_SDK@"/usr/lib/libc++abi.dylib "$cxxabi_library.before-m765"; fi
|
||||
fi
|
||||
install -m755 build/riot-libc++abi.dylib "$cxxabi_library.next"
|
||||
mv "$cxxabi_library.next" "$cxxabi_library"
|
||||
@@ -165,7 +166,7 @@ mv "$cxxabi_library.next" "$cxxabi_library"
|
||||
indium_library="$guest_home/RuntimeLibraries/libindium.dylib"
|
||||
if [ ! -f "$indium_library.before-m766" ]; then
|
||||
if [ -f "$indium_library" ]; then cp -p "$indium_library" "$indium_library.before-m766"
|
||||
else cp -p @DARLING_SDK@/usr/lib/darling/libindium.dylib "$indium_library.before-m766"; fi
|
||||
else cp -p "@DARLING_SDK@"/usr/lib/darling/libindium.dylib "$indium_library.before-m766"; fi
|
||||
fi
|
||||
install -m755 build/riot-libindium.dylib "$indium_library.next"
|
||||
mv "$indium_library.next" "$indium_library"
|
||||
@@ -174,7 +175,7 @@ mv "$indium_library.next" "$indium_library"
|
||||
iridium_library="$guest_home/RuntimeLibraries/libiridium.dylib"
|
||||
if [ ! -f "$iridium_library.before-m767" ]; then
|
||||
if [ -f "$iridium_library" ]; then cp -p "$iridium_library" "$iridium_library.before-m767"
|
||||
else cp -p @DARLING_SDK@/usr/lib/darling/libiridium.dylib "$iridium_library.before-m767"; fi
|
||||
else cp -p "@DARLING_SDK@"/usr/lib/darling/libiridium.dylib "$iridium_library.before-m767"; fi
|
||||
fi
|
||||
install -m755 build/riot-libiridium.dylib "$iridium_library.next"
|
||||
mv "$iridium_library.next" "$iridium_library"
|
||||
@@ -182,7 +183,7 @@ mv "$iridium_library.next" "$iridium_library"
|
||||
pthread_library="$guest_home/RuntimeLibraries/libsystem_pthread.dylib"
|
||||
if [ ! -f "$pthread_library.before-gpu-direct" ]; then
|
||||
if [ -f "$pthread_library" ]; then cp -p "$pthread_library" "$pthread_library.before-gpu-direct"
|
||||
else cp -p @DARLING_SDK@/usr/lib/system/libsystem_pthread.dylib "$pthread_library.before-gpu-direct"; fi
|
||||
else cp -p "@DARLING_SDK@"/usr/lib/system/libsystem_pthread.dylib "$pthread_library.before-gpu-direct"; fi
|
||||
fi
|
||||
install -m755 build/riot-libsystem_pthread.dylib "$pthread_library.next"
|
||||
mv "$pthread_library.next" "$pthread_library"
|
||||
@@ -23,7 +23,9 @@ import shutil
|
||||
import stat
|
||||
import tempfile
|
||||
|
||||
ROOT = Path(__file__).resolve().parent.parent
|
||||
from runtime_paths import runtime_paths
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
|
||||
# (built artifact, file name in the guest's RuntimeLibraries directory). The
|
||||
# artifacts are the ones tools/build-riot-libs-runtime.sh builds.
|
||||
@@ -91,6 +93,7 @@ def install(libraries, backup_folder):
|
||||
else:
|
||||
shutil.copy2(destination, backup)
|
||||
metadata = destination.stat() if destination.is_file() else None
|
||||
destination.parent.mkdir(parents=True, exist_ok=True)
|
||||
descriptor, temporary = tempfile.mkstemp(prefix="." + destination.name + "-staged-",
|
||||
dir=destination.parent)
|
||||
staged.append((Path(temporary), destination))
|
||||
@@ -186,9 +189,13 @@ def main(argv=None):
|
||||
parser.exit(1, str(error) + "\n")
|
||||
return
|
||||
config = json.loads((ROOT / "build/config.json").read_text())
|
||||
prefix = arguments.prefix or config["prefix"]
|
||||
guest_home = arguments.guest_home or config["guest_home"]
|
||||
libraries = destinations(prefix, guest_home)
|
||||
prefix, host_guest_home = runtime_paths(config)
|
||||
prefix = arguments.prefix or prefix
|
||||
if arguments.prefix and not os.environ.get("RIOT_GUEST_HOME"):
|
||||
host_guest_home = prefix / config["guest_home"].lstrip("/")
|
||||
if arguments.guest_home:
|
||||
host_guest_home = prefix / arguments.guest_home.lstrip("/")
|
||||
libraries = destinations(host_guest_home, "")
|
||||
if arguments.only:
|
||||
wanted = set(arguments.only.split(","))
|
||||
unknown = wanted - {name for _, name in LIBRARIES}
|
||||
|
||||
@@ -10,7 +10,9 @@ import shutil
|
||||
import stat
|
||||
import tempfile
|
||||
|
||||
ROOT = Path(__file__).resolve().parent.parent
|
||||
from runtime_paths import runtime_paths
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
# The optimized relink from tools/build-riot-kqueue-runtime.py is the library the
|
||||
# client runtime is supposed to run; the plain CMake build (no -O flag) is not.
|
||||
DEFAULT_ARTIFACT = ROOT / "build/riot-libsystem_kernel.dylib"
|
||||
@@ -84,10 +86,11 @@ def prefix_destinations(config, binary, artifact):
|
||||
install the artifact itself leaves it untouched. That is what keeps the
|
||||
optimized relink from being silently replaced by the plain CMake build.
|
||||
"""
|
||||
prefix, guest_home = runtime_paths(config)
|
||||
destinations = [
|
||||
Path(config["prefix"]) / config["guest_home"].lstrip("/") / "RuntimeLibraries/libsystem_kernel.dylib",
|
||||
guest_home / "RuntimeLibraries/libsystem_kernel.dylib",
|
||||
# Keep the per-prefix bootstrap copy consistent; leave the system SDK alone.
|
||||
Path(config["prefix"]) / "usr/lib/system/libsystem_kernel.dylib",
|
||||
prefix / "usr/lib/system/libsystem_kernel.dylib",
|
||||
]
|
||||
if not artifact.exists():
|
||||
return destinations, "the prepared artifact " + str(artifact) + " does not exist yet"
|
||||
|
||||
@@ -4,7 +4,8 @@ set -eu
|
||||
project_dir=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)
|
||||
source_dir="$project_dir/build/darling-src"
|
||||
build_dir="$source_dir/build"
|
||||
guest_home="${RIOT_GUEST_HOME:-$HOME/.darling@GUEST_HOME@}"
|
||||
. "$project_dir/tools/runtime-paths.sh"
|
||||
mkdir -p "$project_dir/build"
|
||||
make -C "$build_dir/src/external/xnu/darling/src/libsystem_kernel" system_kernel -j8
|
||||
make -C "$build_dir/src/external/libplatform" platform -j8
|
||||
make -C "$build_dir/src/external/corefoundation" CoreFoundation_x86_64 -j8
|
||||
@@ -17,14 +18,16 @@ cc -shared -fPIC -O3 -march=native -mtune=generic -Wall -Wextra \
|
||||
"$project_dir/tools/m58f299-xshm.c" -o "$project_dir/build/libdarling-xshm.next.so" \
|
||||
-pthread $(pkg-config --cflags --libs x11 x11-xcb xcb-shm xext)
|
||||
clang -target x86_64-apple-macosx11.0 -fuse-ld=lld -dynamiclib -nostdlib -O3 -march=native -mtune=generic \
|
||||
-isysroot @DARLING_SDK@ \
|
||||
-isysroot "@DARLING_SDK@" \
|
||||
-I"$source_dir/src/startup/mldr/elfcalls" \
|
||||
"-DDARLING_XSHM_HOST_LIBRARY=\"$project_dir/build/libdarling-xshm.so\"" \
|
||||
-Wl,-undefined,dynamic_lookup -Wl,-install_name,@GUEST_HOME@/libDarlingXShm.dylib \
|
||||
"$project_dir/tools/m58f299-native-wrapper.c" -o "$guest_home/libDarlingXShm.next.dylib"
|
||||
-Wl,-undefined,dynamic_lookup "-Wl,-install_name,@GUEST_HOME@/libDarlingXShm.dylib" \
|
||||
"$project_dir/tools/m58f299-native-wrapper.c" -o "$project_dir/build/libDarlingXShm.next.dylib"
|
||||
# Stop before changing the overlay's upper directory, even with atomic writes.
|
||||
darling shutdown || true
|
||||
python3 "$project_dir/tools/stop-darling-runtime.py"
|
||||
mkdir -p "$guest_home"
|
||||
mv "$project_dir/build/libdarling-xshm.next.so" "$project_dir/build/libdarling-xshm.so"
|
||||
install -m755 "$project_dir/build/libDarlingXShm.next.dylib" "$guest_home/libDarlingXShm.next.dylib"
|
||||
mv "$guest_home/libDarlingXShm.next.dylib" "$guest_home/libDarlingXShm.dylib"
|
||||
mkdir -p "$guest_home/RuntimeFrameworks"
|
||||
for framework in AppKit QuartzCore CoreFoundation SystemConfiguration CFNetwork; do
|
||||
@@ -52,7 +55,6 @@ atomic_install "$build_dir/src/external/xnu/darling/src/libsystem_kernel/libsyst
|
||||
|
||||
# Bootstrap services can start before the app's DYLD_LIBRARY_PATH is applied.
|
||||
# The prefix overlay is user-owned; install the same corrected kernel there.
|
||||
prefix_dir="${DPREFIX:-$HOME/.darling}"
|
||||
mkdir -p "$prefix_dir/usr/lib/system"
|
||||
atomic_install "$build_dir/src/external/xnu/darling/src/libsystem_kernel/libsystem_kernel.dylib" "$prefix_dir/usr/lib/system/libsystem_kernel.dylib"
|
||||
|
||||
|
||||
@@ -39,6 +39,10 @@ with open({str(log)!r}, "a") as output:
|
||||
prefix = folder / "prefix"
|
||||
(prefix / "Applications/Riot Client.app").mkdir(parents=True)
|
||||
env["DPREFIX"] = str(prefix)
|
||||
env.pop("RIOT_GUEST_HOME", None)
|
||||
(folder / "runtime-paths.sh").write_text(
|
||||
(ROOT / "tools/runtime-paths.sh").read_text()
|
||||
.replace("@DPREFIX@", str(prefix)).replace("@GUEST_HOME@", "/Users/offline-check"))
|
||||
env["DYLD_INSERT_LIBRARIES"] = "/Users/offline-check/zzlogdir.dylib:/tmp/inherited.dylib"
|
||||
env["RCLOL_APP_ARGS"] = "--inherited-shim-argument"
|
||||
env["RCLOL_APP_ARG2"] = "--inherited-shim-argument-2"
|
||||
@@ -60,7 +64,7 @@ with open({str(log)!r}, "a") as output:
|
||||
records = [json.loads(line) for line in log.read_text().splitlines()]
|
||||
maintenance = [r for r in records if r["command"] == "python3"]
|
||||
assert [Path(r["args"][0]).name for r in maintenance] == [
|
||||
"ensure-darling-runtime.py", "ensure-darling-service-accounts.py", "ensure-league-runtime-layout.py"
|
||||
"runtime_paths.py", "ensure-darling-runtime.py", "ensure-darling-service-accounts.py", "ensure-league-runtime-layout.py"
|
||||
], "unexpected automatic helper"
|
||||
launches = [r for r in records if r["command"] == "darling"]
|
||||
assert len(launches) == 1, "unexpected launch count"
|
||||
|
||||
@@ -8,6 +8,7 @@ if [ "${RCLOL_CORE_DUMPS:-0}" != 1 ]; then
|
||||
ulimit -c 0
|
||||
fi
|
||||
runner_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
|
||||
. "$runner_dir/runtime-paths.sh"
|
||||
python3 "$runner_dir/ensure-darling-runtime.py"
|
||||
python3 "$runner_dir/ensure-darling-service-accounts.py"
|
||||
python3 "$runner_dir/ensure-league-runtime-layout.py"
|
||||
@@ -21,7 +22,12 @@ for option in RCLOL_GPU_DIRECT_PRESENT RCLOL_GPU_DIRECT_ASYNC RCLOL_GPU_DIRECT_V
|
||||
eval 'value=${'"$option"'-1}'
|
||||
case "$value" in 0|'') unset "$option";; *) export "$option=$value";; esac
|
||||
done
|
||||
prefix=${DPREFIX:-$HOME/.darling}
|
||||
prefix=$prefix_dir
|
||||
# RIOT_GUEST_HOME is host-side; DYLD paths must be relative to the guest root.
|
||||
case "$guest_home" in
|
||||
"$prefix"/*) guest_path=/${guest_home#"$prefix"/} ;;
|
||||
*) echo "RIOT_GUEST_HOME must be inside DPREFIX" >&2; exit 1 ;;
|
||||
esac
|
||||
# The first-time installer puts the client in /Users/Shared/Riot Games and then
|
||||
# hands off through LaunchServices, which does not start it under Darling. Link
|
||||
# the installed client where the normal launch expects it.
|
||||
@@ -85,9 +91,9 @@ exec env -u ELECTRON_RUN_AS_NODE -u DYLD_INSERT_LIBRARIES EGL_PLATFORM=x11 \
|
||||
LANG="${RCLOL_GUEST_LOCALE:-en_US.UTF-8}" LC_ALL="${RCLOL_GUEST_LOCALE:-en_US.UTF-8}" \
|
||||
mesa_glthread="${RCLOL_MESA_GLTHREAD-${mesa_glthread-false}}" \
|
||||
XMODIFIERS="${RCLOL_XMODIFIERS:-@im=none}" DISPLAY="${DISPLAY:-:1}" \
|
||||
DYLD_LIBRARY_PATH="${DYLD_LIBRARY_PATH:-@GUEST_HOME@/RuntimeLibraries}" \
|
||||
DYLD_FRAMEWORK_PATH="${DYLD_FRAMEWORK_PATH:-@GUEST_HOME@/RuntimeFrameworks}" \
|
||||
DARLING_XSHM_LIBRARY="${DARLING_XSHM_LIBRARY:-@GUEST_HOME@/libDarlingXShm.dylib}" \
|
||||
DYLD_LIBRARY_PATH="${DYLD_LIBRARY_PATH:-$guest_path/RuntimeLibraries}" \
|
||||
DYLD_FRAMEWORK_PATH="${DYLD_FRAMEWORK_PATH:-$guest_path/RuntimeFrameworks}" \
|
||||
DARLING_XSHM_LIBRARY="${DARLING_XSHM_LIBRARY:-$guest_path/libDarlingXShm.dylib}" \
|
||||
darling "$A" --region="${RCLOL_REGION:-EUW}" --locale="${RCLOL_LOCALE:-en_GB}" \
|
||||
"$@" \
|
||||
--log-dir="@GUEST_HOME@/Library/Logs/Riot Games/Riot Client"
|
||||
--log-dir="$guest_path/Library/Logs/Riot Games/Riot Client"
|
||||
@@ -0,0 +1,18 @@
|
||||
# Sourced by configured runtime installers; RIOT_GUEST_HOME is a host path.
|
||||
# Keep these defaults aligned with runtime_paths.py.
|
||||
prefix_dir=${DPREFIX:-"@DPREFIX@"}
|
||||
guest_home=${RIOT_GUEST_HOME:-"$prefix_dir@GUEST_HOME@"}
|
||||
case "$prefix_dir" in
|
||||
/*) : ;;
|
||||
*) echo "DPREFIX must be an absolute host path" >&2; exit 1 ;;
|
||||
esac
|
||||
prefix_dir=${prefix_dir%/}
|
||||
case "$guest_home" in
|
||||
"$prefix_dir"/*) : ;;
|
||||
*) echo "RIOT_GUEST_HOME must be inside DPREFIX" >&2; exit 1 ;;
|
||||
esac
|
||||
case "$guest_home/" in
|
||||
*/../*|*/./*) echo "RIOT_GUEST_HOME must not contain dot components" >&2; exit 1 ;;
|
||||
esac
|
||||
export DPREFIX="$prefix_dir" RIOT_GUEST_HOME="$guest_home"
|
||||
python3 "@PROJECT_ROOT@/build/runtime/tools/runtime_paths.py" "$prefix_dir" || exit 1
|
||||
@@ -0,0 +1,24 @@
|
||||
"""Shared host-side destinations for configured runtime installers."""
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def runtime_paths(config):
|
||||
prefix = Path(os.environ.get("DPREFIX") or config["prefix"])
|
||||
guest_home = Path(os.environ.get("RIOT_GUEST_HOME") or
|
||||
str(prefix / config["guest_home"].lstrip("/")))
|
||||
if not prefix.is_absolute() or not guest_home.is_absolute():
|
||||
raise ValueError("Runtime paths must be absolute host paths")
|
||||
if ".." in guest_home.parts or not guest_home.is_relative_to(prefix) or guest_home == prefix:
|
||||
raise ValueError("RIOT_GUEST_HOME must be inside DPREFIX")
|
||||
if not guest_home.resolve().is_relative_to(prefix.resolve()) or guest_home.resolve() == prefix.resolve():
|
||||
raise ValueError("RIOT_GUEST_HOME must resolve inside DPREFIX")
|
||||
return prefix, guest_home
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
try:
|
||||
runtime_paths({'prefix': sys.argv[1], 'guest_home': '/'},)
|
||||
except (ValueError, OSError) as error:
|
||||
raise SystemExit(str(error))
|
||||
@@ -0,0 +1,78 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Validate installed overlays, refusing missing, empty or unreadable inputs."""
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
from runtime_paths import runtime_paths
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
REQUIRED = (
|
||||
'RuntimeFrameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libvDSP.dylib',
|
||||
'libDarlingXShm.dylib',
|
||||
*(f'RuntimeLibraries/{name}' for name in (
|
||||
'libsystem_kernel.dylib', 'libsystem_c.dylib', 'libsystem_platform.dylib',
|
||||
'libsystem_malloc.dylib', 'libsystem_pthread.dylib',
|
||||
'libobjc.A.dylib', 'libc++abi.dylib', 'libc++.1.dylib',
|
||||
'libGL.dylib', 'libindium.dylib', 'libiridium.dylib')),
|
||||
*(f'RuntimeFrameworks/{name}.framework/Versions/{version}/{name}'
|
||||
for name, version in (
|
||||
('AppKit', 'C'), ('QuartzCore', 'A'), ('CoreFoundation', 'A'),
|
||||
('SystemConfiguration', 'A'), ('CFNetwork', 'A'), ('IOSurface', 'A'),
|
||||
('OpenGL', 'A'), ('CoreVideo', 'A'), ('CoreAudio', 'A'),
|
||||
('AudioToolbox', 'A'), ('CoreGraphics', 'A'), ('CoreText', 'A'),
|
||||
('Metal', 'A'), ('CarbonCore', 'A'), ('LaunchServices', 'A'))),
|
||||
'RuntimeFrameworks/AppKit.framework/Versions/C/Resources/Backends/X11.backend/Contents/MacOS/X11',
|
||||
'RuntimeFrameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib',
|
||||
'Library/Audio/Plug-Ins/Components/DarlingRiotAudio.component/Contents/MacOS/CoreAudio',
|
||||
)
|
||||
MACHO = (b'\xcf\xfa\xed\xfe', b'\xca\xfe\xba\xbe')
|
||||
|
||||
|
||||
def inputs(guest_home):
|
||||
def enumeration_error(error):
|
||||
raise error
|
||||
|
||||
def is_macho(path):
|
||||
with path.open('rb') as source:
|
||||
return source.read(4) in MACHO
|
||||
|
||||
required = [guest_home / relative for relative in REQUIRED]
|
||||
for path in required:
|
||||
if not is_macho(path):
|
||||
raise ValueError('Expected installed Mach-O runtime binary: ' + str(path))
|
||||
binaries = set(required)
|
||||
for name in ('RuntimeLibraries', 'RuntimeFrameworks'):
|
||||
folder = guest_home / name
|
||||
if not folder.is_dir():
|
||||
raise ValueError('Missing runtime directory: ' + str(folder))
|
||||
found = []
|
||||
for directory, _, files in os.walk(folder, onerror=enumeration_error):
|
||||
for name in files:
|
||||
if any(marker in name for marker in ('.before-', '.rt-', '.llvm')):
|
||||
continue
|
||||
path = Path(directory) / name
|
||||
if is_macho(path):
|
||||
found.append(path)
|
||||
if not found:
|
||||
raise ValueError('No Mach-O runtime binaries found in ' + str(folder))
|
||||
binaries.update(found)
|
||||
return sorted(binaries)
|
||||
|
||||
|
||||
def main():
|
||||
try:
|
||||
_, guest_home = runtime_paths(json.loads((ROOT / 'build/config.json').read_text()))
|
||||
binaries = inputs(guest_home)
|
||||
subprocess.run([sys.executable, str(ROOT / 'tools/check-darwin-tlv-calls.py'),
|
||||
*map(str, binaries)], check=True)
|
||||
except (OSError, ValueError, subprocess.CalledProcessError) as error:
|
||||
print('Runtime validation failed: ' + str(error), file=sys.stderr)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
raise SystemExit(main())
|
||||
Reference in new issue
Block a user