(Compiler Errors): Say `@end defmac' after `defmac'.
[emacs.git] / admin / quick-install-emacs
blobba39f7962f3fe36a086684181aca14d35dc32e08
1 #!/bin/sh
2 # quick-install-emacs -- do a halfway-decent job of installing emacs quickly
3 # Written by Miles Bader <miles@gnu.org>
5 # This script is mainly intended for emacs maintainer or pretesters who
6 # install emacs very often. See the --help output for more details.
8 PUBLIC_LIBSRC_BINARIES='b2m emacsclient etags ctags ebrowse'
9 PUBLIC_LIBSRC_SCRIPTS='grep-changelog rcs-checkin'
11 AVOID="CVS -DIC README COPYING ChangeLog ~ \.orig$ \.rej$ Makefile makefile stamp-subdir .cvsignore \.[cho]$ make-docfile testfile test-distrib"
13 # Prune old binaries lying around in the source tree
14 PRUNE=no
15 # Re-install files even if they already exist
16 FORCE=no
17 # Command verbose flag
18 VERBOSE=''
20 me="`basename $0`"
22 # Install commands (these commands are also expected to understand the
23 # GNU -v (--verbose) option)
24 LINK='cp -lf'
25 COPY='cp -f'
26 REMOVE='rm -r'
28 # Used to execute commands once once we create them
29 EXEC='sh'
30 MKDIR='mkdir --verbose -p'
32 NAWK=/usr/bin/nawk
34 # avoid non-standard command output from non-C locales
35 unset LANG LC_ALL LC_MESSAGES
37 # Some messages
38 USAGE="Usage: $me [OPTION...] BUILD_TREE [PREFIX]"
39 TRY="Try "\`"$me --help' for more information."
41 # Parse command-line options
42 while :; do
43 case "$1" in
44 -n|--dry-run)
45 EXEC=cat; shift;;
46 -p|--prune)
47 PRUNE=yes; shift;;
48 -P|--no-prune)
49 PRUNE=no; shift;;
50 --prune-only)
51 PRUNE=only; shift;;
52 -f|--force)
53 FORCE=yes; shift;;
54 -v|--verbose)
55 VERBOSE="-v"; shift;;
56 --help)
57 cat <<EOF
58 $USAGE
59 Install emacs quickly
61 -n, --dry-run print installation commands instead of
62 executing them
64 -f, --force install even files that haven't changed
65 -v, --verbose print messages describing what is done
67 -p, --prune prune old generated files
68 -P, --no-prune don't prune old generated files (default)
69 --prune-only prune old generated files, but don't install
71 --help display this help and exit
72 --version output version information and exit
74 $me install emacs \`incrementally,' that is, it will
75 install only those files that have changed since the last time it was
76 invoked, and remove any obsolete files from the installation
77 directories. It also uses hard-links into the source and build trees to
78 do the install, so it uses much less space than the default Makefile
79 install target; however, this also means that $me can
80 not install onto a disk partition other than the one on which the source
81 and build directories reside.
83 Optionally, $me can also remove old versions of
84 automatically generated files that are version-specific (such as the
85 versioned emacs executables in the \`src' directory, and the DOC-* files
86 in the \`etc' directory). The latter action is called \`pruning,' and
87 can be enabled using the \`-p' or \`--prune' options.
88 EOF
89 exit 0
91 --version)
92 cat <<EOF
93 $me 1.6
95 Written by Miles Bader <miles@gnu.org>
96 EOF
97 exit 0
99 -[^-]?*)
100 # split concatenated single-letter options apart
101 FIRST="$1"; shift
102 set -- `echo $FIRST | sed 's/-\(.\)\(.*\)/-\1 -\2/'` "$@"
105 echo 1>&2 "$me: unrecognized option "\`"$1'"
106 echo 1>&2 "$TRY"
107 exit 1
110 break;
111 esac
112 done
114 LINK_CMD="$LINK $VERBOSE"
115 REMOVE_CMD="$REMOVE $VERBOSE"
117 case $# in
118 1) BUILD="$1";;
119 2) BUILD="$1"; prefix="$2";;
121 echo 1>&2 "$USAGE"
122 echo 1>&2 "$TRY"
123 exit 1
125 esac
127 if test ! -d "$BUILD"; then
128 echo 1>&2 "$me: $BUILD: Build tree not found"
129 exit 2
130 elif test ! -r "$BUILD/config.status"; then
131 echo 1>&2 "$me: $BUILD: Not a proper build tree, config.status not found"
132 exit 2
135 CONFIG_STATUS="$BUILD/config.status"
136 function get_config_var () {
137 if ! sed -n "s/^s\(.\)@$1@\1\(.*\)\1.*$/\2/p" $CONFIG_STATUS | sed q | grep ''
138 then
139 echo 1>&2 "$me: $1: Configuration variable not found in $CONFIG_STATUS"
140 exit 4
144 test x"$SRC" = x && { SRC="`get_config_var srcdir`" || exit 4 ; }
145 test x"$prefix" = x && { prefix="`get_config_var prefix`" || exit 4 ; }
146 test x"$ARCH" = x && { ARCH="`get_config_var host`" || exit 4 ; }
148 VERSION=`grep 'defconst[ ]*emacs-version' $SRC/lisp/version.el \
149 | sed -e 's/^[^"]*"\([^"]*\)".*$/\1/'`
151 DST_SHARE="$prefix/share/emacs/$VERSION"
152 DST_BIN="$prefix/bin"
153 DST_LIBEXEC="$prefix/libexec/emacs/$VERSION/$ARCH"
154 DST_INFO="$prefix/info"
156 function maybe_mkdir () {
157 if ! test -d "$1"; then
158 $MKDIR "$1" 2>&1 | sed "s/^mkdir:/$me:/" 1>&2
162 maybe_mkdir "$DST_BIN"
163 maybe_mkdir "$DST_SHARE"
164 maybe_mkdir "$DST_SHARE/site-lisp"
165 maybe_mkdir "$DST_LIBEXEC"
166 maybe_mkdir "$DST_INFO"
168 ( # start of command-generating sub-shell
170 PRUNED=""
171 if test x"$PRUNE" != xno; then
172 for D in `ls -1t $BUILD/etc/DOC-* | sed 1d`; do
173 echo $REMOVE_CMD $D
174 PRUNED="$PRUNED $D"
175 done
176 for D in `ls -1t $BUILD/src/emacs-$VERSION.* | sed 1d`; do
177 echo $REMOVE_CMD $D
178 PRUNED="$PRUNED $D"
179 done
180 for D in `ls -1t $BUILD/lib-src/fns-* | sed 1d`; do
181 echo $REMOVE_CMD $D
182 PRUNED="$PRUNED $D"
183 done
186 test x"$PRUNE" = xonly && exit 0
188 function maybe_emit_copy () {
189 if test "$FORCE" = yes || ! cmp -s $1 $2; then
190 echo $LINK_CMD $1 $2
194 maybe_emit_copy $BUILD/src/emacs $DST_BIN/emacs
195 maybe_emit_copy $BUILD/src/emacs $DST_BIN/emacs-$VERSION
197 for F in $PUBLIC_LIBSRC_BINARIES; do
198 maybe_emit_copy $BUILD/lib-src/$F $DST_BIN/$F
199 done
200 for F in $PUBLIC_LIBSRC_SCRIPTS; do
201 maybe_emit_copy $SRC/lib-src/$F $DST_BIN/$F
202 done
204 if test x"$SRC" = x"$BUILD"; then
205 PFXS="$BUILD"
206 else
207 PFXS="$SRC $BUILD"
210 for SUBDIR in lisp leim etc lib-src info; do
211 # defaults
212 SHARED=no
213 FORCED=''
214 AVOID_PAT="`echo "($AVOID)" | tr ' ' '|'`"
216 # Set subdir-specific values
217 case $SUBDIR in
218 lisp|leim)
219 DST="$DST_SHARE/$SUBDIR"
221 etc)
222 DST="$DST_SHARE/$SUBDIR"
223 # COPYING is in the avoid list, but there should be a copy of it in
224 # the install etc dir, so make that here.
225 FORCED="$DST/COPYING"
227 lib-src)
228 DST="$DST_LIBEXEC"
229 AVOID_PAT="`echo "($AVOID ($PUBLIC_LIBSRC_BINARIES $PUBLIC_LIBSRC_SCRIPTS)\$)" | tr ' ' '|'`"
231 info)
232 DST="$DST_INFO"
233 SHARED=yes
235 esac
237 for PFX in $PFXS; do
238 if [ -d $PFX/$SUBDIR ]; then
239 for DIR in `(cd $PFX/$SUBDIR; find . -type d -print | sed 's@^./@@')`; do
240 if [ -d $DST/$DIR ]; then
241 echo Directory $DST/$DIR exists
242 else
243 echo Directory $DST/$DIR non-existant
244 if [ "`echo $DIR | egrep -v "$AVOID_PAT"`" ]; then
245 maybe_mkdir $DST/$DIR
248 done
249 diff -sqr $PFX/$SUBDIR $DST
251 done | $NAWK '
252 BEGIN {
253 src_pat = "^'"$SRC"'/'"$SUBDIR"'/"
254 build_pat = "^'"$BUILD"'/'"$SUBDIR"'/"
255 dst_pat = "^'"$DST"'/"
256 dst_pfx = "'"$DST"'/"
257 avoid_pat = "'"$AVOID_PAT"'"
258 force = ("'"$FORCE"'" == "yes")
259 shared = ("'"$SHARED"'" == "yes")
260 init_bool_array(pruned, "'"$PRUNED"'")
261 init_bool_array(forced, "'"$FORCED"'")
263 function init_bool_array(array, string, a,k)
265 split (string, a)
266 for (k in a)
267 array[a[k]] = 1
269 function install(src, dst)
271 if (! (src in pruned)) {
272 cp[src] = dst;
273 from[dst] = src;
274 delete rm[dst];
277 function update(src, dst, copy)
279 if (src in pruned) {
280 rm[dst] = 1;
281 delete from[dst]
282 } else {
283 if (copy)
284 cp[src] = dst;
285 from[dst] = src;
286 delete rm[dst];
289 function uninstall(dst)
291 if (!(dst in from))
292 rm[dst] = 1;
294 /^Directory / {
295 if ($2 ~ avoid_pat) {
296 if ($NF == "exists")
297 uninstall($2)
298 } else
299 update(0, $2, 0)
300 next
302 /^Files / {
303 if ($4 ~ avoid_pat && !($4 in forced))
304 uninstall($4)
305 else if ($NF == "identical")
306 update($2, $4, force)
307 else
308 update($2, $4, 1)
309 next
311 /^Only / {
312 pfx = $3
313 sub (/:$/, "/", pfx)
315 if (pfx ~ dst_pat) {
316 if (! shared)
317 uninstall(pfx $4)
318 } else {
319 subdir = pfx
320 if (subdir ~ src_pat)
321 sub (src_pat, "", subdir)
322 else
323 sub (build_pat, "", subdir)
325 dst = dst_pfx subdir $4
326 if (! (dst ~ avoid_pat))
327 install(pfx $4, dst)
329 next
331 END {
332 for (f in rm)
333 print "'"$REMOVE_CMD"' " f
334 for (f in cp)
335 print "'"$LINK_CMD"' " f " " cp[f]
338 done
340 ) | eval $EXEC