bug#27722: libtool makes it impossible to build a package statically

Bruno Haible <[email protected]>
Newsgroups gmane.comp.gnu.libtool.bugs
Message-ID <3009480.1b2adHvoDB@omega>
Hi,

Summary
-------

The processing of the '-static' option by "libtool --mode=link" makes it
impossible to build a package in such a way that
  1) all libraries are static,
  2) all binaries are statically linked (ldd reports "not a dynamic executable").

Motivation
----------

There are many use-cases of statically linked binaries. In my case it's
because I want to run programs under qemu in "user mode", and for big-endian
CPUs currently only statically linked binaries work. [1]

Details
-------

In packages that don't create shared libraries and therefore don't use libtool,
the way to achieve statically linked binaries (assuming GCC) is simple:

  $ ./configure LDFLAGS="-static"

For packages that create *only* shared libraries, the GNU libtool manual
provides a solution [2][3]:

  $ ./configure --enable-static --disable-shared LDFLAGS="-all-static"

But this is not a general solution: Some packages, like GNU libffcall,
create shared libraries AND static libraries. But there is only 1 LDFLAGS
parameter that can be passed to 'configure'.

'configure' (thankfully!) does not take 2 different variables LDFLAGS
(for non-libtool linking) and LTLDFLAGS (for libtool linking), because
the use of libtool is an internal detail of a package, and the user who
wants to install it should not see added complexity because of libtool.

So,
1) $ ./configure --enable-static --disable-shared LDFLAGS="-static"
   does not work for producing statically linked binaries because libtool
   intercepts the 'static' option. The result (according to 'ldd') is
   a binary that is linked against the *shared* libc.
2) $ ./configure --enable-static --disable-shared LDFLAGS="-all-static"
   does not work because GCC does not understand a '-all-static' option.
3) The hint given in [4]
   $ ./configure --enable-static --disable-shared LDFLAGS="-Xcompiler -static"
   does not work because GCC does not understand a '-Xcompiler' option.

How to reproduce
----------------

$ wget https://haible.de/bruno/gnu/libiconv-20170715.tar.gz

1) $ tar xvfz libiconv-20170715.tar.gz
   $ cd libiconv-20170715
   $ ./configure --enable-static --disable-shared LDFLAGS="-static"
   $ make
   $ make install DESTDIR=/tmp/inst
   $ LC_ALL=C ldd /tmp/inst/usr/local/bin/iconv
           linux-vdso.so.1 =>  (0x00007fff1a74d000)
           libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fddde90b000)
           /lib64/ld-linux-x86-64.so.2 (0x00005580e2f6c000)

2) $ tar xvfz libiconv-20170715.tar.gz
   $ cd libiconv-20170715
   $ ./configure --enable-static --disable-shared LDFLAGS="-all-static"
   ...
   checking whether the C compiler works... no
   configure: error: in `/tmp/libiconv-20170715':
   configure: error: C compiler cannot create executables
   See `config.log' for more details

3) $ tar xvfz libiconv-20170715.tar.gz
   $ cd libiconv-20170715
   $ ./configure --enable-static --disable-shared LDFLAGS="-Xcompiler -static"
   ...
   checking whether the C compiler works... no
   configure: error: in `/tmp/libiconv-20170715':
   configure: error: C compiler cannot create executables
   See `config.log' for more details

Past reports
------------

In 2004, this was discussed here: [5] already gave the solution, namely to
rename libtool's options. [6] gives the rationale.

For the specific case of GNU binutils, it was reported in 2011: [7][8]

Reported again in 2012: [9][10]

My workaround
-------------

I work around it with the solution from [5]. Instead of '-lt-static'
I chose '-static-uninstalled-libs', in order to reduce the confusion
with the existing option '-static-libtool-libs'.

Patch attached. It touches only the *link* mode of libtool. I don't
see a reason for touching the *compile* mode of libtool, since the
right place for the '-static' option is LDFLAGS, not CFLAGS. [11]

With this patch, it works as expected:

   $ tar xvfz libiconv-20170715.tar.gz
   $ cd libiconv-20170715
   $ patch -p1 < /tmp/libtool-allow-static.diff
   $ ./configure --enable-static --disable-shared LDFLAGS="-static"
   $ make
   $ make install DESTDIR=/tmp/inst
   $ LC_ALL=C ldd /tmp/inst/usr/local/bin/iconv
           not a dynamic executable


