Skip to content

libstatic/libvips

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

13 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

libvips, static, built from source

This builds libvips and as many of its format libraries as I could get working, all as static .a files, compiled from source inside an Alpine/musl container. Nothing comes from apk - every dependency here is a git submodule pinned to a specific version, built by hand with whatever flags it took to keep it static on musl.

Why

I got tired of the usual problems with libvips packaging: whatever your distro ships is a few versions behind, you don't get any say in which codecs are compiled in, and if you use the shared library you now have to track its exact version alongside your own binary at deploy time. Building it static from source fixes the version tracking problem outright and gives you real control over what's compiled in.

Also, most people using libvips don't need every format it supports. If you're serving JPEG/PNG/WebP/AVIF thumbnails you don't need PDF rendering or all of ImageMagick's delegate libraries riding along in your binary for no reason.

Layout

The Makefile has one target per dependency (binary/.stamps/<name>), so if something dies halfway through a build you just run make build again and it picks up from there instead of starting over. Everything installs into binary/ - separate .a and .pc files per library, not one big merged archive, so you link against whichever ones you actually need (pkg-config --static --libs vips, or by hand).

Not everything here was equally easy to get working on musl. JPEG, PNG, WebP, TIFF, EXIF and GIF-save were straightforward. JPEG2000, AVIF/HEIC decode, JPEG XL, OpenEXR, lcms2, pyramid save (libarchive), and the performance libraries (highway, orc, fftw) took more work but got there. A few formats aren't in here yet: librsvg and the current imagequant/quantizr are both Rust now, so no Rust toolchain means no indexed PNG/GIF save and no SVG loading. PDF (poppler/pdfium), ImageMagick, and OpenSlide all need either a huge dependency tree or something that doesn't fit cleanly into a static musl build, so those are on hold for later.

Building

podman build -t libvips-static -f Dockerfile .
podman run -d --name libvips-build -v $(pwd):/work:Z -w /work libvips-static sleep infinity
podman exec libvips-build make build

That builds every dependency in order and then libvips itself. Run make verify afterward - it compiles a small test binary against whatever got built and actually exercises it: round-trips real images through each codec, checks that EXIF metadata survives a save/load cycle, runs a real ICC transform through lcms2, and pushes an image through libvips's FFTW-backed FFT path. That's a better check than just "did it compile."

The static libraries and headers land in binary/lib/*.a and binary/include/. binary/bin only has two things left in it - glib-mkenums and glib-genmarshal - because those are the only tools libvips's own build actually calls. Every other CLI tool each dependency installs (cjpeg, gio, dec265, fftw-wisdom, and so on) gets deleted right after that dependency finishes.

Only want some formats?

FORMATS is a Makefile variable:

make build FORMATS="jpeg png webp avif"
make formats   # see all the available keys

The Makefile figures out which dependencies and which libvips build flags that needs. Pick jxl on its own and it still correctly builds highway, brotli, and lcms2 underneath it, because libjxl's own Makefile target already lists those as its own dependencies and Make follows that automatically - nothing extra to work out by hand. Since this only ever builds what you asked for in the first place, there's nothing to clean up afterward. Change FORMATS between runs and libvips gets reconfigured and rebuilt correctly, even when you're removing formats, which normally Make wouldn't notice since none of the files on disk get any older. There's a small sentinel file, binary/.formats-used, that exists just to catch that case.

What's missing

librsvg, PDF, ImageMagick, OpenSlide, and the scientific formats (matio, nifti, cfitsio) - see above for why. GIF save and indexed PNG save need a quantizer, and the only ones around now are written in Rust, which this build avoids.

About

Build libvips along with all its dependencies, from source to build statically. Single binary to deploy to lightweight containers.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors