gitlog-to-changelog: Tweak documentation.
[gnulib.git] / build-aux / libtool-next-version
blobce87bc8b4a96bf1dd34346503050662705521c68
1 #! /bin/sh
3 # Copyright (C) 2019-2024 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
25 # LTV_CURRENT
26 # LTV_REVISION
27 # LTV_AGE
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
35 # increment LTV_AGE.
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.
45 scriptversion=2024-06-13
47 # func_usage
48 # outputs to stdout the --help usage message.
49 func_usage ()
51 echo "\
52 Usage: libtool-next-version [OPTION]... PREVIOUS-LIBRARY CURRENT-LIBRARY
54 Determines the next version to use for a libtool library.
56 PREVIOUS-LIBRARY is the installed library (in .a or .so format) of the
57 previous release.
59 CURRENT-LIBRARY is the installed library (in .a or .so format) of the current
60 release candidate.
62 Options:
63 --help print this help and exit
64 --version print version information and exit
66 Send patches and bug reports to <bug-gnulib@gnu.org>."
69 # func_version
70 # outputs to stdout the --version message.
71 func_version ()
73 copyright_year=`echo "$scriptversion" | sed -e 's/[^0-9].*//'`
74 echo "libtool-next-version (GNU gnulib) $scriptversion"
75 echo "Copyright (C) ${copyright_year} Free Software Foundation, Inc.
76 License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.
77 This is free software: you are free to change and redistribute it.
78 There is NO WARRANTY, to the extent permitted by law."
79 echo
80 printf 'Written by %s.\n' "Bruno Haible"
83 # func_fatal_error message
84 # outputs to stderr a fatal error message, and terminates the program.
85 func_fatal_error ()
87 echo "libtool-next-version: *** $1" 1>&2
88 echo "libtool-next-version: *** Stop." 1>&2
89 exit 1
92 # func_tmpdir
93 # creates a temporary directory.
94 # Sets variable
95 # - tmp pathname of freshly created temporary directory
96 func_tmpdir ()
98 # Use the environment variable TMPDIR, falling back to /tmp. This allows
99 # users to specify a different temporary directory, for example, if their
100 # /tmp is filled up or too small.
101 : "${TMPDIR=/tmp}"
103 # Use the mktemp program if available. If not available, hide the error
104 # message.
105 tmp=`(umask 077 && mktemp -d -q "$TMPDIR/gtXXXXXX") 2>/dev/null` &&
106 test -n "$tmp" && test -d "$tmp"
107 } ||
109 # Use a simple mkdir command. It is guaranteed to fail if the directory
110 # already exists. $RANDOM is bash specific and expands to empty in shells
111 # other than bash, ksh and zsh. Its use does not increase security;
112 # rather, it minimizes the probability of failure in a very cluttered /tmp
113 # directory.
114 tmp=$TMPDIR/gt$$-$RANDOM
115 (umask 077 && mkdir "$tmp")
116 } ||
118 echo "$0: cannot create a temporary directory in $TMPDIR" >&2
119 { (exit 1); exit 1; }
123 # func_read_yesno
124 # reads an answer (yes or no).
125 # Sets variable
126 # - ans yes or no
127 func_read_yesno ()
129 while true; do
130 read ans
131 if test yes = "$ans" || test no = "$ans"; then
132 break
134 echo "Invalid answer. Please answer yes or no."
135 done
138 # Command-line option processing.
139 while test $# -gt 0; do
140 case "$1" in
141 --help | --hel | --he | --h )
142 func_usage
143 exit 0 ;;
144 --version | --versio | --versi | --vers | --ver | --ve | --v )
145 func_version
146 exit 0 ;;
147 -- ) # Stop option processing
148 shift; break ;;
149 -* )
150 func_fatal_error "unrecognized option: $option"
153 break ;;
154 esac
155 done
157 test $# = 2 || {
158 if test $# -gt 2; then
159 func_fatal_error "too many arguments"
160 else
161 func_fatal_error "Usage: libtool-next-version [OPTION]... PREVIOUS-LIBRARY CURRENT-LIBRARY"
165 test -f "$1" || func_fatal_error "file $1 not found"
166 test -f "$2" || func_fatal_error "file $2 not found"
168 (type nm) >/dev/null || func_fatal_error "program 'nm' not found"
169 # Determine how to extract a symbol list from the 'nm' output.
170 case `uname -s` in
171 Linux | FreeBSD | NetBSD | OpenBSD) nm_filter="sed -n -e 's/^.* [TWDRB] //p'" ;;
172 Darwin) nm_filter="sed -n -e 's/^.* [TWDRB] _//p'" ;;
173 Minix) nm_filter="sed -n -e 's/^.* [TDC] _//p'" ;;
174 AIX) nm_filter="sed -n -e 's/ *[UD] .*//p' | sed -e 's/^\\.//'" ;;
175 HP-UX) nm_filter="grep '|extern|\\(code\\|data\\) |' | sed -e 's/|.*//' | sed -e 's/ *$//'" ;;
176 IRIX) nm_filter="grep '|\\(GLOB\\|WEAK\\)' | sed -e 's/^.*|//'" ;;
177 SunOS)
178 case `uname -r` in
179 5.10) nm_filter="sed -n -e 's/^.* [ATWDRBV] //p'" ;;
180 *) nm_filter="grep '|\\(GLOB\\|WEAK\\)' | grep -v '|UNDEF' | grep -v '|SUNW' | sed -e 's/^.*|//'" ;;
181 esac
183 CYGWIN*) nm_filter="sed -n -e 's/^.* T _//p'" ;;
184 *) func_fatal_error "unknown OS - don't know how to interpret the 'nm' output" ;;
185 esac
186 nm_filter="$nm_filter | LC_ALL=C sort -u"
188 func_tmpdir
189 eval "nm '$1' | $nm_filter > '$tmp/symlist1'"
190 eval "nm '$2' | $nm_filter > '$tmp/symlist2'"
192 echo "Please enter the libtool version of the library in the previous release."
194 printf "LTV_CURRENT="; read current
195 nondigits=`echo "$current" | tr -d '0123456789'`
196 { test -n "$current" && test -z "$nondigits"; } \
197 || func_fatal_error "LTV_CURRENT is invalid. It should be a nonnegative integer."
199 printf "LTV_REVISION="; read revision
200 nondigits=`echo "$revision" | tr -d '0123456789'`
201 { test -n "$revision" && test -z "$nondigits"; } \
202 || func_fatal_error "LTV_REVISION is invalid. It should be a nonnegative integer."
204 printf "LTV_AGE="; read age
205 nondigits=`echo "$age" | tr -d '0123456789'`
206 { test -n "$age" && test -z "$nondigits"; } \
207 || func_fatal_error "LTV_AGE is invalid. It should be a nonnegative integer."
209 echo
210 echo "-------------------------------------------------------------------------------"
211 echo "Did the library's code change at all since the previous version?"
212 echo "You can usually detect this by looking at the source code changes in git;"
213 echo "don't forget source code that is imported from other projects."
214 if cmp "$tmp/symlist1" "$tmp/symlist2" >/dev/null; then
215 echo "Please answer yes or no."
216 else
217 echo "The symbol list changed. Here are the differences:"
218 (cd "$tmp" && diff symlist1 symlist2 | grep '^[<>]' | sed -e 's/^/ /')
219 echo "Please answer yes or no (probably yes)."
221 func_read_yesno
222 if test "$ans" = yes; then
224 revision=`expr $revision + 1`
226 echo
227 echo "-------------------------------------------------------------------------------"
228 echo "Have any interfaces (functions, variables, classes) been removed since the"
229 echo "previous release? What matters here are interfaces at the linker level;"
230 echo "whether macros have been removed from the include files does not matter."
231 if diff "$tmp/symlist1" "$tmp/symlist2" | grep '^< ' >/dev/null; then
232 echo "Some symbols have been removed:"
233 diff "$tmp/symlist1" "$tmp/symlist2" | grep '^< ' | sed -e 's/^< / /'
234 echo "Please answer yes or no (probably yes)."
235 else
236 echo "Please answer yes or no."
238 func_read_yesno
240 if test "$ans" = yes; then
242 current=`expr $current + 1`
243 revision=0
244 age=0
246 else
248 echo
249 echo "-------------------------------------------------------------------------------"
250 echo "Have any interfaces (functions, variables, classes) been changed since the"
251 echo "previous release? This includes signature changes. It includes also details of"
252 echo "how functions produce their results and the values of variables, IF AND ONLY IF"
253 echo "users of the library are likely use these details in their test suite."
254 echo "Please answer yes or no."
255 func_read_yesno
257 if test "$ans" = yes; then
259 current=`expr $current + 1`
260 revision=0
261 age=0
263 else
265 echo
266 echo "-------------------------------------------------------------------------------"
267 echo "Have any interfaces (functions, variables, classes) been added since the"
268 echo "previous release? What matters here are interfaces at the linker level;"
269 echo "whether macros have been added to the include files does not matter."
270 if diff "$tmp/symlist1" "$tmp/symlist2" | grep '^> ' >/dev/null; then
271 echo "Some symbols have been added:"
272 diff "$tmp/symlist1" "$tmp/symlist2" | grep '^> ' | sed -e 's/^> / /'
273 echo "Please answer yes or no (probably yes)."
274 else
275 echo "Please answer yes or no."
277 func_read_yesno
279 if test "$ans" = yes; then
281 current=`expr $current + 1`
282 revision=0
283 age=`expr $age + 1`
290 echo
291 echo "-------------------------------------------------------------------------------"
292 echo "This is the libtool version of the library for the new release:"
293 echo "LTV_CURRENT=$current"
294 echo "LTV_REVISION=$revision"
295 echo "LTV_AGE=$age"