* build-aux/bootstrap: Sync from coreutils:
[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 ! sha1sum -c --status "$cksum_file" < "$new_po" > /dev/null; then
290       echo "updated $po_dir/$po.po..."
291       cp "$new_po" "$po_dir/$po.po" && sha1sum < "$new_po" > "$cksum_file"
292     fi
293   done
294 }
295
296 case $SKIP_PO in
297 '')
298   if test -d po; then
299     update_po_files po $package || exit
300   fi
301
302   if test -d runtime-po; then
303     update_po_files runtime-po $package-runtime || exit
304   fi;;
305 esac
306
307 symlink_to_dir()
308 {
309   src=$1/$2
310   dst=${3-$2}
311
312   test -f "$src" && {
313
314     # If the destination directory doesn't exist, create it.
315     # This is required at least for "lib/uniwidth/cjk.h".
316     dst_dir=`dirname "$dst"`
317     if ! test -d "$dst_dir"; then
318       mkdir -p "$dst_dir"
319
320       # If we've just created a directory like lib/uniwidth,
321       # tell version control system(s) it's ignorable.
322       # FIXME: for now, this does only one level
323       parent=`dirname "$dst_dir"`
324       for dot_ig in x $vc_ignore; do
325         test $dot_ig = x && continue
326         ig=$parent/$dot_ig
327         insert_sorted_if_absent $ig `echo "$dst_dir"|sed 's,.*/,,'`
328       done
329     fi
330
331     if $copy; then
332       {
333         test ! -h "$dst" || {
334           echo "$0: rm -f $dst" &&
335           rm -f "$dst"
336         }
337       } &&
338       test -f "$dst" &&
339       cmp -s "$src" "$dst" || {
340         echo "$0: cp -fp $src $dst" &&
341         cp -fp "$src" "$dst"
342       }
343     else
344       test -h "$dst" &&
345       src_ls=`ls -diL "$src" 2>/dev/null` && set $src_ls && src_i=$1 &&
346       dst_ls=`ls -diL "$dst" 2>/dev/null` && set $dst_ls && dst_i=$1 &&
347       test "$src_i" = "$dst_i" || {
348         dot_dots=
349         case $src in
350         /*) ;;
351         *)
352           case /$dst/ in
353           *//* | */../* | */./* | /*/*/*/*/*/)
354              echo >&2 "$0: invalid symlink calculation: $src -> $dst"
355              exit 1;;
356           /*/*/*/*/)    dot_dots=../../../;;
357           /*/*/*/)      dot_dots=../../;;
358           /*/*/)        dot_dots=../;;
359           esac;;
360         esac
361
362         echo "$0: ln -fs $dot_dots$src $dst" &&
363         ln -fs "$dot_dots$src" "$dst"
364       }
365     fi
366   }
367 }
368
369 cp_mark_as_generated()
370 {
371   cp_src=$1
372   cp_dst=$2
373
374   if cmp -s "$cp_src" "$GNULIB_SRCDIR/$cp_dst"; then
375     symlink_to_dir "$GNULIB_SRCDIR" "$cp_dst"
376   elif cmp -s "$cp_src" "$local_gl_dir/$cp_dst"; then
377     symlink_to_dir $local_gl_dir "$cp_dst"
378   else
379     case $cp_dst in
380       *.[ch])             c1='/* '; c2=' */';;
381       *.texi)             c1='@c '; c2=     ;;
382       *.m4|*/Make*|Make*) c1='# ' ; c2=     ;;
383       *)                  c1=     ; c2=     ;;
384     esac
385
386     if test -z "$c1"; then
387       cmp -s "$cp_src" "$cp_dst" || {
388         echo "$0: cp -f $cp_src $cp_dst" &&
389         rm -f "$cp_dst" &&
390         sed "s!$bt_regex/!!g" "$cp_src" > "$cp_dst"
391       }
392     else
393       # Copy the file first to get proper permissions if it
394       # doesn't already exist.  Then overwrite the copy.
395       cp "$cp_src" "$cp_dst-t" &&
396       (
397         echo "$c1-*- buffer-read-only: t -*- vi: set ro:$c2" &&
398         echo "${c1}DO NOT EDIT! GENERATED AUTOMATICALLY!$c2" &&
399         sed "s!$bt_regex/!!g" "$cp_src"
400       ) > $cp_dst-t &&
401       if cmp -s "$cp_dst-t" "$cp_dst"; then
402         rm -f "$cp_dst-t"
403       else
404         echo "$0: cp $cp_src $cp_dst # with edits" &&
405         mv -f "$cp_dst-t" "$cp_dst"
406       fi
407     fi
408   fi
409 }
410
411 version_controlled_file() {
412   dir=$1
413   file=$2
414   found=no
415   if test -d CVS; then
416     grep -F "/$file/" $dir/CVS/Entries 2>/dev/null |
417              grep '^/[^/]*/[0-9]' > /dev/null && found=yes
418   elif test -d .git; then
419     git-rm -n "$dir/$file" > /dev/null 2>&1 && found=yes
420   else
421     echo "$0: no version control for $dir/$file?" >&2
422   fi
423   test $found = yes
424 }
425
426 slurp() {
427   for dir in . `(cd $1 && find * -type d -print)`; do
428     copied=
429     sep=
430     for file in `ls -a $1/$dir`; do
431       case $file in
432       .|..) continue;;
433       .*) continue;; # FIXME: should all file names starting with "." be ignored?
434       esac
435       test -d $1/$dir/$file && continue
436       for excluded_file in $excluded_files; do
437         test "$dir/$file" = "$excluded_file" && continue 2
438       done
439       if test $file = Makefile.am; then
440         copied=$copied${sep}$gnulib_mk; sep=$nl
441         remove_intl='/^[^#].*\/intl/s/^/#/;'"s!$bt_regex/!!g"
442         sed "$remove_intl" $1/$dir/$file | cmp -s - $dir/$gnulib_mk || {
443           echo "$0: Copying $1/$dir/$file to $dir/$gnulib_mk ..." &&
444           rm -f $dir/$gnulib_mk &&
445           sed "$remove_intl" $1/$dir/$file >$dir/$gnulib_mk
446         }
447       elif { test "${2+set}" = set && test -r $2/$dir/$file; } ||
448            version_controlled_file $dir $file; then
449         echo "$0: $dir/$file overrides $1/$dir/$file"
450       else
451         copied=$copied$sep$file; sep=$nl
452         if test $file = gettext.m4; then
453           echo "$0: patching m4/gettext.m4 to remove need for intl/* ..."
454           rm -f $dir/$file
455           sed '
456             /^AC_DEFUN(\[AM_INTL_SUBDIR],/,/^]/c\
457               AC_DEFUN([AM_INTL_SUBDIR], [
458             /^AC_DEFUN(\[gt_INTL_SUBDIR_CORE],/,/^]/c\
459               AC_DEFUN([gt_INTL_SUBDIR_CORE], [])
460             $a\
461               AC_DEFUN([gl_LOCK_EARLY], [])
462           ' $1/$dir/$file >$dir/$file
463         else
464           cp_mark_as_generated $1/$dir/$file $dir/$file
465         fi
466       fi || exit
467     done
468
469     for dot_ig in x $vc_ignore; do
470       test $dot_ig = x && continue
471       ig=$dir/$dot_ig
472       if test -n "$copied"; then
473         insert_sorted_if_absent $ig "$copied"
474         # If an ignored file name ends with .in.h, then also add
475         # the name with just ".h".  Many gnulib headers are generated,
476         # e.g., stdint.in.h -> stdint.h, dirent.in.h ->..., etc.
477         # Likewise for .gperf -> .h, .y -> .c, and .sin -> .sed
478         f=`echo "$copied"|sed 's/\.in\.h$/.h/;s/\.sin$/.sed/;s/\.y$/.c/;s/\.gperf$/.h/'`
479         insert_sorted_if_absent $ig "$f"
480
481         # For files like sys_stat.in.h and sys_time.in.h, record as
482         # ignorable the directory we might eventually create: sys/.
483         f=`echo "$copied"|sed 's/sys_.*\.in\.h$/sys/'`
484         insert_sorted_if_absent $ig "$f"
485       fi
486     done
487   done
488 }
489
490
491 # Create boot temporary directories to import from gnulib and gettext.
492 rm -fr $bt $bt2 &&
493 mkdir $bt $bt2 || exit
494
495 # Import from gnulib.
496
497 gnulib_tool_options="\
498  --import\
499  --no-changelog\
500  --aux-dir $bt/$build_aux\
501  --doc-base $bt/doc\
502  --lib $gnulib_name\
503  --m4-base $bt/m4/\
504  --source-base $bt/lib/\
505  --tests-base $bt/tests\
506  --local-dir $local_gl_dir\
507 $gnulib_tool_option_extras\
508 "
509 echo "$0: $gnulib_tool $gnulib_tool_options --import ..."
510 $gnulib_tool $gnulib_tool_options --import $gnulib_modules &&
511 slurp $bt || exit
512
513 for file in $gnulib_files; do
514   symlink_to_dir "$GNULIB_SRCDIR" $file || exit
515 done
516
517
518 # Import from gettext.
519 with_gettext=yes
520 grep '^[         ]*AM_GNU_GETTEXT_VERSION(' configure.ac >/dev/null || \
521     with_gettext=no
522
523 if test $with_gettext = yes; then
524   echo "$0: (cd $bt2; autopoint) ..."
525   cp configure.ac $bt2 &&
526   (cd $bt2 && autopoint && rm configure.ac) &&
527   slurp $bt2 $bt || exit
528
529   rm -fr $bt $bt2 || exit
530 fi
531
532 # Coreutils is unusual in that it generates some of its test-related
533 # Makefile.am files.  That must be done before invoking automake.
534 mam_template=tests/Makefile.am.in
535 if test -f $mam_template; then
536   PERL=perl
537   for tool in cut head join pr sort tac tail test tr uniq wc; do
538     m=tests/$tool/Makefile.am
539     t=${m}t
540     rm -f $m $t
541     sed -n '1,/^##test-files-begin/p' $mam_template > $t
542     echo "x = $tool" >> $t
543     srcdir=tests/$tool
544     $PERL -I$srcdir -w -- tests/mk-script $srcdir --list >> $t
545     sed -n '/^##test-files-end/,$p' $mam_template >> $t
546     chmod -w $t
547     mv $t $m
548   done
549 fi
550
551 # Reconfigure, getting other files.
552
553 for command in \
554   libtool \
555   'aclocal --force -I m4' \
556   'autoconf --force' \
557   'autoheader --force' \
558   'automake --add-missing --copy --force-missing';
559 do
560   if test "$command" = libtool; then
561     grep '^[     ]*AM_PROG_LIBTOOL\>' configure.ac >/dev/null ||
562       continue
563     command='libtoolize -c -f'
564   fi
565   echo "$0: $command ..."
566   $command || exit
567 done
568
569
570 # Get some extra files from gnulib, overriding existing files.
571 for file in $gnulib_extra_files; do
572   case $file in
573   */INSTALL) dst=INSTALL;;
574   build-aux/*) dst=$build_aux/`expr "$file" : 'build-aux/\(.*\)'`;;
575   *) dst=$file;;
576   esac
577   symlink_to_dir "$GNULIB_SRCDIR" $file $dst || exit
578 done
579
580 if test $with_gettext = yes; then
581   # Create gettext configuration.
582   echo "$0: Creating po/Makevars from po/Makevars.template ..."
583   rm -f po/Makevars
584   sed '
585     /^EXTRA_LOCALE_CATEGORIES *=/s/=.*/= '"$EXTRA_LOCALE_CATEGORIES"'/
586     /^MSGID_BUGS_ADDRESS *=/s/=.*/= bug-'"$package"'@gnu.org/
587     /^XGETTEXT_OPTIONS *=/{
588       s/$/ \\/
589       a\
590           '"$XGETTEXT_OPTIONS"' $${end_of_xgettext_options+}
591     }
592   ' po/Makevars.template >po/Makevars
593
594   if test -d runtime-po; then
595     # Similarly for runtime-po/Makevars, but not quite the same.
596     rm -f runtime-po/Makevars
597     sed '
598       /^DOMAIN *=.*/s/=.*/= '"$package"'-runtime/
599       /^subdir *=.*/s/=.*/= runtime-po/
600       /^MSGID_BUGS_ADDRESS *=/s/=.*/= bug-'"$package"'@gnu.org/
601       /^XGETTEXT_OPTIONS *=/{
602         s/$/ \\/
603         a\
604             '"$XGETTEXT_OPTIONS_RUNTIME"' $${end_of_xgettext_options+}
605       }
606     ' <po/Makevars.template >runtime-po/Makevars
607
608     # Copy identical files from po to runtime-po.
609     (cd po && cp -p Makefile.in.in *-quot *.header *.sed *.sin ../runtime-po)
610   fi
611 fi
612
613 echo "$0: done.  Now you can run './configure'."