Here is a testsuite addition to get some exposure to versioning. OK to push (and add Mike to THANKS)? It'd be good if somebody proof-read it so there are no silly typos or thinkos.
Thanks, Ralf 2009-01-24 Ralf Wildenhues <[email protected]> Add versioning tests. * tests/versioning.at (versioning): New file, new test. * Makefile.am (TESTSUITE_AT): Adjust. * THANKS: Update. Prompted by bug report from Mike Gorchak. diff --git a/Makefile.am b/Makefile.am index 7982025..50e1b58 100644 --- a/Makefile.am +++ b/Makefile.am @@ -472,6 +472,7 @@ TESTSUITE_AT = tests/testsuite.at \ tests/infer-tag.at \ tests/localization.at \ tests/install.at \ + tests/versioning.at \ tests/destdir.at \ tests/old-m4-iface.at \ tests/am-subdir.at \ diff --git a/tests/versioning.at b/tests/versioning.at new file mode 100644 index 0000000..1c5cb00 --- /dev/null +++ b/tests/versioning.at @@ -0,0 +1,255 @@ +# versioning.at -- test libtool versioning -*- Autotest -*- +# +# Copyright (C) 2009 Free Software Foundation, Inc. +# +# This file is part of GNU Libtool. +# +# GNU Libtool 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 of +# the License, or (at your option) any later version. +# +# GNU Libtool 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 GNU Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, +# or obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +#### + +AT_SETUP([versioning]) +AT_KEYWORDS([libtool]) + +eval `$LIBTOOL --config | $EGREP '^(objdir)='` + +# Setup some library and program sources: +# a library (a1), a new revision (a2), a compatible update (a3), +# an incompatible update (a4). +# Another library (libb) using liba, and a couple of programs, +# using liba directly and indirectly through libb. + +AT_DATA([liba1.c], [[ +int a (void) +{ + return 0; +} +]]) + +AT_DATA([liba2.c], [[ +/* The internal detail should be static. It isn't static in this test, + so we can later find out that it's this revision of the library. */ +int internal_detail = 42; +int a (void) +{ + return internal_detail - 42; +} +]]) + +AT_DATA([liba3.c], [[ +int a (void) +{ + return 0; +} +int aa (void) +{ + return 0; +} +]]) + +AT_DATA([liba4.c], [[ +int aa (void) +{ + return 0; +} +]]) + +AT_DATA([libb.c], [[ +extern int a (void); +int b (void) +{ + return a (); +} +]]) + +AT_DATA([prog1.c], [[ +extern int a (void); +int main (void) +{ + return a (); +} +]]) + +AT_DATA([prog2.c], [[ +extern int b (void); +int main (void) +{ + return b (); +} +]]) + +AT_DATA([prog3.c], [[ +extern int a (void), internal_detail; +int main (void) +{ + return a () + internal_detail - 42; +} +]]) + + +inst=`pwd`/inst +libdir=$inst/lib +bindir=$inst/bin +mkdir $inst $libdir $bindir + +LDFLAGS="$LDFLAGS -no-undefined" + +for file in liba1.c liba2.c liba3.c liba4.c libb.c; do + $LIBTOOL --mode=compile $CC $CPPFLAGS $CFLAGS -c $file +done +for file in prog1.c prog2.c prog3.c; do + $CC $CPPFLAGS $CFLAGS -c $file +done + +# Setup is finished here. + +# Hypothesis: -version-info is ignored for convenience archives. +AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o liba.la liba1.lo ]dnl + [-version-info 0:0:0], [], [ignore], [stderr]) +AT_CHECK([grep 'version-info.*ignored for convenience' stderr], [], [ignore]) + +# Hypothesis: the deprecated -version-number works. +# Be sure not to use zero here. +for version_number in 1 1:1 2:1 1:1:1 3:2:1; do + AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o liba.la liba1.lo ]dnl + [-version-number $version_number -rpath $libdir], [], [ignore], [ignore]) +done + +# Hypothesis: -version-info can be passed kinds of values, esp. zero ones +# and large ones. +for version_info in 1 1:2 0:0:0 1:1:1 13:241:7 1001:2419:189; do + AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o liba.la liba1.lo ]dnl + [-version-info $version_info -rpath $libdir], [], [ignore], [ignore]) +done + +# Hypothesis: we diagnose when AGE is higher than CURRENT. +AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o liba.la liba1.lo ]dnl + [-version-info 1:3:2 -rpath $libdir], [1], [ignore], [stderr]) +AT_CHECK([grep 'AGE.*is greater than' stderr], [], [ignore]) + +# Hypothesis: we diagnose invalid values. +for version_info in 1:2:3:4 -1 0:-1 0:0:-1; do + AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o liba.la liba1.lo ]dnl + [-version-info $version_info -rpath $libdir], [1], [ignore], [ignore]) +done + + +# Now, create an original version of the library and associated users. +# This setup will be reused for further hypotheses below, and these +# functions will be used to test working programs. + +test_uninstalled () +{ + # temporarily move installed libraries out of the way in order to avoid + # skewing test results: + mv $libdir temp + LT_AT_EXEC_CHECK([./prog1]) + LT_AT_EXEC_CHECK([./prog2]) + mv temp $libdir +} + +test_installed () +{ + # temporarily move uninstalled libraries out of the way in order to avoid + # skewing test results: + mv $objdir temp + LT_AT_EXEC_CHECK([$bindir/prog1]) + LT_AT_EXEC_CHECK([$bindir/prog2]) + mv temp $objdir +} + +AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o liba.la liba1.lo ]dnl + [-version-info 0:0:0 -rpath $libdir], [], [ignore], [ignore]) +AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o libb.la libb.lo liba.la ]dnl + [-version-info 0:0:0 -rpath $libdir], [], [ignore], [ignore]) +AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o prog1$EXEEXT prog1.$OBJEXT ]dnl + [liba.la], [], [ignore], [ignore]) +AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o prog2$EXEEXT prog2.$OBJEXT ]dnl + [libb.la], [], [ignore], [ignore]) +test_uninstalled +AT_CHECK([$LIBTOOL --mode=install cp liba.la libb.la $libdir], + [], [ignore], [ignore]) +AT_CHECK([$LIBTOOL --mode=install cp prog1$EXEEXT prog2$EXEEXT $bindir], + [], [ignore], [ignore]) +AT_CHECK([$LIBTOOL --mode=clean rm -f liba.la], [], [ignore], [ignore]) +test_installed +AT_CHECK([$LIBTOOL --mode=uninstall rm -f $libdir/liba.la], [], [ignore], [ignore]) + + +# Hypothesis: library revision updates do not require (uninstalled +# nor installed) programs to be relinked. +AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o liba.la liba2.lo ]dnl + [-version-info 0:1:0 -rpath $libdir], [], [ignore], [ignore]) +test_uninstalled +AT_CHECK([$LIBTOOL --mode=install cp liba.la libb.la $libdir], + [], [ignore], [ignore]) +AT_CHECK([$LIBTOOL --mode=clean rm -f liba.la], [], [ignore], [ignore]) +test_installed +AT_CHECK([$LIBTOOL --mode=uninstall rm -f $libdir/liba.la], [], [ignore], [ignore]) + + +# Hypothesis: backward compatible library updates do not require +# (uninstalled nor installed) programs to be relinked. +AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o liba.la liba3.lo ]dnl + [-version-info 1:0:1 -rpath $libdir], [], [ignore], [ignore]) +test_uninstalled +AT_CHECK([$LIBTOOL --mode=install cp liba.la libb.la $libdir], + [], [ignore], [ignore]) +test_installed +# do not uninstall here, because we reuse the library for the next ... + + +# Hypothesis: with shared libraries, incompatible library updates +# will not cause old installed programs (linked against the old +# library version) to break. +AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o liba.la liba4.lo ]dnl + [-version-info 2:0:0 -rpath $libdir], [], [ignore], [ignore]) +# We do not guarantee that old versions of an uninstalled library are still +# available, so test_uninstalled will not necessarily work here any more. +AT_CHECK([$LIBTOOL --mode=install cp liba.la libb.la $libdir], + [], [ignore], [ignore]) +AT_CHECK([$LIBTOOL --mode=clean rm -f liba.la], [], [ignore], [ignore]) +test_installed + + +# Hypothesis: if two libraries have identical CURRENT and AGE numbers, +# then the dynamic linker chooses the library with the greater REVISION +# number (see @node{Libtool versioning}). + +# We recreate the necessary libraries here, and test this for installed +# libtool and non-libtool libraries only. +rm -rf $inst +mkdir $inst $libdir $bindir +AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o liba.la liba1.lo ]dnl + [-version-info 0:0:0 -rpath $libdir], [], [ignore], [ignore]) +AT_CHECK([$LIBTOOL --mode=install cp liba.la $libdir], [], [ignore], [ignore]) +AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o liba.la liba2.lo ]dnl + [-version-info 0:1:0 -rpath $libdir], [], [ignore], [ignore]) +AT_CHECK([$LIBTOOL --mode=install cp liba.la $libdir], [], [ignore], [ignore]) +AT_CHECK([$LIBTOOL --mode=clean rm -f liba.la], [], [ignore], [ignore]) +AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o prog3$EXEEXT prog3.$OBJEXT ]dnl + [$libdir/liba.la], [], [ignore], [ignore]) +LT_AT_EXEC_CHECK([./prog3]) +AT_CHECK([$LIBTOOL --mode=install cp prog3$EXEEXT $bindir], [], [ignore], [ignore]) +LT_AT_EXEC_CHECK([$bindir/prog3]) +rm -f $libdir/liba.la +AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o prog3$EXEEXT prog3.$OBJEXT ]dnl + [-L$libdir -la -R$libdir], [], [ignore], [ignore]) +LT_AT_EXEC_CHECK([./prog3]) +AT_CHECK([$LIBTOOL --mode=install cp prog3$EXEEXT $bindir], [], [ignore], [ignore]) +LT_AT_EXEC_CHECK([$bindir/prog3]) + +AT_CLEANUP
