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