cactus_sys/lib.rs
1//! # cactus-sys
2//!
3//! Raw FFI bindings to [Cactus Compute](https://cactuscompute.com) inference engines.
4//!
5//! ## What is cactus-sys?
6//!
7//! Cactus Compute ships its engines as prebuilt static libraries with a small C API. This crate
8//! links one of them and declares that API, nothing more: every item is `unsafe`, and no Rust
9//! type stands between the caller and the engine. For a safe, typed API use
10//! [`cactus-rs`](https://docs.rs/cactus-rs) instead.
11//!
12//! ## Key Features
13//!
14//! - **Needle 3**: the five functions of `needle.h`, behind the `needle` feature (default)
15//! - **Pinned Binaries**: the archive is fetched from one Hugging Face commit and checked
16//! against a SHA-256 recorded in this crate
17//! - **Offline Builds**: point `CACTUS_NEEDLE_LIB_DIR` at a local archive and nothing is
18//! downloaded
19//! - **No Dependencies**: `#![no_std]`, and no runtime crates
20//!
21//! ## Engines
22//!
23//! | Engine | Header | Feature | Status |
24//! | --- | --- | --- | --- |
25//! | Needle 3 | `include/needle.h` | `needle` | supported |
26//! | Cactus | `cactus_engine.h` | none yet | planned |
27//!
28//! ## Linking
29//!
30//! The build script picks the first source that applies:
31//!
32//! | Source | Behaviour |
33//! | --- | --- |
34//! | `DOCS_RS` | Links nothing, so documentation builds need no archive. |
35//! | `CACTUS_NEEDLE_LIB_DIR` | Links `libneedle.a` from that directory. |
36//! | feature `download-binaries` (default) | Downloads the archive for the target from the pinned commit and verifies its SHA-256. |
37//!
38//! With `download-binaries` off and `CACTUS_NEEDLE_LIB_DIR` unset the build fails and says so.
39//!
40//! Every upstream archive is built against LLVM libc++, never libstdc++. The build script links
41//! `c++` on Apple and Windows (gnullvm) targets, `c++` and `c++abi` on Linux, and `c++_shared`
42//! on Android. On Debian
43//! and Ubuntu that means installing `libc++-dev libc++abi-dev`, and a native Linux build without
44//! libc++ stops early and says so. The archive also needs one function that libc++ 18 and 20 do
45//! not export, so on Linux this crate links a weak definition of it (`shim/libcxx_compat.c`);
46//! a libc++ that has the real one takes precedence.
47//!
48//! Set `CACTUS_CXXSTDLIB` to a comma-separated list to replace the default: a bare name links
49//! dynamically, `static=name` links the static archive, and an empty string links nothing.
50//! `CACTUS_CXXSTDLIB="static=c++,static=c++abi"` was checked on Ubuntu 24.04 and gives a binary
51//! with no libc++ dependency (add the directory holding `libc++.a` to the linker search path).
52//!
53//! Upstream publishes no archive for Intel macOS, and its Windows archives are llvm-mingw builds
54//! that link only with the `*-pc-windows-gnullvm` targets, not MSVC.
55//!
56//! ## What the archive contains
57//!
58//! The engine is CPU only. Its symbol table names kernels for AVX2, AVX-512, AVX-512 VNNI and AMX
59//! on x86 and for NEON on ARM, chosen at startup from what the CPU offers, and it has no CUDA,
60//! Vulkan, OpenCL or Metal symbols. `nm` also shows no socket, resolver or HTTP symbols, so the
61//! telemetry note in upstream's documentation covers their command-line runner and Python
62//! package rather than this library.
63//!
64//! ## Safety Guarantees
65//!
66//! None. The engine is one process-global, non-thread-safe model with no handles, so every call
67//! must be serialised by the caller, and nothing here enforces that. Each function documents the
68//! contract that was measured against the shipped archive under `# Safety`.
69//!
70//! ## Affiliation
71//!
72//! This crate is unofficial and is not affiliated with Cactus Compute. The engine it links is
73//! published by them under Apache-2.0.
74//!
75//! ## Examples
76//!
77//! ```
78//! // The pin the `download-binaries` feature fetches from.
79//! assert_eq!(cactus_sys::NEEDLE_ENGINE_COMMIT.len(), 40);
80//! ```
81
82#![no_std]
83
84#[cfg(feature = "needle")]
85pub mod needle;
86
87#[cfg(feature = "needle")]
88pub use needle::{
89 NEEDLE_ENGINE_COMMIT, needle_complete, needle_embed, needle_init, needle_load, needle_reset,
90};