fix(macos): pin window helper deployment target to fix older systems

- Build the Swift window-tracking helper with an explicit `-target ...-apple-macos12.0` instead of letting swiftc stamp the build machine's OS, so the overlay attaches to mpv on older macOS (e.g. Ventura) instead of crashing at load
- Fold the standalone build-macos-helper.sh into prepare-build-assets.mjs and update docs/tests to match
This commit is contained in:
2026-08-23 00:58:24 -07:00
parent 03ea903927
commit 8cb3c8c90a
5 changed files with 31 additions and 59 deletions
@@ -0,0 +1,4 @@
type: fixed
area: overlay
- The macOS window-tracking helper is now built for macOS 12.0+, so the overlay attaches to mpv on older systems (previously the helper required the macOS version of the build machine and crashed on e.g. Ventura, leaving the overlay stuck on "Overlay loading").
+1 -1
View File
@@ -6,7 +6,7 @@ For internal architecture/workflow guidance, use `docs/README.md` at the repo ro
- [Bun](https://bun.sh) - [Bun](https://bun.sh)
- A system `lua` interpreter for `bun run test:launcher` / `bun run test:plugin:src` - A system `lua` interpreter for `bun run test:launcher` / `bun run test:plugin:src`
- macOS builds compile a Swift helper via `scripts/build-macos-helper.sh` (skip with `SUBMINER_SKIP_MACOS_HELPER_BUILD=1`) - macOS builds compile a Swift helper via `scripts/prepare-build-assets.mjs` (skip with `SUBMINER_SKIP_MACOS_HELPER_BUILD=1`)
## Setup ## Setup
-54
View File
@@ -1,54 +0,0 @@
#!/bin/bash
# Build macOS window tracking helper binary
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SWIFT_SOURCE="$SCRIPT_DIR/get-mpv-window-macos.swift"
OUTPUT_DIR="$SCRIPT_DIR/../dist/scripts"
OUTPUT_BINARY="$OUTPUT_DIR/get-mpv-window-macos"
OUTPUT_SOURCE_COPY="$OUTPUT_DIR/get-mpv-window-macos.swift"
fallback_to_source() {
echo "Falling back to source fallback: $OUTPUT_SOURCE_COPY"
mkdir -p "$OUTPUT_DIR"
cp "$SWIFT_SOURCE" "$OUTPUT_SOURCE_COPY"
}
build_swift_helper() {
echo "Compiling macOS window tracking helper..."
if ! command -v swiftc >/dev/null 2>&1; then
echo "swiftc not found in PATH; skipping compilation."
return 1
fi
if ! swiftc -O "$SWIFT_SOURCE" -o "$OUTPUT_BINARY"; then
return 1
fi
chmod +x "$OUTPUT_BINARY"
echo "✓ Built $OUTPUT_BINARY"
return 0
}
# Optional skip flag for non-macOS CI/dev environments
if [[ "${SUBMINER_SKIP_MACOS_HELPER_BUILD:-}" == "1" ]]; then
echo "Skipping macOS helper build (SUBMINER_SKIP_MACOS_HELPER_BUILD=1)"
fallback_to_source
exit 0
fi
# Only build on macOS
if [[ "$(uname)" != "Darwin" ]]; then
echo "Skipping macOS helper build (not on macOS)"
fallback_to_source
exit 0
fi
# Create output directory
mkdir -p "$OUTPUT_DIR"
# Compile Swift script to binary, fallback to source if unavailable or compilation fails
if ! build_swift_helper; then
fallback_to_source
fi
+17 -2
View File
@@ -1,4 +1,5 @@
import fs from 'node:fs'; import fs from 'node:fs';
import os from 'node:os';
import path from 'node:path'; import path from 'node:path';
import { execFileSync } from 'node:child_process'; import { execFileSync } from 'node:child_process';
import { fileURLToPath } from 'node:url'; import { fileURLToPath } from 'node:url';
@@ -52,6 +53,16 @@ function fallbackToMacosSource() {
process.stdout.write(`Staged macOS helper source fallback: ${macosHelperSourceCopyPath}\n`); process.stdout.write(`Staged macOS helper source fallback: ${macosHelperSourceCopyPath}\n`);
} }
// Pin the minimum macOS to the app's own floor (Electron's `minos`). Without an
// explicit target, swiftc stamps the build machine's OS version as the binary's
// minimum and the helper fails to load on older systems (#213). The arch stays
// the host's, matching the single-arch app electron-builder packages here.
const MACOS_HELPER_DEPLOYMENT_TARGET = '12.0';
function macosHelperTarget() {
return `${os.arch() === 'x64' ? 'x86_64' : 'arm64'}-apple-macos${MACOS_HELPER_DEPLOYMENT_TARGET}`;
}
function shouldSkipMacosHelperBuild() { function shouldSkipMacosHelperBuild() {
return process.env.SUBMINER_SKIP_MACOS_HELPER_BUILD === '1'; return process.env.SUBMINER_SKIP_MACOS_HELPER_BUILD === '1';
} }
@@ -72,9 +83,13 @@ function buildMacosHelper() {
ensureDir(scriptsOutputDir); ensureDir(scriptsOutputDir);
try { try {
execFileSync('swiftc', ['-O', macosHelperSourcePath, '-o', macosHelperBinaryPath], { execFileSync(
'swiftc',
['-O', '-target', macosHelperTarget(), macosHelperSourcePath, '-o', macosHelperBinaryPath],
{
stdio: 'inherit', stdio: 'inherit',
}); },
);
fs.chmodSync(macosHelperBinaryPath, 0o755); fs.chmodSync(macosHelperBinaryPath, 0o755);
process.stdout.write(`Built macOS helper: ${macosHelperBinaryPath}\n`); process.stdout.write(`Built macOS helper: ${macosHelperBinaryPath}\n`);
} catch (error) { } catch (error) {
+8 -1
View File
@@ -8,7 +8,7 @@ test('macOS helper build creates dist scripts directory before swiftc output', (
const buildFunctionIndex = source.indexOf('function buildMacosHelper()'); const buildFunctionIndex = source.indexOf('function buildMacosHelper()');
assert.notEqual(buildFunctionIndex, -1); assert.notEqual(buildFunctionIndex, -1);
const swiftcIndex = source.indexOf("execFileSync('swiftc'", buildFunctionIndex); const swiftcIndex = source.indexOf("'swiftc'", buildFunctionIndex);
assert.notEqual(swiftcIndex, -1); assert.notEqual(swiftcIndex, -1);
const ensureDirIndex = source.lastIndexOf('ensureDir(scriptsOutputDir)', swiftcIndex); const ensureDirIndex = source.lastIndexOf('ensureDir(scriptsOutputDir)', swiftcIndex);
@@ -18,3 +18,10 @@ test('macOS helper build creates dist scripts directory before swiftc output', (
'buildMacosHelper must create dist/scripts before swiftc writes the helper binary', 'buildMacosHelper must create dist/scripts before swiftc writes the helper binary',
); );
}); });
// Regression guard for #213: an untargeted swiftc stamps the build machine's OS
// version as the helper's minimum, so released builds refuse to load on older macOS.
test('macOS helper is compiled with an explicit deployment target', () => {
assert.match(source, /-target/);
assert.match(source, /apple-macos\$\{MACOS_HELPER_DEPLOYMENT_TARGET\}/);
});