* bootstrap (update_po_files): Work also when there are no .po files in po/.
[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   langs=`cd $ref_po_dir && echo *.po|sed 's/\.po//g'`
285   test "$langs" = '*' && langs=x
286   for po in `cd $ref_po_dir && echo *.po|sed 's/\.po//g'`; do
287     case $po in x) continue;; esac
288     new_po="$ref_po_dir/$po.po"
289     cksum_file="$ref_po_dir/$po.s1"
290     if ! sha1sum -c --status "$cksum_file" < "$new_po" > /dev/null; then
291       echo "updated $po_dir/$po.po..."
292       cp "$new_po" "$po_dir/$po.po" && sha1sum < "$new_po" > "$cksum_file"
293     fi
294   done
295 }
296
297 case $SKIP_PO in
298 '')
299   if test -d po; then
300     update_po_files po $package || exit
301   fi
302
303   if test -d runtime-po; then
304     update_po_files runtime-po $package-runtime || exit
305   fi;;
306 esac
307
308 symlink_to_dir()
309 {
310   src=$1/$2
311   dst=${3-$2}
312
313   test -f "$src" && {
314
315     # If the destination directory doesn't exist, create it.
316     # This is required at least for "lib/uniwidth/cjk.h".
317     dst_dir=`dirname "$dst"`
318     if ! test -d "$dst_dir"; then
319       mkdir -p "$dst_dir"
320
321       # If we've just created a directory like lib/uniwidth,
322       # tell version control system(s) it's ignorable.
323       # FIXME: for now, this does only one level
324       parent=`dirname "$dst_dir"`
325       for dot_ig in x $vc_ignore; do
326         test $dot_ig = x && continue
327         ig=$parent/$dot_ig
328         insert_sorted_if_absent $ig `echo "$dst_dir"|sed 's,.*/,,'`
329       done
330     fi
331
332     if $copy; then
333       {
334         test ! -h "$dst" || {
335           echo "$0: rm -f $dst" &&
336           rm -f "$dst"
337         }
338       } &&
339       test -f "$dst" &&
340       cmp -s "$src" "$dst" || {
341         echo "$0: cp -fp $src $dst" &&
342         cp -fp "$src" "$dst"
343       }
344     else
345       test -h "$dst" &&
346       src_ls=`ls -diL "$src" 2>/dev/null` && set $src_ls && src_i=$1 &&
347       dst_ls=`ls -diL "$dst" 2>/dev/null` && set $dst_ls && dst_i=$1 &&
348       test "$src_i" = "$dst_i" || {
349         dot_dots=
350         case $src in
351         /*) ;;
352         *)
353           case /$dst/ in
354           *//* | */../* | */./* | /*/*/*/*/*/)
355              echo >&2 "$0: invalid symlink calculation: $src -> $dst"
356              exit 1;;
357           /*/*/*/*/)    dot_dots=../../../;;
358           /*/*/*/)      dot_dots=../../;;
359           /*/*/)        dot_dots=../;;
360           esac;;
361         esac
362
363         echo "$0: ln -fs $dot_dots$src $dst" &&
364         ln -fs "$dot_dots$src" "$dst"
365       }
366     fi
367   }
368 }
369
370 cp_mark_as_generated()
371 {
372   cp_src=$1
373   cp_dst=$2
374
375   if cmp -s "$cp_src" "$GNULIB_SRCDIR/$cp_dst"; then
376     symlink_to_dir "$GNULIB_SRCDIR" "$cp_dst"
377   elif cmp -s "$cp_src" "$local_gl_dir/$cp_dst"; then
378     symlink_to_dir $local_gl_dir "$cp_dst"
379   else
380     case $cp_dst in
381       *.[ch])             c1='/* '; c2=' */';;
382       *.texi)             c1='@c '; c2=     ;;
383       *.m4|*/Make*|Make*) c1='# ' ; c2=     ;;
384       *)                  c1=     ; c2=     ;;
385     esac
386
387     if test -z "$c1"; then
388       cmp -s "$cp_src" "$cp_dst" || {
389         echo "$0: cp -f $cp_src $cp_dst" &&
390         rm -f "$cp_dst" &&
391         sed "s!$bt_regex/!!g" "$cp_src" > "$cp_dst"
392       }
393     else
394       # Copy the file first to get proper permissions if it
395       # doesn't already exist.  Then overwrite the copy.
396       cp "$cp_src" "$cp_dst-t" &&
397       (
398         echo "$c1-*- buffer-read-only: t -*- vi: set ro:$c2" &&
399         echo "${c1}DO NOT EDIT! GENERATED AUTOMATICALLY!$c2" &&
400         sed "s!$bt_regex/!!g" "$cp_src"
401       ) > $cp_dst-t &&
402       if cmp -s "$cp_dst-t" "$cp_dst"; then
403         rm -f "$cp_dst-t"
404       else
405         echo "$0: cp $cp_src $cp_dst # with edits" &&
406         mv -f "$cp_dst-t" "$cp_dst"
407       fi
408     fi
409   fi
410 }
411
412 version_controlled_file() {
413   dir=$1
414   file=$2
415   found=no
416   if test -d CVS; then
417     grep -F "/$file/" $dir/CVS/Entries 2>/dev/null |
418              grep '^/[^/]*/[0-9]' > /dev/null && found=yes
419   elif test -d .git; then
420     git-rm -n "$dir/$file" > /dev/null 2>&1 && found=yes
421   else
422     echo "$0: no version control for $dir/$file?" >&2
423   fi
424   test $found = yes
425 }
426
427 slurp() {
428   for dir in . `(cd $1 && find * -type d -print)`; do
429     copied=
430     sep=
431     for file in `ls -a $1/$dir`; do
432       case $file in
433       .|..) continue;;
434       .*) continue;; # FIXME: should all file names starting with "." be ignored?
435       esac
436       test -d $1/$dir/$file && continue
437       for excluded_file in $excluded_files; do
438         test "$dir/$file" = "$excluded_file" && continue 2
439       done
440       if test $file = Makefile.am; then
441         copied=$copied${sep}$gnulib_mk; sep=$nl
442         remove_intl='/^[^#].*\/intl/s/^/#/;'"s!$bt_regex/!!g"
443         sed "$remove_intl" $1/$dir/$file | cmp -s - $dir/$gnulib_mk || {
444           echo "$0: Copying $1/$dir/$file to $dir/$gnulib_mk ..." &&
445           rm -f $dir/$gnulib_mk &&
446           sed "$remove_intl" $1/$dir/$file >$dir/$gnulib_mk
447         }
448       elif { test "${2+set}" = set && test -r $2/$dir/$file; } ||
449            version_controlled_file $dir $file; then
450         echo "$0: $dir/$file overrides $1/$dir/$file"
451       else
452         copied=$copied$sep$file; sep=$nl
453         if test $file = gettext.m4; then
454           echo "$0: patching m4/gettext.m4 to remove need for intl/* ..."
455           rm -f $dir/$file
456           sed '
457             /^AC_DEFUN(\[AM_INTL_SUBDIR],/,/^]/c\
458               AC_DEFUN([AM_INTL_SUBDIR], [
459             /^AC_DEFUN(\[gt_INTL_SUBDIR_CORE],/,/^]/c\
460               AC_DEFUN([gt_INTL_SUBDIR_CORE], [])
461             $a\
462               AC_DEFUN([gl_LOCK_EARLY], [])
463           ' $1/$dir/$file >$dir/$file
464         else
465           cp_mark_as_generated $1/$dir/$file $dir/$file
466         fi
467       fi || exit
468     done
469
470     for dot_ig in x $vc_ignore; do
471       test $dot_ig = x && continue
472       ig=$dir/$dot_ig
473       if test -n "$copied"; then
474         insert_sorted_if_absent $ig "$copied"
475         # If an ignored file name ends with .in.h, then also add
476         # the name with just ".h".  Many gnulib headers are generated,
477         # e.g., stdint.in.h -> stdint.h, dirent.in.h ->..., etc.
478         # Likewise for .gperf -> .h, .y -> .c, and .sin -> .sed
479         f=`echo "$copied"|sed 's/\.in\.h$/.h/;s/\.sin$/.sed/;s/\.y$/.c/;s/\.gperf$/.h/'`
480         insert_sorted_if_absent $ig "$f"
481
482         # For files like sys_stat.in.h and sys_time.in.h, record as
483         # ignorable the directory we might eventually create: sys/.
484         f=`echo "$copied"|sed 's/sys_.*\.in\.h$/sys/'`
485         insert_sorted_if_absent $ig "$f"
486       fi
487     done
488   done
489 }
490
491
492 # Create boot temporary directories to import from gnulib and gettext.
493 rm -fr $bt $bt2 &&
494 mkdir $bt $bt2 || exit
495
496 # Import from gnulib.
497
498 gnulib_tool_options="\
499  --import\
500  --no-changelog\
501  --aux-dir $bt/$build_aux\
502  --doc-base $bt/doc\
503  --lib $gnulib_name\
504  --m4-base $bt/m4/\
505  --source-base $bt/lib/\
506  --tests-base $bt/tests\
507  --local-dir $local_gl_dir\
508 $gnulib_tool_option_extras\
509 "
510 echo "$0: $gnulib_tool $gnulib_tool_options --import ..."
511 $gnulib_tool $gnulib_tool_options --import $gnulib_modules &&
512 slurp $bt || exit
513
514 for file in $gnulib_files; do
515   symlink_to_dir "$GNULIB_SRCDIR" $file || exit
516 done
517
518
519 # Import from gettext.
520 with_gettext=yes
521 grep '^[         ]*AM_GNU_GETTEXT_VERSION(' configure.ac >/dev/null || \
522     with_gettext=no
523
524 if test $with_gettext = yes; then
525   echo "$0: (cd $bt2; autopoint) ..."
526   cp configure.ac $bt2 &&
527   (cd $bt2 && autopoint && rm configure.ac) &&
528   slurp $bt2 $bt || exit
529
530   rm -fr $bt $bt2 || exit
531 fi
532
533 # Coreutils is unusual in that it generates some of its test-related
534 # Makefile.am files.  That must be done before invoking automake.
535 mam_template=tests/Makefile.am.in
536 if test -f $mam_template; then
537   PERL=perl
538   for tool in cut head join pr sort tac tail test tr uniq wc; do
539     m=tests/$tool/Makefile.am
540     t=${m}t
541     rm -f $m $t
542     sed -n '1,/^##test-files-begin/p' $mam_template > $t
543     echo "x = $tool" >> $t
544     srcdir=tests/$tool
545     $PERL -I$srcdir -w -- tests/mk-script $srcdir --list >> $t
546     sed -n '/^##test-files-end/,$p' $mam_template >> $t
547     chmod -w $t
548     mv $t $m
549   done
550 fi
551
552 # Reconfigure, getting other files.
553
554 for command in \
555   libtool \
556   'aclocal --force -I m4' \
557   'autoconf --force' \
558   'autoheader --force' \
559   'automake --add-missing --copy --force-missing';
560 do
561   if test "$command" = libtool; then
562     grep '^[     ]*AM_PROG_LIBTOOL\>' configure.ac >/dev/null ||
563       continue
564     command='libtoolize -c -f'
565   fi
566   echo "$0: $command ..."
567   $command || exit
568 done
569
570
571 # Get some extra files from gnulib, overriding existing files.
572 for file in $gnulib_extra_files; do
573   case $file in
574   */INSTALL) dst=INSTALL;;
575   build-aux/*) dst=$build_aux/`expr "$file" : 'build-aux/\(.*\)'`;;
576   *) dst=$file;;
577   esac
578   symlink_to_dir "$GNULIB_SRCDIR" $file $dst || exit
579 done
580
581 if test $with_gettext = yes; then
582   # Create gettext configuration.
583   echo "$0: Creating po/Makevars from po/Makevars.template ..."
584   rm -f po/Makevars
585   sed '
586     /^EXTRA_LOCALE_CATEGORIES *=/s/=.*/= '"$EXTRA_LOCALE_CATEGORIES"'/
587     /^MSGID_BUGS_ADDRESS *=/s/=.*/= bug-'"$package"'@gnu.org/
588     /^XGETTEXT_OPTIONS *=/{
589       s/$/ \\/
590       a\
591           '"$XGETTEXT_OPTIONS"' $${end_of_xgettext_options+}
592     }
593   ' po/Makevars.template >po/Makevars
594
595   if test -d runtime-po; then
596     # Similarly for runtime-po/Makevars, but not quite the same.
597     rm -f runtime-po/Makevars
598     sed '
599       /^DOMAIN *=.*/s/=.*/= '"$package"'-runtime/
600       /^subdir *=.*/s/=.*/= runtime-po/
601       /^MSGID_BUGS_ADDRESS *=/s/=.*/= bug-'"$package"'@gnu.org/
602       /^XGETTEXT_OPTIONS *=/{
603         s/$/ \\/
604         a\
605             '"$XGETTEXT_OPTIONS_RUNTIME"' $${end_of_xgettext_options+}
606       }
607     ' <po/Makevars.template >runtime-po/Makevars
608
609     # Copy identical files from po to runtime-po.
610     (cd po && cp -p Makefile.in.in *-quot *.header *.sed *.sin ../runtime-po)
611   fi
612 fi
613
614 echo "$0: done.  Now you can run './configure'."