Static linked vips (libvips) binary - static-libraries

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.

Related

compilation of binutils-gdb can't find ncurses

I'm trying to compile the binutils for the i686-elf target according to this tutorial:
https://wiki.osdev.org/GCC_Cross-Compiler
I just added the --enable-tui option, so that I have the support in the gdb.
I did the following:
# get sources
git clone git://sourceware.org/git/binutils-gdb.git
# store settings
export PREFIX="`pwd`/opt/cross"
export TARGET=i686-elf
export PATH="$PREFIX/bin:$PATH"
# create build folder
mkdir build-binutils
cd build-binutils
# run configure
../binutils-gdb/configure -target=$TARGET --prefix="$PREFIX" --with-sysroot --disable-nls --disable-werror --enable-tui
# make
make
This runs for some time and terminates with the following error:
checking for library containing socketpair... (cached) none required
checking for ld used by GCC... (cached) ld
checking if the linker (ld) is GNU ld... (cached) yes
checking for shared library run path origin... (cached) done
checking for iconv... (cached) yes
checking for iconv declaration... (cached)
extern size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);
checking for library containing waddstr... (cached) no
configure: error: no enhanced curses library found; disable TUI
make[1]: *** [Makefile:11329: configure-gdb] Error 1
make[1]: Leaving directory '/home/noexpandtab/dev/build-binutils'
make: *** [Makefile:853: all] Error 2
For me it seems, that the ncurses library cannot be found.
I have a Debian 10 running and installed the following additional packages:
libncurses-dev
ncurses-base
ncurses-doc
libncurses5-dev
Do I have to install additional packages? Or am I missing some options for the configure script?
You're cross-compiling to a different architecture (i686-elf) than whatever you're running on—the $TARGET mentioned in the question. gdb will have to be linked with libraries which are built for that architecture.
Debian provides ncurses packages which run on the current architecture, but does not provide a suitable package for the cross-compiled application. So you get to do this for yourself.
When cross-compiling ncurses, you'll have to keep in mind that part of it builds/runs on the current architecture (to generate source-files for compiling by the cross-compiler). That's defined in the environment as $BUILD_CC (rather than $CC), as you might see when reading the script for the mingw cross-compiling. There's a section in the INSTALL file (in the ncurses sources) which outlines the process.
There's no tutorial (that would be off-topic here anyway), but others have read the instructions and cross-compiled ncurses as evidenced by a recent bug report.
I retried the whole compilation, and suddenly it works! I tested a bit and I assume I found my fault: I executed configure without --enable-tui, where make worked. Then I executed configure with --enable-tui in the same folder without cleaning it. After cleaning or running in a new folder it compiled.
Thanks to the one user who posted to delete the contents of opt/cross. (The comment itself was already somehow deleted in between.) This wasn't the solution, but leaded me in the right direction.
TL;DR: Clean the build folder before running configure with different parameters again.

How to build a static tar command

