<http://thread.gmane.org/gmane.comp.gnu.libtool.patches/9063/focus=9113>
* Ralf Wildenhues wrote on Mon, Jan 26, 2009 at 11:33:43PM CET: > * Bob Friesenhahn wrote on Sat, Jan 24, 2009 at 05:18:32PM CET: > > On Sat, 24 Jan 2009, Ralf Wildenhues wrote: > > > >> Here is a testsuite addition to get some exposure to versioning. > > I read it and did not see any silly typos or thinkos, but then again it > > is not easy reading. It should be interesting to see where these tests > > report a failure. > > Well, I did test that setting $version_type to "qnx" on my GNU/Linux > system would cause the failure that Mike reported, so one can expect > they are not completely useless, e.g., for porting to a new platform, > or for ensuring that future changes to ltmain will not break documented > semantics. > > OTOH, the tests need a gloss over. Mike's testing already exposed one > bug in them, in that one cannot assume the major version of a library is > $current - $age, it might just be $current (plus or minus one or so). This should be fixed in the patch below, which I have pushed now. > Another bit, my test for this hypothesis: > > | If two libraries have identical CURRENT and AGE numbers, then the > | dynamic linker chooses the library with the greater REVISION number. > > is too weak for what I thought of. On GNU/Linux, you can install two > libraries differing only in revision, and `ldconfig -n $libdir' will > take care to let the respective versioned symlink point to the newer > revision. Cool, huh? I didn't even know that, but I think that's what > the sentence above tried to imply. Problem of course is, this surely > doesn't happen for systems that don't encode a revision into the name, > and may not either hold for some that do. I'd have to test, and will > try to come up with a better patch (and documentation fix) for this > hypothesis then. Well, I'm punting, and just removing that hypothesis and test from the test group now. It is certainly not portable; the manual should be adjusted to reflect this. In the patch below, I've also lowered the used version numbers a bit, for they will cause exceedingly long command lines on OSF and IRIX, with their complicated versioning scheme. This should be fixed as well properly in the ltmain code somehow, but I have no idea yet how. Cheers, Ralf Add versioning tests. * tests/versioning.at (versioning): New file, new test. * Makefile.am (TESTSUITE_AT): Adjust. Prompted by bug report from Mike Gorchak. diff --git a/Makefile.am b/Makefile.am index c49f749..a18955e 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..136a549 --- /dev/null +++ b/tests/versioning.at @@ -0,0 +1,239 @@ +# 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 + +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, it's not portable. +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. +# TODO: check something like 1001:2419:189 after fixing issues +# for `version_type's of `irix', `nonstopux', or `osf'. +for version_info in 1 1:2 0:0:0 1:1:1 13:241:7; 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 +# do not uninstall here: the library may be reused in the next test. + +# Hypothesis: backward compatible library updates do not require +# (uninstalled nor installed) programs to be relinked. +# This can have one of several reasons: +# - the soname is the difference between $current and $age, thus +# unchanged; in this case, the newly installed library will be used, +# - the soname is only $current, or we are linking statically, in which case +# the old installed library code will be used, +# - the numbers are not encoded at all, in which case the newly installed +# library will be used. +AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o liba.la liba3.lo ]dnl + [-version-info 1:0:1 -rpath $libdir], [], [ignore], [ignore]) +# Do not test the uninstalled program, it may be broken (in the second case). +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 +# do not uninstall here: the library may be reused in the next test. + + +# Hypothesis: with shared libraries, incompatible library updates +# will not cause old installed programs (linked against the old +# library version) to break. +# This can have one of several reasons: +# - the soname has changed, so the old installed library will still be +# available, +# - we are linking statically, so the old library code will still be used. +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 + + +AT_CLEANUP