Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions bindings/rust/sys/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,27 @@ $env:CARGO_TARGET_DIR = "C:\tc-target"
cargo build --features vulkan
```

## Linking a prebuilt install

Set `TRANSCRIBE_DIR` (OPENSSL_DIR-style) to skip the source build and link an
existing install prefix instead:

```bash
cmake -B build -DTRANSCRIBE_INSTALL=ON [-DTRANSCRIBE_BUILD_SHARED=ON ...]
cmake --build build
cmake --install build --prefix /opt/transcribe
TRANSCRIBE_DIR=/opt/transcribe cargo build
```

The prefix must contain the installed `lib*/transcribe-link.json` manifest;
the link line is reconstructed from it exactly as in a source build. Cargo
features (`shared`, `vulkan`, ...) do not apply on this path — the prebuilt
already fixed its configuration, and the manifest records it (including
static vs shared). For a shared-library prefix, running consumer binaries
may additionally need the prefix's lib dir on the loader path (e.g.
`LD_LIBRARY_PATH=$TRANSCRIBE_DIR/lib`): the rpath the build emits does not
propagate to downstream binaries.

## Build-flag escape hatch

The features above cover the common, tested configurations. Anything else CMake
Expand Down
41 changes: 35 additions & 6 deletions bindings/rust/sys/build.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
//! Build script for `transcribe-cpp-sys`.
//!
//! Source build is the primary (and currently only) path: the `cmake` crate
//! drives the vendored C++ tree with `TRANSCRIBE_INSTALL=ON`, and the link
//! line is reconstructed from NOTHING but the installed
//! `lib/transcribe-link.json` manifest — the same artifact the `link_smoke`
//! CI lane compiles a toy C consumer against. No per-platform link lists are
//! hardcoded here (the whisper-rs drift class this avoids).
//! Source build is the primary path: the `cmake` crate drives the vendored
//! C++ tree with `TRANSCRIBE_INSTALL=ON`, and the link line is reconstructed
//! from NOTHING but the installed `lib/transcribe-link.json` manifest — the
//! same artifact the `link_smoke` CI lane compiles a toy C consumer against.
//! No per-platform link lists are hardcoded here (the whisper-rs drift class
//! this avoids).
//!
//! Prebuilt path: setting TRANSCRIBE_DIR (OPENSSL_DIR-style) to an install
//! prefix produced by `cmake --install` of a TRANSCRIBE_INSTALL=ON build
//! skips the source build entirely and links against that prefix's manifest
//! instead. Cargo features are inert there: the prebuilt already decided its
//! configuration (static/shared, backends), and the manifest records it.
//!
//! Cargo features map directly to CMake options:
//! `shared` -> TRANSCRIBE_BUILD_SHARED=ON (default: static)
Expand Down Expand Up @@ -83,6 +89,29 @@ fn main() {
println!("cargo:rerun-if-changed={}", root.join(p).display());
}

// Prebuilt path: TRANSCRIBE_DIR points at an existing install prefix (a
// `cmake --install` tree from a TRANSCRIBE_INSTALL=ON configure). Skip the
// source build and emit the link line from that prefix's manifest; the
// manifest records the install's own posture (static/shared, backends), so
// the Cargo features below never apply here.
println!("cargo:rerun-if-env-changed=TRANSCRIBE_DIR");
if let Some(dir) = env::var_os("TRANSCRIBE_DIR") {
let prefix = PathBuf::from(dir);
let manifest = find_manifest(&prefix).unwrap_or_else(|| {
panic!(
"TRANSCRIBE_DIR is set but no lib/transcribe-link.json (or lib64/) exists \
under {}. It must point at an install prefix of this library, produced by \
`cmake -B build -DTRANSCRIBE_INSTALL=ON && cmake --build build && \
cmake --install build --prefix <dir>`. Unset TRANSCRIBE_DIR to build \
the vendored sources instead.",
prefix.display()
)
});
println!("cargo:rerun-if-changed={}", manifest.display());
emit_link_lines(&prefix, &manifest);
return;
}

// `dynamic-backends` (loadable backend modules) requires a shared library,
// so it implies `shared`. The Cargo manifest already encodes that implication
// (`dynamic-backends = ["shared"]`), but treat it as load-bearing here too.
Expand Down
5 changes: 4 additions & 1 deletion docs/bindings.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,10 @@ binding's generated files:
`GGML_BACKEND_DL` installs — `module_dir`, the directory to hand to
`transcribe_init_backends()`. Proven per push by the link-smoke CI lane,
which compiles a toy C consumer from nothing but this manifest in both
static and shared postures.
static and shared postures. The Rust `-sys` crate consumes it from two
sources: its own vendored source build (the default), or — with the
`TRANSCRIBE_DIR` env var pointing at an installed prefix — a prebuilt
tree, skipping the source build entirely.

## Result text pointers: copy at the FFI boundary

Expand Down