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