I downloaded tar 1.28 and am attempting to compile a static binary to use on system recovery media on Fedora Linux (x86_64). It doesn't have to include common libraries, such as libc or pthreads, but I'd like to eliminate dependencies on selinux, acl, attr, pcre and lzma, etc.
The README indicates I can use
./configure CC=gcc LDFLAGS=-static
but this creates a fully static binary (including libc), but is missing support for anything normally found in the shared libraries (SELinux, ACLs, etc). Reading the config.log shows failed attempts to find a static library for acl
So, I installed libselinux-devel-static RPM, and this time got the selinux support in there, but I can't find static libraries for anything else. Search results say that libacl.a is in libacl-devel, but not mine.
A fully static binary is ok, but really just want to get the odd-balls in there so I don't have to put the shared libraries on the media.
I was looking at this as well, and i would get the following error message:
CCLD tar
../gnu/libgnu.a(quotearg.o): In function `quote':
/home/anarcat/dist/tar-1.27.1/gnu/quotearg.c:968: multiple definition of `quote'
/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../../lib/libacl.a(quote.o):(.text+0x0): first defined here
names.o: In function `gid_to_gname':
/home/anarcat/dist/tar-1.27.1/src/names.c:95: warning: Using 'getgrgid' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
names.o: In function `gname_to_gid':
/home/anarcat/dist/tar-1.27.1/src/names.c:155: warning: Using 'getgrnam' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
names.o: In function `uname_to_uid':
/home/anarcat/dist/tar-1.27.1/src/names.c:125: warning: Using 'getpwnam' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
names.o: In function `uid_to_uname':
/home/anarcat/dist/tar-1.27.1/src/names.c:65: warning: Using 'getpwuid' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
../lib/libtar.a(rtapelib.o): In function `rmt_open__':
/home/anarcat/dist/tar-1.27.1/lib/rtapelib.c:428: warning: Using 'gethostbyname' 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:1304: recipe for target 'tar' failed
I don't quite get it, but apparently, "You cannot getpwnam and friends with the whole flexibility that glibc has without shared libraries".
So game over? unclear.
For Fedora you can enable Repository CERT Forensics Tools
and complete build dependencies with some static libs (non-exhaustive list)
zlib-static
libiconv-static
libffi-devel
gettext-devel
pcre-static
ncurses-static
nss-devel
glibc-static
libselinux-static
libsepol-static
libattr-devel
libacl-devel
if libacl.a is missing you have to download source first from:
git clone https://git.savannah.nongnu.org/git/attr.git
git clone https://git.savannah.nongnu.org/git/acl.git
and compile with (first libattr, then libacl, then tar):
./autogen.sh
./configure --prefix=/usr --libexecdir=/usr/lib --enable-static --disable-shared --disable-rpath
make CFLAGS='-static'
make install

checking for suffix of object files... configure: error: cannot compute suffix of object files: cannot compile

While building ARM toolchain , I got the following error
checking for suffix of object files... configure: error: cannot compute suffix of object files: cannot compile
See `config.log' for more details.
make[1]: *** [configure-target-libgcc] Error 1
make[1]: Leaving directory `<path>/gcc-4.3.2-arm-elf'
make: *** [all] Error 2
what might be the problem?
Did you read http://gcc.gnu.org/wiki/FAQ#configure_suffix ?
Have you installed GMP, MPFR and MPC? Are they in your library search path?
See http://gcc.gnu.org/wiki/InstallingGCC and make sure you've followed the basic instructions. By far the simplest way to build GCC (including as a cross compiler) is to follow these instructions:
Alternatively, after extracting the GCC source archive, simply run the ./contrib/download_prerequisites script in the GCC source directory. That will download the support libraries and create symlinks, causing them to be built automatically as part of the GCC build process.
"*Building GCC is not trivial, but is not difficult if you follow the instructions carefully.
Many people rush into trying to build it without reading the installation docs properly and make one or more of these common mistakes:
1) do not run ./configure from gcc src dir (this is not supported) => you need to run configure from outside the gcc source directory
2) Note: if GCC links dynamically to the prerequisite libs (GMP/MPFR/MPC) then the shared libraries must be in the dynamic linker's path (LD_LIBRARY_PATH), both when building gcc and when using the installed compiler.*"
Simple example (without dynamic link to GMP/MPFR/MPC):
tar xzf gcc-4.8.0.tar.gz
cd gcc-4.8.0
./contrib/download_prerequisites
cd ..
mkdir objdir
cd objdir
$PWD/../gcc-4.8.0/configure --prefix=/opt/gcc-4.8.0
make
make install
Sources:
Advogato Doc -
GNU Doc
export LD_LIBRARY_PATH=/path/for/libraries:$LD_LIBRARY_PATH
path/for/libraries is where the GMP MPFR and MPC libraries are present.
I was compiling GCC on ubuntu 12.04 and these linraries present in the path /usr/local/lib

Building GCC cross compiler (from "Linux" to "Windows")

I want to build "gcc cross-compiler" to compile "c/c++" applications on "Linux" environment but for "Windows" target.
I have made this so far:
Installed the necessary tools and packages for building GCC listed on "Prerequisites for GCC" page.
Downloaded required sources:
"gcc-core-4.4.1", "gcc-g++-4.4.1", "binutils-2.19.1", "w32api-3.13-mingw32", "mingwrt-3.16-mingw32"
Created this directory hierarchy:
"${HOME}/gcc/" - for final cross-compiler
"${HOME}/src/" - for sources
"${HOME}/src/build-binutils/i386-mingw32/" - for building binutils to "i386-mingw32" target
"${HOME}/src/build-gcc/i386-mingw32/" - for building gcc to "i386-mingw32" target
Builded binutils package:
cd "${HOME}/src/build-binutils/i386-mingw32/"
../../binutils-2.19.1/configure --prefix="${HOME}/gcc" --target=i386-mingw32 --disable-nls
make
make install
Copied "w32api" and "mingwrt" headers to the install directory:
cp -R "${HOME}/src/w32api-3.13-mingw32/include" "${HOME}/gcc/i386-mingw32"
cp -R "${HOME}/src/mingwrt-3.16-mingw32/include" "${HOME}/gcc/i386-mingw32"
And now when I am trying to build the "c (only) cross-compiler":
cd "${HOME}/src/build-gcc/i386-mingw32/"
../../gcc-4.4.1/configure --prefix="${HOME}/gcc" --target=i386-mingw32 --enable-languages=c --with-headers="${HOME}/gcc/i386-mingw32/include" --disable-nls
make<br>
it was building something about 4 minutes and then gives me these errors:
${HOME}/gcc/i386-mingw32/bin/ld: dllcrt2.o: No such file: No such file or directory
collect2: ld returned 1 exit status
make[2]: *** [libgcc_s.dll] Error 1
make[2]: Leaving directory `${HOME}/src/build-gcc/i386-mingw32/i386-mingw32/libgcc'
make[1]: *** [all-target-libgcc] Error 2
make[1]: Leaving directory `${HOME}/src/build-gcc/i386-mingw32'
make: *** [all] Error 2
From that error message I really don't know what to do now :-((( .
Does anybody know where is the problem?
Thanks.
That's actually OK: the way things go, you need to
build binutils
install headers
build the a partial C compiler: enough to create object files, but not enough to link
build the win32api and mingw runtime (which includes your missing dllcrt2.o)
build a complete C compiler (and other front-ends, such as C++, Fortran, Ada, whatever, if you want them)
You have successful performed step 3 above; it fails building libgcc (which is a GCC support library), but that means the C compiler core is functionnal (although it won't be able to link, it can still create valid object files). You can check that by looking at the gcc/xgcc file in your GCC build directory.
So, you need to go to the next step, not worrying about your current failure.
(To actuall install the partial C compiler, you should run make with the -k option, to have it do it best, even in the face of errors. For example, use make -k install.)
There are precompiled cross-compilers of MinGW-w64 available.
This allows to compile native 32- and 64-bit Windows binaries from Linux, a two minute tutorial is available at http://www.blogcompiler.com/2010/07/11/compile-for-windows-on-linux/
Just in case you don't want to spend a lot of time trying to build it yourself.
I grepped through the MinGW sources, and found that dllcrt2.o is something built off the mingwrt package. I assume you have to compile and install that, not just copy the headers?

Error 1 & 2 when compiling GCC 4.4.2 on OpenSolaris 2009.06

My problem:
I've been trying to compile, build, and install GCC 4.4.2 in my installation of OpenSolaris 2009.06 on my VirtualBox 3 i386 machine. But I keep getting this same error when running make:
> checking whether ln -s works... yes
checking for i386-pc-solaris2.11-gcc... /src/gcc-4.4.2/host-i386-pc-solaris2.11/gcc/xgcc -B/src/gcc-4.4.2/host-i386-pc-solaris2.11/gcc/ -B/usr/gnu/i386-pc-solaris2.11/bin/ -B/usr/gnu/i386-pc-solaris2.11/lib/ -isystem /usr/gnu/i386-pc-solaris2.11/include -isystem /usr/gnu/i386-pc-solaris2.11/sys-include
checking for suffix of object files... configure: error: in `/src/gcc-4.4.2/i386-pc-solaris2.11/libgcc':
configure: error: cannot compute suffix of object files: cannot compile
See `config.log' for more details.
make[2]: *** [configure-stage1-target-libgcc] Error 1
make[2]: Leaving directory `/src/gcc-4.4.2'
make[1]: *** [stage1-bubble] Error 2
make[1]: Leaving directory `/src/gcc-4.4.2'
make: *** [all] Error 2
Attempted solutions:
I tried the answer to this question:
Problem compiling gcc 4.4.0 on OpenSolaris 2009.6 i.e.
./configure --prefix=/usr/gnu --with-gmp=/usr/gnu --with-mpfr=/usr/gnu --with-as=/usr/sfw/bin/gas --with-gnu-as --with-gnu-ld
I tried GNU GCC's platform specific solution:
GNU Solaris specific build instructions
i.e.
./configure --prefix=/usr/gnu --with-gmp=/usr/gnu --with-mpfr=/usr/gnu --with-as=/usr/sfw/bin/gas --with-gnu-as --with-ld=/usr/ccs/bin/ld --without-gnu-ld --enable-shared
I am still getting the same errors despite running ./configure with the two solutions above
Any help would be appreciated!
Thanks!
Can you compile programs with the existing GCC?
If not, you need to resolve that.
If you can, then you need to look at that monstrous 7-argument command (the one where it says 'checking for i386-pc-solaris2.11-gcc' - why those 7 arguments?).
Are you running 'make bootstrap'?
If not, what happens when you do?
If so, whereabouts in the processing is it? (Is this stage 1, or stage 2, or what?)
Are you using the recommended setup, with the source for GCC in, say, /src/gcc-4.4.2 and the object files in, say, /src/gcc-4.4.2-obj?
If not, do so. Use: cd /src/gcc-4.4.2-obj; ../gcc-4.4.2/configure ...
Which shell do you use?
On regular Solaris 10 (not OpenSolaris - and SPARC, not Intel), I have to set CONFIG_SHELL=/bin/ksh in the environment to make things compile (by default, it uses /bin/sh, but the /bin/sh on Solaris 10 is Bourne shell and there's a script deep down in the Java section (IIRC) that uses Bash/Korn/POSIX shell notations like $(cmd ...)). However, that normally affects a much later stage in the processing.
However, I have got GCC 4.4.2 on Solaris 10 without problem (using GCC 4.4.1 as the bootstrap compiler).

Resources