diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 171b2d3..c2f3b4e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -379,6 +379,22 @@ jobs: # `bundled,models` is a heavier build — it links sherpa-onnx — so it is a second step rather # than a change to the one above: the ten fast suites should not wait for it to fail. - run: cargo build --bin summo-engine --features bundled,models + # sherpa-onnx ships as a shared library, and it is the crate's *build script* that puts it + # beside the binary — so a cache hit, which skips the build script, produces a binary linked + # with an `$ORIGIN` rpath and nothing at `$ORIGIN` to find. The daemon then dies with + # "libsherpa-onnx-c-api.so: cannot open shared object file" and the harness reports it as + # "the daemon did not come up", which is a long way from the cause. + # + # Rebuilding just that crate is the cheapest way to make the copy happen again, and it only + # costs anything on the runs where it was missing. + - name: The speech libraries, beside the binary + run: | + ls -l target/debug/libsherpa* 2>/dev/null || echo "not beside the binary" + if [ ! -e target/debug/libsherpa-onnx-c-api.so ]; then + cargo clean -p sherpa-rs-sys + cargo build --bin summo-engine --features bundled,models + ls -l target/debug/libsherpa* + fi - run: pnpm -C apps/web e2e:full-flow env: SUMMO_REGISTRY_DIR: ${{ github.workspace }}/.registry diff --git a/apps/web/e2e/daemon.mjs b/apps/web/e2e/daemon.mjs index c733474..e3e3354 100644 --- a/apps/web/e2e/daemon.mjs +++ b/apps/web/e2e/daemon.mjs @@ -128,6 +128,25 @@ Họ muốn bản dùng thử. * `port: 0` asks the operating system for a free one, so two suites running at once cannot collide * — which is what a fixed port did the first time this was tried in parallel. */ +/** + * Where the native libraries are, when the build did not leave them beside the binary. + * + * A build with `--features models` links sherpa-onnx, and the binary is linked with an `$ORIGIN` + * rpath — right for the shipped bundle, where the libraries sit beside the executable. Out of + * `target/debug` that only works because Cargo copies them there while the build script *runs*; on + * a machine with a warm cache it does not run, the copy never happens, and the daemon dies with + * "libsherpa-onnx-c-api.so: cannot open shared object file". Cargo's own `deps/` always has them, + * so the harness points at it: the failure has nothing to do with whatever is being tested, which + * is the worst kind of red build. + */ +function libraries() { + const beside = dirname(BINARY); + const key = process.platform === "darwin" ? "DYLD_LIBRARY_PATH" : "LD_LIBRARY_PATH"; + return { + [key]: [beside, join(beside, "deps"), process.env[key]].filter(Boolean).join(":"), + }; +} + export async function boot({ name = "e2e", seed = true, registry = REGISTRY } = {}) { const home = join("/tmp", `summo-${name}-${process.pid}`); rmSync(home, { recursive: true, force: true }); @@ -141,7 +160,7 @@ export async function boot({ name = "e2e", seed = true, registry = REGISTRY } = // tests a real registry without depending on a deployed CDN — and so it keeps passing when the // network is not there. A caller can substitute one: `models.mjs` builds a registry whose file // URLs point at a local server, so installing does not reach the public internet either. - env: { ...process.env, SUMMO_REGISTRY: registry }, + env: { ...process.env, SUMMO_REGISTRY: registry, ...libraries() }, }); // Detached from Node's own exit accounting. A suite that forgets `stop()` should end with a // failed assertion, not hang until whatever is running it gives up — which is how a passing diff --git a/crates/summo-cli/src/daemon.rs b/crates/summo-cli/src/daemon.rs index 37b63af..16824a6 100644 --- a/crates/summo-cli/src/daemon.rs +++ b/crates/summo-cli/src/daemon.rs @@ -117,6 +117,10 @@ pub async fn start_background(paths: &Paths, port: u16, dev: bool) -> Result String {