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
6 changes: 6 additions & 0 deletions bindings/rust/sys/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,12 @@ fn emit_link_lines(prefix: &Path, manifest_path: &Path) {
let lib_dir = prefix.join(json["lib_dir"].as_str().unwrap_or("lib"));
println!("cargo:rustc-link-search=native={}", lib_dir.display());

// Extra linker search directories recorded at configure time (e.g. the
// CUDA toolkit's library dir, which is rarely on the default path).
for dir in strs("search_dirs") {
println!("cargo:rustc-link-search=native={dir}");
}

// Archives (static) or the single shared lib. The manifest order is
// single-pass-GNU-ld safe (each archive's undefined refs resolve in a
// later one: transcribe -> ggml -> backends -> ggml-base).
Expand Down
22 changes: 22 additions & 0 deletions cmake/transcribe-install.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ endif()
set(_libraries transcribe)
set(_library_paths "")
set(_system_libs "")
set(_search_dirs "")
set(_frameworks "")
set(_link_flags "")

Expand Down Expand Up @@ -137,6 +138,25 @@ if(NOT TRANSCRIBE_BUILD_SHARED)
if("vulkan" IN_LIST _kinds)
list(APPEND _system_libs vulkan)
endif()
if("cuda" IN_LIST _kinds)
# The ggml-cuda archive references the CUDA runtime and cuBLAS and —
# unless VMM was disabled at configure time — the CUDA driver API
# (mirrors ggml/src/ggml-cuda/CMakeLists.txt). Record the toolkit's
# library directory too: it is rarely on the default linker path, so
# names alone leave every non-CMake consumer guessing an install
# root. The stubs directory satisfies `-lcuda` on machines that
# build without a display driver; at runtime the real libcuda
# resolves through the loader as usual.
find_package(CUDAToolkit REQUIRED)
list(APPEND _system_libs cudart cublas)
if(NOT GGML_CUDA_NO_VMM)
list(APPEND _system_libs cuda)
endif()
list(APPEND _search_dirs "${CUDAToolkit_LIBRARY_DIR}")
if(EXISTS "${CUDAToolkit_LIBRARY_DIR}/stubs")
list(APPEND _search_dirs "${CUDAToolkit_LIBRARY_DIR}/stubs")
endif()
endif()
if(_frameworks)
list(REMOVE_DUPLICATES _frameworks)
endif()
Expand Down Expand Up @@ -184,6 +204,7 @@ endfunction()
_transcribe_json_strings(_kinds_json ${_kinds})
_transcribe_json_strings(_libraries_json ${_libraries})
_transcribe_json_strings(_library_paths_json ${_library_paths})
_transcribe_json_strings(_search_dirs_json ${_search_dirs})
_transcribe_json_strings(_system_libs_json ${_system_libs})
_transcribe_json_strings(_frameworks_json ${_frameworks})
_transcribe_json_strings(_link_flags_json ${_link_flags})
Expand All @@ -201,6 +222,7 @@ file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/transcribe-link.json"
\"lib_dir\": \"${CMAKE_INSTALL_LIBDIR}\",
\"libraries\": [${_libraries_json}],
\"library_paths\": [${_library_paths_json}],
\"search_dirs\": [${_search_dirs_json}],
\"system_libs\": [${_system_libs_json}],
\"frameworks\": [${_frameworks_json}],
\"link_flags\": [${_link_flags_json}]
Expand Down
13 changes: 8 additions & 5 deletions docs/bindings.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,14 @@ binding's generated files:
- **`lib/transcribe-link.json`** — installed by `cmake --install` (the
`TRANSCRIBE_INSTALL` rules): the machine-readable link interface for
non-CMake consumers building from source (the Rust `-sys` crate's
`build.rs`). Archive order, system libs, frameworks, flags, and — for
`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.
`build.rs`). Archive order, system libs, `search_dirs` (extra linker
search directories recorded at configure time — e.g. the CUDA toolkit's
library dir and its driver-stub subdirectory, which back the `cudart` /
`cublas` / `cuda` entries CUDA builds add to `system_libs`), frameworks,
flags, and — for `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.

## Result text pointers: copy at the FFI boundary

Expand Down
3 changes: 3 additions & 0 deletions scripts/ci/link_smoke.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ def main() -> int:
cmd = [args.cc, str(SOURCE), f"-I{include_dir}", "-o", str(out)]
cmd += manifest["link_flags"]
cmd += [f"-L{lib_dir}"]
# Configure-time search dirs (e.g. the CUDA toolkit's library dir);
# absent in pre-0.1.4 manifests.
cmd += [f"-L{path}" for path in manifest.get("search_dirs", [])]

libs = [f"-l{name}" for name in manifest["libraries"]]
if manifest["libraries"][1:] and platform.system() == "Linux":
Expand Down