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
-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
+18 -3
View File
@@ -1,4 +1,5 @@
import fs from 'node:fs';
import os from 'node:os';
import path from 'node:path';
import { execFileSync } from 'node:child_process';
import { fileURLToPath } from 'node:url';
@@ -52,6 +53,16 @@ function fallbackToMacosSource() {
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() {
return process.env.SUBMINER_SKIP_MACOS_HELPER_BUILD === '1';
}
@@ -72,9 +83,13 @@ function buildMacosHelper() {
ensureDir(scriptsOutputDir);
try {
execFileSync('swiftc', ['-O', macosHelperSourcePath, '-o', macosHelperBinaryPath], {
stdio: 'inherit',
});
execFileSync(
'swiftc',
['-O', '-target', macosHelperTarget(), macosHelperSourcePath, '-o', macosHelperBinaryPath],
{
stdio: 'inherit',
},
);
fs.chmodSync(macosHelperBinaryPath, 0o755);
process.stdout.write(`Built macOS helper: ${macosHelperBinaryPath}\n`);
} 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()');
assert.notEqual(buildFunctionIndex, -1);
const swiftcIndex = source.indexOf("execFileSync('swiftc'", buildFunctionIndex);
const swiftcIndex = source.indexOf("'swiftc'", buildFunctionIndex);
assert.notEqual(swiftcIndex, -1);
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',
);
});
// 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\}/);
});