sherpa-onnx's native libraries, for THIS platform and no other.
sherpa publishes one native jar per platform, each 8-13 MB and each carrying
BOTH libsherpa-onnx-jni and the exact libonnxruntime it was linked
against, side by side under sherpa-onnx/native/<platform>/. Depending on
all five in deps.edn makes every machine download 51 MB to use one of them,
so core depends on the 187 KB API jar alone and the pair arrives
here, one of three ways:
sherpa_onnx.native.path names a directory holding
both libraries. This is sherpa's own first loading method, so it is also
the seam for a self-built native (an espeak-free one, say) and nothing is
downloaded or checked out from under the user.build.clj puts the BUILD HOST's native jar on the image
classpath and -H:IncludeResources bakes that one directory in, and any
JVM run that puts a sherpa-onnx-native-lib-* jar on the classpath.deps.edn pins, unpacked into ~/.vis, and handed to
sherpa through sherpa_onnx.native.path.No digest is pinned for that download: JitPack rebuilds a tag when its cache
evicts, so a pinned digest would eventually break every user rather than
catch anything. Integrity comes from the transfer being length-checked
(files/download!), from the install being atomic, and from the loaded
library having to answer version — which sherpa-native-test asserts.
;; JNI and not java.lang.foreign, because the choice is upstream's: the library
;; Vis ships, libsherpa-onnx-jni, exports 133 Java_* entry points and not one
;; SherpaOnnx* C symbol, so a Panama downcall has nothing to bind to. sherpa's C
;; API is a separate artifact — per-platform tarballs under no Maven coordinate —
;; whose 156 functions over 86 structs would leave us owning their layouts. Vis
;; does use FFM where it owns the boundary (internal/foundation/pty); here the
;; image registers the API jar's types for JNI instead
;; (reachability-metadata.json, pinned by sherpa-test).
sherpa-onnx's native libraries, for THIS platform and no other. sherpa publishes one native jar per platform, each 8-13 MB and each carrying BOTH `libsherpa-onnx-jni` and the exact `libonnxruntime` it was linked against, side by side under `sherpa-onnx/native/<platform>/`. Depending on all five in `deps.edn` makes every machine download 51 MB to use one of them, so core depends on the 187 KB API jar alone and the pair arrives here, one of three ways: - **Already loadable** — `sherpa_onnx.native.path` names a directory holding both libraries. This is sherpa's own first loading method, so it is also the seam for a self-built native (an espeak-free one, say) and nothing is downloaded or checked out from under the user. - **Embedded** — the libraries are classpath resources. That is the native image, where `build.clj` puts the BUILD HOST's native jar on the image classpath and `-H:IncludeResources` bakes that one directory in, and any JVM run that puts a `sherpa-onnx-native-lib-*` jar on the classpath. - **Downloaded** — the host platform's jar is fetched once from the same JitPack coordinate `deps.edn` pins, unpacked into `~/.vis`, and handed to sherpa through `sherpa_onnx.native.path`. No digest is pinned for that download: JitPack rebuilds a tag when its cache evicts, so a pinned digest would eventually break every user rather than catch anything. Integrity comes from the transfer being length-checked (`files/download!`), from the install being atomic, and from the loaded library having to answer `version` — which `sherpa-native-test` asserts. ;; JNI and not `java.lang.foreign`, because the choice is upstream's: the library ;; Vis ships, `libsherpa-onnx-jni`, exports 133 `Java_*` entry points and not one ;; `SherpaOnnx*` C symbol, so a Panama downcall has nothing to bind to. sherpa's C ;; API is a separate artifact — per-platform tarballs under no Maven coordinate — ;; whose 156 functions over 86 structs would leave us owning their layouts. Vis ;; does use FFM where it owns the boundary (`internal/foundation/pty`); here the ;; image registers the API jar's types for JNI instead ;; (`reachability-metadata.json`, pinned by `sherpa-test`).
(call-native f)Run f with the native runtime provisioned, reporting a linker failure -
here or inside sherpa's own loader - as native-failure rather than as a
stack trace. Every engine entry point goes through this, so no surface has to
know what a JNI is to tell a human what to do.
A linker failure met HERE is also handed to the host, because this is where it is normally met: sherpa loads its library from the static initializer of the first class a call touches, long after provisioning answered. Recording it is what stops every later call from fetching 13 MB to meet the same wall.
Run `f` with the native runtime provisioned, reporting a linker failure - here or inside sherpa's own loader - as [[native-failure]] rather than as a stack trace. Every engine entry point goes through this, so no surface has to know what a JNI is to tell a human what to do. A linker failure met HERE is also handed to the host, because this is where it is normally met: sherpa loads its library from the static initializer of the first class a call touches, long after provisioning answered. Recording it is what stops every later call from fetching 13 MB to meet the same wall.
(default-native-dir)(default-native-dir token)~/.vis path for the downloaded pair. A function, never a top-level def:
native-image initializes this namespace at BUILD time, so a captured
user.home would point every installed binary at the BUILDER's home.
~/.vis path for the downloaded pair. A function, never a top-level `def`: `native-image` initializes this namespace at BUILD time, so a captured `user.home` would point every installed binary at the BUILDER's home.
(embedded?)(embedded? token)True when the libraries are already on the classpath as resources, which is exactly where sherpa's own loader looks second.
True when the libraries are already on the classpath as resources, which is exactly where sherpa's own loader looks second.
(ensure-native!)Make sherpa's JNI loadable, ONCE, and return how: {:source :property |:embedded|:downloaded :platform <token> :dir <path?>}. Every entry point
that touches a com.k2fsa.sherpa.onnx class calls this first, because the
class's static initializer is what runs sherpa's loader — after that first
touch, a missing library is an UnsatisfiedLinkError no property can undo.
Whether an answer is worth keeping is the HOST's rule, not this pack's: a download that failed is retried on the next call, while a library this JVM has already refused to link is answered from memory instead of fetched again.
Make sherpa's JNI loadable, ONCE, and return how: `{:source :property
|:embedded|:downloaded :platform <token> :dir <path?>}`. Every entry point
that touches a `com.k2fsa.sherpa.onnx` class calls this first, because the
class's static initializer is what runs sherpa's loader — after that first
touch, a missing library is an `UnsatisfiedLinkError` no property can undo.
Whether an answer is worth keeping is the HOST's rule, not this pack's: a
download that failed is retried on the next call, while a library this JVM has
already refused to link is answered from memory instead of fetched again.(installed? dir)True when dir holds both libraries. Never a partial answer: a directory
with one of them is as unloadable as an empty one.
True when `dir` holds both libraries. Never a partial answer: a directory with one of them is as unloadable as an empty one.
(jar-url token)Where the platform jar comes from, and the ONE place a Vis release does not
mirror. sherpa's VITS path phonemizes through espeak-ng, which is compiled
INTO libsherpa-onnx-jni — 10 espeak_* symbols and its data paths are in
the shipped library — so the jar is GPL-3 object code. It is fetched by the
user from the project that published it and is never re-hosted by Vis.
Where the platform jar comes from, and the ONE place a Vis release does not mirror. sherpa's VITS path phonemizes through espeak-ng, which is compiled INTO `libsherpa-onnx-jni` — 10 `espeak_*` symbols and its data paths are in the shipped library — so the jar is GPL-3 object code. It is fetched by the user from the project that published it and is never re-hosted by Vis.
(library-names)The two files a sherpa native directory holds, in LOAD order: the ONNX
Runtime first, because sherpa loads it before its own JNI so a system copy
cannot win. System/mapLibraryName is what sherpa itself calls, so these are
libonnxruntime.dylib, libonnxruntime.so or onnxruntime.dll in step with
the platform the jar was built for.
The two files a sherpa native directory holds, in LOAD order: the ONNX Runtime first, because sherpa loads it before its own JNI so a system copy cannot win. `System/mapLibraryName` is what sherpa itself calls, so these are `libonnxruntime.dylib`, `libonnxruntime.so` or `onnxruntime.dll` in step with the platform the jar was built for.
(native-failure t)Turn a linker failure into an ex-info a HUMAN can act on.
A class whose static initializer already failed can NEVER load again in the
same process - the JVM caches that verdict - so an engine that met a missing
library once keeps answering NoClassDefFoundError however much is downloaded
afterwards. That is exactly the reported "voice only works after restarting
Vis", so in that state the message SAYS to restart instead of repeating a
linker error nobody can act on.
Turn a linker failure into an ex-info a HUMAN can act on. A class whose static initializer already failed can NEVER load again in the same process - the JVM caches that verdict - so an engine that met a missing library once keeps answering `NoClassDefFoundError` however much is downloaded afterwards. That is exactly the reported "voice only works after restarting Vis", so in that state the message SAYS to restart instead of repeating a linker error nobody can act on.
sherpa's own override, documented at the top of its LibraryUtils: a
directory holding sherpa-onnx-jni AND onnxruntime, loaded in that order.
sherpa's own override, documented at the top of its `LibraryUtils`: a directory holding sherpa-onnx-jni AND onnxruntime, loaded in that order.
(platform-token)(platform-token os-name os-arch)The sherpa-onnx/native/<token> directory name for an os/arch pair — the
MIRROR of LibraryUtils.getOsArch(), including the ORDER of its tests, since
x86_64 matches the x64 branch before the x86 one and arm64 means
win-arm64 but linux-aarch64. Drifting from it means downloading a jar
whose resources sherpa then cannot find.
The `sherpa-onnx/native/<token>` directory name for an os/arch pair — the MIRROR of `LibraryUtils.getOsArch()`, including the ORDER of its tests, since `x86_64` matches the x64 branch before the x86 one and `arm64` means `win-arm64` but `linux-aarch64`. Drifting from it means downloading a jar whose resources sherpa then cannot find.
The platforms k2-fsa publishes a native jar for. LibraryUtils also names
linux-arm, win-arm64 and the x86 pair, but no jar exists for those — they
need sherpa_onnx.native.path and a self-built library.
The platforms k2-fsa publishes a native jar for. `LibraryUtils` also names linux-arm, win-arm64 and the x86 pair, but no jar exists for those — they need `sherpa_onnx.native.path` and a self-built library.
The sherpa-onnx release this subsystem is built against. deps.edn pins tag
v<version> of the API jar and the native pair MUST come from that same tag:
the JNI and the ONNX Runtime beside it are one unit, which is the whole
reason there is no ONNX Runtime coordinate to keep in step any more.
The sherpa-onnx release this subsystem is built against. `deps.edn` pins tag `v<version>` of the API jar and the native pair MUST come from that same tag: the JNI and the ONNX Runtime beside it are one unit, which is the whole reason there is no ONNX Runtime coordinate to keep in step any more.
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |