2 ### make-dist: create an Emacs distribution tar file from current srcdir
4 ## Copyright (C) 1995, 1997-1998, 2000-2024 Free Software Foundation,
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/>.
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.
33 ### Exit if a command fails.
36 ### Print out each line we read, for debugging's sake.
43 export LANGUAGE LC_ALL LC_MESSAGES LANG
45 ## Remove unnecessary restrictions on file access.
58 while [ $# -gt 0 ]; do
60 ## This option tells make-dist to delete the staging directory
61 ## when done. It is useless to use this unless you make a tar file.
65 ## This option tells make-dist to make a tar file.
69 ## This option tells make-dist not to recompile or do analogous things.
73 ## This option says don't check for bad file names, etc.
80 ## This options tells make-dist to skip the info files. This can
81 ## be useful for creating a tarball purely for test purposes.
85 ## This option tells make-dist to make the distribution normally, then
86 ## remove all files older than the given timestamp file. This is useful
87 ## for creating incremental or patch distributions.
93 ## This option tells make-dist to use 'bzip2' instead of gzip.
111 "--tests"|
"--no-tests")
112 echo "The option $1 no longer does anything"
121 printf '%s\n' "Usage: ${progname} [options]"
123 echo " --bzip2 use bzip2 instead of gzip"
124 echo " --clean-up delete staging directories when done"
125 echo " --xz use xz instead of gzip"
126 echo " --no-compress don't compress"
127 echo " --newer=TIME don't include files older than TIME"
128 echo " --no-check don't check for bad file names etc."
129 echo " --no-update don't recompile or do analogous things"
130 echo " --no-changelog don't generate the top-level ChangeLog"
131 echo " --no-info don't include info files"
132 echo " --snapshot same as --clean-up --no-update --tar"
133 echo " --tar make a tar file"
134 echo " --verbose noisier output"
140 printf '%s\n' "${progname}: Unrecognized argument: $1" >&2
147 ### Make sure we're running in the right place.
148 if [ ! -d src
-o ! -f src
/lisp.h
-o ! -d lisp
-o ! -f lisp
/subr.el
]; then
149 printf '%s\n' "${progname}: Can't find 'src/lisp.h' and 'lisp/subr.el'." >&2
150 printf '%s\n' "${progname} must be run in the top directory of the Emacs" >&2
151 printf '%s\n' "distribution tree. cd to that directory and try again." >&2
155 ### Find where to run Emacs.
156 ### (Accept only absolute file names.)
157 if [ $update = yes ];
161 EMACS
=`pwd`/src
/emacs
166 if [ ! -f "$EMACS" ]; then
167 printf '%s\n' "$0: You must set the EMACS environment variable " \
168 "to an absolute file name." 2>&1
175 ### Find out which version of Emacs this is.
177 sed -n 's/^AC_INIT(\[GNU Emacs],[ ]*\[\([^]]*\).*/\1/p' <configure.ac
179 if [ ! "${version}" ]; then
181 "${progname}: can't find current Emacs version in './src/emacs.c'" >&2
185 echo Version number is
"$version"
187 if [ $update = yes ]; then
188 if ! grep -q "tree holds version *${version}" README
; then
189 echo "WARNING: README has the wrong version number"
190 echo "Consider running M-x set-version from admin/admin.el"
195 ### Make sure we don't already have a directory emacs-${version}.
197 emacsname
="emacs-${version}${new_extension}"
199 if [ -d ${emacsname} ]
201 echo Directory
"${emacsname}" already exists
>&2
205 ### Make sure the subdirectory is available.
206 tempparent
="make-dist.tmp.$$"
207 if [ -d ${tempparent} ]; then
208 printf '%s\n' "${progname}: staging directory '${tempparent}' already exists.
209 Perhaps a previous invocation of '${progname}' failed to clean up after
210 itself. Check that directories whose names are of the form
211 'make-dist.tmp.NNNNN' don't contain any important information, remove
212 them, and try again." >&2
216 if [ $check = yes ]; then
218 echo "Sanity checking (use --no-check to disable this)..."
222 temp_el
=/tmp
/make-dist.tmp.$$
224 temp_elelc
=$temp_el.2
225 temp_elcel
=$temp_el.3
227 ls -1 lisp
/[a-zA-Z
]*.el lisp
/[a-z
]*/[a-zA-Z0-9
]*.el \
228 lisp
/[a-z
]*/[a-z
]*/[a-zA-Z0-9
]*.el \
229 lisp
/[a-z
]*/[a-z
]*/[a-z
]*/[a-zA-Z0-9
]*.el
> $temp_el
231 ls -1 lisp
/[a-zA-Z
]*.elc lisp
/[a-z
]*/[a-zA-Z0-9
]*.elc \
232 lisp
/[a-z
]*/[a-z
]*/[a-zA-Z0-9
]*.elc \
233 lisp
/[a-z
]*/[a-z
]*/[a-z
]*/[a-zA-Z0-9
]*.elc
> $temp_elc
235 ## Check for .elc files with no corresponding .el file.
236 sed 's/\.el$/.elc/' $temp_el > $temp_elelc
238 bogosities
=`comm -13 $temp_elelc $temp_elc`
239 if [ x
"${bogosities}" != x
"" ]; then
241 echo "The following .elc files have no corresponding .el files:"
245 ### Check for .el files with no corresponding .elc file.
246 sed 's/\.elc$/.el/' $temp_elc > $temp_elcel
247 losers
=`comm -23 $temp_el $temp_elcel`
251 el
=`echo $elc | sed 's/c$//'`
252 [ -r "$el" ] ||
continue
253 [ "$elc" -nt "$el" ] || bogosities
="$bogosities $elc"
256 if [ x
"${bogosities}" != x
"" ]; then
258 echo "The following .elc files are older than their .el files:"
265 for file in $losers; do
266 grep -q "^;.*no-byte-compile: t" "$file" && continue
268 site-init.el | site-load.el | site-start.el | default.el
) continue ;;
271 bogosities
="$file $bogosities"
274 if [ x
"${bogosities}" != x
"" ]; then
276 echo "The following .el files have no corresponding .elc files:"
281 ## This is only a crude check, eg it does not handle .info
282 ## files with multiple .texi source files.
283 find doc
-name '*.texi' > $temp_el
287 info
=`sed -n 's/^@setfilename //p' $texi | sed 's|.*info/||'`
288 [ x
"${info}" != x
"" ] ||
continue
290 [ -r "$info" ] ||
continue
291 [ "$info" -nt "$texi" ] || bogosities
="$bogosities $info"
296 if [ x
"${bogosities}" != x
"" ]; then
298 echo "The following .info files are older than their .texi files:"
302 ## Is this a release?
305 if [ -r ChangeLog
]; then
306 if ! grep -q "Version $version released" ChangeLog
; then
307 echo "No release notice in ChangeLog"
311 echo "A release must have a ChangeLog"
317 if [ $error = yes ]; then
318 echo "Failed checks" >&2
324 if [ $update = yes ]; then
326 ## Make sure configure is newer than configure.ac, etc.
327 ## It is better to let autoreconf do what is needed than
328 ## for us to try and duplicate all its checks.
329 echo "Running autoreconf"
330 autoreconf
-i -I m4 ||
{ x
=$?
; echo Autoreconf FAILED
! >&2; exit $x; }
332 if [ "$make_info" = yes ] ; then
333 echo "Updating Info files"
337 echo "Updating finder, custom and autoload data"
338 (cd lisp
&& make updates EMACS
="$EMACS")
340 echo "Updating leim-list.el"
341 (cd leim
&& make leim-list.el EMACS
="$EMACS")
343 echo "Recompiling Lisp files"
344 $EMACS -batch -f batch-byte-recompile-directory lisp
347 if [ "$changelog" = yes ] && [ -r .git
]; then
348 top_level_ChangeLog
=ChangeLog
353 # Files to distribute that might not be under version control.
354 # Don't distribute site-init.el, site-load.el, or default.el.
355 possibly_non_vc_files
="
357 MANIFEST aclocal.m4 configure
358 admin/charsets/jisx2131-filter
360 exec/configure exec/config.h.in
361 exec/config.sub exec/config.guess
363 leim/small-ja-dic-option
365 find admin doc etc lisp \
366 \
( -name '*.el' -o -name '*.elc' -o -name '*.map' -o -name '*.stamp' \
367 -o -name '*.texi' -o -name '*.tex' -o -name '*.txt' -o -name '*.pdf' \
) \
368 ! -name 'site-init*' ! -name 'site-load*' ! -name 'default*'
371 if [ $with_info = yes ]; then
372 info_files
="info/dir $(echo info/*.info)" ||
exit
377 echo "Creating staging directory: '${tempparent}'"
379 mkdir
${tempparent} ||
exit
380 tempdir
="${tempparent}/${emacsname}"
384 [ -f $manifest ] || manifest
=${tempparent}/MANIFEST
386 # If Git is in use update the file MANIFEST, which can substitute for
387 # 'git ls-files' later (e.g., after extraction from a tarball).
388 # Otherwise, rely on the existing MANIFEST, which should be maintained some
389 # other way when adding or deleting a distributed file while not using Git.
390 # TODO: maybe this should ignore $update, and always update MANIFEST
391 # if .git is present.
392 # Filter out the files in msdos/autogen/, as they aren't useful in the
393 # tarball, and get in the way during the build of the MSDOS port.
394 if ( [ $update = yes ] ||
[ ! -f $manifest ] ) && [ -r .git
]; then
395 echo "Updating $manifest"
396 git ls-files |
sed -e '/^msdos\/autogen\//d' > $manifest ||
exit
397 printf '%s\n' $possibly_non_vc_files $info_files >>$manifest ||
exit
398 sort -u -o $manifest $manifest ||
exit
403 ### This trap ensures that the staging directory will be cleaned up even
404 ### when the script is interrupted in mid-career.
405 if [ "${clean_up}" = yes ]; then
406 trap "echo 'Cleaning up the staging directory'; rm -rf ${tempparent}" EXIT
409 echo "Creating top directory: '${tempdir}'"
410 if [ $verbose = yes ] && (mkdir
--verbose ${tempdir}) >/dev
/null
2>&1; then
411 mkdir_verbose
='mkdir --verbose'
413 mkdir
$tempdir ||
exit
414 mkdir_verbose
="mkdir"
417 # file_to_skip is normally empty to link every file,
418 # but it can be 'ChangeLog' if we do not want to link the
419 # top-level ChangeLog.
422 if [ "$changelog" = yes ]; then
423 if test -r .git
; then
424 ## When making a release or pretest the ChangeLog should already
425 ## have been created and edited as needed. Don't ignore it.
426 if [ -r ChangeLog
] && [ ! -L ChangeLog
]; then
427 echo "Using existing top-level ChangeLog"
429 echo "Making top-level ChangeLog"
430 make ChangeLog CHANGELOG
=${tempdir}/ChangeLog || \
431 { x
=$?
; echo "make ChangeLog FAILED (try --no-changelog?)" >&2; exit $x; }
432 file_to_skip
=ChangeLog
435 echo "No repository, so omitting top-level ChangeLog"
439 echo "Creating subdirectories"
440 MANIFEST_subdir_sed
='
449 tempsubdirs
=$
(sed "$MANIFEST_subdir_sed" $manifest |
sort -u)
450 $mkdir_verbose -p $tempsubdirs ||
exit
452 echo "Making links to files"
455 MANIFEST
) ln $manifest $tempdir/MANIFEST ||
exit ;;
456 $file_to_skip) continue ;;
457 *) ln "$file" $tempdir/"$file" ||
exit ;;
461 if [ "${newer}" ]; then
462 printf '%s\n' "Removing files older than $newer"
463 ## We remove .elc files unconditionally, on the theory that anyone picking
464 ## up an incremental distribution already has a running Emacs to byte-compile
466 find ${tempdir} \
( -name '*.elc' -o ! -newer "${newer}" \
) \
467 -exec rm -f {} \
; ||
exit
470 if [ "${make_tar}" = yes ]; then
471 echo "Looking for $default_gzip"
473 temppath
=`printf '%s\n' "$PATH" |
474 sed -e 's/^:/.:/' -e 's/::/:.:/g' -e 's/:$/:./' -e 's/:/ /g'
476 for dir
in ${temppath}; do
477 [ -x "${dir}"/$default_gzip ] ||
continue
480 if [ "$found" = "0" ]; then
481 echo "WARNING: '$default_gzip' not found, will not compress" >&2
484 case "${default_gzip}" in
485 bzip2) gzip_extension
=.bz2
;;
486 xz
) gzip_extension
=.xz
;;
487 gzip) gzip_extension
=.gz
; default_gzip
="gzip --best --no-name";;
488 *) gzip_extension
= ;;
490 echo "Creating tar file"
491 taropt
='--numeric-owner --owner=0 --group=0 --mode=go+u,go-w'
492 tar -H ustar
-cf /dev
/null
$tempdir/src
/lisp.h
2>/dev
/null
&&
493 taropt
="$taropt -H ustar"
494 tar --sort=name
-cf /dev
/null
$tempdir/src
/lisp.h
2>/dev
/null
&&
495 taropt
="$taropt --sort=name"
496 [ "$verbose" = "yes" ] && taropt
="$taropt --verbose"
499 case $default_gzip in
500 cat) tar $taropt -cf - $emacsname;;
501 *) if tar $taropt -cf /dev
/null
--use-compress-program="$default_gzip" \
502 $emacsname/src
/lisp.h
> /dev
/null
2>&1
504 tar $taropt -cf - --use-compress-program="$default_gzip" $emacsname
506 tar $taropt -cf $emacsname.
tar $emacsname &&
507 $default_gzip <$emacsname.
tar
510 ) >$emacsname.
tar"$gzip_extension" ||
exit
513 ## Why are we deleting the staging directory if clean_up is no?
514 if [ "${clean_up}" != yes ]; then
515 (cd ${tempparent} && mv ${emacsname} ..
) &&