tests: move input-tty into a test-lib.sh function
[platform/upstream/coreutils.git] / bootstrap
1 #! /bin/sh
2
3 # Bootstrap this package from checked-out sources.
4
5 # Copyright (C) 2003-2008 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 source_base=lib
100 m4_base=m4
101 doc_base=doc
102 tests_base=tests
103
104 # Extra files from gnulib, which override files from other sources.
105 gnulib_extra_files="
106         $build_aux/install-sh
107         $build_aux/missing
108         $build_aux/mdate-sh
109         $build_aux/texinfo.tex
110         $build_aux/depcomp
111         $build_aux/config.guess
112         $build_aux/config.sub
113         doc/INSTALL
114 "
115
116 # Additional gnulib-tool options to use.  Use "\newline" to break lines.
117 gnulib_tool_option_extras=
118
119 # Other locale categories that need message catalogs.
120 EXTRA_LOCALE_CATEGORIES=
121
122 # Additional xgettext options to use.  Use "\\\newline" to break lines.
123 XGETTEXT_OPTIONS='\\\
124  --flag=_:1:pass-c-format\\\
125  --flag=N_:1:pass-c-format\\\
126  --flag=error:3:c-format --flag=error_at_line:5:c-format\\\
127 '
128
129 # Package bug report address for gettext files
130 MSGID_BUGS_ADDRESS=bug-$package@gnu.org
131
132 # Files we don't want to import.
133 excluded_files=
134
135 # File that should exist in the top directory of a checked out hierarchy,
136 # but not in a distribution tarball.
137 checkout_only_file=README-hacking
138
139 # Whether to use copies instead of symlinks.
140 copy=false
141
142 # Set this to '.cvsignore .gitignore' in bootstrap.conf if you want
143 # those files to be generated in directories like lib/, m4/, and po/.
144 # Or set it to 'auto' to make this script select which to use based
145 # on which version control system (if any) is used in the source directory.
146 vc_ignore=auto
147
148 # Override the default configuration, if necessary.
149 test -r bootstrap.conf && . ./bootstrap.conf
150
151 if test "$vc_ignore" = auto; then
152   vc_ignore=
153   test -d .git && vc_ignore=.gitignore
154   test -d CVS && vc_ignore="$vc_ignore .cvsignore"
155 fi
156
157 # Translate configuration into internal form.
158
159 # Parse options.
160
161 for option
162 do
163   case $option in
164   --help)
165     usage
166     exit;;
167   --gnulib-srcdir=*)
168     GNULIB_SRCDIR=`expr "X$option" : 'X--gnulib-srcdir=\(.*\)'`;;
169   --skip-po)
170     SKIP_PO=t;;
171   --force)
172     checkout_only_file=;;
173   --copy)
174     copy=true;;
175   *)
176     echo >&2 "$0: $option: unknown option"
177     exit 1;;
178   esac
179 done
180
181 if test -n "$checkout_only_file" && test ! -r "$checkout_only_file"; then
182   echo "$0: Bootstrapping from a non-checked-out distribution is risky." >&2
183   exit 1
184 fi
185
186 # If $STR is not already on a line by itself in $FILE, insert it,
187 # sorting the new contents of the file and replacing $FILE with the result.
188 insert_sorted_if_absent() {
189   file=$1
190   str=$2
191   test -f $file || touch $file
192   echo "$str" | sort -u - $file | cmp -s - $file \
193     || echo "$str" | sort -u - $file -o $file \
194     || exit 1
195 }
196
197 # Die if there is no AC_CONFIG_AUX_DIR($build_aux) line in configure.ac.
198 found_aux_dir=no
199 grep '^[         ]*AC_CONFIG_AUX_DIR(\['"$build_aux"'\])' configure.ac \
200     >/dev/null && found_aux_dir=yes
201 grep '^[         ]*AC_CONFIG_AUX_DIR('"$build_aux"')' configure.ac \
202     >/dev/null && found_aux_dir=yes
203 if test $found_aux_dir = no; then
204   echo "$0: expected line not found in configure.ac. Add the following:" >&2
205   echo "  AC_CONFIG_AUX_DIR([$build_aux])" >&2
206   exit 1
207 fi
208
209 # If $build_aux doesn't exist, create it now, otherwise some bits
210 # below will malfunction.  If creating it, also mark it as ignored.
211 if test ! -d $build_aux; then
212   mkdir $build_aux
213   for dot_ig in x $vc_ignore; do
214     test $dot_ig = x && continue
215     insert_sorted_if_absent $dot_ig $build_aux
216   done
217 fi
218
219 echo "$0: Bootstrapping from checked-out $package sources..."
220
221 cleanup_gnulib() {
222   status=$?
223   rm -fr gnulib
224   exit $status
225 }
226
227 # Get gnulib files.
228
229 case ${GNULIB_SRCDIR--} in
230 -)
231   if [ ! -d gnulib ]; then
232     echo "$0: getting gnulib files..."
233
234     trap cleanup_gnulib 1 2 13 15
235
236     git clone --depth 2 git://git.sv.gnu.org/gnulib ||
237       cleanup_gnulib
238
239     trap - 1 2 13 15
240   fi
241   GNULIB_SRCDIR=gnulib
242 esac
243
244 gnulib_tool=$GNULIB_SRCDIR/gnulib-tool
245 <$gnulib_tool || exit
246
247 # Get translations.
248
249 download_po_files() {
250   subdir=$1
251   domain=$2
252   echo "$0: getting translations into $subdir for $domain..."
253   cmd=`printf "$po_download_command_format" "$domain" "$subdir"`
254   eval "$cmd"
255 }
256
257 # Download .po files to $po_dir/.reference and copy only the new
258 # or modified ones into $po_dir.  Also update $po_dir/LINGUAS.
259 update_po_files() {
260   # Directory containing primary .po files.
261   # Overwrite them only when we're sure a .po file is new.
262   po_dir=$1
263   domain=$2
264
265   # Download *.po files into this dir.
266   # Usually contains *.s1 checksum files.
267   ref_po_dir="$po_dir/.reference"
268
269   test -d $ref_po_dir || mkdir $ref_po_dir || return
270   download_po_files $ref_po_dir $domain \
271     && ls "$ref_po_dir"/*.po 2>/dev/null |
272       sed 's|.*/||; s|\.po$||' > "$po_dir/LINGUAS"
273
274   langs=`cd $ref_po_dir && echo *.po|sed 's/\.po//g'`
275   test "$langs" = '*' && langs=x
276   for po in $langs; do
277     case $po in x) continue;; esac
278     new_po="$ref_po_dir/$po.po"
279     cksum_file="$ref_po_dir/$po.s1"
280     if ! test -f "$cksum_file" ||
281         ! test -f "$po_dir/$po.po" ||
282         ! sha1sum -c --status "$cksum_file" < "$new_po" > /dev/null; then
283       echo "updated $po_dir/$po.po..."
284       cp "$new_po" "$po_dir/$po.po" && sha1sum < "$new_po" > "$cksum_file"
285     fi
286   done
287 }
288
289 case $SKIP_PO in
290 '')
291   if test -d po; then
292     update_po_files po $package || exit
293   fi
294
295   if test -d runtime-po; then
296     update_po_files runtime-po $package-runtime || exit
297   fi;;
298 esac
299
300 symlink_to_dir()
301 {
302   src=$1/$2
303   dst=${3-$2}
304
305   test -f "$src" && {
306
307     # If the destination directory doesn't exist, create it.
308     # This is required at least for "lib/uniwidth/cjk.h".
309     dst_dir=`dirname "$dst"`
310     if ! test -d "$dst_dir"; then
311       mkdir -p "$dst_dir"
312
313       # If we've just created a directory like lib/uniwidth,
314       # tell version control system(s) it's ignorable.
315       # FIXME: for now, this does only one level
316       parent=`dirname "$dst_dir"`
317       for dot_ig in x $vc_ignore; do
318         test $dot_ig = x && continue
319         ig=$parent/$dot_ig
320         insert_sorted_if_absent $ig `echo "$dst_dir"|sed 's,.*/,,'`
321       done
322     fi
323
324     if $copy; then
325       {
326         test ! -h "$dst" || {
327           echo "$0: rm -f $dst" &&
328           rm -f "$dst"
329         }
330       } &&
331       test -f "$dst" &&
332       cmp -s "$src" "$dst" || {
333         echo "$0: cp -fp $src $dst" &&
334         cp -fp "$src" "$dst"
335       }
336     else
337       test -h "$dst" &&
338       src_ls=`ls -diL "$src" 2>/dev/null` && set $src_ls && src_i=$1 &&
339       dst_ls=`ls -diL "$dst" 2>/dev/null` && set $dst_ls && dst_i=$1 &&
340       test "$src_i" = "$dst_i" || {
341         dot_dots=
342         case $src in
343         /*) ;;
344         *)
345           case /$dst/ in
346           *//* | */../* | */./* | /*/*/*/*/*/)
347              echo >&2 "$0: invalid symlink calculation: $src -> $dst"
348              exit 1;;
349           /*/*/*/*/)    dot_dots=../../../;;
350           /*/*/*/)      dot_dots=../../;;
351           /*/*/)        dot_dots=../;;
352           esac;;
353         esac
354
355         echo "$0: ln -fs $dot_dots$src $dst" &&
356         ln -fs "$dot_dots$src" "$dst"
357       }
358     fi
359   }
360 }
361
362 cp_mark_as_generated()
363 {
364   cp_src=$1
365   cp_dst=$2
366
367   if cmp -s "$cp_src" "$GNULIB_SRCDIR/$cp_dst"; then
368     symlink_to_dir "$GNULIB_SRCDIR" "$cp_dst"
369   elif cmp -s "$cp_src" "$local_gl_dir/$cp_dst"; then
370     symlink_to_dir $local_gl_dir "$cp_dst"
371   else
372     case $cp_dst in
373       *.[ch])             c1='/* '; c2=' */';;
374       *.texi)             c1='@c '; c2=     ;;
375       *.m4|*/Make*|Make*) c1='# ' ; c2=     ;;
376       *)                  c1=     ; c2=     ;;
377     esac
378
379     # If the destination directory doesn't exist, create it.
380     # This is required at least for "lib/uniwidth/cjk.h".
381     dst_dir=`dirname "$cp_dst"`
382     test -d "$dst_dir" || mkdir -p "$dst_dir"
383
384     if test -z "$c1"; then
385       cmp -s "$cp_src" "$cp_dst" || {
386         # Copy the file first to get proper permissions if it
387         # doesn't already exist.  Then overwrite the copy.
388         echo "$0: cp -f $cp_src $cp_dst" &&
389         rm -f "$cp_dst" &&
390         cp "$cp_src" "$cp_dst-t" &&
391         sed "s!$bt_regex/!!g" "$cp_src" > "$cp_dst-t" &&
392         mv -f "$cp_dst-t" "$cp_dst"
393       }
394     else
395       # Copy the file first to get proper permissions if it
396       # doesn't already exist.  Then overwrite the copy.
397       cp "$cp_src" "$cp_dst-t" &&
398       (
399         echo "$c1-*- buffer-read-only: t -*- vi: set ro:$c2" &&
400         echo "${c1}DO NOT EDIT! GENERATED AUTOMATICALLY!$c2" &&
401         echo '#line 1' &&
402         sed "s!$bt_regex/!!g" "$cp_src"
403       ) > $cp_dst-t &&
404       if cmp -s "$cp_dst-t" "$cp_dst"; then
405         rm -f "$cp_dst-t"
406       else
407         echo "$0: cp $cp_src $cp_dst # with edits" &&
408         mv -f "$cp_dst-t" "$cp_dst"
409       fi
410     fi
411   fi
412 }
413
414 version_controlled_file() {
415   dir=$1
416   file=$2
417   found=no
418   if test -d CVS; then
419     grep -F "/$file/" $dir/CVS/Entries 2>/dev/null |
420              grep '^/[^/]*/[0-9]' > /dev/null && found=yes
421   elif test -d .git; then
422     git rm -n "$dir/$file" > /dev/null 2>&1 && found=yes
423   elif test -d .svn; then
424     svn log -r HEAD "$dir/$file" > /dev/null 2>&1 && found=yes
425   else
426     echo "$0: no version control for $dir/$file?" >&2
427   fi
428   test $found = yes
429 }
430
431 slurp() {
432   for dir in . `(cd $1 && find * -type d -print)`; do
433     copied=
434     sep=
435     for file in `ls -a $1/$dir`; do
436       case $file in
437       .|..) continue;;
438       .*) continue;; # FIXME: should all file names starting with "." be ignored?
439       esac
440       test -d $1/$dir/$file && continue
441       for excluded_file in $excluded_files; do
442         test "$dir/$file" = "$excluded_file" && continue 2
443       done
444       if test $file = Makefile.am; then
445         copied=$copied${sep}$gnulib_mk; sep=$nl
446         remove_intl='/^[^#].*\/intl/s/^/#/;'"s!$bt_regex/!!g"
447         sed "$remove_intl" $1/$dir/$file | cmp -s - $dir/$gnulib_mk || {
448           echo "$0: Copying $1/$dir/$file to $dir/$gnulib_mk ..." &&
449           rm -f $dir/$gnulib_mk &&
450           sed "$remove_intl" $1/$dir/$file >$dir/$gnulib_mk
451         }
452       elif { test "${2+set}" = set && test -r $2/$dir/$file; } ||
453            version_controlled_file $dir $file; then
454         echo "$0: $dir/$file overrides $1/$dir/$file"
455       else
456         copied=$copied$sep$file; sep=$nl
457         if test $file = gettext.m4; then
458           echo "$0: patching m4/gettext.m4 to remove need for intl/* ..."
459           rm -f $dir/$file
460           sed '
461             /^AC_DEFUN(\[AM_INTL_SUBDIR],/,/^]/c\
462               AC_DEFUN([AM_INTL_SUBDIR], [
463             /^AC_DEFUN(\[gt_INTL_SUBDIR_CORE],/,/^]/c\
464               AC_DEFUN([gt_INTL_SUBDIR_CORE], [])
465             $a\
466               AC_DEFUN([gl_LOCK_EARLY], [])
467           ' $1/$dir/$file >$dir/$file
468         else
469           cp_mark_as_generated $1/$dir/$file $dir/$file
470         fi
471       fi || exit
472     done
473
474     for dot_ig in x $vc_ignore; do
475       test $dot_ig = x && continue
476       ig=$dir/$dot_ig
477       if test -n "$copied"; then
478         insert_sorted_if_absent $ig "$copied"
479         # If an ignored file name ends with .in.h, then also add
480         # the name with just ".h".  Many gnulib headers are generated,
481         # e.g., stdint.in.h -> stdint.h, dirent.in.h ->..., etc.
482         # Likewise for .gperf -> .h, .y -> .c, and .sin -> .sed
483         f=`echo "$copied"|sed 's/\.in\.h$/.h/;s/\.sin$/.sed/;s/\.y$/.c/;s/\.gperf$/.h/'`
484         insert_sorted_if_absent $ig "$f"
485
486         # For files like sys_stat.in.h and sys_time.in.h, record as
487         # ignorable the directory we might eventually create: sys/.
488         f=`echo "$copied"|sed 's/sys_.*\.in\.h$/sys/'`
489         insert_sorted_if_absent $ig "$f"
490       fi
491     done
492   done
493 }
494
495
496 # Create boot temporary directories to import from gnulib and gettext.
497 rm -fr $bt $bt2 &&
498 mkdir $bt $bt2 || exit
499
500 # Import from gnulib.
501
502 gnulib_tool_options="\
503  --import\
504  --no-changelog\
505  --aux-dir $bt/$build_aux\
506  --doc-base $bt/$doc_base\
507  --lib $gnulib_name\
508  --m4-base $bt/$m4_base/\
509  --source-base $bt/$source_base/\
510  --tests-base $bt/$tests_base\
511  --local-dir $local_gl_dir\
512  $gnulib_tool_option_extras\
513 "
514 echo "$0: $gnulib_tool $gnulib_tool_options --import ..."
515 $gnulib_tool $gnulib_tool_options --import $gnulib_modules &&
516 slurp $bt || exit
517
518 for file in $gnulib_files; do
519   symlink_to_dir "$GNULIB_SRCDIR" $file || exit
520 done
521
522
523 # Import from gettext.
524 with_gettext=yes
525 grep '^[         ]*AM_GNU_GETTEXT_VERSION(' configure.ac >/dev/null || \
526     with_gettext=no
527
528 if test $with_gettext = yes; then
529   echo "$0: (cd $bt2; autopoint) ..."
530   cp configure.ac $bt2 &&
531   (cd $bt2 && autopoint && rm configure.ac) &&
532   slurp $bt2 $bt || exit
533 fi
534 rm -fr $bt $bt2 || exit
535
536 # Remove any dangling symlink matching "*.m4" or "*.[ch]" in some
537 # gnulib-populated directories.  Such .m4 files would cause aclocal to fail.
538 # The following requires GNU find 4.2.3 or newer.  Considering the usual
539 # portability constraints of this script, that may seem a very demanding
540 # requirement, but it should be ok.  Ignore any failure, which is fine,
541 # since this is only a convenience to help developers avoid the relatively
542 # unusual case in which a symlinked-to .m4 file is git-removed from gnulib
543 # between successive runs of this script.
544 find "$m4_base" "$source_base" \
545   -depth \( -name '*.m4' -o -name '*.[ch]' \) \
546   -type l -xtype l -delete > /dev/null 2>&1
547
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/=.*/= '"$MSGID_BUGS_ADDRESS"'/
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 # Horrible, coreutils-specific kludges.
612 # Change paths in gnulib-tests/gnulib.mk from "../.." to "..".
613 m=gnulib-tests/gnulib.mk
614 sed 's,\.\./\.\.,..,g' $m > $m-t
615 mv -f $m-t $m
616
617 echo "$0: done.  Now you can run './configure'."