Best regards,

         Bruno


[1] https://bugs.launchpad.net/qemu/+bug/1701798
[2] https://www.gnu.org/software/libtool/manual/html_node/LT_005fINIT.html
[3] https://www.sourceware.org/autobook/autobook/autobook_59.html#Linking-against-Libtool-Libraries-with-Automake
[4] https://debbugs.gnu.org/cgi/bugreport.cgi?bug=11064
[5] https://lists.gnu.org/archive/html/libtool/2004-11/msg00017.html
[6] https://lists.gnu.org/archive/html/libtool/2004-11/msg00024.html
[7] https://sourceware.org/ml/binutils/2011-08/msg00159.html
[8] https://sourceware.org/bugzilla/show_bug.cgi?id=13891
[9] https://debbugs.gnu.org/cgi/bugreport.cgi?bug=11064
[10] https://lists.gnu.org/archive/html/bug-libtool/2012-03/msg00011.html
[11] https://www.gnu.org/software/autoconf/manual/autoconf-2.69/html_node/Preset-Output-Variables.html

_______________________________________________
Bug-libtool mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/bug-libtool
libtool-allow-static.diff (text/x-patch, 2.7 KB)
diff --git a/build-aux/ltmain.sh b/build-aux/ltmain.sh
index 0f0a2da..1d0185a 100644
--- a/build-aux/ltmain.sh
+++ b/build-aux/ltmain.sh
@@ -3720,6 +3720,7 @@ a program from several object files.
 The following components of LINK-COMMAND are treated specially:
 
   -all-static       do not do any dynamic linking at all
+  -static           do not do any dynamic linking at all
   -avoid-version    do not add a version suffix if possible
   -bindir BINDIR    specify path to binaries directory (for systems where
                     libraries must be found in the PATH setting at runtime)
@@ -3746,7 +3747,8 @@ The following components of LINK-COMMAND are treated specially:
   -R[ ]LIBDIR       add LIBDIR to the runtime path of programs and libraries
   -shared           only do dynamic linking of libtool libraries
   -shrext SUFFIX    override the standard shared library file extension
-  -static           do not do any dynamic linking of uninstalled libtool libraries
+  -static-uninstalled-libs
+                    do not do any dynamic linking of uninstalled libtool libraries
   -static-libtool-libs
                     do not do any dynamic linking of libtool libraries
   -version-info CURRENT[:REVISION[:AGE]]
@@ -6573,9 +6575,9 @@ func_mode_link ()
 	build_old_libs=no
 	break
 	;;
-      -all-static | -static | -static-libtool-libs)
+      -all-static | -static | -static-uninstalled-libs | -static-libtool-libs)
 	case $arg in
-	-all-static)
+	-all-static | -static)
 	  if test yes = "$build_libtool_libs" && test -z "$link_static_flag"; then
 	    func_warning "complete static linking is impossible in this configuration"
 	  fi
@@ -6584,7 +6586,7 @@ func_mode_link ()
 	  fi
 	  prefer_static_libs=yes
 	  ;;
-	-static)
+	-static-uninstalled-libs)
 	  if test -z "$pic_flag" && test -n "$link_static_flag"; then
 	    dlopen_self=$dlopen_self_static
 	  fi
@@ -6883,7 +6885,7 @@ func_mode_link ()
       prevarg=$arg
 
       case $arg in
-      -all-static)
+      -all-static | -static)
 	if test -n "$link_static_flag"; then
 	  # See comment for -static flag below, for more details.
 	  func_append compile_command " $link_static_flag"
@@ -7174,9 +7176,9 @@ func_mode_link ()
 	continue
 	;;
 
-      -static | -static-libtool-libs)
-	# The effects of -static are defined in a previous loop.
-	# We used to do the same as -all-static on platforms that
+      -static-uninstalled-libs | -static-libtool-libs)
+	# The effects of -static-uninstalled-libs are defined in a previous
+	# loop.  We used to do the same as -all-static on platforms that
 	# didn't have a PIC flag, but the assumption that the effects
 	# would be equivalent was wrong.  It would break on at least
 	# Digital Unix and AIX.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.