diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 57810c00587..ebafe4afa24 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -47,6 +47,7 @@ jobs: - 'Cargo.lock' gpui: - '.gitattributes' + - 'scripts/setup.js' - 'apps/desktop-gpui/**' - 'apps/desktop/src/assets/**' - 'apps/desktop/src-tauri/src/recording_start_sound.rs' @@ -340,6 +341,18 @@ jobs: env: RUST_TARGET_TRIPLE: ${{ matrix.settings.target }} + # setup.js strips the local symbols from Microsoft's ONNX Runtime dylib + # before Cap bundles it; the C API ort loads through must still resolve + # and run a real inference. + - name: Test the prepared ONNX Runtime + if: ${{ runner.os == 'macOS' }} + shell: bash + run: | + set -euo pipefail + dylib=target/native-deps/onnxruntime/lib/libonnxruntime.dylib + nm -gU "$dylib" | grep -q OrtGetApiBase + cargo test --locked -p cap-camera-effects --lib segmentation::tests::inference_runs_from_a_caller_with_a_tiny_stack -- --ignored --exact + # The test build compiles every line the binary build does (the app has # no cfg(not(test)) code), so a separate binary build only repeated the # app crate's compile and link. Release builds still produce the binary. diff --git a/scripts/setup.js b/scripts/setup.js index d61d0898c32..278e30a588e 100644 --- a/scripts/setup.js +++ b/scripts/setup.js @@ -434,6 +434,9 @@ async function setupMacOSOnnxRuntime() { const outputDir = path.join(targetDir, "native-deps", "onnxruntime", "lib"); const outputPath = path.join(outputDir, "libonnxruntime.dylib"); const markerPath = path.join(outputDir, "asset.txt"); + // Microsoft's dylib keeps ~12 MB of local symbols nothing in Cap reads; the + // marker changes with the preparation so a cached unstripped copy is redone. + const preparedMarker = `${asset.name}:stripped`; const marker = await fs .readFile(markerPath, "utf-8") .then((value) => value.trim()) @@ -448,7 +451,7 @@ async function setupMacOSOnnxRuntime() { console.log(`Downloaded ${asset.name}`); } else console.log(`Using cached ${asset.name}`); - if (!(await fileExists(outputPath)) || marker !== asset.name) { + if (!(await fileExists(outputPath)) || marker !== preparedMarker) { await fs.rm(extractDir, { recursive: true, force: true }).catch(() => {}); await execFile("tar", ["xf", archivePath, "-C", targetDir]); await fs.mkdir(outputDir, { recursive: true }); @@ -456,8 +459,11 @@ async function setupMacOSOnnxRuntime() { path.join(extractDir, "lib", "libonnxruntime.dylib"), outputPath, ); + // Local symbols only: the exported C API (OrtGetApiBase) that ort loads + // through is unchanged. + await execFile("strip", ["-x", outputPath]); await signMacOSDylib(outputPath); - await fs.writeFile(markerPath, asset.name); + await fs.writeFile(markerPath, preparedMarker); console.log("Prepared ONNX Runtime dylib"); } else { console.log("Using cached ONNX Runtime dylib");