* Ralf Wildenhues wrote on Mon, Jan 30, 2006 at 02:01:53PM CET: > > I will followup to this mail (to libtool-patches only for size) with a > patch to implement per-deplib flags for programs (for CVS HEAD) and add > comprehensive tests for the static flags.
Here goes the test. Note that the tests uncovered that hardcoding was not done in all cases where necessary with the `-static' flag since we changed its behavior; a fix will be proposed in a followup. BTW, this was by far the most time-consuming task of these patches. OK to apply? Cheers, Ralf * tests/static.at: New tests for comprehensive test exposure of all current and proposed static linking flags for programs. * Makefile.am, tests/testsuite.at: Updated. --- tests/testsuite.at 2006-01-30 18:33:32.000000000 +0100 +++ tests/testsuite.at 2006-01-30 18:34:21.000000000 +0100 @@ -290,6 +290,8 @@ m4_include([link-order.at]) # ensure failure m4_include([fail.at]) +# all the diverse static flags +m4_include([static.at]) # Ensure our continued support for old interfaces. m4_include([old-m4-iface.at]) # Torturing subdir-objects builds --- Makefile.am 2006-01-30 18:33:32.000000000 +0100 +++ Makefile.am 2006-01-30 18:34:21.000000000 +0100 @@ -396,6 +396,7 @@ tests/fail.at \ tests/convenience.at \ tests/early-libtool.at \ + tests/static.at \ tests/template.at EXTRA_DIST += $(TESTSUITE) $(TESTSUITE_AT) tests/package.m4 --- /dev/null 2006-01-25 19:46:43.433914872 +0100 +++ tests/static.at 2006-01-30 22:11:38.000000000 +0100 @@ -0,0 +1,294 @@ +# Hand crafted tests for GNU Libtool. -*- Autotest -*- +# Copyright 2006 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. + +# Test flags for controlling static/dynamic linking, +# when creating programs. + +##### NOTES ##### +# +# - How do we test whether a library was linked statically? +# We could +# - try $NM on the program to see whether it includes the symbol definitions. +# disadvantage: for uninstalled programs, we may need to find out the name +# of the _real_ linked-against-uninstalled executable +# (.libs/prog vs .libs/lt-prog etc). +# - simply remove the libraries before execution. If the program still works, +# then the library was linked statically. +# -Does this work on all systems? +# -No, it will fail on AIX with non-rtl-created libraries: plain `-static' +# will only cause the linker not to consider `*.so' libraries, but only +# `*.a'. The latter, however, may still be shared images. :-/ +# `-all-static' still works, however. +# +# It will not work with dlpreloading until we fix its related bug. +# +# Let's try the latter until we know better. + +# - Test -Bstatic/-Bdynamic. It should work with all of: +# - (un)installed libtool libraries +# - non-libtool libraries +# - direct or pulled-in libraries +# - libraries of which there are only one kind available (TODO) +# (in the static case, should having only the shared one provoke failure?) + +# - Check no extraneous run paths have been added. + +# - make sure -Bstatic/-Bdynamic cannot be mixed with -all-static (TODO) + +# - should -Bstatic/-Bdynamic be mixable with -static or -static-libtool-libs? +# Semantics could be as follows: +# - `-static'/`-static-libtool-libs' set the default which is the initial +# value, then `-Bstatic'/`-Bdynamic' override that +# - `-Bdefault' resets to the default value given by the other switches. + +# - TODO: test exposure for dlopened and dlpreopened modules, +# without and with diverse static flag combinations. + +# - TODO: test other tags: C++ etc. +# (most likely the Sun compiler suite will be the only problem child). + +AT_SETUP([static linking flags for programs]) + +LDFLAGS="$LDFLAGS -no-undefined" +prefix=`pwd`/inst +libdir=$prefix/lib +bindir=$prefix/bin +srcdir_broken=`pwd`/b +libdir_broken=`pwd`/b-lib + +have_static=false +have_shared=false +per_deplib=false +$LIBTOOL --features | grep 'enable static libraries' >/dev/null && have_static=: +$LIBTOOL --features | grep 'enable shared libraries' >/dev/null && have_shared=: +eval `$LIBTOOL --config | $EGREP '^per_deplib_(static|dynamic)_flag='` +if test -n "$per_deplib_static_flag" && test -n "$per_deplib_dynamic_flag"; then + per_deplib=: +fi + + +# Create broken libraries. They will later be moved to those +# directories where the respective libraries should be linked +# statically from. This detects both failure to link statically +# and failure to omit extraneous run paths. +mkdir $srcdir_broken $libdir_broken +( + cd $srcdir_broken + echo 'int this_should_not_be_linked_against() { return 0; }' > a.c + $LIBTOOL --mode=compile $CC $CPPFLAGS $CFLAGS -c a.c + for i in 1 1dep 2 2dep 3 3dep; do + $LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o lib$i.la a.lo -rpath $libdir_broken + $LIBTOOL --mode=install cp lib$i.la $libdir_broken/lib$i.la + done +) + +func_move_libs () +{ + mv ${1} ${1}-moved + mv ${2} ${2}-moved + mv $srcdir_broken ${1} + mv $libdir_broken ${2} +} + +func_restore_libs () +{ + mv ${2} $libdir_broken + mv ${1} $srcdir_broken + mv ${2}-moved ${2} + mv ${1}-moved ${1} +} + +# make sure the program can be run. +func_test_exec () +{ + # On AIX without runtimelinking, this does not make sense. + if $have_static; then + echo "## The following should succeed:" + for st + do + echo "# m$st" + LT_AT_EXEC_CHECK([./m$st]) + # For some per-deplib flag combinations there may be no installed program, + # because liba2 is not yet installed. + if test -f "$bindir/m$st"; then + LT_AT_EXEC_CHECK([$bindir/m$st]) + fi + done + fi +} + +# make sure the program cannot be run. +func_test_exec_fail () +{ + # No point in testing if we're linking statically anyway. + # TODO: Maybe in the `else' case we could test for success? + if $have_shared; then + echo "## The following should fail:" + for st + do + echo "# m$st" + LT_AT_EXEC_CHECK([./m$st || (exit 1)], [1], [], [ignore]) + # For some per-deplib flag combinations there may be no installed program, + # because liba2 is not yet installed. + if test -f "$bindir/m$st"; then + LT_AT_EXEC_CHECK([$bindir/m$st || (exit 1)], [1], [], [ignore]) + fi + done + fi +} + + +# Try three independent libraries, +# one installed libtool library, +# one uninstalled libtool library, +# one non-libtool library, +# the libtool libraries each having a dependency, or not. +# Try both an uninstalled and the corresponding installed program. + +for withdep in no yes; do + echo + echo "### libraries with dependencies: $withdep" + rm -rf src $prefix $bindir + mkdir src $prefix $bindir + cd src + + ### build the libraries. + for i in 1 2 3; do + mkdir a$i $libdir$i + cd a$i + case $withdep,$i in + no,* | yes,3) + echo "int a$i() { return 0; }" > a$i.c + $LIBTOOL --mode=compile $CC $CPPFLAGS $CFLAGS -c a$i.c + $LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o liba$i.la a$i.lo -rpath $libdir$i + ;; + *) + echo "int a${i}dep() { return 0; }" > a${i}dep.c + $LIBTOOL --mode=compile $CC $CPPFLAGS $CFLAGS -c a${i}dep.c + $LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o liba${i}dep.la a${i}dep.lo -rpath $libdir$i + echo "extern int a${i}dep(); int a$i() { return a${i}dep(); }" > a$i.c + $LIBTOOL --mode=compile $CC $CPPFLAGS $CFLAGS -c a$i.c + $LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o liba$i.la a$i.lo -rpath $libdir$i ./liba${i}dep.la + ;; + esac + cd .. + done + + ### install the libraries. + test "$withdep" = yes && $LIBTOOL --mode=install cp a1/liba1dep.la ${libdir}1/liba1dep.la + $LIBTOOL --mode=install cp a1/liba1.la ${libdir}1/liba1.la + $LIBTOOL --mode=install cp a3/liba3.la ${libdir}3/liba3.la + $LIBTOOL --mode=clean rm -f a1/liba1.la a3/liba3.la + test "$withdep" = yes && $LIBTOOL --mode=clean rm -f a1/liba1dep.la + # simulate a non-libtool lib: + rm -f ${libdir}3/liba3.la + + + ### build the programs. + echo 'extern int a1(), a2(), a3(); + int main() { return a1() + a2() + a3(); }' > m.c + $CC $CPPFLAGS $CFLAGS -c m.c + + # global static flags. + for st in -static -static-libtool-libs -all-static; do + AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS $st -o m$st m.$OBJEXT \ + -L${libdir}1 $R -la1 a2/liba2.la -L${libdir}3 -R${libdir}3 -la3], + [0], [ignore], [ignore]) + done + + # per-deplib static/shared flags. + # also try a bit redundant flags, and shuffled order (for run paths check). + if $per_deplib; then + AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o m1 m.$OBJEXT \ + -L${libdir}1 -Bstatic -la1 -Bdynamic a2/liba2.la -L${libdir}3 -R${libdir}3 -la3], + [0], [ignore], [ignore]) + AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o m2 m.$OBJEXT \ + -L${libdir}1 -la1 -Bstatic a2/liba2.la -Bdynamic -L${libdir}3 -R${libdir}3 -la3], + [0], [ignore], [ignore]) + AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o m3 m.$OBJEXT \ + -L${libdir}1 -la1 a2/liba2.la -L${libdir}3 -Bstatic -la3 -Bdynamic], + [0], [ignore], [ignore]) + AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o m12 m.$OBJEXT \ + -L${libdir}1 -Bstatic -la1 a2/liba2.la -Bdynamic -L${libdir}3 -R${libdir}3 -la3], + [0], [ignore], [ignore]) + AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o m13 m.$OBJEXT \ + -L${libdir}1 -Bstatic -la1 -Bdynamic a2/liba2.la \ + -L${libdir}3 -Bstatic -la3 -Bdynamic], + [0], [ignore], [ignore]) + AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o m31 m.$OBJEXT \ + -L${libdir}3 -Bstatic -la3 -Bdynamic a2/liba2.la \ + -L${libdir}1 -Bstatic -la1 -Bdynamic], + [0], [ignore], [ignore]) + AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o m23 m.$OBJEXT \ + -L${libdir}1 -la1 -Bstatic a2/liba2.la -Bdynamic \ + -L${libdir}3 -Bstatic -la3 -Bdynamic], + [0], [ignore], [ignore]) + AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o m123 m.$OBJEXT \ + -L${libdir}1 -Bstatic -la1 a2/liba2.la -L${libdir}3 -la3 -Bdynamic], + [0], [ignore], [ignore]) + AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o m123a m.$OBJEXT \ + -L${libdir}1 -Bstatic -la1 -Bdynamic -Bstatic a2/liba2.la -Bdynamic \ + -Bstatic -L${libdir}3 -la3 -Bdynamic], + [0], [ignore], [ignore]) + dnl # This usually fails. So don't do it. + dnl AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o m123b m.$OBJEXT \ + dnl -L${libdir}1 -Bstatic -la1 a2/liba2.la -L${libdir}3 -la3], + dnl [0], [ignore], [ignore]) + fi + + ### install the programs. + # We can't install any program that links dynamically against liba2. + for st in -static -static-libtool-libs -all-static `$per_deplib && echo 2 12 23 123 123a`; do + echo "# m$st" + AT_CHECK([$LIBTOOL --mode=install cp m$st $bindir/m$st], [0], [ignore], [stderr]) + if $have_static; then + AT_CHECK([$EGREP 'relinking|has not been installed' stderr], [1], [], []) + fi + done + dnl AT_CHECK([$LIBTOOL --mode=install cp m123b $bindir/m123b], [0], [ignore], [ignore]) + + + ### Run each program once so that relinking has happened. + func_test_exec -static -static-libtool-libs -all-static `$per_deplib && echo 1 2 3 12 13 23 31 123 123a` + + # For each library: + # - remove the library images to catch failure to link statically/dynamically, + # - add false other deplibs in the paths to catch (some) wrongly added run paths. + + echo "### test whether installed libtool library liba2 was linked statically" + func_move_libs a2 ${libdir}2 + func_test_exec -static -static-libtool-libs -all-static `$per_deplib && echo 2 12 23 123 123a` + $per_deplib && func_test_exec_fail 1 3 13 31 + func_restore_libs a2 ${libdir}2 + + echo "### test whether uninstalled libtool library liba1 was linked statically" + func_move_libs a1 ${libdir}1 + func_test_exec -static-libtool-libs -all-static `$per_deplib && echo 1 12 13 31 123 123a` + $per_deplib && func_test_exec_fail -static 2 3 23 + func_restore_libs a1 ${libdir}1 + + echo "### test whether non-libtool library liba3 was linked statically" + func_move_libs a3 ${libdir}3 + func_test_exec -all-static `$per_deplib && echo 3 13 23 31 123 123a` + func_test_exec_fail -static -static-libtool-libs `$per_deplib && echo 1 2 12` + func_restore_libs a3 ${libdir}3 + + cd .. +done + +AT_CLEANUP