Merge bootstrap changes from gnulib.
[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 # 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 # Package bug report address for gettext files
125 MSGID_BUGS_ADDRESS=bug-$package@gnu.org
126
127 # Files we don't want to import.
128 excluded_files=
129
130 # File that should exist in the top directory of a checked out hierarchy,
131 # but not in a distribution tarball.
132 checkout_only_file=README-hacking
133
134 # Whether to use copies instead of symlinks.
135 copy=false
136
137 # Set this to '.cvsignore .gitignore' in bootstrap.conf if you want
138 # those files to be generated in directories like lib/, m4/, and po/.
139 # Or set it to 'auto' to make this script select which to use based
140 # on which version control system (if any) is used in the source directory.
141 vc_ignore=auto
142
143 # Override the default configuration, if necessary.
144 test -r bootstrap.conf && . ./bootstrap.conf
145
146 if test "$vc_ignore" = auto; then
147   vc_ignore=
148   test -d .git && vc_ignore=.gitignore
149   test -d CVS && vc_ignore="$vc_ignore .cvsignore"
150 fi
151
152 # Translate configuration into internal form.
153
154 # Parse options.
155
156 for option
157 do
158   case $option in
159   --help)
160     usage
161     exit;;
162   --gnulib-srcdir=*)
163     GNULIB_SRCDIR=`expr "$option" : '--gnulib-srcdir=\(.*\)'`;;
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     trap cleanup_gnulib 1 2 13 15
230
231     git clone --depth 2 git://git.sv.gnu.org/gnulib ||
232       cleanup_gnulib
233
234     trap - 1 2 13 15
235   fi
236   GNULIB_SRCDIR=gnulib
237 esac
238
239 gnulib_tool=$GNULIB_SRCDIR/gnulib-tool
240 <$gnulib_tool || exit
241
242 # Get translations.
243
244 download_po_files() {
245   subdir=$1
246   domain=$2
247   echo "$0: getting translations into $subdir for $domain..."
248   cmd=`printf "$po_download_command_format" "$domain" "$subdir"`
249   eval "$cmd"
250 }
251
252 # Download .po files to $po_dir/.reference and copy only the new
253 # or modified ones into $po_dir.  Also update $po_dir/LINGUAS.
254 update_po_files() {
255   # Directory containing primary .po files.
256   # Overwrite them only when we're sure a .po file is new.
257   po_dir=$1
258   domain=$2
259
260   # Download *.po files into this dir.
261   # Usually contains *.s1 checksum files.
262   ref_po_dir="$po_dir/.reference"
263
264   test -d $ref_po_dir || mkdir $ref_po_dir || return
265   download_po_files $ref_po_dir $domain \
266     && ls "$ref_po_dir"/*.po 2>/dev/null |
267       sed 's|.*/||; s|\.po$||' > "$po_dir/LINGUAS"
268
269   langs=`cd $ref_po_dir && echo *.po|sed 's/\.po//g'`
270   test "$langs" = '*' && langs=x
271   for po in `cd $ref_po_dir && echo *.po|sed 's/\.po//g'`; do
272     case $po in x) continue;; esac
273     new_po="$ref_po_dir/$po.po"
274     cksum_file="$ref_po_dir/$po.s1"
275     if ! test -f "$cksum_file" ||
276         ! test -f "$po_dir/$po.po" ||
277         ! sha1sum -c --status "$cksum_file" < "$new_po" > /dev/null; then
278       echo "updated $po_dir/$po.po..."
279       cp "$new_po" "$po_dir/$po.po" && sha1sum < "$new_po" > "$cksum_file"
280     fi
281   done
282 }
283
284 case $SKIP_PO in
285 '')
286   if test -d po; then
287     update_po_files po $package || exit
288   fi
289
290   if test -d runtime-po; then
291     update_po_files runtime-po $package-runtime || exit
292   fi;;
293 esac
294
295 symlink_to_dir()
296 {
297   src=$1/$2
298   dst=${3-$2}
299
300   test -f "$src" && {
301
302     # If the destination directory doesn't exist, create it.
303     # This is required at least for "lib/uniwidth/cjk.h".
304     dst_dir=`dirname "$dst"`
305     if ! test -d "$dst_dir"; then
306       mkdir -p "$dst_dir"
307
308       # If we've just created a directory like lib/uniwidth,
309       # tell version control system(s) it's ignorable.
310       # FIXME: for now, this does only one level
311       parent=`dirname "$dst_dir"`
312       for dot_ig in x $vc_ignore; do
313         test $dot_ig = x && continue
314         ig=$parent/$dot_ig
315         insert_sorted_if_absent $ig `echo "$dst_dir"|sed 's,.*/,,'`
316       done
317     fi
318
319     if $copy; then
320       {
321         test ! -h "$dst" || {
322           echo "$0: rm -f $dst" &&
323           rm -f "$dst"
324         }
325       } &&
326       test -f "$dst" &&
327       cmp -s "$src" "$dst" || {
328         echo "$0: cp -fp $src $dst" &&
329         cp -fp "$src" "$dst"
330       }
331     else
332       test -h "$dst" &&
333       src_ls=`ls -diL "$src" 2>/dev/null` && set $src_ls && src_i=$1 &&
334       dst_ls=`ls -diL "$dst" 2>/dev/null` && set $dst_ls && dst_i=$1 &&
335       test "$src_i" = "$dst_i" || {
336         dot_dots=
337         case $src in
338         /*) ;;
339         *)
340           case /$dst/ in
341           *//* | */../* | */./* | /*/*/*/*/*/)
342              echo >&2 "$0: invalid symlink calculation: $src -> $dst"
343              exit 1;;
344           /*/*/*/*/)    dot_dots=../../../;;
345           /*/*/*/)      dot_dots=../../;;
346           /*/*/)        dot_dots=../;;
347           esac;;
348         esac
349
350         echo "$0: ln -fs $dot_dots$src $dst" &&
351         ln -fs "$dot_dots$src" "$dst"
352       }
353     fi
354   }
355 }
356
357 cp_mark_as_generated()
358 {
359   cp_src=$1
360   cp_dst=$2
361
362   if cmp -s "$cp_src" "$GNULIB_SRCDIR/$cp_dst"; then
363     symlink_to_dir "$GNULIB_SRCDIR" "$cp_dst"
364   elif cmp -s "$cp_src" "$local_gl_dir/$cp_dst"; then
365     symlink_to_dir $local_gl_dir "$cp_dst"
366   else
367     case $cp_dst in
368       *.[ch])             c1='/* '; c2=' */';;
369       *.texi)             c1='@c '; c2=     ;;
370       *.m4|*/Make*|Make*) c1='# ' ; c2=     ;;
371       *)                  c1=     ; c2=     ;;
372     esac
373
374     # If the destination directory doesn't exist, create it.
375     # This is required at least for "lib/uniwidth/cjk.h".
376     dst_dir=`dirname "$cp_dst"`
377     test -d "$dst_dir" || mkdir -p "$dst_dir"
378
379     if test -z "$c1"; then
380       cmp -s "$cp_src" "$cp_dst" || {
381         echo "$0: cp -f $cp_src $cp_dst" &&
382         rm -f "$cp_dst" &&
383         sed "s!$bt_regex/!!g" "$cp_src" > "$cp_dst"
384       }
385     else
386       # Copy the file first to get proper permissions if it
387       # doesn't already exist.  Then overwrite the copy.
388       cp "$cp_src" "$cp_dst-t" &&
389       (
390         echo "$c1-*- buffer-read-only: t -*- vi: set ro:$c2" &&
391         echo "${c1}DO NOT EDIT! GENERATED AUTOMATICALLY!$c2" &&
392         sed "s!$bt_regex/!!g" "$cp_src"
393       ) > $cp_dst-t &&
394       if cmp -s "$cp_dst-t" "$cp_dst"; then
395         rm -f "$cp_dst-t"
396       else
397         echo "$0: cp $cp_src $cp_dst # with edits" &&
398         mv -f "$cp_dst-t" "$cp_dst"
399       fi
400     fi
401   fi
402 }
403
404 version_controlled_file() {
405   dir=$1
406   file=$2
407   found=no
408   if test -d CVS; then
409     grep -F "/$file/" $dir/CVS/Entries 2>/dev/null |
410              grep '^/[^/]*/[0-9]' > /dev/null && found=yes
411   elif test -d .git; then
412     git rm -n "$dir/$file" > /dev/null 2>&1 && found=yes
413   else
414     echo "$0: no version control for $dir/$file?" >&2
415   fi
416   test $found = yes
417 }
418
419 slurp() {
420   for dir in . `(cd $1 && find * -type d -print)`; do
421     copied=
422     sep=
423     for file in `ls -a $1/$dir`; do
424       case $file in
425       .|..) continue;;
426       .*) continue;; # FIXME: should all file names starting with "." be ignored?
427       esac
428       test -d $1/$dir/$file && continue
429       for excluded_file in $excluded_files; do
430         test "$dir/$file" = "$excluded_file" && continue 2
431       done
432       if test $file = Makefile.am; then
433         copied=$copied${sep}$gnulib_mk; sep=$nl
434         remove_intl='/^[^#].*\/intl/s/^/#/;'"s!$bt_regex/!!g"
435         sed "$remove_intl" $1/$dir/$file | cmp -s - $dir/$gnulib_mk || {
436           echo "$0: Copying $1/$dir/$file to $dir/$gnulib_mk ..." &&
437           rm -f $dir/$gnulib_mk &&
438           sed "$remove_intl" $1/$dir/$file >$dir/$gnulib_mk
439         }
440       elif { test "${2+set}" = set && test -r $2/$dir/$file; } ||
441            version_controlled_file $dir $file; then
442         echo "$0: $dir/$file overrides $1/$dir/$file"
443       else
444         copied=$copied$sep$file; sep=$nl
445         if test $file = gettext.m4; then
446           echo "$0: patching m4/gettext.m4 to remove need for intl/* ..."
447           rm -f $dir/$file
448           sed '
449             /^AC_DEFUN(\[AM_INTL_SUBDIR],/,/^]/c\
450               AC_DEFUN([AM_INTL_SUBDIR], [
451             /^AC_DEFUN(\[gt_INTL_SUBDIR_CORE],/,/^]/c\
452               AC_DEFUN([gt_INTL_SUBDIR_CORE], [])
453             $a\
454               AC_DEFUN([gl_LOCK_EARLY], [])
455           ' $1/$dir/$file >$dir/$file
456         else
457           cp_mark_as_generated $1/$dir/$file $dir/$file
458         fi
459       fi || exit
460     done
461
462     for dot_ig in x $vc_ignore; do
463       test $dot_ig = x && continue
464       ig=$dir/$dot_ig
465       if test -n "$copied"; then
466         insert_sorted_if_absent $ig "$copied"
467         # If an ignored file name ends with .in.h, then also add
468         # the name with just ".h".  Many gnulib headers are generated,
469         # e.g., stdint.in.h -> stdint.h, dirent.in.h ->..., etc.
470         # Likewise for .gperf -> .h, .y -> .c, and .sin -> .sed
471         f=`echo "$copied"|sed 's/\.in\.h$/.h/;s/\.sin$/.sed/;s/\.y$/.c/;s/\.gperf$/.h/'`
472         insert_sorted_if_absent $ig "$f"
473
474         # For files like sys_stat.in.h and sys_time.in.h, record as
475         # ignorable the directory we might eventually create: sys/.
476         f=`echo "$copied"|sed 's/sys_.*\.in\.h$/sys/'`
477         insert_sorted_if_absent $ig "$f"
478       fi
479     done
480   done
481 }
482
483
484 # Create boot temporary directories to import from gnulib and gettext.
485 rm -fr $bt $bt2 &&
486 mkdir $bt $bt2 || exit
487
488 # Import from gnulib.
489
490 gnulib_tool_options="\
491  --import\
492  --no-changelog\
493  --aux-dir $bt/$build_aux\
494  --doc-base $bt/doc\
495  --lib $gnulib_name\
496  --m4-base $bt/m4/\
497  --source-base $bt/lib/\
498  --tests-base $bt/tests\
499  --local-dir $local_gl_dir\
500  $gnulib_tool_option_extras\
501 "
502 echo "$0: $gnulib_tool $gnulib_tool_options --import ..."
503 $gnulib_tool $gnulib_tool_options --import $gnulib_modules &&
504 slurp $bt || exit
505
506 for file in $gnulib_files; do
507   symlink_to_dir "$GNULIB_SRCDIR" $file || exit
508 done
509
510
511 # Import from gettext.
512 with_gettext=yes
513 grep '^[         ]*AM_GNU_GETTEXT_VERSION(' configure.ac >/dev/null || \
514     with_gettext=no
515
516 if test $with_gettext = yes; then
517   echo "$0: (cd $bt2; autopoint) ..."
518   cp configure.ac $bt2 &&
519   (cd $bt2 && autopoint && rm configure.ac) &&
520   slurp $bt2 $bt || exit
521
522   rm -fr $bt $bt2 || exit
523 fi
524
525 # Coreutils is unusual in that it generates some of its test-related
526 # Makefile.am files.  That must be done before invoking automake.
527 mam_template=tests/Makefile.am.in
528 if test -f $mam_template; then
529   PERL=perl
530   for tool in cut head join pr sort tac tail test tr uniq wc; do
531     m=tests/$tool/Makefile.am
532     t=${m}t
533     rm -f $m $t
534     sed -n '1,/^##test-files-begin/p' $mam_template > $t
535     echo "x = $tool" >> $t
536     srcdir=tests/$tool
537     $PERL -I$srcdir -w -- tests/mk-script $srcdir --list >> $t
538     sed -n '/^##test-files-end/,$p' $mam_template >> $t
539     chmod -w $t
540     mv $t $m
541   done
542 fi
543
544 # Remove dangling symlinks in gnulib-populated directories, since
545 # a dangling m4/*.m4 symlink would cause aclocal to fail.
546 # This depends on GNU find, and a relatively recent version at that.
547 # Ignore any failure for now, since it's only to avoid the relatively
548 # unusual case in which a symlinked-to file in gnulib/ or gl/ is removed.
549 find m4 lib build-aux -depth -type l -xtype l -delete > /dev/null 2>&1
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/=.*/= '"$MSGID_BUGS_ADDRESS"'/
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 # Horrible, coreutils-specific kludges.
614 # Change paths in gnulib-tests/gnulib.mk from "../.." to "..".
615 m=gnulib-tests/gnulib.mk
616 sed 's,\.\./\.\.,..,g' $m > $m-t
617 mv -f $m-t $m
618
619 chmod a+x gnulib-tests/test-*.sh
620
621 echo "$0: done.  Now you can run './configure'."