quick-install-emacs: Use more portable shell syntax
[bpt/emacs.git] / admin / quick-install-emacs
CommitLineData
d9a88584 1#!/bin/sh
82be670e
GM
2### quick-install-emacs --- do a halfway-decent job of installing emacs quickly
3
114f9c96 4## Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
82be670e
GM
5## Free Software Foundation, Inc.
6
7## Author: Miles Bader <miles@gnu.org>
8
9## This file is part of GNU Emacs.
10
9ad5de0c 11## GNU Emacs is free software: you can redistribute it and/or modify
82be670e 12## it under the terms of the GNU General Public License as published by
9ad5de0c
GM
13## the Free Software Foundation, either version 3 of the License, or
14## (at your option) any later version.
82be670e
GM
15
16## GNU Emacs is distributed in the hope that it will be useful,
17## but WITHOUT ANY WARRANTY; without even the implied warranty of
18## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19## GNU General Public License for more details.
20
21## You should have received a copy of the GNU General Public License
9ad5de0c
GM
22## along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
23
82be670e
GM
24
25### Commentary:
26
27## This script is mainly intended for emacs maintainer or pretesters who
28## install emacs very often. See the --help output for more details.
d9a88584 29
d9a88584
MB
30
31PUBLIC_LIBSRC_BINARIES='b2m emacsclient etags ctags ebrowse'
32PUBLIC_LIBSRC_SCRIPTS='grep-changelog rcs-checkin'
33
f758ab59 34AVOID="CVS -DIC README COPYING ChangeLog ~ [.]orig$ [.]rej$ Makefile$ Makefile.in$ Makefile.c$ makefile$ makefile.w32-in$ stamp-subdir [.]cvsignore [.]arch-ids [{]arch[}] [.][cho]$ make-docfile testfile test-distrib"
d9a88584
MB
35
36# Prune old binaries lying around in the source tree
37PRUNE=no
38# Re-install files even if they already exist
39FORCE=no
40# Command verbose flag
41VERBOSE=''
42
43me="`basename $0`"
44
9a1c5fbf
MB
45# Install commands (if the user specifies the `--verbose' option, it is
46# passed to these commands, so that feature only works if these commands
47# implement it too)
d9a88584
MB
48LINK='cp -lf'
49COPY='cp -f'
50REMOVE='rm -r'
9a1c5fbf 51MKDIR='mkdir -p'
d9a88584
MB
52
53# Used to execute commands once once we create them
54EXEC='sh'
d9a88584
MB
55
56NAWK=/usr/bin/nawk
57
a819ec1a
MB
58# avoid non-standard command output from non-C locales
59unset LANG LC_ALL LC_MESSAGES
60
d9a88584
MB
61# Some messages
62USAGE="Usage: $me [OPTION...] BUILD_TREE [PREFIX]"
63TRY="Try "\`"$me --help' for more information."
64
65# Parse command-line options
66while :; do
67 case "$1" in
68 -n|--dry-run)
69 EXEC=cat; shift;;
70 -p|--prune)
71 PRUNE=yes; shift;;
72 -P|--no-prune)
73 PRUNE=no; shift;;
74 --prune-only)
75 PRUNE=only; shift;;
76 -f|--force)
77 FORCE=yes; shift;;
78 -v|--verbose)
79 VERBOSE="-v"; shift;;
80 --help)
81 cat <<EOF
82$USAGE
83Install emacs quickly
84
85 -n, --dry-run print installation commands instead of
86 executing them
87
88 -f, --force install even files that haven't changed
89 -v, --verbose print messages describing what is done
90
91 -p, --prune prune old generated files
92 -P, --no-prune don't prune old generated files (default)
93 --prune-only prune old generated files, but don't install
94
95 --help display this help and exit
96 --version output version information and exit
97
98$me install emacs \`incrementally,' that is, it will
99install only those files that have changed since the last time it was
100invoked, and remove any obsolete files from the installation
101directories. It also uses hard-links into the source and build trees to
102do the install, so it uses much less space than the default Makefile
103install target; however, this also means that $me can
104not install onto a disk partition other than the one on which the source
105and build directories reside.
106
107Optionally, $me can also remove old versions of
108automatically generated files that are version-specific (such as the
109versioned emacs executables in the \`src' directory, and the DOC-* files
110in the \`etc' directory). The latter action is called \`pruning,' and
111can be enabled using the \`-p' or \`--prune' options.
112EOF
113 exit 0
114 ;;
115 --version)
116 cat <<EOF
ca2135af 117$me 1.6
d9a88584
MB
118
119Written by Miles Bader <miles@gnu.org>
120EOF
121 exit 0
122 ;;
61c26472 123 -[!-]?*)
d9a88584
MB
124 # split concatenated single-letter options apart
125 FIRST="$1"; shift
126 set -- `echo $FIRST | sed 's/-\(.\)\(.*\)/-\1 -\2/'` "$@"
127 ;;
128 -*)
129 echo 1>&2 "$me: unrecognized option "\`"$1'"
130 echo 1>&2 "$TRY"
131 exit 1
132 ;;
133 *)
134 break;
135 esac
136done
137
138LINK_CMD="$LINK $VERBOSE"
139REMOVE_CMD="$REMOVE $VERBOSE"
140
141case $# in
142 1) BUILD="$1";;
143 2) BUILD="$1"; prefix="$2";;
144 *)
145 echo 1>&2 "$USAGE"
146 echo 1>&2 "$TRY"
147 exit 1
148 ;;
149esac
150
151if test ! -d "$BUILD"; then
152 echo 1>&2 "$me: $BUILD: Build tree not found"
153 exit 2
154elif test ! -r "$BUILD/config.status"; then
155 echo 1>&2 "$me: $BUILD: Not a proper build tree, config.status not found"
156 exit 2
157fi
158
159CONFIG_STATUS="$BUILD/config.status"
feebeb72
MB
160get_config_var ()
161{
d94c90b9
MB
162 { sed -n "s/^S[[]\"$1\"[]]=\"\([^\"]*\)\"/\1/p" $CONFIG_STATUS | sed q | grep ''; } ||
163 { sed -n "s/^s\(.\)@$1@\1\(|#_!!_#|\)*\(.*\)\1.*$/\3/p" $CONFIG_STATUS | sed q | grep ''; } ||
164 {
d9a88584
MB
165 echo 1>&2 "$me: $1: Configuration variable not found in $CONFIG_STATUS"
166 exit 4
d94c90b9 167 }
d9a88584
MB
168}
169
c5915370
MB
170test x"$SRC" = x && { SRC="`get_config_var srcdir`" || exit 4 ; }
171test x"$prefix" = x && { prefix="`get_config_var prefix`" || exit 4 ; }
c5915370 172test x"$ARCH" = x && { ARCH="`get_config_var host`" || exit 4 ; }
d9a88584 173
892de428
MB
174VERSION=`grep 'defconst[ ]*emacs-version' $SRC/lisp/version.el \
175 | sed -e 's/^[^"]*"\([^"]*\)".*$/\1/'`
176
d9a88584
MB
177DST_SHARE="$prefix/share/emacs/$VERSION"
178DST_BIN="$prefix/bin"
179DST_LIBEXEC="$prefix/libexec/emacs/$VERSION/$ARCH"
40c3f434
MB
180
181# There are various common places for the info dir to be, so try to
182# use whatever's already there, defaulting to (and preferring)
183# .../share/info.
184#
185DST_INFO=''
186for D in "$prefix/share/info" "$prefix/info"; do
187 if test -d "$D"; then
188 DST_INFO="$D"
189 break
190 fi
191done
192DST_INFO=${DST_INFO:-"$prefix/share/info"}
d9a88584 193
feebeb72
MB
194maybe_mkdir ()
195{
d9a88584 196 if ! test -d "$1"; then
9a1c5fbf 197 $MKDIR $VERBOSE "$1" 2>&1 | sed "s/^mkdir:/$me:/" 1>&2
d9a88584
MB
198 fi
199}
200
201maybe_mkdir "$DST_BIN"
202maybe_mkdir "$DST_SHARE"
203maybe_mkdir "$DST_SHARE/site-lisp"
204maybe_mkdir "$DST_LIBEXEC"
205maybe_mkdir "$DST_INFO"
206
207( # start of command-generating sub-shell
208
209PRUNED=""
210if test x"$PRUNE" != xno; then
6461c636 211 for D in `ls -1t $BUILD/etc/DOC-* | sed 1d`; do
d9a88584
MB
212 echo $REMOVE_CMD $D
213 PRUNED="$PRUNED $D"
214 done
6461c636 215 for D in `ls -1t $BUILD/src/emacs-$VERSION.* | sed 1d`; do
d9a88584
MB
216 echo $REMOVE_CMD $D
217 PRUNED="$PRUNED $D"
218 done
d9a88584
MB
219fi
220
221test x"$PRUNE" = xonly && exit 0
222
feebeb72
MB
223maybe_emit_copy ()
224{
d9a88584
MB
225 if test "$FORCE" = yes || ! cmp -s $1 $2; then
226 echo $LINK_CMD $1 $2
227 fi
228}
229
230maybe_emit_copy $BUILD/src/emacs $DST_BIN/emacs
231maybe_emit_copy $BUILD/src/emacs $DST_BIN/emacs-$VERSION
232
233for F in $PUBLIC_LIBSRC_BINARIES; do
234 maybe_emit_copy $BUILD/lib-src/$F $DST_BIN/$F
235done
236for F in $PUBLIC_LIBSRC_SCRIPTS; do
237 maybe_emit_copy $SRC/lib-src/$F $DST_BIN/$F
238done
239
240if test x"$SRC" = x"$BUILD"; then
241 PFXS="$BUILD"
242else
243 PFXS="$SRC $BUILD"
244fi
245
246for SUBDIR in lisp leim etc lib-src info; do
247 # defaults
248 SHARED=no
249 FORCED=''
250 AVOID_PAT="`echo "($AVOID)" | tr ' ' '|'`"
251
252 # Set subdir-specific values
253 case $SUBDIR in
254 lisp|leim)
255 DST="$DST_SHARE/$SUBDIR"
256 ;;
257 etc)
258 DST="$DST_SHARE/$SUBDIR"
259 # COPYING is in the avoid list, but there should be a copy of it in
260 # the install etc dir, so make that here.
261 FORCED="$DST/COPYING"
262 ;;
263 lib-src)
264 DST="$DST_LIBEXEC"
265 AVOID_PAT="`echo "($AVOID ($PUBLIC_LIBSRC_BINARIES $PUBLIC_LIBSRC_SCRIPTS)\$)" | tr ' ' '|'`"
266 ;;
267 info)
268 DST="$DST_INFO"
269 SHARED=yes
270 ;;
271 esac
272
273 for PFX in $PFXS; do
274 if [ -d $PFX/$SUBDIR ]; then
275 for DIR in `(cd $PFX/$SUBDIR; find . -type d -print | sed 's@^./@@')`; do
276 if [ -d $DST/$DIR ]; then
277 echo Directory $DST/$DIR exists
278 else
296271c0 279 echo Directory $DST/$DIR non-existent
d9a88584
MB
280 if [ "`echo $DIR | egrep -v "$AVOID_PAT"`" ]; then
281 maybe_mkdir $DST/$DIR
282 fi
283 fi
284 done
285 diff -sqr $PFX/$SUBDIR $DST
286 fi
287 done | $NAWK '
288BEGIN {
289 src_pat = "^'"$SRC"'/'"$SUBDIR"'/"
290 build_pat = "^'"$BUILD"'/'"$SUBDIR"'/"
291 dst_pat = "^'"$DST"'/"
292 dst_pfx = "'"$DST"'/"
293 avoid_pat = "'"$AVOID_PAT"'"
294 force = ("'"$FORCE"'" == "yes")
295 shared = ("'"$SHARED"'" == "yes")
296 init_bool_array(pruned, "'"$PRUNED"'")
297 init_bool_array(forced, "'"$FORCED"'")
298}
299function init_bool_array(array, string, a,k)
300{
301 split (string, a)
302 for (k in a)
303 array[a[k]] = 1
304}
305function install(src, dst)
306{
307 if (! (src in pruned)) {
308 cp[src] = dst;
309 from[dst] = src;
310 delete rm[dst];
311 }
312}
313function update(src, dst, copy)
314{
315 if (src in pruned) {
316 rm[dst] = 1;
317 delete from[dst]
318 } else {
319 if (copy)
320 cp[src] = dst;
321 from[dst] = src;
322 delete rm[dst];
323 }
324}
325function uninstall(dst)
326{
327 if (!(dst in from))
328 rm[dst] = 1;
329}
330/^Directory / {
331 if ($2 ~ avoid_pat) {
332 if ($NF == "exists")
333 uninstall($2)
334 } else
335 update(0, $2, 0)
336 next
337}
338/^Files / {
339 if ($4 ~ avoid_pat && !($4 in forced))
340 uninstall($4)
341 else if ($NF == "identical")
342 update($2, $4, force)
343 else
344 update($2, $4, 1)
345 next
346}
347/^Only / {
348 pfx = $3
349 sub (/:$/, "/", pfx)
350
351 if (pfx ~ dst_pat) {
352 if (! shared)
353 uninstall(pfx $4)
354 } else {
355 subdir = pfx
356 if (subdir ~ src_pat)
357 sub (src_pat, "", subdir)
358 else
359 sub (build_pat, "", subdir)
360
361 dst = dst_pfx subdir $4
362 if (! (dst ~ avoid_pat))
363 install(pfx $4, dst)
364 }
365 next
366}
367END {
368 for (f in rm)
369 print "'"$REMOVE_CMD"' " f
370 for (f in cp)
371 print "'"$LINK_CMD"' " f " " cp[f]
372}
373'
374done
375
376) | eval $EXEC
ab5796a9
MB
377
378# arch-tag: 9322b572-9755-4cf7-a67a-21e6505f1477