summaryrefslogtreecommitdiff
path: root/build-aux/libtool-next-version
diff options
context:
space:
mode:
authorBruno Haible <bruno@clisp.org>2019-05-12 16:10:30 +0200
committerBruno Haible <bruno@clisp.org>2019-05-12 16:12:06 +0200
commit9bba04193bbc49a43702110e72b104791a23a6c6 (patch)
tree1293d64c9389b6d52c56857bb9bc61e833c92641 /build-aux/libtool-next-version
parent569b5e1064b22fddc9ca7204d2ffc4f959302558 (diff)
downloadgnulib-9bba04193bbc49a43702110e72b104791a23a6c6.tar.gz
libtool-next-version: New program.
* build-aux/libtool-next-version: New file.
Diffstat (limited to 'build-aux/libtool-next-version')
-rwxr-xr-xbuild-aux/libtool-next-version291
1 files changed, 291 insertions, 0 deletions
diff --git a/build-aux/libtool-next-version b/build-aux/libtool-next-version
new file mode 100755
index 0000000000..db441f7f17
--- /dev/null
+++ b/build-aux/libtool-next-version
@@ -0,0 +1,291 @@
+#! /bin/sh
+#
+# Copyright (C) 2019 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 3 of the License, 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, see <https://www.gnu.org/licenses/>.
+#
+
+# This program is a wizard that helps a maintainer update the libtool
+# version of a shared library, according to the documentation section
+# 'Updating version info'
+# <https://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html>.
+#
+# Let's call the three parts of the version
+# LTV_CURRENT
+# LTV_REVISION
+# LTV_AGE
+#
+# The list of steps given in this documentation section
+# - If the library source code has changed at all since the last update,
+# then increment LTV_REVISION.
+# - If any interfaces have been added, removed, or changed since the last
+# update, increment LTV_CURRENT and set LTV_REVISION to 0.
+# - If any interfaces have been added since the last public release, then
+# increment LTV_AGE.
+# - If any interfaces have been removed or changed since the last public
+# release, then set LTV_AGE to 0.
+# leads to mistakes, because
+# - It does not say what "interfaces" are.
+# - It does not enforce that applying the second, third, or fourth rule
+# is only possible after applying the first rule.
+# - It does not enforce that applying the third or fourth rule is only
+# possible after applying the second rule.
+
+# func_usage
+# outputs to stdout the --help usage message.
+func_usage ()
+{
+ echo "\
+Usage: libtool-next-version [OPTION]... PREVIOUS-LIBRARY CURRENT-LIBRARY
+
+Determines the next version to use for a libtool library.
+
+PREVIOUS-LIBRARY is the installed library (in .a or .so format) of the
+previous release.
+
+CURRENT-LIBRARY is the installed library (in .a or .so format) of the current
+release candidate.
+
+Options:
+ --help print this help and exit
+ --version print version information and exit
+
+Report bugs to <bruno@clisp.org>."
+}
+
+# func_version
+# outputs to stdout the --version message.
+func_version ()
+{
+ echo "libtool-next-version (GNU gnulib)"
+ echo "Copyright (C) 2019 Free Software Foundation, Inc.
+License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>
+This is free software: you are free to change and redistribute it.
+There is NO WARRANTY, to the extent permitted by law."
+ echo "Written by" "Bruno Haible"
+}
+
+# func_fatal_error message
+# outputs to stderr a fatal error message, and terminates the program.
+func_fatal_error ()
+{
+ echo "declared.sh: *** $1" 1>&2
+ echo "declared.sh: *** Stop." 1>&2
+ exit 1
+}
+
+# func_tmpdir
+# creates a temporary directory.
+# Sets variable
+# - tmp pathname of freshly created temporary directory
+func_tmpdir ()
+{
+ # Use the environment variable TMPDIR, falling back to /tmp. This allows
+ # users to specify a different temporary directory, for example, if their
+ # /tmp is filled up or too small.
+ : ${TMPDIR=/tmp}
+ {
+ # Use the mktemp program if available. If not available, hide the error
+ # message.
+ tmp=`(umask 077 && mktemp -d -q "$TMPDIR/gtXXXXXX") 2>/dev/null` &&
+ test -n "$tmp" && test -d "$tmp"
+ } ||
+ {
+ # Use a simple mkdir command. It is guaranteed to fail if the directory
+ # already exists. $RANDOM is bash specific and expands to empty in shells
+ # other than bash, ksh and zsh. Its use does not increase security;
+ # rather, it minimizes the probability of failure in a very cluttered /tmp
+ # directory.
+ tmp=$TMPDIR/gt$$-$RANDOM
+ (umask 077 && mkdir "$tmp")
+ } ||
+ {
+ echo "$0: cannot create a temporary directory in $TMPDIR" >&2
+ { (exit 1); exit 1; }
+ }
+}
+
+# func_read_yesno
+# reads an answer (yes or no).
+# Sets variable
+# - ans yes or no
+func_read_yesno ()
+{
+ while true; do
+ read ans
+ if test yes = "$ans" || test no = "$ans"; then
+ break
+ fi
+ echo "Invalid answer. Please answer yes or no."
+ done
+}
+
+# Command-line option processing.
+while test $# -gt 0; do
+ case "$1" in
+ --help | --hel | --he | --h )
+ func_usage
+ exit 0 ;;
+ --version | --versio | --versi | --vers | --ver | --ve | --v )
+ func_version
+ exit 0 ;;
+ -- ) # Stop option processing
+ shift; break ;;
+ -* )
+ func_fatal_error "unrecognized option: $option"
+ ;;
+ * )
+ break ;;
+ esac
+done
+
+test $# = 2 || {
+ if test $# -gt 2; then
+ func_fatal_error "too many arguments"
+ else
+ func_fatal_error "Usage: libtool-next-version [OPTION]... PREVIOUS-LIBRARY CURRENT-LIBRARY"
+ fi
+}
+
+test -f "$1" || func_fatal_error "file $1 not found"
+test -f "$2" || func_fatal_error "file $2 not found"
+
+(type nm) >/dev/null || func_fatal_error "program 'nm' not found"
+# Determine how to extract a symbol list from the 'nm' output.
+case `uname -s` in
+ Linux | FreeBSD | NetBSD | OpenBSD) nm_filter="sed -n -e 's/^.* [TWDRB] //p'" ;;
+ Darwin) nm_filter="sed -n -e 's/^.* [TWDRB] _//p'" ;;
+ Minix) nm_filter="sed -n -e 's/^.* [TDC] _//p'" ;;
+ AIX) nm_filter="sed -n -e 's/ *[UD] .*//p' | sed -e 's/^\\.//'" ;;
+ HP-UX) nm_filter="grep '|extern|\\(code\\|data\\) |' | sed -e 's/|.*//' | sed -e 's/ *$//'" ;;
+ IRIX) nm_filter="grep '|\\(GLOB\\|WEAK\\)' | sed -e 's/^.*|//'" ;;
+ SunOS)
+ case `uname -r` in
+ 5.10) nm_filter="sed -n -e 's/^.* [ATWDRBV] //p'" ;;
+ *) nm_filter="grep '|\\(GLOB\\|WEAK\\)' | grep -v '|UNDEF' | grep -v '|SUNW' | sed -e 's/^.*|//'" ;;
+ esac
+ ;;
+ CYGWIN*) nm_filter="sed -n -e 's/^.* T _//p'" ;;
+ *) func_fatal_error "unknown OS - don't know how to interpret the 'nm' output" ;;
+esac
+nm_filter="$nm_filter | LC_ALL=C sort -u"
+
+func_tmpdir
+eval "nm '$1' | $nm_filter > '$tmp/symlist1'"
+eval "nm '$2' | $nm_filter > '$tmp/symlist2'"
+
+echo "Please enter the libtool version of the library in the previous release."
+
+printf "LTV_CURRENT="; read current
+nondigits=`echo "$current" | tr -d '0123456789'`
+{ test -n "$current" && test -z "$nondigits"; } \
+ || func_fatal_error "LTV_CURRENT is invalid. It should be a nonnegative integer."
+
+printf "LTV_REVISION="; read revision
+nondigits=`echo "$revision" | tr -d '0123456789'`
+{ test -n "$revision" && test -z "$nondigits"; } \
+ || func_fatal_error "LTV_REVISION is invalid. It should be a nonnegative integer."
+
+printf "LTV_AGE="; read age
+nondigits=`echo "$age" | tr -d '0123456789'`
+{ test -n "$age" && test -z "$nondigits"; } \
+ || func_fatal_error "LTV_AGE is invalid. It should be a nonnegative integer."
+
+echo
+echo "-------------------------------------------------------------------------------"
+echo "Did the library's code change at all since the previous version?"
+echo "You can usually detect this by looking at the source code changes in git;"
+echo "don't forget source code that is imported from other projects."
+if cmp "$tmp/symlist1" "$tmp/symlist2" >/dev/null; then
+ echo "Please answer yes or no."
+else
+ echo "The symbol list changed. Here are the differences:"
+ (cd "$tmp" && diff symlist1 symlist2 | grep '^[<>]' | sed -e 's/^/ /')
+ echo "Please answer yes or no (probably yes)."
+fi
+func_read_yesno
+if test "$ans" = yes; then
+
+ revision=`expr $revision + 1`
+
+ echo
+ echo "-------------------------------------------------------------------------------"
+ echo "Have any interfaces (functions, variables, classes) been removed since the"
+ echo "previous release? What matters here are interfaces at the linker level;"
+ echo "whether macros have been removed from the include files does not matter."
+ if diff "$tmp/symlist1" "$tmp/symlist2" | grep '^< ' >/dev/null; then
+ echo "Some symbols have been removed:"
+ diff "$tmp/symlist1" "$tmp/symlist2" | grep '^< ' | sed -e 's/^< / /'
+ echo "Please answer yes or no (probably yes)."
+ else
+ echo "Please answer yes or no."
+ fi
+ func_read_yesno
+
+ if test "$ans" = yes; then
+
+ current=`expr $current + 1`
+ revision=0
+ age=0
+
+ else
+
+ echo
+ echo "-------------------------------------------------------------------------------"
+ echo "Have any interfaces (functions, variables, classes) been changed since the"
+ echo "previous release? This includes signature changes. It includes also details of"
+ echo "how functions produce their results and the values of variables, IF AND ONLY IF"
+ echo "users of the library are likely use these details in their test suite."
+ echo "Please answer yes or no."
+ func_read_yesno
+
+ if test "$ans" = yes; then
+
+ current=`expr $current + 1`
+ revision=0
+ age=0
+
+ else
+
+ echo
+ echo "-------------------------------------------------------------------------------"
+ echo "Have any interfaces (functions, variables, classes) been added since the"
+ echo "previous release? What matters here are interfaces at the linker level;"
+ echo "whether macros have been added to the include files does not matter."
+ if diff "$tmp/symlist1" "$tmp/symlist2" | grep '^> ' >/dev/null; then
+ echo "Some symbols have been added:"
+ diff "$tmp/symlist1" "$tmp/symlist2" | grep '^> ' | sed -e 's/^> / /'
+ echo "Please answer yes or no (probably yes)."
+ else
+ echo "Please answer yes or no."
+ fi
+ func_read_yesno
+
+ if test "$ans" = yes; then
+
+ current=`expr $current + 1`
+ revision=0
+ age=`expr $age + 1`
+
+ fi
+ fi
+ fi
+fi
+
+echo
+echo "-------------------------------------------------------------------------------"
+echo "This is the libtool version of the library for the new release:"
+echo "LTV_CURRENT=$current"
+echo "LTV_REVISION=$revision"
+echo "LTV_AGE=$age"