Autoconf and Libtool Are Insanely Stubborn about Static Linkage - gcc

I'm using MinGW-w64 with POSIX threads. I want to build GNU gettext with POSIX threads and as shared libraries (DLLs in this case). However, when one builds runtime artifacts (such as DLLs or executables) which depend on POSIX threads with MinGW/MinGW-w64, one ends up with these artifacts being dependent on libwinpthread-1.dll. In my case, I want to avoid that and link any runtime artifacts against POSIX threads statically! The only way one can do that on MinGW/MinGW-w64 is to supply -static flag during the linkage stage. I've done that hundreds of times before, so I know that it works.
The problem now is that I have to deal with notorious Autotools which have just proven yet again that they are absolutely inflexible, unfriendly, and cumbersome to use. So there we go:
LDFLAGS="-static-libgcc -static-libstdc++ -static" ../configure --build=x86_64-w64-mingw32 --disable-static --enable-shared --disable-java --disable-native-java --enable-relocatable --enable-threads=posix --prefix=<prefix>
Guess what? This guy somehow parses that I've added -static and it does the following to my build:
All the GNU gettext libraries that should have been built as DLLs (due to --enable-shared and --disable-static) are now built as static libraries/archives;
All the GNU gettext executables are built with -static excluded what makes them dependent on libwinpthread-1.dll, for instance:
gcc -pipe -Wall -Wextra -O3 -static-libgcc -static-libstdc++ -o test-lock.exe test-lock.o lock.o threadlib.o -lpthread
as we can see Autotools have intentionally filtered out only the -static without my permission and any logical reason to do so.
I tried various things, and even found:
link_static_flag="-static"
in the libtool file. I've tried to change it to:
link_static_flag=""
in hope that it will prevent libtool from reacting like that when the -static flag is present. Unfortunately, no success yet. This is incredibly frustrating.
OK, Autotools gurus, now it's finally your time to shine.

Related

Mingw gcc, "-shared -static" passing together

When studying Scintilla's makefile for MinGW under windows, I noticed that it is passing -shared and -static together as LDFLAGS to gcc.
LDFLAGS=-shared -static -mwindows $(LDMINGW)
I googled, and only find some information from clang: https://reviews.llvm.org/D43811
[MinGW, CrossWindows] Allow passing -static together with -shared
In these combinations, link a DLL as usual, but pass -Bstatic instead of -Bdynamic to indicate prefering static libraries.
My question is: Would GCC do the same?
I haven't find any proof yet.
You can pass both -static and -shared in a GCC linkage. Their
combined effect is the same as you found described in your llvm link,
and this has always been the case for GCC.
-shared directs a GCC linkage to produce a shared library rather than a program,
which it achieves by passing on the option -shared to its invocation of
the linker.
-static directs a GCC linkage to ignore shared libraries when resolving
input library options -lname. By default -lname would be resolved by
searching the specified or default linker search directories for either
the shared library libname.so (on Windows, [lib]name.dll)
or the static library libname.a (on Windows also [lib]name.lib) and to prefer
the shared library if both of them are found in the same directory. -static
simply excludes all shared libraries from the search. GCC achieves this by passing the option -Bstatic
through to its invocation of the linker at a position in the generated linker
commandline that precedes all of the -lname options.
The GNU linker documentation of -Bstatic is explicit
that this option is consistent with -shared and that the effect is to produce a shared library
all of whose dependent libraries have been statically resolved.
-Bstatic
-dn
-non_shared
-static
Do not link against shared libraries. This is only meaningful on platforms for which shared libraries are supported.
The different variants of this option are for compatibility with various systems. You may use this option multiple times on the command line:
it affects library searching for -l options which follow it. This option also implies --unresolved-symbols=report-all.
This option can be used with -shared. Doing so means that a shared library is being created but that all of the library’s external references must be resolved by pulling in entries from static libraries.
(emphasis mine).
Although static linkage of shared library is in principle just a linkage restricted
in the same way as static linkage of a program, in practice it frequently encounters
a snag on Unix and Linux because all the object code linked into an ELF shared library
libname.so must be Position Independent Code,
as produced by the GCC compilation option -fPIC, whereas object files that are destined to be
archived in static libraries are customarily not compiled with -fPIC. Linkages using
-shared ... -static are thus apt to fail because necessary static libraries contain
non-PIC object files.
You do not have this worry with GCC on Windows, however, because there
is no such distinction as PIC v. non-PIC in Windows PE
object code.

