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