From 912a36eab1ba0ccd5db3e59a2738aa0b940e7b98 Mon Sep 17 00:00:00 2001 From: Ileana Dumitrescu Date: Thu, 28 Aug 2025 20:58:52 +0300 Subject: [PATCH] Add test file for libtool-next-version script * Makefile.am: Add versioning_script.at to testsuite. * doc/libtool.texi: Update to describe new test file. * tests/versioning_script.at: Autotest file for testing the output of the libtool-next-version script. --- Makefile.am | 1 + doc/libtool.texi | 4 + tests/versioning_script.at | 303 +++++++++++++++++++++++++++++++++++++ 3 files changed, 308 insertions(+) create mode 100644 tests/versioning_script.at diff --git a/Makefile.am b/Makefile.am index e869211b3..f25663d86 100644 --- a/Makefile.am +++ b/Makefile.am @@ -738,6 +738,7 @@ TESTSUITE_AT = tests/testsuite.at \ tests/bug_62343.at \ tests/bug_71489.at \ tests/bug_42313.at \ + tests/versioning_script.at \ $(NOTHING_ELSE) EXTRA_DIST += $(testsuite) $(TESTSUITE_AT) $(package_m4) diff --git a/doc/libtool.texi b/doc/libtool.texi index 2ec65c9f9..07aa1e7e0 100644 --- a/doc/libtool.texi +++ b/doc/libtool.texi @@ -5809,6 +5809,10 @@ Tests that @command{libtool} can handle C++ code utilizing templates. Main testsuite framework file processed by @command{autom4te} processes enable running the @command{libtool} test cases. +@item @file{tests/versioning_script.at} +Tests @command{libtool-next-version} for verifying the helper script determines +the next version to use for a @command{libtool} library correctly. + @item @file{tests/versioning.at} Tests @command{libtool}'s versioning system. Tests begin with verifying the behaviour of @command{libtool} versioning flags @option{-version-info} and diff --git a/tests/versioning_script.at b/tests/versioning_script.at new file mode 100644 index 000000000..d0c1c907d --- /dev/null +++ b/tests/versioning_script.at @@ -0,0 +1,303 @@ +# versioning_script.at -- test the libtool versioning script: libtool-next-version -*- Autotest -*- +# +# Copyright (C) 2025 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. If not, see . +#### +#### + +AT_SETUP([Test libtool-next-version script]) +AT_KEYWORDS([libtool]) +# Testing the script. Let's create an old library and a new library. + +eval `$LIBTOOL --config | $EGREP '^(libname_spec|libext)='` + +mkdir -p libexample/src +mkdir -p new_libexample/src + +mkdir libexample/m4 +mkdir new_libexample/m4 + +touch libexample/src/Makefile.am new_libexample/src/Makefile.am + +AT_DATA([libexample/Makefile.am], [[ +# Makefile.am +ACLOCAL_AMFLAGS = -I m4 +SUBDIRS = src + +# Enable subdir-objects option +AM_CFLAGS = -I$(srcdir)/src + +# Enable subdir-objects +AUTOMAKE_OPTIONS = subdir-objects + +lib_LTLIBRARIES = libexample.la + +libexample_la_SOURCES = src/example.c src/example.h +]]) + +AT_DATA([new_libexample/Makefile.am], [[ +# Makefile.am +ACLOCAL_AMFLAGS = -I m4 +SUBDIRS = src + +# Enable subdir-objects option +AM_CFLAGS = -I$(srcdir)/src + +# Enable subdir-objects +AUTOMAKE_OPTIONS = subdir-objects + +lib_LTLIBRARIES = libexample.la + +libexample_la_SOURCES = src/example.c src/example.h +]]) + +AT_DATA([libexample/configure.ac], [[ +# configure.ac +AC_INIT([libexample], [1.0]) +AM_INIT_AUTOMAKE([-Wall -Werror foreign]) + +# Add the macro directory +AC_CONFIG_MACRO_DIRS([m4]) + +# Initialize the archiver +AM_PROG_AR + +AC_PROG_CC + +# Set Libtool versioning +LT_INIT + +AC_CONFIG_SRCDIR([src/example.c]) +AC_CONFIG_HEADERS([config.h]) + +AC_CONFIG_FILES([Makefile src/Makefile]) +AC_OUTPUT +]]) + +AT_DATA([new_libexample/configure.ac], [[ +# configure.ac +AC_INIT([libexample], [1.0]) +AM_INIT_AUTOMAKE([-Wall -Werror foreign]) + +# Add the macro directory +AC_CONFIG_MACRO_DIRS([m4]) + +# Initialize the archiver +AM_PROG_AR + +AC_PROG_CC + +# Set Libtool versioning +LT_INIT +AC_CONFIG_SRCDIR([src/example.c]) +AC_CONFIG_HEADERS([config.h]) + +AC_CONFIG_FILES([Makefile src/Makefile]) +AC_OUTPUT +]]) + +AT_DATA([libexample/src/example.c], [[ +// src/example.c +#include + +void example_function() { + printf("Hello from example_function!\n"); +} +]]) + +AT_DATA([libexample/src/example.h], [[ +// src/example.h +#ifndef EXAMPLE_H +#define EXAMPLE_H + +void example_function(); + +#endif // EXAMPLE_H +]]) + + +AT_DATA([new_libexample/src/example.c], [[ +// src/example.c +#include + +void example_function() { + printf("Hello from example_function!\n"); +} + +void new_function() { + printf("new\n"); +} +]]) + +AT_DATA([new_libexample/src/example.h], [[ +// src/example.h +// +#ifndef EXAMPLE_H +#define EXAMPLE_H + +void example_function(); +void new_function(); +#endif // EXAMPLE_H +]]) + +echo "Running autoreconf on libexample directory, the original library" +( + cd libexample + LT_AT_LIBTOOLIZE([--copy --ltdl]) + LT_AT_AUTORECONF([-ivf]) + LT_AT_CONFIGURE([], [configure]) + LT_AT_MAKE([]) +) + +echo "Running autoreconf on new_libexample directory, the updated library" +( + cd new_libexample + LT_AT_LIBTOOLIZE([--copy --ltdl]) + LT_AT_AUTORECONF([-ivf]) + LT_AT_CONFIGURE([], [configure]) + LT_AT_MAKE([]) +) + +remove_whitespace() { + input_string=$1 + echo "$input_string" | tr -d '[[:space:]]' +} + +# Check if the version script exists +if test -f "$_lt_pkgdatadir/libtool-next-version"; then + script_path=$_lt_pkgdatadir/libtool-next-version +elif test -f "$abs_builddir/../libtool-next-version"; then + script_path=$abs_builddir/../libtool-next-version +elif test -f "../../../libtool-next-version"; then + script_path=../../../libtool-next-version +else + echo "Couldn't find script" +fi + +AT_CHECK([test -f "$script_path"]) + +name=example +eval libname=\"$libname_spec\" + +# Set version to 1.0.0. Select the default options for determining the new version of the library. +(echo "1"; echo "0"; echo "0"; echo yes; echo no; echo no; echo yes) \ + | $script_path libexample/.libs/$libname.$libext new_libexample/.libs/$libname.$libext > actual + +tr -d '[[:space:]]' < actual > temp && mv temp actual + +# Verify --help works +$script_path --help > actual +tr -d '[[:space:]]' < actual > temp && mv temp actual + +expected="Options: --help print this help and exit --version print version information and exit" +expected=$(remove_whitespace "$expected") +echo "expected is $expected" +AT_CHECK([$GREP -i $expected actual], + [0], [ignore]) + +# Verify --version works +$script_path --version > actual +tr -d '[[:space:]]' < actual > temp && mv temp actual +expected="libtool-next-version (GNU libtool)" +expected=$(remove_whitespace "$expected") +echo "expected is $expected" +AT_CHECK([$GREP -i $expected actual], + [0], [ignore]) + +# Try each possible answer to the version script. + +# Case 1: Indicate to the script that there has not been any code change. +(echo "1"; echo "0"; echo "0"; echo no) \ + | $script_path libexample/.libs/$libname.$libext new_libexample/.libs/$libname.$libext > actual + +tr -d '[[:space:]]' < actual > temp && mv temp actual +expected_version="This is the libtool version of the library for the new release: LTV_CURRENT=1 LTV_REVISION=0 LTV_AGE=0" +expected_version=$(echo "$expected_version" | tr -d '[[:space:]]') +AT_CHECK([$GREP -i $expected_version actual], + [0], [ignore]) + +# Case 2: There is a code change. An interface has been removed. +(echo "1"; echo "0"; echo "0"; echo yes; echo yes) \ + | $script_path libexample/.libs/$libname.$libext new_libexample/.libs/$libname.$libext > actual + +tr -d '[[:space:]]' < actual > temp && mv temp actual +expected_version="This is the libtool version of the library for the new release: LTV_CURRENT=2 LTV_REVISION=0 LTV_AGE=0" +expected_version=$(echo "$expected_version" | tr -d '[[:space:]]') +AT_CHECK([$GREP -i $expected_version actual], + [0], [ignore]) + +# Case 3: There is a code change. No interfaces have been removed. An interface has changed. +(echo "1"; echo "0"; echo "0"; echo yes; echo no; echo yes) \ + | $script_path libexample/.libs/$libname.$libext new_libexample/.libs/$libname.$libext> actual + +tr -d '[[:space:]]' < actual > temp && mv temp actual +expected_version="This is the libtool version of the library for the new release: LTV_CURRENT=2 LTV_REVISION=0 LTV_AGE=0" +expected_version=$(echo "$expected_version" | tr -d '[[:space:]]') +AT_CHECK([$GREP -i $expected_version actual], + [0], [ignore]) + + # Case 4: There is a code change. No interfaces have been removed. No interfaces have changed. An interface has been added. +(echo "1"; echo "0"; echo "0"; echo yes; echo no; echo no; echo yes) \ + | $script_path libexample/.libs/$libname.$libext new_libexample/.libs/$libname.$libext > actual + +tr -d '[[:space:]]' < actual > temp && mv temp actual +expected_version="This is the libtool version of the library for the new release: LTV_CURRENT=2 LTV_REVISION=0 LTV_AGE=1" +expected_version=$(echo "$expected_version" | tr -d '[[:space:]]') +AT_CHECK([$GREP -i $expected_version actual], + [0], [ignore]) + +# Case 5: There is a code change. No interfaces have been removed. No interfaces have changed. No interfaces have been added. +(echo "1"; echo "0"; echo "0"; echo yes; echo no; echo no; echo no; echo yes) \ + | $script_path libexample/.libs/$libname.$libext new_libexample/.libs/$libname.$libext > actual + +tr -d '[[:space:]]' < actual > temp && mv temp actual +expected_version="This is the libtool version of the library for the new release: LTV_CURRENT=1 LTV_REVISION=1 LTV_AGE=0" +expected_version=$(echo "$expected_version" | tr -d '[[:space:]]') +AT_CHECK([$GREP -i $expected_version actual], + [0], [ignore]) + +case $host_os in +mingw* | windows* | cygwin* | solaris* | linux-musl*) + echo "Version script not testing code change differences on Solaris, Alpine Linux, and Windows platforms". + ;; +*) + echo "Version script testing code change differences on $host_os" + # Test on differences from the old library to the new library + (echo "1"; echo "0"; echo "0"; echo yes; echo no; echo no; echo yes) \ + | $script_path libexample/.libs/$libname.$libext new_libexample/.libs/$libname.$libext > actual + + tr -d '[[:space:]]' < actual > temp && mv temp actual + + # If the symbol list has changed and something has been added, roll the CURRENT and AGE version. + # That is, the new version is 2.0.1 + expected_version="This is the libtool version of the library for the new release: LTV_CURRENT=2 LTV_REVISION=0 LTV_AGE=1" + expected_version=$(echo "$expected_version" | tr -d '[[:space:]]') + AT_CHECK([$GREP -i $expected_version actual], + [0], [ignore]) + + # Verify the symbol list has changed and is a new_function + expected_1="The symbol list changed. Here are the differences:" + expected_2=new_function + expected_1=$(remove_whitespace "$expected_1") + expected_2=$(remove_whitespace "$expected_2") + echo "expected is $expected_1 && $expected_2" + AT_CHECK([$GREP -i $expected_1 actual && $GREP -i $expected_2 actual], + [0], [ignore]) +esac + + +AT_CLEANUP -- 2.47.3