Improve quail-update-leim-list-file error messaging
[emacs.git] / make-dist
blob606fdd9e3a0b98b85798500e01074975bcb92e53
1 #!/bin/sh
2 ### make-dist: create an Emacs distribution tar file from current srcdir
4 ## Copyright (C) 1995, 1997-1998, 2000-2021 Free Software Foundation,
5 ## Inc.
7 ## This file is part of GNU Emacs.
9 ## GNU Emacs is free software: you can redistribute it and/or modify
10 ## it under the terms of the GNU General Public License as published by
11 ## the Free Software Foundation, either version 3 of the License, or
12 ## (at your option) any later version.
14 ## GNU Emacs is distributed in the hope that it will be useful,
15 ## but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ## GNU General Public License for more details.
19 ## You should have received a copy of the GNU General Public License
20 ## along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
22 ### Commentary:
24 ## This basically creates a duplicate directory structure, and then
25 ## hard links into it only those files that should be distributed.
26 ## This means that if you add a file with an odd name, you should make
27 ## sure that this script will include it.
29 ### Code:
31 progname="$0"
33 ### Exit if a command fails.
34 #set -e
36 ### Print out each line we read, for debugging's sake.
37 #set -v
39 LANGUAGE=C
40 LC_ALL=C
41 LC_MESSAGES=
42 LANG=
43 export LANGUAGE LC_ALL LC_MESSAGES LANG
45 ## Remove unnecessary restrictions on file access.
46 umask 022
48 update=yes
49 check=yes
50 clean_up=no
51 make_tar=no
52 default_gzip=gzip
53 newer=""
54 with_info=yes
55 with_tests=yes
56 changelog=yes
57 verbose=no
59 while [ $# -gt 0 ]; do
60 case "$1" in
61 ## This option tells make-dist to delete the staging directory
62 ## when done. It is useless to use this unless you make a tar file.
63 "--clean-up" )
64 clean_up=yes
66 ## This option tells make-dist to make a tar file.
67 "--tar" )
68 make_tar=yes
70 ## This option tells make-dist not to recompile or do analogous things.
71 "--no-update" )
72 update=no
74 ## This option says don't check for bad file names, etc.
75 "--no-check" )
76 check=no
78 "--no-changelog" )
79 changelog=no
81 ## This options tells make-dist to skip the info files. This can
82 ## be useful for creating a tarball purely for test purposes.
83 "--no-info" )
84 with_info=no
86 ## This option tells make-dist to make the distribution normally, then
87 ## remove all files older than the given timestamp file. This is useful
88 ## for creating incremental or patch distributions.
89 "--newer")
90 newer="$2"
91 new_extension=".new"
92 shift
94 ## This option tells make-dist to use 'bzip2' instead of gzip.
95 "--bzip2")
96 default_gzip="bzip2"
98 ## Same with xz.
99 "--xz")
100 default_gzip="xz"
102 "--no-compress")
103 default_gzip="cat"
106 "--snapshot")
107 clean_up=yes
108 make_tar=yes
109 update=no
112 ## Include the test/ directory.
113 ## This is for backward compatibility to when --no-tests was the default.
114 "--tests")
115 with_tests=yes
118 ## Exclude the test/ directory.
119 "--no-tests")
120 with_tests=no
123 "--verbose")
124 verbose=yes
127 "--help")
128 printf '%s\n' "Usage: ${progname} [options]"
129 echo ""
130 echo " --bzip2 use bzip2 instead of gzip"
131 echo " --clean-up delete staging directories when done"
132 echo " --xz use xz instead of gzip"
133 echo " --no-compress don't compress"
134 echo " --newer=TIME don't include files older than TIME"
135 echo " --no-check don't check for bad file names etc."
136 echo " --no-update don't recompile or do analogous things"
137 echo " --no-changelog don't generate the top-level ChangeLog"
138 echo " --no-info don't include info files"
139 echo " --no-tests don't include the test/ directory"
140 echo " --snapshot same as --clean-up --no-update --tar"
141 echo " --tar make a tar file"
142 echo " --verbose noisier output"
143 echo ""
144 exit 0
148 printf '%s\n' "${progname}: Unrecognized argument: $1" >&2
149 exit 1
151 esac
152 shift
153 done
155 ### Make sure we're running in the right place.
156 if [ ! -d src -o ! -f src/lisp.h -o ! -d lisp -o ! -f lisp/subr.el ]; then
157 printf '%s\n' "${progname}: Can't find 'src/lisp.h' and 'lisp/subr.el'." >&2
158 printf '%s\n' "${progname} must be run in the top directory of the Emacs" >&2
159 printf '%s\n' "distribution tree. cd to that directory and try again." >&2
160 exit 1
163 ### Find where to run Emacs.
164 ### (Accept only absolute file names.)
165 if [ $update = yes ];
166 then
167 if [ -f src/emacs ];
168 then
169 EMACS=`pwd`/src/emacs
170 else
171 case $EMACS in
172 /*) ;;
174 if [ ! -f "$EMACS" ]; then
175 printf '%s\n' "$0: You must set the EMACS environment variable " \
176 "to an absolute file name." 2>&1
177 exit 1
178 fi;;
179 esac
183 ### Find out which version of Emacs this is.
184 version=`
185 sed -n 's/^AC_INIT(GNU Emacs,[ ]*\([^ ,)]*\).*/\1/p' <configure.ac
186 ` || version=
187 if [ ! "${version}" ]; then
188 printf '%s\n' \
189 "${progname}: can't find current Emacs version in './src/emacs.c'" >&2
190 exit 1
193 echo Version number is "$version"
195 if [ $update = yes ]; then
196 if ! grep -q "tree holds version *${version}" README; then
197 echo "WARNING: README has the wrong version number"
198 echo "Consider running M-x set-version from admin/admin.el"
199 sleep 5
203 ### Make sure we don't already have a directory emacs-${version}.
205 emacsname="emacs-${version}${new_extension}"
207 if [ -d ${emacsname} ]
208 then
209 echo Directory "${emacsname}" already exists >&2
210 exit 1
213 ### Make sure the subdirectory is available.
214 tempparent="make-dist.tmp.$$"
215 if [ -d ${tempparent} ]; then
216 printf '%s\n' "${progname}: staging directory '${tempparent}' already exists.
217 Perhaps a previous invocation of '${progname}' failed to clean up after
218 itself. Check that directories whose names are of the form
219 'make-dist.tmp.NNNNN' don't contain any important information, remove
220 them, and try again." >&2
221 exit 1
224 if [ $check = yes ]; then
226 echo "Sanity checking (use --no-check to disable this)..."
228 error=no
230 temp_el=/tmp/make-dist.tmp.$$
231 temp_elc=$temp_el.1
232 temp_elelc=$temp_el.2
233 temp_elcel=$temp_el.3
235 ls -1 lisp/[a-zA-Z]*.el lisp/[a-z]*/[a-zA-Z0-9]*.el \
236 lisp/[a-z]*/[a-z]*/[a-zA-Z0-9]*.el \
237 lisp/[a-z]*/[a-z]*/[a-z]*/[a-zA-Z0-9]*.el > $temp_el
239 ls -1 lisp/[a-zA-Z]*.elc lisp/[a-z]*/[a-zA-Z0-9]*.elc \
240 lisp/[a-z]*/[a-z]*/[a-zA-Z0-9]*.elc \
241 lisp/[a-z]*/[a-z]*/[a-z]*/[a-zA-Z0-9]*.elc > $temp_elc
243 ## Check for .elc files with no corresponding .el file.
244 sed 's/\.el$/.elc/' $temp_el > $temp_elelc
246 bogosities=`comm -13 $temp_elelc $temp_elc`
247 if [ x"${bogosities}" != x"" ]; then
248 error=yes
249 echo "The following .elc files have no corresponding .el files:"
250 echo "${bogosities}"
253 ### Check for .el files with no corresponding .elc file.
254 sed 's/\.elc$/.el/' $temp_elc > $temp_elcel
255 losers=`comm -23 $temp_el $temp_elcel`
257 bogosities=
258 while read elc; do
259 el=`echo $elc | sed 's/c$//'`
260 [ -r "$el" ] || continue
261 [ "$elc" -nt "$el" ] || bogosities="$bogosities $elc"
262 done < $temp_elc
264 if [ x"${bogosities}" != x"" ]; then
265 error=yes
266 echo "The following .elc files are older than their .el files:"
267 echo "${bogosities}"
270 rm -f $temp_el*
272 bogosities=
273 for file in $losers; do
274 grep -q "^;.*no-byte-compile: t" "$file" && continue
275 case $file in
276 site-init.el | site-load.el | site-start.el | default.el) continue ;;
277 esac
279 bogosities="$file $bogosities"
281 done
282 if [ x"${bogosities}" != x"" ]; then
283 error=yes
284 echo "The following .el files have no corresponding .elc files:"
285 echo "${bogosities}"
289 ## This is only a crude check, eg it does not handle .info
290 ## files with multiple .texi source files.
291 find doc -name '*.texi' > $temp_el
293 bogosities=
294 while read texi; do
295 info=`sed -n 's/^@setfilename //p' $texi | sed 's|.*info/||'`
296 [ x"${info}" != x"" ] || continue
297 info=info/$info
298 [ -r "$info" ] || continue
299 [ "$info" -nt "$texi" ] || bogosities="$bogosities $info"
300 done < $temp_el
302 rm -f $temp_el
304 if [ x"${bogosities}" != x"" ]; then
305 error=yes
306 echo "The following .info files are older than their .texi files:"
307 echo "${bogosities}"
310 ## This exits with non-zero status if any .info files need
311 ## rebuilding.
312 if [ -r Makefile ] && [ "$with_info" = "yes" ]; then
313 echo "Checking to see if info files are up-to-date..."
314 make --question info || error=yes
317 ## Is this a release?
318 case $version in
319 [1-9][0-9].[0-9])
320 if [ -r ChangeLog ]; then
321 if ! grep -q "Version $version released" ChangeLog; then
322 echo "No release notice in ChangeLog"
323 error=yes
325 else
326 echo "A release must have a ChangeLog"
327 error=yes
330 esac
332 if [ $error = yes ]; then
333 echo "Failed checks" >&2
334 exit 1
339 if [ $update = yes ]; then
341 ## Make sure configure is newer than configure.ac, etc.
342 ## It is better to let autoreconf do what is needed than
343 ## for us to try and duplicate all its checks.
344 echo "Running autoreconf"
345 autoreconf -i -I m4 || { x=$?; echo Autoreconf FAILED! >&2; exit $x; }
347 if [ "$make_info" = yes ] ; then
348 echo "Updating Info files"
349 make info
352 echo "Updating finder, custom and autoload data"
353 (cd lisp && make updates EMACS="$EMACS")
355 echo "Updating leim-list.el"
356 (cd leim && make leim-list.el EMACS="$EMACS")
358 echo "Recompiling Lisp files"
359 $EMACS -batch -f batch-byte-recompile-directory lisp
360 fi # $update = yes
362 if [ "$changelog" = yes ] && [ -r .git ]; then
363 top_level_ChangeLog=ChangeLog
364 else
365 top_level_ChangeLog=
368 # Files to distribute that might not be under version control.
369 # Don't distribute site-init.el, site-load.el, or default.el.
370 possibly_non_vc_files="
371 $top_level_ChangeLog
372 MANIFEST aclocal.m4 configure
373 admin/charsets/jisx2131-filter
374 src/config.in
376 find admin doc etc lisp \
377 \( -name '*.el' -o -name '*.elc' -o -name '*.map' -o -name '*.stamp' \
378 -o -name '*.texi' -o -name '*.tex' -o -name '*.txt' \) \
379 ! -name 'site-init*' ! -name 'site-load*' ! -name 'default*'
380 ) || exit
382 if [ $with_info = yes ]; then
383 info_files="info/dir $(echo info/*.info)" || exit
384 else
385 info_files=
388 echo "Creating staging directory: '${tempparent}'"
390 mkdir ${tempparent} || exit
391 tempdir="${tempparent}/${emacsname}"
393 manifest=MANIFEST
395 [ -f $manifest ] || manifest=${tempparent}/MANIFEST
397 # If Git is in use update the file MANIFEST, which can substitute for
398 # 'git ls-files' later (e.g., after extraction from a tarball).
399 # Otherwise, rely on the existing MANIFEST, which should be maintained some
400 # other way when adding or deleting a distributed file while not using Git.
401 # TODO: maybe this should ignore $update, and always update MANIFEST
402 # if .git is present.
403 if ( [ $update = yes ] || [ ! -f $manifest ] ) && [ -r .git ]; then
404 echo "Updating $manifest"
405 if [ $with_tests = yes ]; then
406 git ls-files > $manifest
407 else
408 git ls-files | grep -v '^test' >$manifest
409 fi || exit
410 printf '%s\n' $possibly_non_vc_files $info_files >>$manifest || exit
411 sort -u -o $manifest $manifest || exit
414 <$manifest || exit
416 ### This trap ensures that the staging directory will be cleaned up even
417 ### when the script is interrupted in mid-career.
418 if [ "${clean_up}" = yes ]; then
419 trap "echo 'Cleaning up the staging directory'; rm -rf ${tempparent}" EXIT
422 echo "Creating top directory: '${tempdir}'"
423 if [ $verbose = yes ] && (mkdir --verbose ${tempdir}) >/dev/null 2>&1; then
424 mkdir_verbose='mkdir --verbose'
425 else
426 mkdir $tempdir || exit
427 mkdir_verbose="mkdir"
430 # file_to_skip is normally empty to link every file,
431 # but it can be 'ChangeLog' if we do not want to link the
432 # top-level ChangeLog.
433 file_to_skip=
435 if [ "$changelog" = yes ]; then
436 if test -r .git; then
437 ## When making a release or pretest the ChangeLog should already
438 ## have been created and edited as needed. Don't ignore it.
439 if [ -r ChangeLog ] && [ ! -L ChangeLog ]; then
440 echo "Using existing top-level ChangeLog"
441 else
442 echo "Making top-level ChangeLog"
443 make ChangeLog CHANGELOG=${tempdir}/ChangeLog || \
444 { x=$?; echo "make ChangeLog FAILED (try --no-changelog?)" >&2; exit $x; }
445 file_to_skip=ChangeLog
447 else
448 echo "No repository, so omitting top-level ChangeLog"
452 echo "Creating subdirectories"
453 MANIFEST_subdir_sed='
455 '$tempdir'/info\
456 '$tempdir'/site-lisp
457 s,[^/]*$,,
458 s,/$,,
459 /^$/d
460 s,^,'$tempdir'/,
462 tempsubdirs=$(sed "$MANIFEST_subdir_sed" $manifest | sort -u)
463 $mkdir_verbose -p $tempsubdirs || exit
465 echo "Making links to files"
466 while read file; do
467 case $file in
468 MANIFEST) ln $manifest $tempdir/MANIFEST || exit ;;
469 $file_to_skip) continue ;;
470 *) ln "$file" $tempdir/"$file" || exit ;;
471 esac
472 done <$manifest
474 if [ "${newer}" ]; then
475 printf '%s\n' "Removing files older than $newer"
476 ## We remove .elc files unconditionally, on the theory that anyone picking
477 ## up an incremental distribution already has a running Emacs to byte-compile
478 ## them with.
479 find ${tempdir} \( -name '*.elc' -o ! -newer "${newer}" \) \
480 -exec rm -f {} \; || exit
483 if [ "${make_tar}" = yes ]; then
484 echo "Looking for $default_gzip"
485 found=0
486 temppath=`printf '%s\n' "$PATH" |
487 sed -e 's/^:/.:/' -e 's/::/:.:/g' -e 's/:$/:./' -e 's/:/ /g'
489 for dir in ${temppath}; do
490 [ -x "${dir}"/$default_gzip ] || continue
491 found=1; break
492 done
493 if [ "$found" = "0" ]; then
494 echo "WARNING: '$default_gzip' not found, will not compress" >&2
495 default_gzip="cat"
497 case "${default_gzip}" in
498 bzip2) gzip_extension=.bz2 ;;
499 xz) gzip_extension=.xz ;;
500 gzip) gzip_extension=.gz ; default_gzip="gzip --best --no-name";;
501 *) gzip_extension= ;;
502 esac
503 echo "Creating tar file"
504 taropt='--numeric-owner --owner=0 --group=0 --mode=go+u,go-w'
505 tar --sort=name -cf /dev/null $tempdir/src/lisp.h 2>/dev/null &&
506 taropt="$taropt --sort=name"
507 [ "$verbose" = "yes" ] && taropt="$taropt --verbose"
509 (cd $tempparent &&
510 case $default_gzip in
511 cat) tar $taropt -cf - $emacsname;;
512 *) if tar $taropt -cf /dev/null --use-compress-program="$default_gzip" \
513 $emacsname/src/lisp.h > /dev/null 2>&1
514 then
515 tar $taropt -cf - --use-compress-program="$default_gzip" $emacsname
516 else
517 tar $taropt -cf $emacsname.tar $emacsname &&
518 $default_gzip <$emacsname.tar
519 fi;;
520 esac
521 ) >$emacsname.tar"$gzip_extension" || exit
524 ## Why are we deleting the staging directory if clean_up is no?
525 if [ "${clean_up}" != yes ]; then
526 (cd ${tempparent} && mv ${emacsname} ..) &&
527 rm -rf ${tempparent}
530 # Local Variables:
531 # sh-basic-offset: 2
532 # End: