Low-level Rust FFI bindings for libvips. Designed to be stable, minimal, and a foundation for higher-level wrappers.
libvips >= 8.2 (bindings generated from 8.18.7)| Default | Feature bindgen |
|
|---|---|---|
| Bindings | Pregenerated src/bindings/prebuilt.rs |
Live bindgen via clang |
| Needs libclang? | No | Yes |
Typical cargo build |
Seconds | Slower (first time) |
| Use when | Normal development / CI | Updating API surface / new libvips |
Normal builds do not run bindgen. You only need a libvips library to link against.
helpers::shutdown is now unsafe: callers must prove every libvips user has
finished and no later calls can occur. Normal applications should keep libvips
initialized for the process lifetime. Failed initialization can be retried.
Feature v8_18 requests a libvips 8.18+ link probe. The default declarations
also contain newer symbols, but a declaration does not add that symbol to an
older system library. Only call APIs present in the library you link.
The vendored source is pinned to the latest release, 8.18.7. Its public headers are unchanged from 8.18.6. See the upstream audit.
brew install vips pkg-config
# Apple Silicon:
export PKG_CONFIG_PATH=/opt/homebrew/lib/pkgconfig
sudo apt-get install -y libvips-dev pkg-config
set VCPKG_ROOT=C:\path\to\vcpkg
vcpkg install libvips:x64-windows
set VCPKGRS_TRIPLET=x64-windows
set VCPKGRS_DYNAMIC=1
set PATH=%VCPKG_ROOT%\installed\x64-windows\bin;%PATH%
cargo test --features helpers
The official port name is libvips. The Unix pkg-config name remains vips;
link library names are read from the installed port manifest and its dependencies.
Dynamic triplets require VCPKGRS_DYNAMIC=1 and their DLLs on PATH.
For static libvips with Rust’s default dynamic CRT:
vcpkg install libvips:x64-windows-static-md
set VCPKGRS_TRIPLET=x64-windows-static-md
cargo test --features helpers,static
For a static CRT, use x64-windows-static together with
RUSTFLAGS=-Ctarget-feature=+crt-static. Replace x64 with arm64 or x86 to
match the Rust target. VCPKGRS_TRIPLET takes precedence over
VCPKG_DEFAULT_TRIPLET; absent both, static requests select the target
architecture and CRT, while other requests use vcpkg-rs defaults (static-md
unless dynamic linking or a static CRT is selected).
The MSVC backend follows Cargo’s target environment, including cross-compilation. This selects headers and link metadata; a cross linker and target-built libraries are still required for producing a working executable.
[dependencies]
vips-sys = { version = "0.3.0", features = ["helpers"] }
| Feature | Default | Description |
|---|---|---|
| (none) | ✓ | Pregenerated bindings + link probe |
helpers |
init / is_initialized / unsafe shutdown / cached version queries |
|
static |
Prefer static linking (LIBVIPS_STATIC=1 overrides) |
|
dynamic |
Prefer dynamic linking | |
bindgen |
Regenerate bindings with clang against local headers | |
stub |
Link stub/vips_stub.c when no system libvips is found (tests only) |
cargo test --features helpers,stub
If pkg-config/vcpkg/LIBVIPS_LIB_DIR cannot find a real library, stub builds a
tiny C stand-in (vips_init / vips_version / …) so unit tests can link. When a
real library is present it is always preferred — never ship production binaries
built with stub.
vips-sys = { version = "0.3.0", features = ["static"] }
LIBVIPS_STATIC=1 cargo build
Resolution order:
pkg-config --static / vcpkg static triplet if a static libvips is installedvendor/libvips into OUT_DIR (if tools are on PATH)The static preference selects the libvips archive; system codec dependencies
may remain dynamic. The vendor builder requires Meson 0.60+, Ninja and native
GLib/codec development files. MESON_PATH / NINJA_PATH select the tools, and
CXXSTDLIB overrides the platform C++ runtime when using a custom toolchain.
It builds the archive and development artifacts only. Ninja handles source
changes incrementally; compiler/environment changes reset Meson configuration.
Cross targets require prebuilt target libraries rather than this native builder.
vendor/libvips tracks libvips at v8.18.7
(see rust-sys-crate):
git clone --recurse-submodules <this-repo>
# or:
git submodule update --init --recursive
Link / header resolution:
LIBVIPS_LIB_DIR / LIBVIPS_INCLUDE_DIR (optional LIBVIPS_STATIC=1)pkg-config (Unix) or vcpkg (MSVC)static is requested# Requires: libclang, glib headers, and vips headers (system or vendor submodule)
cargo build --features bindgen
# build.rs prints the OUT_DIR path — copy it over:
python3 scripts/refresh-prebuilt.py target/debug/build/<exact-build-id>/out/binding.rs --version 8.18.7
Use headers configured with deprecated APIs enabled when refreshing the complete prebuilt surface. The refresh script checks the version, refuses accidental API removal and keeps optional codec build details out of the reusable defaults.
wrapper.h is the single bindgen entry point and is kept in the repo.
generate.sh was removed in favor of the bindgen feature.
Build-time exports:
LIBVIPS_VERSION — detected version string (from pkg-config when available)cfg(vips_8_16) / cfg(vips_8_17) / cfg(vips_8_18) — when version is new enoughhelpers)use vips_sys::helpers;
fn main() {
helpers::init("vips-sys-example").expect("vips init failed");
let (a, b, c) = helpers::version();
println!("libvips {}.{}.{} ({})", a, b, c, helpers::version_string());
// Global resources remain available until process exit.
}
| Variable | Purpose |
|---|---|
PKG_CONFIG_PATH |
Find vips.pc |
LIBVIPS_LIB_DIR / LIBVIPS_INCLUDE_DIR |
Explicit library / headers |
LIBVIPS_STATIC |
1 prefer static; 0/false/off disable |
LIBVIPS_NO_VENDOR |
Ignore vendor/libvips |
LIBVIPS_NO_BINDGEN |
With bindgen, copy pregenerated bindings without parsing headers |
LIBVIPS_VERSION |
Override version string for cfg |
VCPKG_ROOT |
Windows vcpkg installation root |
VCPKGRS_TRIPLET / VCPKG_DEFAULT_TRIPLET |
Explicit triplet (Rust helper override wins) |
VCPKGRS_DYNAMIC |
Required opt-in for dynamic vcpkg libraries |
BINDGEN_EXTRA_CLANG_ARGS |
Extra clang flags (bindgen feature) |
LIBCLANG_PATH |
libclang location (bindgen feature) |
MESON_PATH / NINJA_PATH |
Native vendor build tools |
CXXSTDLIB |
Override the static provider’s C++ runtime |
libvips-dev / vcpkg install libvips)libclang, glib headers, and vips headersVCPKG_ROOT so include paths resolveThis crate’s Rust source code (including build.rs and src/) is licensed under
MIT.
libvips itself is LGPL-2.1
(and depends on other LGPL/GPL-compatible components such as GLib). That license is
not MIT and does not relicense this crate.
| Artifact | License |
|---|---|
vips-sys sources / pregenerated FFI declarations |
MIT |
Linked libvips library (system, vcpkg, or built from vendor/) |
LGPL-2.1 |
| Your final binary that links libvips | Must comply with LGPL-2.1 for libvips |
Practical notes:
static feature or vendored meson build): LGPL obligations are
stricter (e.g. allow relinking against a modified libvips). Evaluate before shipping.vendor/libvips git submodule is LGPL-2.1 source. It is excluded from the
crates.io package (exclude = ["vendor/"]); if you redistribute that tree yourself,
do so under LGPL-2.1.This is engineering guidance, not legal advice. For commercial compliance, consult counsel.
See CHANGELOG.md.