Files
onyx/Scripts/build-mediaremote-adapter.sh
Scarriffle a0342205fd Phase 9: Einrichtung, Autostart, Notarisierung — und die Mixer-Optik
Die Einrichtung beim ersten Start erklärt jede der vier Sachen einzeln und
fragt jede einzeln an. Vier Systemdialoge hintereinander wären der übliche
Weg und der falsche: wer nicht weiß wofür, klickt viermal „Nicht erlauben",
und danach fragt macOS nie wieder. Sie kommt beim ersten Start immer, auch
wenn zufällig schon alles erlaubt ist — sie erklärt auch den Helfer und den
Autostart.

Beim Autostart ist `requiresApproval` der Zustand, der weh tut. Wer das
Anmeldeobjekt in den Systemeinstellungen abgeschaltet hat, kann in Onyx auf
den Schalter drücken, so oft er will. Als „aus" angezeigt führt das in eine
Schleife, also steht dort jetzt, wo es weitergeht.

Der Mixer verliert den Schalter je Programm. Zehn Mini-Schalter untereinander
sind das, was den Eindruck macht; am Regler zu ziehen ist ohnehin die
Entscheidung, dieses Programm zu regeln, und der große Ausschalter stellt
alles zurück. Der Regler ist selbst gezeichnet — der Systemregler bringt sein
eigenes Erscheinungsbild mit und kann nicht zeigen, worauf es hier ankommt:
den Pegel und die Grenze bei 100 %.

Der Pegel wird im selben Durchlauf gemessen, in dem verstärkt wird, und über
`Atomic` weitergereicht. Eine gewöhnliche Eigenschaft wäre ein Wettlauf, eine
Sperre im Audiothread der klassische Weg zu Aussetzern. Dabei fällt das
`Date()` aus dem Echtzeitpfad, das dort nie hingehört hat.

Zwei Funde beim Bauen des Release-Wegs, beide hätten erst nach dem Hochladen
zur Ablehnung geführt: der Helfer wurde ohne sicheren Zeitstempel signiert,
und das Adapter-Framework ad-hoc. Beides gilt jetzt nur noch im Debug.
Scripts/release.sh prüft Zertifikat und Notarisierungsprofil vorweg, statt
nach zehn Minuten Bauen zu scheitern.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-11 10:36:26 +02:00

98 lines
3.5 KiB
Bash
Executable File

#!/bin/bash
# Baut den mediaremote-adapter aus dem mitgelieferten Quellcode.
#
# Wird als Build-Schritt des App-Targets aufgerufen. Repliziert das
# CMakeLists.txt des Projekts mit clang — cmake ist keine Voraussetzung, die
# man einem Mitentwickler zumuten will.
#
# Der Umweg über /usr/bin/perl ist kein Trick um seiner selbst willen: seit
# macOS 15.4 prüft mediaremoted Entitlements, und Fremdprogramme bekommen keine
# Now-Playing-Daten mehr. Perl ist ein berechtigtes Systemprogramm und lädt das
# hier gebaute Framework.
#
# Quelle: https://github.com/ungive/mediaremote-adapter (BSD-3-Clause),
# eingebettet unter Vendor/ — siehe ONYX-VERSION.txt für den Stand.
set -euo pipefail
export DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer
SRC="${SRC:-$(cd "$(dirname "$0")/.." && pwd)/Vendor/mediaremote-adapter}"
OUT="${OUT:?Zielverzeichnis fehlt}"
NAME=MediaRemoteAdapter
FW="$OUT/$NAME.framework"
[[ -d "$SRC" ]] || { echo "Quellen fehlen unter $SRC" >&2; exit 1; }
rm -rf "$OUT"
mkdir -p "$FW/Versions/A/Headers" "$FW/Versions/A/Resources"
SOURCES=(
"$SRC"/src/adapter/{env,get,globals,keys,now_playing,repeat,seek,send,shuffle,speed,stream,test}.m
"$SRC"/src/private/MediaRemote.m
"$SRC"/src/utility/{Debounce,helpers}.m
)
echo "→ Framework-Binary"
xcrun clang -dynamiclib -fobjc-arc -fvisibility=default -O2 \
-arch arm64 -mmacosx-version-min=26.0 \
-I"$SRC/include" -I"$SRC/src" \
-framework Foundation -framework AppKit -framework UniformTypeIdentifiers \
-install_name "@rpath/$NAME.framework/Versions/A/$NAME" \
-o "$FW/Versions/A/$NAME" \
"${SOURCES[@]}"
cp "$SRC/include/$NAME.h" "$FW/Versions/A/Headers/"
cat > "$FW/Versions/A/Resources/Info.plist" <<PLIST
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleExecutable</key><string>$NAME</string>
<key>CFBundleIdentifier</key><string>com.vandenbe.$NAME</string>
<key>CFBundleName</key><string>$NAME</string>
<key>CFBundlePackageType</key><string>FMWK</string>
<key>CFBundleShortVersionString</key><string>0.1</string>
<key>CFBundleVersion</key><string>0.1.0</string>
</dict>
</plist>
PLIST
ln -sf A "$FW/Versions/Current"
ln -sf "Versions/Current/$NAME" "$FW/$NAME"
ln -sf Versions/Current/Headers "$FW/Headers"
ln -sf Versions/Current/Resources "$FW/Resources"
echo "→ Test-Client"
xcrun clang -fobjc-arc -O2 -arch arm64 \
-I"$SRC/src/test" \
-framework Foundation -framework MediaPlayer \
-o "$OUT/${NAME}TestClient" \
"$SRC"/src/test/{main,NowPlayingTest}.m
# Signieren.
#
# Ad-hoc genügt zum Entwickeln, aber nicht zum Notarisieren: Apple verlangt,
# dass jede Mach-O-Datei im Bundle mit derselben Developer-ID signiert ist,
# mit Hardened Runtime und sicherem Zeitstempel. Eine ad-hoc signierte
# Bibliothek führt zur Ablehnung — und die merkt man erst nach dem Hochladen.
if [ -n "${SIGN_IDENTITY:-}" ]; then
echo "→ signieren mit $SIGN_IDENTITY"
codesign --force --options runtime --timestamp \
--sign "$SIGN_IDENTITY" "$FW/Versions/A/$NAME"
codesign --force --options runtime --timestamp \
--sign "$SIGN_IDENTITY" "$FW"
codesign --force --options runtime --timestamp \
--sign "$SIGN_IDENTITY" "$OUT/${NAME}TestClient"
else
echo "→ ad-hoc signieren"
codesign --force --deep --sign - "$FW"
codesign --force --sign - "$OUT/${NAME}TestClient"
fi
cp "$SRC/bin/mediaremote-adapter.pl" "$OUT/"
echo
echo "Fertig: $OUT"
ls -la "$OUT"