Building shared libraries for Ada

I'm having some trouble building shared libraries from Ada packages without using GPR's.
I have a package, Numerics, in files "numerics.ads" and "numerics.adb". They have no dependencies. There is a small build script which does:
gnatmake -Os numerics.ad[bs] -cargs -fPIC
gcc -shared numerics.o -o libnumerics.so -Wl,-soname,libnumerics.so
The .so and .ali files are installed at /usr/lib, and the .ads file is installed at /usr/include.
gnatls -v outputs the following relevant parts:
Source Search Path:
<Current_Directory>
/usr/include
/usr/lib/gcc/x86_64-unknown-linux-gnu/5.1.0/adainclude
Object Search Path:
<Current_Directory>
/usr/lib
/usr/lib/gcc/x86_64-unknown-linux-gnu/5.1.0/adalib
So GNAT should have no problem finding the files.
Then, trying to compile a package that depends on Numerics:
gnatmake -O2 mathematics.ad[bs] -cargs -fPIC
outputs:
gcc -c -fPIC mathematics.adb
gcc -c -I./ -fPIC -I- /usr/include/numerics.ads
cannot generate code for file numerics.ads (package spec)
gnatmake: "/usr/include/numerics.ads" compilation error
This error has me thinking GNAT doesn't recognize the shared library, and is trying to rebuild Numerics.
I'd like to be building shared libraries, and only supply the spec for reference/documentation purposes.
edit:
So, it looks like gprbuild does two things I'm not doing. The first, is also passing -lnumerics to the compiler. The second, which shouldn't matter since libnumerics.so is in a standard directory anyways, is -L«ProjectDirectory». GPRbuild is obviously not doing desired behavior either, even though it's building the dependent project. It should be using the installed library /usr/lib/libnumerics.so, but instead is using «path»/Numerics/build/libnumerics.so. Furthermore, after building Numerics with GPRbuild, and then renaming the body to make it as if the body didn't exist (like with the installed files), when building Mathematics with GPRbuild, it complains about the exact same problem. It's as if the libraries aren't even shared, and GPRBuild is just making them look that way (except readelf reports the correct dependencies inside the libraries).
Adding -lnumerics to the build script accomplishes nothing; the build error is exactly the same. I'm completely lost at this point.
edit:
Following the link from Simon, the buildscript has changed to:
gnatmake -O2 mathematics.ad[bs] \
-aI/usr/include \
-aO/usr/lib \
-cargs -fPIC \
-largs -lnumerics
The error is essentially the same:
gcc -c -O2 -I/usr/include/ -fPIC mathematics.adb
gcc -c -I./ -O2 -I/usr/include/ -fPIC -I- /usr/include/numerics.ads
cannot generate code for file numerics.ads (package spec)
gnatmake: "/usr/include/numerics.ads" compilation error
I thought to check libnumerics.so is actually a correct shared library. ldd reports:
linux-vdso.so.1 (0x00007ffd944c1000)
libc.so.6 => /usr/lib/libc.so.6 (0x00007f50d3927000)
/usr/lib64/ld-linux-x86-64.so.2 (0x00007f50d3ed4000)
So I'm thinking yes, the library is fine, and gnatmake still isn't recognizing it.
In general, you need to install the body of the packages as well (numerics.adb in your case). Also, I suspect you want to set the ALI files
(numerics.ali) as read-only, so that gnatmake does not try to recompile them.

binutils bfd links against system iberty instead of built iberty

