Switch to recommended form of GPLv3 permissions notice.
[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
b9b14d13 4## Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
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
e04e1ce2 34AVOID="CVS -DIC README COPYING ChangeLog ~ [.]orig$ [.]rej$ Makefile makefile 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 ;;
123 -[^-]?*)
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{
1fc8c92b 162 if ! sed -n "s/^s\(.\)@$1@\1\(|#_!!_#|\)*\(.*\)\1.*$/\3/p" $CONFIG_STATUS | sed q | grep ''
d9a88584
MB
163 then
164 echo 1>&2 "$me: $1: Configuration variable not found in $CONFIG_STATUS"
165 exit 4
166 fi
167}
168
c5915370
MB
169test x"$SRC" = x && { SRC="`get_config_var srcdir`" || exit 4 ; }
170test x"$prefix" = x && { prefix="`get_config_var prefix`" || exit 4 ; }
c5915370 171test x"$ARCH" = x && { ARCH="`get_config_var host`" || exit 4 ; }
d9a88584 172
892de428
MB
173VERSION=`grep 'defconst[ ]*emacs-version' $SRC/lisp/version.el \
174 | sed -e 's/^[^"]*"\([^"]*\)".*$/\1/'`
175
d9a88584
MB
176DST_SHARE="$prefix/share/emacs/$VERSION"
177DST_BIN="$prefix/bin"
178DST_LIBEXEC="$prefix/libexec/emacs/$VERSION/$ARCH"
179DST_INFO="$prefix/info"
180
feebeb72
MB
181maybe_mkdir ()
182{
d9a88584 183 if ! test -d "$1"; then
9a1c5fbf 184 $MKDIR $VERBOSE "$1" 2>&1 | sed "s/^mkdir:/$me:/" 1>&2
d9a88584
MB
185 fi
186}
187
188maybe_mkdir "$DST_BIN"
189maybe_mkdir "$DST_SHARE"
190maybe_mkdir "$DST_SHARE/site-lisp"
191maybe_mkdir "$DST_LIBEXEC"
192maybe_mkdir "$DST_INFO"
193
194( # start of command-generating sub-shell
195
196PRUNED=""
197if test x"$PRUNE" != xno; then
6461c636 198 for D in `ls -1t $BUILD/etc/DOC-* | sed 1d`; do
d9a88584
MB
199 echo $REMOVE_CMD $D
200 PRUNED="$PRUNED $D"
201 done
6461c636 202 for D in `ls -1t $BUILD/src/emacs-$VERSION.* | sed 1d`; do
d9a88584
MB
203 echo $REMOVE_CMD $D
204 PRUNED="$PRUNED $D"
205 done
d9a88584
MB
206fi
207
208test x"$PRUNE" = xonly && exit 0
209
feebeb72
MB
210maybe_emit_copy ()
211{
d9a88584
MB
212 if test "$FORCE" = yes || ! cmp -s $1 $2; then
213 echo $LINK_CMD $1 $2
214 fi
215}
216
217maybe_emit_copy $BUILD/src/emacs $DST_BIN/emacs
218maybe_emit_copy $BUILD/src/emacs $DST_BIN/emacs-$VERSION
219
220for F in $PUBLIC_LIBSRC_BINARIES; do
221 maybe_emit_copy $BUILD/lib-src/$F $DST_BIN/$F
222done
223for F in $PUBLIC_LIBSRC_SCRIPTS; do
224 maybe_emit_copy $SRC/lib-src/$F $DST_BIN/$F
225done
226
227if test x"$SRC" = x"$BUILD"; then
228 PFXS="$BUILD"
229else
230 PFXS="$SRC $BUILD"
231fi
232
233for SUBDIR in lisp leim etc lib-src info; do
234 # defaults
235 SHARED=no
236 FORCED=''
237 AVOID_PAT="`echo "($AVOID)" | tr ' ' '|'`"
238
239 # Set subdir-specific values
240 case $SUBDIR in
241 lisp|leim)
242 DST="$DST_SHARE/$SUBDIR"
243 ;;
244 etc)
245 DST="$DST_SHARE/$SUBDIR"
246 # COPYING is in the avoid list, but there should be a copy of it in
247 # the install etc dir, so make that here.
248 FORCED="$DST/COPYING"
249 ;;
250 lib-src)
251 DST="$DST_LIBEXEC"
252 AVOID_PAT="`echo "($AVOID ($PUBLIC_LIBSRC_BINARIES $PUBLIC_LIBSRC_SCRIPTS)\$)" | tr ' ' '|'`"
253 ;;
254 info)
255 DST="$DST_INFO"
256 SHARED=yes
257 ;;
258 esac
259
260 for PFX in $PFXS; do
261 if [ -d $PFX/$SUBDIR ]; then
262 for DIR in `(cd $PFX/$SUBDIR; find . -type d -print | sed 's@^./@@')`; do
263 if [ -d $DST/$DIR ]; then
264 echo Directory $DST/$DIR exists
265 else
266 echo Directory $DST/$DIR non-existant
267 if [ "`echo $DIR | egrep -v "$AVOID_PAT"`" ]; then
268 maybe_mkdir $DST/$DIR
269 fi
270 fi
271 done
272 diff -sqr $PFX/$SUBDIR $DST
273 fi
274 done | $NAWK '
275BEGIN {
276 src_pat = "^'"$SRC"'/'"$SUBDIR"'/"
277 build_pat = "^'"$BUILD"'/'"$SUBDIR"'/"
278 dst_pat = "^'"$DST"'/"
279 dst_pfx = "'"$DST"'/"
280 avoid_pat = "'"$AVOID_PAT"'"
281 force = ("'"$FORCE"'" == "yes")
282 shared = ("'"$SHARED"'" == "yes")
283 init_bool_array(pruned, "'"$PRUNED"'")
284 init_bool_array(forced, "'"$FORCED"'")
285}
286function init_bool_array(array, string, a,k)
287{
288 split (string, a)
289 for (k in a)
290 array[a[k]] = 1
291}
292function install(src, dst)
293{
294 if (! (src in pruned)) {
295 cp[src] = dst;
296 from[dst] = src;
297 delete rm[dst];
298 }
299}
300function update(src, dst, copy)
301{
302 if (src in pruned) {
303 rm[dst] = 1;
304 delete from[dst]
305 } else {
306 if (copy)
307 cp[src] = dst;
308 from[dst] = src;
309 delete rm[dst];
310 }
311}
312function uninstall(dst)
313{
314 if (!(dst in from))
315 rm[dst] = 1;
316}
317/^Directory / {
318 if ($2 ~ avoid_pat) {
319 if ($NF == "exists")
320 uninstall($2)
321 } else
322 update(0, $2, 0)
323 next
324}
325/^Files / {
326 if ($4 ~ avoid_pat && !($4 in forced))
327 uninstall($4)
328 else if ($NF == "identical")
329 update($2, $4, force)
330 else
331 update($2, $4, 1)
332 next
333}
334/^Only / {
335 pfx = $3
336 sub (/:$/, "/", pfx)
337
338 if (pfx ~ dst_pat) {
339 if (! shared)
340 uninstall(pfx $4)
341 } else {
342 subdir = pfx
343 if (subdir ~ src_pat)
344 sub (src_pat, "", subdir)
345 else
346 sub (build_pat, "", subdir)
347
348 dst = dst_pfx subdir $4
349 if (! (dst ~ avoid_pat))
350 install(pfx $4, dst)
351 }
352 next
353}
354END {
355 for (f in rm)
356 print "'"$REMOVE_CMD"' " f
357 for (f in cp)
358 print "'"$LINK_CMD"' " f " " cp[f]
359}
360'
361done
362
363) | eval $EXEC
ab5796a9
MB
364
365# arch-tag: 9322b572-9755-4cf7-a67a-21e6505f1477