From: Ralf Wildenhues Date: Mon, 20 Mar 2006 20:46:30 +0000 (+0000) Subject: * tests/static.at: New tests for comprehensive test exposure of X-Git-Tag: release-2-1b~308 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=193cfe320b94e5566e66c3f6126b5abf5faa8147;p=thirdparty%2Flibtool.git * tests/static.at: New tests for comprehensive test exposure of all current and proposed static linking flags for programs. * Makefile.am: Updated. --- diff --git a/ChangeLog b/ChangeLog index ae4573629..495cc67b4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2006-03-20 Ralf Wildenhues + * tests/static.at: New tests for comprehensive test exposure of + all current and proposed static linking flags for programs. + * Makefile.am: Updated. + * libltdl/config/ltmain.m4sh (func_mode_link) < -static-libtool-libs >: New option. * doc/libtool.texi (Link mode, Distributing libltdl): diff --git a/Makefile.am b/Makefile.am index f7fbd3965..20a5a9ce7 100644 --- a/Makefile.am +++ b/Makefile.am @@ -389,6 +389,7 @@ TESTSUITE_AT = tests/testsuite.at \ tests/convenience.at \ tests/link-order.at \ tests/fail.at \ + tests/static.at \ tests/old-m4-iface.at \ tests/am-subdir.at \ tests/standalone.at \ diff --git a/tests/static.at b/tests/static.at new file mode 100644 index 000000000..680ee8959 --- /dev/null +++ b/tests/static.at @@ -0,0 +1,300 @@ +# 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]) +AT_KEYWORDS([libtool]) + +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 -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. + + # if -all-static does not work, do not exercise it any more. + all_static=-all-static + eval `$LIBTOOL --config | grep '^link_static_flag='` + test -z "$link_static_flag" && all_static= + + 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