When building binutils, the bfd component is failing to link because it is linking against the system version of libiberty instead of the built version under binutuils/libiberty/lib64/libiberty.a.
I can't see a configure argument to allow me to override this. What's the best way to instruct configure to construct an LD_LIBRARY_PATH that prefers libraries from other components of its build over system versions? Obviously, it needs system libraries that are prerequisites, so I can't exclude this path entirely.
This is the error, due to the system version having not been compiled correctly. The version under binutils/libiberty/lib64 is compiled with -fPIC, so I need to tell configure to use that.
/lib64/libiberty.a(cplus-dem.o): relocation R_X86_64_32S against `.rodata' can not be used when making a shared object; recompile with -fPIC
It doesn't seem as trivial to specify .:/usr/lib64:/lib64 since . is binutils/bfd.
I had a look at the generated automakefile and LDFLAGS was only specifying the system libraries:
LDFLAGS := -L/usr/lib64 -L/usr/lib
So I specified this as an argument to configure. Slightly hacky, but can't see a better way out:
LDFLAGS="-L./ -L../ -L../libiberty/pic -L/usr/lib64 -L/usr/lib" ./confgiure --enable-shared

Basic UNIX configure/make/sudo make install question

I have learned to compile my own source over the years but always left some of the process to "mystery". I'm running into a bitch of a time getting ImageMagick and its myriad dependencies to work correctly on a PowerPC Mac OS X Server.
In setting flags for ./compile where does one typically uncover the various options (flags) that can be set and the descriptions of what each does?!?
For example, in the case of libwmf I'm using:
./configure --without-expat --with-xml --with-png=/usr/X11
...but not really knowing what each flag does. Now I'm having a png compatibility problem and want to find out why --with-png=/usr/X11 flag is being specified in install script I'm following...but can't find any documentation, etc. Any help?
Even a general response of how the UNIX Guru approaches this problem would be helpful.
./configure --help will give you the list of options that a configure script supports. To find out details about each option or the arguments you have to supply in particular cases, you will have to read the installation documentation of the particular package, if it has one. There are certain conventions that you will pick up over time, but they are just conventions. If you build a rather complicated package such as ImageMagick that pulls in dozens of library dependencies, and you use a less-than-common platform such as Mac with hand-compiled stuff, you might really have to dig deep and hard in some cases.
On my Mac, /usr/X11/lib contains a lot of libraries, including libpng.dylib and libpng.3.44.0.dylib in particular. Do you have those libraries? If not, you need to get X11 installed onto your Mac, and things are likely to go more smoothly.
MacOS X for Intel
I've downloaded ImageMagick 6.6.9-9 and configured, built and checked (but not installed) it with minimal issues. I have XCode 4 on my machine - and the only special option I used with ./configure was:
CC=/usr/bin/gcc ./configure
to ensure it picked up the system-provided GCC (4.2.1), not my private version of GCC 4.6.0. (A configuration test failed - for the sizeof(off_t) - because of a library issue. Using the system C compiler avoided that problem.) The ImageMagick configuration printed out:
ImageMagick is configured as follows. Please verify that this configuration
matches your expectations.
Host system type: x86_64-apple-darwin10.7.0
Build system type: x86_64-apple-darwin10.7.0
Option Value
-------------------------------------------------------------------------------
Shared libraries --enable-shared=yes yes
Static libraries --enable-static=yes yes
Module support --with-modules=no no
GNU ld --with-gnu-ld=no no
Quantum depth --with-quantum-depth=16 16
High Dynamic Range Imagery
--enable-hdri=no no
Delegate Configuration:
BZLIB --with-bzlib=yes yes
Autotrace --with-autotrace=no no
Dejavu fonts --with-dejavu-font-dir=default none
DJVU --with-djvu=yes no
DPS --with-dps=yes no
FFTW --with-fftw=yes no
FlashPIX --with-fpx=yes no
FontConfig --with-fontconfig=yes no
FreeType --with-freetype=yes yes
GhostPCL None pcl6 (unknown)
GhostXPS None gxps (unknown)
Ghostscript None gs (unknown)
Ghostscript fonts --with-gs-font-dir=default none
Ghostscript lib --with-gslib=no no
Graphviz --with-gvc=yes no
JBIG --with-jbig=yes no
JPEG v1 --with-jpeg=yes no (failed tests)
JPEG-2000 --with-jp2=yes no
LCMS v1 --with-lcms=yes no
LCMS v2 --with-lcms2=yes no
LQR --with-lqr=yes no
LZMA --with-lzma=yes no
Magick++ --with-magick-plus-plus=yes yes
OpenEXR --with-openexr=yes no
PERL --with-perl=no no
PNG --with-png=yes yes
RSVG --with-rsvg=yes no
TIFF --with-tiff=yes no
WEBP --with-webp=yes no
Windows fonts --with-windows-font-dir= none
WMF --with-wmf=yes no
X11 --with-x= yes
XML --with-xml=yes yes
ZLIB --with-zlib=yes yes
X11 Configuration:
X_CFLAGS =
X_PRE_LIBS = -lSM -lICE
X_LIBS = -L/usr/X11/lib -R/usr/X11/lib
X_EXTRA_LIBS =
Options used to compile and link:
PREFIX = /usr/local
EXEC-PREFIX = /usr/local
VERSION = 6.6.9
CC = /usr/bin/gcc -std=gnu99 -std=gnu99
CFLAGS = -D_THREAD_SAFE -D_THREAD_SAFE -pthread -fopenmp -g -O2 -Wall -D_THREAD_SAFE -pthread
CPPFLAGS = -I/usr/local/include/ImageMagick
PCFLAGS = -fopenmp
DEFS = -DHAVE_CONFIG_H
LDFLAGS = -L/usr/X11/lib -R/usr/X11/lib
MAGICK_LDFLAGS = -L/usr/local/lib -L/usr/X11/lib -R/usr/X11/lib
LIBS = -lMagickCore -lfreetype -lpng -lXext -lXt -lSM -lICE -lX11 -lbz2 -lxml2 -lz -lm -lgomp -lclparser -Wl,-framework,OpenCL -L/System/Library/Frameworks/OpenCL.framework/Versions/A/Libraries -lm -lpthread
CXX = g++
CXXFLAGS = -g -O2 -D_THREAD_SAFE -pthread
FEATURES = OpenMP
Some of the tests failed - I expect that was because I was not actually running an X11 server on the machine at the time. I'm not immediately going to investigate - you are running into problems at a much earlier stage.
MacOS X for PowerPC
As you can see, this is for Snow Leopard (10.6.7) on Intel x86/64. If you are running with Leopard (10.5.x) on PowerPC, you probably have an older XCode and libraries etc, but it would be surprising if the configuration process does not work if you have the XCode on the machine - and X11 installed.
Addressing your question about the flags in the invocation:
./configure --without-expat --with-xml --with-png=/usr/X11
In general, you cannot be certain what each flag does because the
maintainer of the package is completely free to have the flags do whatever
they want. There are certain conventions, but many are not well
understood by the package maintainers so you cannot fully rely on them.
Generally, the --with and --without are simply used to determine
what features to compile in. For example, if you do not have libexpat
installed, you can set --without-expat to complete the build which would otherwise fail.
One would suspect that the default for the package is to attempt
to build with certain features that require libexpat, and the
configury will fail if libexpat is not present, so you set
--without-expat to turn off those features.
The --with-png option with an argument is, IMO, a completely
untrustworthy kludge. I've never seen a package where it
actually works. Typically, all the configure script does
is take your /usr/X11 argument and add it (with "-L"
prepended) to LDFLAGS. The idea is that this will cause
the linker to use /usr/X11/libpng.so and not some other
version of libpng, but the simple fact is that if you
have libpng somewhere else on your system and that other
location is in your LDFLAGS, it will be used. In other
words, if you have /usr/lib/foo.so and /usr/lib/bar.so
and /usr/other/lib/foo.so and /usr/other/lib/bar.so,
there is simply no way to use /usr/lib/foo.so and /usr/lib/other/bar.so
short of deleting one of the libraries. Rather than specifying
a path as an argument to --with-png, you are probably better
off doing "--with-png LDFLAGS='-L/path -L/path2'", or just
ensure that your system is built so that the desired paths are
searched by the linker. (eg, specify the paths in /etc/ld.so.conf
or in /etc/ld.so.conf.d)

How to link to a specific version of the standard library (with gcc)

I've installed GCC 3.4 to /opt/gcc-3.4, and I'm using it to compile legacy code which is incompatible with GCC 4. This also means old versions of the C(++) standard libraries, binutils, and utility libraries.
It works fine for some libraries, but fails when compiling libtiff, because it picks up the system libraries in /usr/lib (see output below). This might be an autotools/configure issue, but I'm not sure. I can't find a configure switch or environment variable, and I'd rather not modify my system /usr/lib/libc.so .
So how to make sure it links to the standard library in /opt/gcc-3.4.4/lib, and ignores /lib and /usr/lib completely?
Output of make (excerpt):
libtool: link: g++ -shared -nostdlib /usr/lib/crti.o /opt/gcc-3.4.3/lib/gcc/i686-pc-linux-gnu/3.4.3/crtbeginS.o .libs/tif_stream.o -Wl,--whole-archive ../port/.libs/libport.a -Wl,--no-whole-archive -Wl,-rpath -Wl,/home/jason/d0src34/prereq/tiff-3.9.4/libtiff/.libs -Wl,-rpath -Wl,/opt/gcc-3.4.3/lib -Wl,-rpath -Wl,/home/jason/d0src34/prereq/usr/lib -Wl,-rpath -Wl,/opt/gcc-3.4.3/lib ../libtiff/.libs/libtiff.so -L/usr/lib /usr/lib/libjpeg.so -lz -L/opt/gcc-3.4.3/lib/gcc/i686-pc-linux-gnu/3.4.3 -L/opt/gcc-3.4.3/lib/gcc/i686-pc-linux-gnu/3.4.3/../../.. /opt/gcc-3.4.3/lib/libstdc++.so -L/home/jason/Downloads/gcc-3.4.3/build/i686-pc-linux-gnu/libstdc++-v3/src -L/home/jason/Downloads/gcc-3.4.3/build/i686-pc-linux-gnu/libstdc++-v3/src/.libs -L/home/jason/Downloads/gcc-3.4.3/build/gcc -lm -lc -lgcc_s /opt/gcc-3.4.3/lib/gcc/i686-pc-linux-gnu/3.4.3/crtendS.o /usr/lib/crtn.o -Wl,-soname -Wl,libtiffxx.so.3 -o .libs/libtiffxx.so.3.9.4
/home/jason/d0src34/prereq/usr/bin/ld:/usr/lib/libc.so: file format not recognized; treating as linker script
/home/jason/d0src34/prereq/usr/bin/ld:/usr/lib/libc.so:5: parse error
I've found a (hackish) answer to my own question:
I've been using binutils 2.15, because later versions have an incompatibility with GCC 3.4. In more recent versions, the format of /usr/lib/libc.so has changed, and the old binutils can't parse it.
I temporarily commented out the last line (with "GROUP"), and my code compiled:
/* GNU ld script
Use the shared library, but some functions are only in
the static library, so try that secondarily. */
OUTPUT_FORMAT(elf32-i386)
/* GROUP ( /lib/libc.so.6 /usr/lib/libc_nonshared.a AS_NEEDED ( /lib/ld-linux.so.2 ) ) */
However, I'm not really satisfied, since I can hardly tell other people who want to use the code to edit their system files. Also, I'm not sure if I've linked it to the correct glibc version, since the system /usr/lib is still in the search path, so I can't tell for sure if the binaries will work on other systems.

Resources