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