Avoid diagnostics from sha1sum when there is no cached checksum.
[gnulib.git] / build-aux / bootstrap
1 #! /bin/sh
2
3 # Bootstrap this package from checked-out sources.
4
5 # Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
6
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 of the License, or
10 # (at your option) any later version.
11
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.
16
17 # You should have received a copy of the GNU General Public License
18 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
20 # Written by Paul Eggert.
21
22 nl='
23 '
24
25 # Ensure file names are sorted consistently across platforms.
26 LC_ALL=C
27 export LC_ALL
28
29 local_gl_dir=gl
30
31 # Temporary directory names.
32 bt='._bootmp'
33 bt_regex=`echo "$bt"| sed 's/\./[.]/g'`
34 bt2=${bt}2
35
36 usage() {
37   echo >&2 "\
38 Usage: $0 [OPTION]...
39 Bootstrap this package from the checked-out sources.
40
41 Options:
42  --gnulib-srcdir=DIRNAME  Specify the local directory where gnulib
43                           sources reside.  Use this if you already
44                           have gnulib sources on your machine, and
45                           do not want to waste your bandwidth downloading
46                           them again.
47  --copy                   Copy files instead of creating symbolic links.
48  --force                  Attempt to bootstrap even if the sources seem
49                           not to have been checked out.
50  --skip-po                Do not download po files.
51  --cvs-user=USERNAME      Set the username to use when checking out
52                           sources from the gnulib repository.
53
54 If the file bootstrap.conf exists in the current working directory, its
55 contents are read as shell variables to configure the bootstrap.
56
57 Running without arguments will suffice in most cases.
58 "
59 }
60
61 # Configuration.
62
63 # Name of the Makefile.am
64 gnulib_mk=gnulib.mk
65
66 # List of gnulib modules needed.
67 gnulib_modules=
68
69 # Any gnulib files needed that are not in modules.
70 gnulib_files=
71
72 # The command to download all .po files for a specified domain into
73 # a specified directory.  Fill in the first %s is the domain name, and
74 # the second with the destination directory.  Use rsync's -L and -r
75 # options because the latest/%s directory and the .po files within are
76 # all symlinks.
77 po_download_command_format=\
78 "rsync -Lrtvz 'translationproject.org::tp/latest/%s/' '%s'"
79
80 extract_package_name='
81   /^AC_INIT(/{
82      /.*,.*,.*,/{
83        s///
84        s/[][]//g
85        p
86        q
87      }
88      s/AC_INIT(\[*//
89      s/]*,.*//
90      s/^GNU //
91      y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
92      s/[^A-Za-z0-9_]/-/g
93      p
94   }
95 '
96 package=`sed -n "$extract_package_name" configure.ac` || exit
97 gnulib_name=lib$package
98
99 build_aux=build-aux
100 # Extra files from gnulib, which override files from other sources.
101 gnulib_extra_files="
102         $build_aux/install-sh
103         $build_aux/missing
104         $build_aux/mdate-sh
105         $build_aux/texinfo.tex
106         $build_aux/depcomp
107         $build_aux/config.guess
108         $build_aux/config.sub
109         doc/INSTALL
110 "
111
112 # Additional gnulib-tool options to use.  Use "\newline" to break lines.
113 gnulib_tool_option_extras=
114
115 # Other locale categories that need message catalogs.
116 EXTRA_LOCALE_CATEGORIES=
117
118 # Additional xgettext options to use.  Use "\\\newline" to break lines.
119 XGETTEXT_OPTIONS='\\\
120  --flag=_:1:pass-c-format\\\
121  --flag=N_:1:pass-c-format\\\
122  --flag=error:3:c-format --flag=error_at_line:5:c-format\\\
123 '
124
125 # Files we don't want to import.
126 excluded_files=
127
128 # File that should exist in the top directory of a checked out hierarchy,
129 # but not in a distribution tarball.
130 checkout_only_file=README-hacking
131
132 # Whether to use copies instead of symlinks.
133 copy=false
134
135 # Set this to '.cvsignore .gitignore' in bootstrap.conf if you want
136 # those files to be generated in directories like lib/, m4/, and po/.
137 # Or set it to 'auto' to make this script select which to use based
138 # on which version control system (if any) is used in the source directory.
139 vc_ignore=auto
140
141 # Override the default configuration, if necessary.
142 test -r bootstrap.conf && . ./bootstrap.conf
143
144 if test "$vc_ignore" = auto; then
145   vc_ignore=
146   test -d .git && vc_ignore=.gitignore
147   test -d CVS && vc_ignore="$vc_ignore .cvsignore"
148 fi
149
150 # Translate configuration into internal form.
151
152 # Parse options.
153
154 for option
155 do
156   case $option in
157   --help)
158     usage
159     exit;;
160   --gnulib-srcdir=*)
161     GNULIB_SRCDIR=`expr "$option" : '--gnulib-srcdir=\(.*\)'`;;
162   --cvs-user=*)
163     CVS_USER=`expr "$option" : '--cvs-user=\(.*\)'`;;
164   --skip-po)
165     SKIP_PO=t;;
166   --force)
167     checkout_only_file=;;
168   --copy)
169     copy=true;;
170   *)
171     echo >&2 "$0: $option: unknown option"
172     exit 1;;
173   esac
174 done
175
176 if test -n "$checkout_only_file" && test ! -r "$checkout_only_file"; then
177   echo "$0: Bootstrapping from a non-checked-out distribution is risky." >&2
178   exit 1
179 fi
180
181 # If $STR is not already on a line by itself in $FILE, insert it,
182 # sorting the new contents of the file and replacing $FILE with the result.
183 insert_sorted_if_absent() {
184   file=$1
185   str=$2
186   test -f $file || touch $file
187   echo "$str" | sort -u - $file | cmp -s - $file \
188     || echo "$str" | sort -u - $file -o $file \
189     || exit 1
190 }
191
192 # Die if there is no AC_CONFIG_AUX_DIR($build_aux) line in configure.ac.
193 found_aux_dir=no
194 grep '^[         ]*AC_CONFIG_AUX_DIR(\['"$build_aux"'\])' configure.ac \
195     >/dev/null && found_aux_dir=yes
196 grep '^[         ]*AC_CONFIG_AUX_DIR('"$build_aux"')' configure.ac \
197     >/dev/null && found_aux_dir=yes
198 if test $found_aux_dir = no; then
199   echo "$0: expected line not found in configure.ac. Add the following:" >&2
200   echo "  AC_CONFIG_AUX_DIR([$build_aux])" >&2
201   exit 1
202 fi
203
204 # If $build_aux doesn't exist, create it now, otherwise some bits
205 # below will malfunction.  If creating it, also mark it as ignored.
206 if test ! -d $build_aux; then
207   mkdir $build_aux
208   for dot_ig in x $vc_ignore; do
209     test $dot_ig = x && continue
210     insert_sorted_if_absent $dot_ig $build_aux
211   done
212 fi
213
214 echo "$0: Bootstrapping from checked-out $package sources..."
215
216 cleanup_gnulib() {
217   status=$?
218   rm -fr gnulib
219   exit $status
220 }
221
222 # Get gnulib files.
223
224 case ${GNULIB_SRCDIR--} in
225 -)
226   if [ ! -d gnulib ]; then
227     echo "$0: getting gnulib files..."
228
229     case ${CVS_AUTH-pserver} in
230     pserver)
231       CVS_PREFIX=':pserver:anonymous@';;
232     ssh)
233       CVS_PREFIX="$CVS_USER${CVS_USER+@}";;
234     *)
235       echo "$0: $CVS_AUTH: Unknown CVS access method" >&2
236       exit 1;;
237     esac
238
239     case $CVS_RSH in
240     '') CVS_RSH=ssh; export CVS_RSH;;
241     esac
242
243     trap cleanup_gnulib 1 2 13 15
244
245     git clone --depth 2 git://git.sv.gnu.org/gnulib ||
246       cleanup_gnulib
247
248     trap - 1 2 13 15
249   fi
250   GNULIB_SRCDIR=gnulib
251 esac
252
253 gnulib_tool=$GNULIB_SRCDIR/gnulib-tool
254 <$gnulib_tool || exit
255
256 # Get translations.
257
258 download_po_files() {
259   subdir=$1
260   domain=$2
261   echo "$0: getting translations into $subdir for $domain..."
262   cmd=`printf "$po_download_command_format" "$domain" "$subdir"`
263   eval "$cmd"
264 }
265
266 # Download .po files to $po_dir/.reference and copy only the new
267 # or modified ones into $po_dir.  Also update $po_dir/LINGUAS.
268 update_po_files() {
269   # Directory containing primary .po files.
270   # Overwrite them only when we're sure a .po file is new.
271   po_dir=$1
272   domain=$2
273
274   # Download *.po files into this dir.
275   # Usually contains *.s1 checksum files.
276   ref_po_dir="$po_dir/.reference"
277
278   test -d $ref_po_dir || mkdir $ref_po_dir || return
279   download_po_files $ref_po_dir $domain \
280     && ls "$ref_po_dir"/*.po 2>/dev/null |
281       sed 's|.*/||; s|\.po$||' > "$po_dir/LINGUAS"
282
283   langs=`cd $ref_po_dir && echo *.po|sed 's/\.po//g'`
284   test "$langs" = '*' && langs=x
285   for po in `cd $ref_po_dir && echo *.po|sed 's/\.po//g'`; do
286     case $po in x) continue;; esac
287     new_po="$ref_po_dir/$po.po"
288     cksum_file="$ref_po_dir/$po.s1"
289     if ! test -f "$cksum_file" ||
290         ! sha1sum -c --status "$cksum_file" < "$new_po" > /dev/null; then
291       echo "updated $po_dir/$po.po..."
292       cp "$new_po" "$po_dir/$po.po" && sha1sum < "$new_po" > "$cksum_file"
293     fi
294   done
295 }
296
297 case $SKIP_PO in
298 '')
299   if test -d po; then
300     update_po_files po $package || exit
301   fi
302
303   if test -d runtime-po; then
304     update_po_files runtime-po $package-runtime || exit
305   fi;;
306 esac
307
308 symlink_to_dir()
309 {
310   src=$1/$2
311   dst=${3-$2}
312
313   test -f "$src" && {
314
315     # If the destination directory doesn't exist, create it.
316     # This is required at least for "lib/uniwidth/cjk.h".
317     dst_dir=`dirname "$dst"`
318     if ! test -d "$dst_dir"; then
319       mkdir -p "$dst_dir"
320
321       # If we've just created a directory like lib/uniwidth,
322       # tell version control system(s) it's ignorable.
323       # FIXME: for now, this does only one level
324       parent=`dirname "$dst_dir"`
325       for dot_ig in x $vc_ignore; do
326         test $dot_ig = x && continue
327         ig=$parent/$dot_ig
328         insert_sorted_if_absent $ig `echo "$dst_dir"|sed 's,.*/,,'`
329       done
330     fi
331
332     if $copy; then
333       {
334         test ! -h "$dst" || {
335           echo "$0: rm -f $dst" &&
336           rm -f "$dst"
337         }
338       } &&
339       test -f "$dst" &&
340       cmp -s "$src" "$dst" || {
341         echo "$0: cp -fp $src $dst" &&
342         cp -fp "$src" "$dst"
343       }
344     else
345       test -h "$dst" &&
346       src_ls=`ls -diL "$src" 2>/dev/null` && set $src_ls && src_i=$1 &&
347       dst_ls=`ls -diL "$dst" 2>/dev/null` && set $dst_ls && dst_i=$1 &&
348       test "$src_i" = "$dst_i" || {
349         dot_dots=
350         case $src in
351         /*) ;;
352         *)
353           case /$dst/ in
354           *//* | */../* | */./* | /*/*/*/*/*/)
355              echo >&2 "$0: invalid symlink calculation: $src -> $dst"
356              exit 1;;
357           /*/*/*/*/)    dot_dots=../../../;;
358           /*/*/*/)      dot_dots=../../;;
359           /*/*/)        dot_dots=../;;
360           esac;;
361         esac
362
363         echo "$0: ln -fs $dot_dots$src $dst" &&
364         ln -fs "$dot_dots$src" "$dst"
365       }
366     fi
367   }
368 }
369
370 cp_mark_as_generated()
371 {
372   cp_src=$1
373   cp_dst=$2
374
375   if cmp -s "$cp_src" "$GNULIB_SRCDIR/$cp_dst"; then
376     symlink_to_dir "$GNULIB_SRCDIR" "$cp_dst"
377   elif cmp -s "$cp_src" "$local_gl_dir/$cp_dst"; then
378     symlink_to_dir $local_gl_dir "$cp_dst"
379   else
380     case $cp_dst in
381       *.[ch])             c1='/* '; c2=' */';;
382       *.texi)             c1='@c '; c2=     ;;
383       *.m4|*/Make*|Make*) c1='# ' ; c2=     ;;
384       *)                  c1=     ; c2=     ;;
385     esac
386
387     if test -z "$c1"; then
388       cmp -s "$cp_src" "$cp_dst" || {
389         echo "$0: cp -f $cp_src $cp_dst" &&
390         rm -f "$cp_dst" &&
391         sed "s!$bt_regex/!!g" "$cp_src" > "$cp_dst"
392       }
393     else
394       # Copy the file first to get proper permissions if it
395       # doesn't already exist.  Then overwrite the copy.
396       cp "$cp_src" "$cp_dst-t" &&
397       (
398         echo "$c1-*- buffer-read-only: t -*- vi: set ro:$c2" &&
399         echo "${c1}DO NOT EDIT! GENERATED AUTOMATICALLY!$c2" &&
400         sed "s!$bt_regex/!!g" "$cp_src"
401       ) > $cp_dst-t &&
402       if cmp -s "$cp_dst-t" "$cp_dst"; then
403         rm -f "$cp_dst-t"
404       else
405         echo "$0: cp $cp_src $cp_dst # with edits" &&
406         mv -f "$cp_dst-t" "$cp_dst"
407       fi
408     fi
409   fi
410 }
411
412 version_controlled_file() {
413   dir=$1
414   file=$2
415   found=no
416   if test -d CVS; then
417     grep -F "/$file/" $dir/CVS/Entries 2>/dev/null |
418              grep '^/[^/]*/[0-9]' > /dev/null && found=yes
419   elif test -d .git; then
420     git-rm -n "$dir/$file" > /dev/null 2>&1 && found=yes
421   else
422     echo "$0: no version control for $dir/$file?" >&2
423   fi
424   test $found = yes
425 }
426
427 slurp() {
428   for dir in . `(cd $1 && find * -type d -print)`; do
429     copied=
430     sep=
431     for file in `ls -a $1/$dir`; do
432       case $file in
433       .|..) continue;;
434       .*) continue;; # FIXME: should all file names starting with "." be ignored?
435       esac
436       test -d $1/$dir/$file && continue
437       for excluded_file in $excluded_files; do
438         test "$dir/$file" = "$excluded_file" && continue 2
439       done
440       if test $file = Makefile.am; then
441         copied=$copied${sep}$gnulib_mk; sep=$nl
442         remove_intl='/^[^#].*\/intl/s/^/#/;'"s!$bt_regex/!!g"
443         sed "$remove_intl" $1/$dir/$file | cmp -s - $dir/$gnulib_mk || {
444           echo "$0: Copying $1/$dir/$file to $dir/$gnulib_mk ..." &&
445           rm -f $dir/$gnulib_mk &&
446           sed "$remove_intl" $1/$dir/$file >$dir/$gnulib_mk
447         }
448       elif { test "${2+set}" = set && test -r $2/$dir/$file; } ||
449            version_controlled_file $dir $file; then
450         echo "$0: $dir/$file overrides $1/$dir/$file"
451       else
452         copied=$copied$sep$file; sep=$nl
453         if test $file = gettext.m4; then
454           echo "$0: patching m4/gettext.m4 to remove need for intl/* ..."
455           rm -f $dir/$file
456           sed '
457             /^AC_DEFUN(\[AM_INTL_SUBDIR],/,/^]/c\
458               AC_DEFUN([AM_INTL_SUBDIR], [
459             /^AC_DEFUN(\[gt_INTL_SUBDIR_CORE],/,/^]/c\
460               AC_DEFUN([gt_INTL_SUBDIR_CORE], [])
461             $a\
462               AC_DEFUN([gl_LOCK_EARLY], [])
463           ' $1/$dir/$file >$dir/$file
464         else
465           cp_mark_as_generated $1/$dir/$file $dir/$file
466         fi
467       fi || exit
468     done
469
470     for dot_ig in x $vc_ignore; do
471       test $dot_ig = x && continue
472       ig=$dir/$dot_ig
473       if test -n "$copied"; then
474         insert_sorted_if_absent $ig "$copied"
475         # If an ignored file name ends with .in.h, then also add
476         # the name with just ".h".  Many gnulib headers are generated,
477         # e.g., stdint.in.h -> stdint.h, dirent.in.h ->..., etc.
478         # Likewise for .gperf -> .h, .y -> .c, and .sin -> .sed
479         f=`echo "$copied"|sed 's/\.in\.h$/.h/;s/\.sin$/.sed/;s/\.y$/.c/;s/\.gperf$/.h/'`
480         insert_sorted_if_absent $ig "$f"
481
482         # For files like sys_stat.in.h and sys_time.in.h, record as
483         # ignorable the directory we might eventually create: sys/.
484         f=`echo "$copied"|sed 's/sys_.*\.in\.h$/sys/'`
485         insert_sorted_if_absent $ig "$f"
486       fi
487     done
488   done
489 }
490
491
492 # Create boot temporary directories to import from gnulib and gettext.
493 rm -fr $bt $bt2 &&
494 mkdir $bt $bt2 || exit
495
496 # Import from gnulib.
497
498 gnulib_tool_options="\
499  --import\
500  --no-changelog\
501  --aux-dir $bt/$build_aux\
502  --doc-base $bt/doc\
503  --lib $gnulib_name\
504  --m4-base $bt/m4/\
505  --source-base $bt/lib/\
506  --tests-base $bt/tests\
507  --local-dir $local_gl_dir\
508 $gnulib_tool_option_extras\
509 "
510 echo "$0: $gnulib_tool $gnulib_tool_options --import ..."
511 $gnulib_tool $gnulib_tool_options --import $gnulib_modules &&
512 slurp $bt || exit
513
514 for file in $gnulib_files; do
515   symlink_to_dir "$GNULIB_SRCDIR" $file || exit
516 done
517
518
519 # Import from gettext.
520 with_gettext=yes
521 grep '^[         ]*AM_GNU_GETTEXT_VERSION(' configure.ac >/dev/null || \
522     with_gettext=no
523
524 if test $with_gettext = yes; then
525   echo "$0: (cd $bt2; autopoint) ..."
526   cp configure.ac $bt2 &&
527   (cd $bt2 && autopoint && rm configure.ac) &&
528   slurp $bt2 $bt || exit
529
530   rm -fr $bt $bt2 || exit
531 fi
532
533 # Coreutils is unusual in that it generates some of its test-related
534 # Makefile.am files.  That must be done before invoking automake.
535 mam_template=tests/Makefile.am.in
536 if test -f $mam_template; then
537   PERL=perl
538   for tool in cut head join pr sort tac tail test tr uniq wc; do
539     m=tests/$tool/Makefile.am
540     t=${m}t
541     rm -f $m $t
542     sed -n '1,/^##test-files-begin/p' $mam_template > $t
543     echo "x = $tool" >> $t
544     srcdir=tests/$tool
545     $PERL -I$srcdir -w -- tests/mk-script $srcdir --list >> $t
546     sed -n '/^##test-files-end/,$p' $mam_template >> $t
547     chmod -w $t
548     mv $t $m
549   done
550 fi
551
552 # Reconfigure, getting other files.
553
554 for command in \
555   libtool \
556   'aclocal --force -I m4' \
557   'autoconf --force' \
558   'autoheader --force' \
559   'automake --add-missing --copy --force-missing';
560 do
561   if test "$command" = libtool; then
562     grep '^[     ]*AM_PROG_LIBTOOL\>' configure.ac >/dev/null ||
563       continue
564     command='libtoolize -c -f'
565   fi
566   echo "$0: $command ..."
567   $command || exit
568 done
569
570
571 # Get some extra files from gnulib, overriding existing files.
572 for file in $gnulib_extra_files; do
573   case $file in
574   */INSTALL) dst=INSTALL;;
575   build-aux/*) dst=$build_aux/`expr "$file" : 'build-aux/\(.*\)'`;;
576   *) dst=$file;;
577   esac
578   symlink_to_dir "$GNULIB_SRCDIR" $file $dst || exit
579 done
580
581 if test $with_gettext = yes; then
582   # Create gettext configuration.
583   echo "$0: Creating po/Makevars from po/Makevars.template ..."
584   rm -f po/Makevars
585   sed '
586     /^EXTRA_LOCALE_CATEGORIES *=/s/=.*/= '"$EXTRA_LOCALE_CATEGORIES"'/
587     /^MSGID_BUGS_ADDRESS *=/s/=.*/= bug-'"$package"'@gnu.org/
588     /^XGETTEXT_OPTIONS *=/{
589       s/$/ \\/
590       a\
591           '"$XGETTEXT_OPTIONS"' $${end_of_xgettext_options+}
592     }
593   ' po/Makevars.template >po/Makevars
594
595   if test -d runtime-po; then
596     # Similarly for runtime-po/Makevars, but not quite the same.
597     rm -f runtime-po/Makevars
598     sed '
599       /^DOMAIN *=.*/s/=.*/= '"$package"'-runtime/
600       /^subdir *=.*/s/=.*/= runtime-po/
601       /^MSGID_BUGS_ADDRESS *=/s/=.*/= bug-'"$package"'@gnu.org/
602       /^XGETTEXT_OPTIONS *=/{
603         s/$/ \\/
604         a\
605             '"$XGETTEXT_OPTIONS_RUNTIME"' $${end_of_xgettext_options+}
606       }
607     ' <po/Makevars.template >runtime-po/Makevars
608
609     # Copy identical files from po to runtime-po.
610     (cd po && cp -p Makefile.in.in *-quot *.header *.sed *.sin ../runtime-po)
611   fi
612 fi
613
614 echo "$0: done.  Now you can run './configure'."