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