avoid silent data loss e.g., on NFS, due to unchecked close of stdout
[gzip.git] / bootstrap
blob81a48820778ccd039a894a545d39207f1639833c
1 #! /bin/sh
3 # Bootstrap this package from checked-out sources.
5 # Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
7 # This program is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 3, or (at your option)
10 # any later version.
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with this program; if not, write to the Free Software
19 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 # 02110-1301, USA.
22 # Written by Paul Eggert.
24 nl='
27 # Ensure file names are sorted consistently across platforms.
28 # Also, ensure diagnostics are in English, e.g., "wget --help" below.
29 LC_ALL=C
30 export LC_ALL
32 # Temporary directory names.
33 bt='._bootmp'
34 bt_regex=`echo "$bt"| sed 's/\./[.]/g'`
35 bt2=${bt}2
37 usage() {
38 echo >&2 "\
39 Usage: $0 [OPTION]...
40 Bootstrap this package from the checked-out sources.
42 Options:
43 --gnulib-srcdir=DIRNAME Specify the local directory where gnulib
44 sources reside. Use this if you already
45 have gnulib sources on your machine, and
46 do not want to waste your bandwidth downloading
47 them again.
48 --copy Copy files instead of creating symbolic links.
49 --force Attempt to bootstrap even if the sources seem
50 not to have been checked out.
51 --skip-po Do not download po files.
52 --cvs-user=USERNAME Set the username to use when checking out
53 sources from the gnulib repository.
55 If the file .bootstrap.conf exists in the current working directory, its
56 contents are read as shell variables to configure the bootstrap.
58 Running without arguments will suffice in most cases.
62 # Configuration.
64 # List of gnulib modules needed.
65 gnulib_modules=
67 # Any gnulib files needed that are not in modules.
68 gnulib_files=
70 # Translation Project URL, for the registry of all projects
71 # and for the translation-team master directory.
72 TP_URL='http://www.iro.umontreal.ca/translation/registry.cgi?domain='
73 TP_PO_URL='http://www.iro.umontreal.ca/translation/teams/PO/'
75 extract_package_name='
76 /^AC_INIT(/{
77 /.*,.*,.*,/{
78 s///
79 s/[][]//g
83 s/AC_INIT(\[*//
84 s/]*,.*//
85 s/^GNU //
86 y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
87 s/[^A-Za-z0-9_]/-/g
91 package=`sed -n "$extract_package_name" configure.ac` || exit
92 gnulib_name=lib$package
94 build_aux=build-aux
95 # Extra files from gnulib, which override files from other sources.
96 gnulib_extra_files="
97 $build_aux/install-sh
98 $build_aux/missing
99 $build_aux/mdate-sh
100 $build_aux/texinfo.tex
101 $build_aux/depcomp
102 $build_aux/config.guess
103 $build_aux/config.sub
104 doc/INSTALL
106 # Additional gnulib-tool options to use. Use "\newline" to break lines.
107 gnulib_tool_option_extras=
109 # Other locale categories that need message catalogs.
110 EXTRA_LOCALE_CATEGORIES=
112 # Additional xgettext options to use. Use "\\\newline" to break lines.
113 XGETTEXT_OPTIONS='\\\
114 --flag=_:1:pass-c-format\\\
115 --flag=N_:1:pass-c-format\\\
116 --flag=error:3:c-format --flag=error_at_line:5:c-format\\\
119 # Files we don't want to import.
120 excluded_files=
122 # File that should exist in the top directory of a checked out hierarchy,
123 # but not in a distribution tarball.
124 checkout_only_file=README-hacking
126 # Whether to use copies instead of symlinks.
127 copy=false
129 # Override the default configuration, if necessary.
130 test -r bootstrap.conf && . ./bootstrap.conf
132 # Translate configuration into internal form.
134 # Parse options.
136 for option
138 case $option in
139 --help)
140 usage
141 exit;;
142 --gnulib-srcdir=*)
143 GNULIB_SRCDIR=`expr "$option" : '--gnulib-srcdir=\(.*\)'`;;
144 --cvs-user=*)
145 CVS_USER=`expr "$option" : '--cvs-user=\(.*\)'`;;
146 --skip-po)
147 SKIP_PO=t;;
148 --force)
149 checkout_only_file=;;
150 --copy)
151 copy=true;;
153 echo >&2 "$0: $option: unknown option"
154 exit 1;;
155 esac
156 done
158 if test -n "$checkout_only_file" && test ! -r "$checkout_only_file"; then
159 echo "$0: Bootstrapping from a non-checked-out distribution is risky." >&2
160 exit 1
163 # If $STR is not already on a line by itself in $FILE, insert it,
164 # sorting the new contents of the file and replacing $FILE with the result.
165 insert_sorted_if_absent() {
166 file=$1
167 str=$2
168 echo "$str" | sort -u - $file | cmp -s - $file \
169 || echo "$str" | sort -u - $file -o $file \
170 || exit 1
173 # Die if there is no AC_CONFIG_AUX_DIR($build_aux) line in configure.ac.
174 found_aux_dir=no
175 grep '^[ ]*AC_CONFIG_AUX_DIR(\['"$build_aux"'\])' configure.ac \
176 >/dev/null && found_aux_dir=yes
177 grep '^[ ]*AC_CONFIG_AUX_DIR('"$build_aux"')' configure.ac \
178 >/dev/null && found_aux_dir=yes
179 if test $found_aux_dir = no; then
180 echo "$0: expected line not found in configure.ac. Add the following:" >&2
181 echo " AC_CONFIG_AUX_DIR([$build_aux])" >&2.
184 # If $build_aux doesn't exist, create it now, otherwise some bits
185 # below will malfunction. If creating it, also mark it as ignored.
186 if test ! -d $build_aux; then
187 mkdir $build_aux
188 for ig in .cvsignore .gitignore; do
189 test -f $ig && insert_sorted_if_absent $ig $build_aux
190 done
193 echo "$0: Bootstrapping from checked-out $package sources..."
195 cleanup_gnulib() {
196 status=$?
197 rm -fr gnulib
198 exit $status
201 # Get gnulib files.
203 case ${GNULIB_SRCDIR--} in
205 if [ ! -d gnulib ]; then
206 echo "$0: getting gnulib files..."
208 case ${CVS_AUTH-pserver} in
209 pserver)
210 CVS_PREFIX=':pserver:anonymous@';;
211 ssh)
212 CVS_PREFIX="$CVS_USER${CVS_USER+@}";;
214 echo "$0: $CVS_AUTH: Unknown CVS access method" >&2
215 exit 1;;
216 esac
218 case $CVS_RSH in
219 '') CVS_RSH=ssh; export CVS_RSH;;
220 esac
222 trap cleanup_gnulib 1 2 13 15
224 cvs -z3 -q -d ${CVS_PREFIX}cvs.savannah.gnu.org:/cvsroot/gnulib co gnulib ||
225 cleanup_gnulib
227 trap - 1 2 13 15
229 GNULIB_SRCDIR=gnulib
230 esac
232 gnulib_tool=$GNULIB_SRCDIR/gnulib-tool
233 <$gnulib_tool || exit
235 # Get translations.
237 get_translations() {
238 subdir=$1
239 domain=$2
241 case $WGET_COMMAND in
243 echo "$0: wget not available; skipping translations";;
245 echo "$0: getting translations into $subdir for $domain..." &&
247 (cd $subdir && rm -f dummy `ls | sed -n '/\.gmo$/p; /\.po/p'`) &&
248 $WGET_COMMAND -O "$subdir/$domain.html" "$TP_URL$domain" &&
250 sed -n 's|.*"http://[^"]*/translation/teams/PO/\([^/"]*\)/'"$domain"'-\([^/"]*\)\.[^."]*\.po".*|\1.\2|p' <"$subdir/$domain.html" |
251 sort -k 1,1 -k 2,2n -k2,2 -k3,3n -k3,3 -k4,4n -k4,4 -k5,5n -k5.5 |
252 awk -F. '
253 { if (lang && $1 != lang) print lang, ver }
254 { lang = $1; ver = substr($0, index($0, ".") + 1) }
255 END { if (lang) print lang, ver }
256 ' | awk -v domain="$domain" -v subdir="$subdir" '
258 lang = $1
259 ver = $2
260 urlfmt = ""
261 printf "{ $WGET_COMMAND -O %s/%s.po '\'"$TP_PO_URL"'/%s/%s-%s.%s.po'\'' &&\n", subdir, lang, lang, domain, ver, lang
262 printf " msgfmt -c -o /dev/null %s/%s.po || {\n", subdir, lang
263 printf " echo >&2 '\'"$0"': omitting translation for %s'\''\n", lang
264 printf " rm -f %s/%s.po; }; } &&\n", subdir, lang
266 END { print ":" }
267 ' | WGET_COMMAND="$WGET_COMMAND" sh;;
268 esac &&
269 ls "$subdir"/*.po 2>/dev/null |
270 sed 's|.*/||; s|\.po$||' >"$subdir/LINGUAS" &&
271 rm -f "$subdir/$domain.html"
274 case $SKIP_PO in
276 case `wget --help` in
277 *'--no-cache'*)
278 WGET_COMMAND='wget -nv --no-cache';;
279 *'--cache=on/off'*)
280 WGET_COMMAND='wget -nv --cache=off';;
281 *'--non-verbose'*)
282 WGET_COMMAND='wget -nv';;
284 WGET_COMMAND='';;
285 esac
287 if test -d po; then
288 get_translations po $package || exit
291 if test -d runtime-po; then
292 get_translations runtime-po $package-runtime || exit
293 fi;;
294 esac
296 symlink_to_gnulib()
298 src=$GNULIB_SRCDIR/$1
299 dst=${2-$1}
301 test -f "$src" && {
302 if $copy; then
304 test ! -h "$dst" || {
305 echo "$0: rm -f $dst" &&
306 rm -f "$dst"
308 } &&
309 test -f "$dst" &&
310 cmp -s "$src" "$dst" || {
311 echo "$0: cp -fp $src $dst" &&
312 cp -fp "$src" "$dst"
314 else
315 test -h "$dst" &&
316 src_ls=`ls -diL "$src" 2>/dev/null` && set $src_ls && src_i=$1 &&
317 dst_ls=`ls -diL "$dst" 2>/dev/null` && set $dst_ls && dst_i=$1 &&
318 test "$src_i" = "$dst_i" || {
319 dot_dots=
320 case $src in
321 /*) ;;
323 case /$dst/ in
324 *//* | */../* | */./* | /*/*/*/*/*/)
325 echo >&2 "$0: invalid symlink calculation: $src -> $dst"
326 exit 1;;
327 /*/*/*/*/) dot_dots=../../../;;
328 /*/*/*/) dot_dots=../../;;
329 /*/*/) dot_dots=../;;
330 esac;;
331 esac
333 echo "$0: ln -fs $dot_dots$src $dst" &&
334 ln -fs "$dot_dots$src" "$dst"
340 cp_mark_as_generated()
342 cp_src=$1
343 cp_dst=$2
345 if cmp -s "$cp_src" "$GNULIB_SRCDIR/$cp_dst"; then
346 symlink_to_gnulib "$cp_dst"
347 else
348 case $cp_dst in
349 *.[ch]) c1='/* '; c2=' */';;
350 *.texi) c1='@c '; c2= ;;
351 *.m4|*/Make*|Make*) c1='# ' ; c2= ;;
352 *) c1= ; c2= ;;
353 esac
355 if test -z "$c1"; then
356 cmp -s "$cp_src" "$cp_dst" || {
357 echo "$0: cp -f $cp_src $cp_dst" &&
358 rm -f "$cp_dst" &&
359 sed "s!$bt_regex/!!g" "$cp_src" > "$cp_dst"
361 else
362 # Copy the file first to get proper permissions if it
363 # doesn't already exist. Then overwrite the copy.
364 cp "$cp_src" "$cp_dst-t" &&
366 echo "$c1-*- buffer-read-only: t -*- vi: set ro:$c2" &&
367 echo "${c1}DO NOT EDIT! GENERATED AUTOMATICALLY!$c2" &&
368 sed "s!$bt_regex/!!g" "$cp_src"
369 ) > $cp_dst-t &&
370 if cmp -s "$cp_dst-t" "$cp_dst"; then
371 rm -f "$cp_dst-t"
372 else
373 echo "$0: cp $cp_src $cp_dst # with edits" &&
374 mv -f "$cp_dst-t" "$cp_dst"
380 version_controlled_file() {
381 dir=$1
382 file=$2
383 found=no
384 if test -d CVS; then
385 grep -F "/$file/" $dir/CVS/Entries 2>/dev/null |
386 grep '^/[^/]*/[0-9]' > /dev/null && found=yes
387 elif test -d .git; then
388 git-rm -n "$dir/$file" > /dev/null 2>&1 && found=yes
389 else
390 echo "$0: no version control for $dir/$file?" >&2
392 test $found = yes
395 slurp() {
396 for dir in . `(cd $1 && find * -type d -print)`; do
397 copied=
398 sep=
399 for file in `ls $1/$dir`; do
400 test -d $1/$dir/$file && continue
401 for excluded_file in $excluded_files; do
402 test "$dir/$file" = "$excluded_file" && continue 2
403 done
404 if test $file = Makefile.am; then
405 copied=$copied${sep}gnulib.mk; sep=$nl
406 remove_intl='/^[^#].*\/intl/s/^/#/;'"s!$bt_regex/!!g"
407 sed "$remove_intl" $1/$dir/$file | cmp -s - $dir/gnulib.mk || {
408 echo "$0: Copying $1/$dir/$file to $dir/gnulib.mk ..." &&
409 rm -f $dir/gnulib.mk &&
410 sed "$remove_intl" $1/$dir/$file >$dir/gnulib.mk
412 elif { test "${2+set}" = set && test -r $2/$dir/$file; } ||
413 version_controlled_file $dir $file; then
414 echo "$0: $dir/$file overrides $1/$dir/$file"
415 else
416 copied=$copied$sep$file; sep=$nl
417 if test $file = gettext.m4; then
418 echo "$0: patching m4/gettext.m4 to remove need for intl/* ..."
419 rm -f $dir/$file
420 sed '
421 /^AC_DEFUN(\[AM_INTL_SUBDIR],/,/^]/c\
422 AC_DEFUN([AM_INTL_SUBDIR], [
423 /^AC_DEFUN(\[gt_INTL_SUBDIR_CORE],/,/^]/c\
424 AC_DEFUN([gt_INTL_SUBDIR_CORE], [])
426 AC_DEFUN([gl_LOCK_EARLY], [])
427 ' $1/$dir/$file >$dir/$file
428 else
429 cp_mark_as_generated $1/$dir/$file $dir/$file
431 fi || exit
432 done
434 for dot_ig in .cvsignore .gitignore; do
435 ig=$dir/$dot_ig
436 if test -n "$copied" && test -f $ig; then
437 insert_sorted_if_absent $ig "$copied"
438 # If an ignored file name ends with _.h, then also add
439 # the name with just ".h". Many gnulib headers are generated,
440 # e.g., stdint_.h -> stdint.h, dirent_.h ->..., etc.
441 f=`echo "$copied"|sed 's/_\.h$/.h/'`
442 insert_sorted_if_absent $ig "$f"
444 done
445 done
449 # Create boot temporary directories to import from gnulib and gettext.
450 rm -fr $bt $bt2 &&
451 mkdir $bt $bt2 || exit
453 # Import from gnulib.
455 gnulib_tool_options="\
456 --import\
457 --no-changelog\
458 --aux-dir $bt/$build_aux\
459 --doc-base $bt/doc\
460 --lib $gnulib_name\
461 --m4-base $bt/m4/\
462 --source-base $bt/lib/\
463 --tests-base $bt/tests\
464 --local-dir gl\
465 $gnulib_tool_option_extras\
467 echo "$0: $gnulib_tool $gnulib_tool_options --import ..."
468 $gnulib_tool $gnulib_tool_options --import $gnulib_modules &&
469 slurp $bt || exit
471 for file in $gnulib_files; do
472 symlink_to_gnulib $file || exit
473 done
476 # Import from gettext.
477 with_gettext=yes
478 grep '^[ ]*AM_GNU_GETTEXT_VERSION(' configure.ac >/dev/null || \
479 with_gettext=no
481 if test $with_gettext = yes; then
482 echo "$0: (cd $bt2; autopoint) ..."
483 cp configure.ac $bt2 &&
484 (cd $bt2 && autopoint && rm configure.ac) &&
485 slurp $bt2 $bt || exit
487 rm -fr $bt $bt2 || exit
491 # Reconfigure, getting other files.
493 for command in \
494 libtool \
495 'aclocal --force -I m4' \
496 'autoconf --force' \
497 'autoheader --force' \
498 'automake --add-missing --copy --force-missing';
500 if test "$command" = libtool; then
501 grep '^[ ]*AM_PROG_LIBTOOL\>' configure.ac >/dev/null ||
502 continue
503 command='libtoolize -c -f'
505 echo "$0: $command ..."
506 $command || exit
507 done
510 # Get some extra files from gnulib, overriding existing files.
512 for file in $gnulib_extra_files; do
513 case $file in
514 */INSTALL) dst=INSTALL;;
515 *) dst=$file;;
516 esac
517 symlink_to_gnulib $file $dst || exit
518 done
520 if test $with_gettext = yes; then
521 # Create gettext configuration.
522 echo "$0: Creating po/Makevars from po/Makevars.template ..."
523 rm -f po/Makevars
524 sed '
525 /^EXTRA_LOCALE_CATEGORIES *=/s/=.*/= '"$EXTRA_LOCALE_CATEGORIES"'/
526 /^MSGID_BUGS_ADDRESS *=/s/=.*/= bug-'"$package"'@gnu.org/
527 /^XGETTEXT_OPTIONS *=/{
528 s/$/ \\/
530 '"$XGETTEXT_OPTIONS"' $${end_of_xgettext_options+}
532 ' po/Makevars.template >po/Makevars
534 if test -d runtime-po; then
535 # Similarly for runtime-po/Makevars, but not quite the same.
536 rm -f runtime-po/Makevars
537 sed '
538 /^DOMAIN *=.*/s/=.*/= '"$package"'-runtime/
539 /^subdir *=.*/s/=.*/= runtime-po/
540 /^MSGID_BUGS_ADDRESS *=/s/=.*/= bug-'"$package"'@gnu.org/
541 /^XGETTEXT_OPTIONS *=/{
542 s/$/ \\/
544 '"$XGETTEXT_OPTIONS_RUNTIME"' $${end_of_xgettext_options+}
546 ' <po/Makevars.template >runtime-po/Makevars
548 # Copy identical files from po to runtime-po.
549 (cd po && cp -p Makefile.in.in *-quot *.header *.sed *.sin ../runtime-po)
553 echo "$0: done. Now you can run './configure'."