vips-sys

English | 简体中文

Crates.io Rust docs.rs License Downloads

Low-level Rust FFI bindings for libvips. Designed to be stable, minimal, and a foundation for higher-level wrappers.

Highlights

  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.

0.3.0 compatibility

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.

Installation

macOS

brew install vips pkg-config
# Apple Silicon:
export PKG_CONFIG_PATH=/opt/homebrew/lib/pkgconfig

Debian / Ubuntu

sudo apt-get install -y libvips-dev pkg-config

Windows (MSVC)

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.

Cargo

[dependencies]
vips-sys = { version = "0.3.0", features = ["helpers"] }

Features

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)

Tests without a system libvips

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.

Static linking

vips-sys = { version = "0.3.0", features = ["static"] }
LIBVIPS_STATIC=1 cargo build

Resolution order:

  1. pkg-config --static / vcpkg static triplet if a static libvips is installed
  2. Meson + ninja build of vendor/libvips into OUT_DIR (if tools are on PATH)
  3. Clear error otherwise

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.

Vendored libvips (submodule)

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:

  1. LIBVIPS_LIB_DIR / LIBVIPS_INCLUDE_DIR (optional LIBVIPS_STATIC=1)
  2. System library via pkg-config (Unix) or vcpkg (MSVC)
  3. Static vendor build when static is requested
  4. Vendored headers for include paths (still need a library to link)

Refreshing pregenerated bindings

# 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:

Example (helpers)

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.
}

Environment variables

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

Troubleshooting

License

This 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.

What that means for you

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:

This is engineering guidance, not legal advice. For commercial compliance, consult counsel.

Changelog

See CHANGELOG.md.