3 # Copyright (C) 2019-2020 Free Software Foundation, Inc.
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 3 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program. If not, see <https://www.gnu.org/licenses/>.
19 # This program is a wizard that helps a maintainer update the libtool
20 # version of a shared library, according to the documentation section
21 # 'Updating version info'
22 # <https://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html>.
24 # Let's call the three parts of the version
29 # The list of steps given in this documentation section
30 # - If the library source code has changed at all since the last update,
31 # then increment LTV_REVISION.
32 # - If any interfaces have been added, removed, or changed since the last
33 # update, increment LTV_CURRENT and set LTV_REVISION to 0.
34 # - If any interfaces have been added since the last public release, then
36 # - If any interfaces have been removed or changed since the last public
37 # release, then set LTV_AGE to 0.
38 # leads to mistakes, because
39 # - It does not say what "interfaces" are.
40 # - It does not enforce that applying the second, third, or fourth rule
41 # is only possible after applying the first rule.
42 # - It does not enforce that applying the third or fourth rule is only
43 # possible after applying the second rule.
46 # outputs to stdout the --help usage message.
50 Usage: libtool-next-version [OPTION]... PREVIOUS-LIBRARY CURRENT-LIBRARY
52 Determines the next version to use for a libtool library.
54 PREVIOUS-LIBRARY is the installed library (in .a or .so format) of the
57 CURRENT-LIBRARY is the installed library (in .a or .so format) of the current
61 --help print this help and exit
62 --version print version information and exit
64 Report bugs to <bruno@clisp.org>."
68 # outputs to stdout the --version message.
71 echo "libtool-next-version (GNU gnulib)"
72 echo "Copyright (C) 2020 Free Software Foundation, Inc.
73 License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>
74 This is free software: you are free to change and redistribute it.
75 There is NO WARRANTY, to the extent permitted by law."
76 echo "Written by" "Bruno Haible"
79 # func_fatal_error message
80 # outputs to stderr a fatal error message, and terminates the program.
83 echo "libtool-next-version: *** $1" 1>&2
84 echo "libtool-next-version: *** Stop." 1>&2
89 # creates a temporary directory.
91 # - tmp pathname of freshly created temporary directory
94 # Use the environment variable TMPDIR, falling back to /tmp. This allows
95 # users to specify a different temporary directory, for example, if their
96 # /tmp is filled up or too small.
99 # Use the mktemp program if available. If not available, hide the error
101 tmp
=`(umask 077 && mktemp -d -q "$TMPDIR/gtXXXXXX") 2>/dev/null` &&
102 test -n "$tmp" && test -d "$tmp"
105 # Use a simple mkdir command. It is guaranteed to fail if the directory
106 # already exists. $RANDOM is bash specific and expands to empty in shells
107 # other than bash, ksh and zsh. Its use does not increase security;
108 # rather, it minimizes the probability of failure in a very cluttered /tmp
110 tmp
=$TMPDIR/gt$$
-$RANDOM
111 (umask 077 && mkdir
"$tmp")
114 echo "$0: cannot create a temporary directory in $TMPDIR" >&2
115 { (exit 1); exit 1; }
120 # reads an answer (yes or no).
127 if test yes = "$ans" ||
test no
= "$ans"; then
130 echo "Invalid answer. Please answer yes or no."
134 # Command-line option processing.
135 while test $# -gt 0; do
137 --help |
--hel |
--he |
--h )
140 --version |
--versio |
--versi |
--vers |
--ver |
--ve |
--v )
143 -- ) # Stop option processing
146 func_fatal_error
"unrecognized option: $option"
154 if test $# -gt 2; then
155 func_fatal_error
"too many arguments"
157 func_fatal_error
"Usage: libtool-next-version [OPTION]... PREVIOUS-LIBRARY CURRENT-LIBRARY"
161 test -f "$1" || func_fatal_error
"file $1 not found"
162 test -f "$2" || func_fatal_error
"file $2 not found"
164 (type nm
) >/dev
/null || func_fatal_error
"program 'nm' not found"
165 # Determine how to extract a symbol list from the 'nm' output.
167 Linux | FreeBSD | NetBSD | OpenBSD
) nm_filter
="sed -n -e 's/^.* [TWDRB] //p'" ;;
168 Darwin
) nm_filter
="sed -n -e 's/^.* [TWDRB] _//p'" ;;
169 Minix
) nm_filter
="sed -n -e 's/^.* [TDC] _//p'" ;;
170 AIX
) nm_filter
="sed -n -e 's/ *[UD] .*//p' | sed -e 's/^\\.//'" ;;
171 HP-UX
) nm_filter
="grep '|extern|\\(code\\|data\\) |' | sed -e 's/|.*//' | sed -e 's/ *$//'" ;;
172 IRIX
) nm_filter
="grep '|\\(GLOB\\|WEAK\\)' | sed -e 's/^.*|//'" ;;
175 5.10) nm_filter
="sed -n -e 's/^.* [ATWDRBV] //p'" ;;
176 *) nm_filter
="grep '|\\(GLOB\\|WEAK\\)' | grep -v '|UNDEF' | grep -v '|SUNW' | sed -e 's/^.*|//'" ;;
179 CYGWIN
*) nm_filter
="sed -n -e 's/^.* T _//p'" ;;
180 *) func_fatal_error
"unknown OS - don't know how to interpret the 'nm' output" ;;
182 nm_filter
="$nm_filter | LC_ALL=C sort -u"
185 eval "nm '$1' | $nm_filter > '$tmp/symlist1'"
186 eval "nm '$2' | $nm_filter > '$tmp/symlist2'"
188 echo "Please enter the libtool version of the library in the previous release."
190 printf "LTV_CURRENT="; read current
191 nondigits
=`echo "$current" | tr -d '0123456789'`
192 { test -n "$current" && test -z "$nondigits"; } \
193 || func_fatal_error
"LTV_CURRENT is invalid. It should be a nonnegative integer."
195 printf "LTV_REVISION="; read revision
196 nondigits
=`echo "$revision" | tr -d '0123456789'`
197 { test -n "$revision" && test -z "$nondigits"; } \
198 || func_fatal_error
"LTV_REVISION is invalid. It should be a nonnegative integer."
200 printf "LTV_AGE="; read age
201 nondigits
=`echo "$age" | tr -d '0123456789'`
202 { test -n "$age" && test -z "$nondigits"; } \
203 || func_fatal_error
"LTV_AGE is invalid. It should be a nonnegative integer."
206 echo "-------------------------------------------------------------------------------"
207 echo "Did the library's code change at all since the previous version?"
208 echo "You can usually detect this by looking at the source code changes in git;"
209 echo "don't forget source code that is imported from other projects."
210 if cmp "$tmp/symlist1" "$tmp/symlist2" >/dev
/null
; then
211 echo "Please answer yes or no."
213 echo "The symbol list changed. Here are the differences:"
214 (cd "$tmp" && diff symlist1 symlist2 |
grep '^[<>]' |
sed -e 's/^/ /')
215 echo "Please answer yes or no (probably yes)."
218 if test "$ans" = yes; then
220 revision
=`expr $revision + 1`
223 echo "-------------------------------------------------------------------------------"
224 echo "Have any interfaces (functions, variables, classes) been removed since the"
225 echo "previous release? What matters here are interfaces at the linker level;"
226 echo "whether macros have been removed from the include files does not matter."
227 if diff "$tmp/symlist1" "$tmp/symlist2" |
grep '^< ' >/dev
/null
; then
228 echo "Some symbols have been removed:"
229 diff "$tmp/symlist1" "$tmp/symlist2" |
grep '^< ' |
sed -e 's/^< / /'
230 echo "Please answer yes or no (probably yes)."
232 echo "Please answer yes or no."
236 if test "$ans" = yes; then
238 current
=`expr $current + 1`
245 echo "-------------------------------------------------------------------------------"
246 echo "Have any interfaces (functions, variables, classes) been changed since the"
247 echo "previous release? This includes signature changes. It includes also details of"
248 echo "how functions produce their results and the values of variables, IF AND ONLY IF"
249 echo "users of the library are likely use these details in their test suite."
250 echo "Please answer yes or no."
253 if test "$ans" = yes; then
255 current
=`expr $current + 1`
262 echo "-------------------------------------------------------------------------------"
263 echo "Have any interfaces (functions, variables, classes) been added since the"
264 echo "previous release? What matters here are interfaces at the linker level;"
265 echo "whether macros have been added to the include files does not matter."
266 if diff "$tmp/symlist1" "$tmp/symlist2" |
grep '^> ' >/dev
/null
; then
267 echo "Some symbols have been added:"
268 diff "$tmp/symlist1" "$tmp/symlist2" |
grep '^> ' |
sed -e 's/^> / /'
269 echo "Please answer yes or no (probably yes)."
271 echo "Please answer yes or no."
275 if test "$ans" = yes; then
277 current
=`expr $current + 1`
287 echo "-------------------------------------------------------------------------------"
288 echo "This is the libtool version of the library for the new release:"
289 echo "LTV_CURRENT=$current"
290 echo "LTV_REVISION=$revision"