I have been attempting to create a statically linked version of vips but have been unable to. Is it possible to create a statically linked vips command?
The platform I am compiling on is Ubuntu 16.04.
The make command I am running:
make LDFLAGS=-all-static
I am not configuring it to use python or imagemagick, (those show "no" in the config output). The error I am getting is:
/usr/bin/ld: cannot find -lgdk_pixbuf-2.0
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libgio-2.0.a(libgio_2_0_la-glocalfileinfo.o): In function `lookup_gid_name':
(.text+0x11d7): warning: Using 'getgrgid_r' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libgio-2.0.a(libgio_2_0_la-glocalvfs.o): In function `g_local_vfs_parse_name':
(.text+0x1cd): warning: Using 'getpwnam' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libglib-2.0.a(libglib_2_0_la-gutils.o): In function `g_get_user_database_entry':
(.text+0x249): warning: Using 'getpwuid' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libglib-2.0.a(libglib_2_0_la-gutils.o): In function `g_get_user_database_entry':
(.text+0xcf): warning: Using 'getpwnam_r' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libgio-2.0.a(libgio_2_0_la-glocalfileinfo.o): In function `lookup_uid_data':
(.text+0x1054): warning: Using 'getpwuid_r' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libxml2.a(nanohttp.o): In function `xmlNanoHTTPConnectHost':
(.text+0x924): warning: Using 'getaddrinfo' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libxml2.a(nanohttp.o): In function `xmlNanoHTTPConnectHost':
(.text+0x9f4): warning: Using 'gethostbyname' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libgio-2.0.a(libgio_2_0_la-gnetworkaddress.o): In function `g_network_address_parse':
(.text+0xc39): warning: Using 'getservbyname' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libgio-2.0.a(libgio_2_0_la-gnetworkaddress.o): In function `g_network_address_parse':
(.text+0xc4e): warning: Using 'endservent' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
collect2: error: ld returned 1 exit status
Makefile:597: recipe for target 'vips' failed
make[2]: *** [vips] Error 1
make[2]: Leaving directory '/usr/local/src/vips-8.4.1/tools'
Makefile:631: recipe for target 'all-recursive' failed
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory '/usr/local/src/vips-8.4.1'
Makefile:536: recipe for target 'all' failed
make: *** [all] Error 2
From what I've found on, for example here: Create statically-linked binary that uses getaddrinfo? is that this is an issue with libnss. But in the ./configure --help output there is no --enable-static-flag. Even so I tried that and it didn't fix my problem.
The libraries I am linking against (according to the config output, I've truncated it):
build radiance support: yes
build analyze support: yes
build PPM support: yes
use fftw3 for FFT: yes
accelerate loops with orc: yes
ICC profile support with lcms: yes (lcms2)
SVG import with librsvg-2.0: yes
zlib: yes
file import/export with libwebp: yes
file import/export with libpng: yes (pkg-config libpng >= 1.2.9)
file import/export with libtiff: yes (pkg-config libtiff-4)
file import/export with giflib: yes (found by search)
file import/export with libjpeg: yes
use libexif to load/save JPEG metadata: yes
Is there a particular library I am linking against that is causing the problem?
After failing to convince the build mechanism to statically link, I was able to successfully create a working static vips
executable with staticx
, after reporting an issue to staticx and seeing that it was fixed. See here for how I'm building.
Just in case that link of mines dies in the future, here are the relevant parts:
RUN curl -sL https://github.com/libvips/libvips/releases/download/v8.9.2/vips-8.9.2.tar.gz | tar -xz -f- --strip-components=1 -C .
# TODO: Add --disable-deprecated
# Blocked by https://github.com/libvips/libvips/pull/1593
# XXX: -static doesn't work here, I'm using staticx to make the final vips binary static.
RUN CFLAGS="-O3 -flto -pipe" CXXFLAGS="-O3 -flto -pipe" \
./configure \
--disable-shared \
--disable-static \
--disable-dependency-tracking
# This is the fastest easiest way I found to compile the
# CLI as fast as possible. You can probably get more optimal,
# but it'd be a lot harder wrestling autotools.
RUN cd libvips \
&& make -j"$(nproc)"
RUN cd tools \
&& make -j"$(nproc)" vips
RUN cd tools \
&& staticx vips ../vips
Since configure automatically feature-detects, here are the Debian 10 (June 22) packages I installed:
libglib2.0-dev \
libexpat1-dev \
libjpeg-dev \
libpng-dev \
libimagequant-dev \
libexif-dev \
liborc-0.4-dev
It weighs 3.3M, which is fairly impressive and a heck of a lot smaller than distribution packages, which is why I set out to do this in the first place.
$ file vips-glibc-gcc
vips-glibc-gcc: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, stripped
$ ls -lah vips-glibc-gcc
-rwxr-xr-x 1 josh josh 3.3M Jun 23 02:51 vips-glibc-gcc
I tried like this:
$ CFLAGS="-static" CXXFLAGS="-static" ./configure --prefix=/home/john/vips --without-python --without-magick
And it seems to work:
$ ls ~/vips/lib
girepository-1.0 libvipsCC.a libvips-cpp.a libvips.la python2.7
libvips.a libvipsCC.la libvips-cpp.la pkgconfig
$ which vips
/home/john/vips/bin/vips
$ ls -l ~/vips/bin/vips
-rwxr-xr-x 1 john john 6373864 Sep 27 13:16 /home/john/vips/bin/vips
$ vips invert /data/john/pics/k2.jpg x.jpg
$ eog x.jpg
I've not tested it much though, and I suspect it's not very static. If you run ldd on the vips
binary, for example, you get a long list. True static binaries do not really exist any more.
Why do you want a static binary? If it's to ease distribution, things like flatpack and snappy might be better. You can also sort-of make your own --- for example, vips comes with a simple wrapper script which can make the shared binary relocatable.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With