getcwd: Fix cross-compilation guess for musl libc.
[gnulib.git] / build-aux / libtool-next-version
blob66e3b7755f49a4a4ac2c1e04acfc68e11bed385b
1 #! /bin/sh
3 # Copyright (C) 2019-2021 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 # func_usage
46 # outputs to stdout the --help usage message.
47 func_usage ()
49 echo "\
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
55 previous release.
57 CURRENT-LIBRARY is the installed library (in .a or .so format) of the current
58 release candidate.
60 Options:
61 --help print this help and exit
62 --version print version information and exit
64 Report bugs to <bruno@clisp.org>."
67 # func_version
68 # outputs to stdout the --version message.
69 func_version ()
71 echo "libtool-next-version (GNU gnulib)"
72 echo "Copyright (C) 2019 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.
81 func_fatal_error ()
83 echo "libtool-next-version: *** $1" 1>&2
84 echo "libtool-next-version: *** Stop." 1>&2
85 exit 1
88 # func_tmpdir
89 # creates a temporary directory.
90 # Sets variable
91 # - tmp pathname of freshly created temporary directory
92 func_tmpdir ()
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.
97 : ${TMPDIR=/tmp}
99 # Use the mktemp program if available. If not available, hide the error
100 # message.
101 tmp=`(umask 077 && mktemp -d -q "$TMPDIR/gtXXXXXX") 2>/dev/null` &&
102 test -n "$tmp" && test -d "$tmp"
103 } ||
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
109 # directory.
110 tmp=$TMPDIR/gt$$-$RANDOM
111 (umask 077 && mkdir "$tmp")
112 } ||
114 echo "$0: cannot create a temporary directory in $TMPDIR" >&2
115 { (exit 1); exit 1; }
119 # func_read_yesno
120 # reads an answer (yes or no).
121 # Sets variable
122 # - ans yes or no
123 func_read_yesno ()
125 while true; do
126 read ans
127 if test yes = "$ans" || test no = "$ans"; then
128 break
130 echo "Invalid answer. Please answer yes or no."
131 done
134 # Command-line option processing.
135 while test $# -gt 0; do
136 case "$1" in
137 --help | --hel | --he | --h )
138 func_usage
139 exit 0 ;;
140 --version | --versio | --versi | --vers | --ver | --ve | --v )
141 func_version
142 exit 0 ;;
143 -- ) # Stop option processing
144 shift; break ;;
145 -* )
146 func_fatal_error "unrecognized option: $option"
149 break ;;
150 esac
151 done
153 test $# = 2 || {
154 if test $# -gt 2; then
155 func_fatal_error "too many arguments"
156 else
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.
166 case `uname -s` in
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/^.*|//'" ;;
173 SunOS)
174 case `uname -r` in
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/^.*|//'" ;;
177 esac
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" ;;
181 esac
182 nm_filter="$nm_filter | LC_ALL=C sort -u"
184 func_tmpdir
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."
205 echo
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."
212 else
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)."
217 func_read_yesno
218 if test "$ans" = yes; then
220 revision=`expr $revision + 1`
222 echo
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)."
231 else
232 echo "Please answer yes or no."
234 func_read_yesno
236 if test "$ans" = yes; then
238 current=`expr $current + 1`
239 revision=0
240 age=0
242 else
244 echo
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."
251 func_read_yesno
253 if test "$ans" = yes; then
255 current=`expr $current + 1`
256 revision=0
257 age=0
259 else
261 echo
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)."
270 else
271 echo "Please answer yes or no."
273 func_read_yesno
275 if test "$ans" = yes; then
277 current=`expr $current + 1`
278 revision=0
279 age=`expr $age + 1`
286 echo
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"
291 echo "LTV_AGE=$age"