* README: Append ".git" to git and cg examples.
[gnulib.git] / build-aux / 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  --cvs-user=USERNAME      Set the username to use when checking out
52                           sources from the gnulib repository.
53
54 If the file bootstrap.conf exists in the current working directory, its
55 contents are read as shell variables to configure the bootstrap.
56
57 Running without arguments will suffice in most cases.
58 "
59 }
60
61 # Configuration.
62
63 # Name of the Makefile.am
64 gnulib_mk=gnulib.mk
65
66 # List of gnulib modules needed.
67 gnulib_modules=
68
69 # Any gnulib files needed that are not in modules.
70 gnulib_files=
71
72 # The command to download all .po files for a specified domain into
73 # a specified directory.  Fill in the first %s is the domain name, and
74 # the second with the destination directory.  Use rsync's -L and -r
75 # options because the latest/%s directory and the .po files within are
76 # all symlinks.
77 po_download_command_format=\
78 "rsync -Lrtvz 'translationproject.org::tp/latest/%s/' '%s'"
79
80 extract_package_name='
81   /^AC_INIT(/{
82      /.*,.*,.*,/{
83        s///
84        s/[][]//g
85        p
86        q
87      }
88      s/AC_INIT(\[*//
89      s/]*,.*//
90      s/^GNU //
91      y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
92      s/[^A-Za-z0-9_]/-/g
93      p
94   }
95 '
96 package=`sed -n "$extract_package_name" configure.ac` || exit
97 gnulib_name=lib$package
98
99 build_aux=build-aux
100 # Extra files from gnulib, which override files from other sources.
101 gnulib_extra_files="
102         $build_aux/install-sh
103         $build_aux/missing
104         $build_aux/mdate-sh
105         $build_aux/texinfo.tex
106         $build_aux/depcomp
107         $build_aux/config.guess
108         $build_aux/config.sub
109         doc/INSTALL
110 "
111
112 # Additional gnulib-tool options to use.  Use "\newline" to break lines.
113 gnulib_tool_option_extras=
114
115 # Other locale categories that need message catalogs.
116 EXTRA_LOCALE_CATEGORIES=
117
118 # Additional xgettext options to use.  Use "\\\newline" to break lines.
119 XGETTEXT_OPTIONS='\\\
120  --flag=_:1:pass-c-format\\\
121  --flag=N_:1:pass-c-format\\\
122  --flag=error:3:c-format --flag=error_at_line:5:c-format\\\
123 '
124
125 # Files we don't want to import.
126 excluded_files=
127
128 # File that should exist in the top directory of a checked out hierarchy,
129 # but not in a distribution tarball.
130 checkout_only_file=README-hacking
131
132 # Whether to use copies instead of symlinks.
133 copy=false
134
135 # Set this to '.cvsignore .gitignore' in bootstrap.conf if you want
136 # those files to be generated in directories like lib/, m4/, and po/.
137 # Or set it to 'auto' to make this script select which to use based
138 # on which version control system (if any) is used in the source directory.
139 vc_ignore=auto
140
141 # Override the default configuration, if necessary.
142 test -r bootstrap.conf && . ./bootstrap.conf
143
144 if test "$vc_ignore" = auto; then
145   vc_ignore=
146   test -d .git && vc_ignore=.gitignore
147   test -d CVS && vc_ignore="$vc_ignore .cvsignore"
148 fi
149
150 # Translate configuration into internal form.
151
152 # Parse options.
153
154 for option
155 do
156   case $option in
157   --help)
158     usage
159     exit;;
160   --gnulib-srcdir=*)
161     GNULIB_SRCDIR=`expr "$option" : '--gnulib-srcdir=\(.*\)'`;;
162   --cvs-user=*)
163     CVS_USER=`expr "$option" : '--cvs-user=\(.*\)'`;;
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     case ${CVS_AUTH-pserver} in
230     pserver)
231       CVS_PREFIX=':pserver:anonymous@';;
232     ssh)
233       CVS_PREFIX="$CVS_USER${CVS_USER+@}";;
234     *)
235       echo "$0: $CVS_AUTH: Unknown CVS access method" >&2
236       exit 1;;
237     esac
238
239     case $CVS_RSH in
240     '') CVS_RSH=ssh; export CVS_RSH;;
241     esac
242
243     trap cleanup_gnulib 1 2 13 15
244
245     cvs -z3 -q -d ${CVS_PREFIX}cvs.savannah.gnu.org:/cvsroot/gnulib co gnulib ||
246       cleanup_gnulib
247
248     trap - 1 2 13 15
249   fi
250   GNULIB_SRCDIR=gnulib
251 esac
252
253 gnulib_tool=$GNULIB_SRCDIR/gnulib-tool
254 <$gnulib_tool || exit
255
256 # Get translations.
257
258 download_po_files() {
259   subdir=$1
260   domain=$2
261   echo "$0: getting translations into $subdir for $domain..."
262   cmd=`printf "$po_download_command_format" "$domain" "$subdir"`
263   eval "$cmd"
264 }
265
266 # Download .po files to $po_dir/.reference and copy only the new
267 # or modified ones into $po_dir.  Also update $po_dir/LINGUAS.
268 update_po_files() {
269   # Directory containing primary .po files.
270   # Overwrite them only when we're sure a .po file is new.
271   po_dir=$1
272   domain=$2
273
274   # Download *.po files into this dir.
275   # Usually contains *.s1 checksum files.
276   ref_po_dir="$po_dir/.reference"
277
278   test -d $ref_po_dir || mkdir $ref_po_dir || return
279   download_po_files $ref_po_dir $domain \
280     && ls "$ref_po_dir"/*.po 2>/dev/null |
281       sed 's|.*/||; s|\.po$||' > "$po_dir/LINGUAS"
282
283   for po in `cd $ref_po_dir && echo *.po|sed 's/\.po//g'`; do
284      new_po="$ref_po_dir/$po.po"
285      cksum_file="$ref_po_dir/$po.s1"
286      if ! sha1sum -c --status "$cksum_file" < "$new_po" > /dev/null; then
287        echo "updated $po_dir/$po.po..."
288        cp "$new_po" "$po_dir/$po.po" && sha1sum < "$new_po" > "$cksum_file"
289      fi
290   done
291 }
292
293 case $SKIP_PO in
294 '')
295   if test -d po; then
296     update_po_files po $package || exit
297   fi
298
299   if test -d runtime-po; then
300     update_po_files runtime-po $package-runtime || exit
301   fi;;
302 esac
303
304 symlink_to_dir()
305 {
306   src=$1/$2
307   dst=${3-$2}
308
309   test -f "$src" && {
310
311     # If the destination directory doesn't exist, create it.
312     # This is required at least for "lib/uniwidth/cjk.h".
313     dst_dir=`dirname "$dst"`
314     if ! test -d "$dst_dir"; then
315       mkdir -p "$dst_dir"
316
317       # If we've just created a directory like lib/uniwidth,
318       # tell version control system(s) it's ignorable.
319       # FIXME: for now, this does only one level
320       parent=`dirname "$dst_dir"`
321       for dot_ig in x $vc_ignore; do
322         test $dot_ig = x && continue
323         ig=$parent/$dot_ig
324         insert_sorted_if_absent $ig `echo "$dst_dir"|sed 's,.*/,,'`
325       done
326     fi
327
328     if $copy; then
329       {
330         test ! -h "$dst" || {
331           echo "$0: rm -f $dst" &&
332           rm -f "$dst"
333         }
334       } &&
335       test -f "$dst" &&
336       cmp -s "$src" "$dst" || {
337         echo "$0: cp -fp $src $dst" &&
338         cp -fp "$src" "$dst"
339       }
340     else
341       test -h "$dst" &&
342       src_ls=`ls -diL "$src" 2>/dev/null` && set $src_ls && src_i=$1 &&
343       dst_ls=`ls -diL "$dst" 2>/dev/null` && set $dst_ls && dst_i=$1 &&
344       test "$src_i" = "$dst_i" || {
345         dot_dots=
346         case $src in
347         /*) ;;
348         *)
349           case /$dst/ in
350           *//* | */../* | */./* | /*/*/*/*/*/)
351              echo >&2 "$0: invalid symlink calculation: $src -> $dst"
352              exit 1;;
353           /*/*/*/*/)    dot_dots=../../../;;
354           /*/*/*/)      dot_dots=../../;;
355           /*/*/)        dot_dots=../;;
356           esac;;
357         esac
358
359         echo "$0: ln -fs $dot_dots$src $dst" &&
360         ln -fs "$dot_dots$src" "$dst"
361       }
362     fi
363   }
364 }
365
366 cp_mark_as_generated()
367 {
368   cp_src=$1
369   cp_dst=$2
370
371   if cmp -s "$cp_src" "$GNULIB_SRCDIR/$cp_dst"; then
372     symlink_to_dir "$GNULIB_SRCDIR" "$cp_dst"
373   elif cmp -s "$cp_src" "$local_gl_dir/$cp_dst"; then
374     symlink_to_dir $local_gl_dir "$cp_dst"
375   else
376     case $cp_dst in
377       *.[ch])             c1='/* '; c2=' */';;
378       *.texi)             c1='@c '; c2=     ;;
379       *.m4|*/Make*|Make*) c1='# ' ; c2=     ;;
380       *)                  c1=     ; c2=     ;;
381     esac
382
383     if test -z "$c1"; then
384       cmp -s "$cp_src" "$cp_dst" || {
385         echo "$0: cp -f $cp_src $cp_dst" &&
386         rm -f "$cp_dst" &&
387         sed "s!$bt_regex/!!g" "$cp_src" > "$cp_dst"
388       }
389     else
390       # Copy the file first to get proper permissions if it
391       # doesn't already exist.  Then overwrite the copy.
392       cp "$cp_src" "$cp_dst-t" &&
393       (
394         echo "$c1-*- buffer-read-only: t -*- vi: set ro:$c2" &&
395         echo "${c1}DO NOT EDIT! GENERATED AUTOMATICALLY!$c2" &&
396         sed "s!$bt_regex/!!g" "$cp_src"
397       ) > $cp_dst-t &&
398       if cmp -s "$cp_dst-t" "$cp_dst"; then
399         rm -f "$cp_dst-t"
400       else
401         echo "$0: cp $cp_src $cp_dst # with edits" &&
402         mv -f "$cp_dst-t" "$cp_dst"
403       fi
404     fi
405   fi
406 }
407
408 version_controlled_file() {
409   dir=$1
410   file=$2
411   found=no
412   if test -d CVS; then
413     grep -F "/$file/" $dir/CVS/Entries 2>/dev/null |
414              grep '^/[^/]*/[0-9]' > /dev/null && found=yes
415   elif test -d .git; then
416     git-rm -n "$dir/$file" > /dev/null 2>&1 && found=yes
417   else
418     echo "$0: no version control for $dir/$file?" >&2
419   fi
420   test $found = yes
421 }
422
423 slurp() {
424   for dir in . `(cd $1 && find * -type d -print)`; do
425     copied=
426     sep=
427     for file in `ls -a $1/$dir`; do
428       case $file in
429       .|..) continue;;
430       .*) continue;; # FIXME: should all file names starting with "." be ignored?
431       esac
432       test -d $1/$dir/$file && continue
433       for excluded_file in $excluded_files; do
434         test "$dir/$file" = "$excluded_file" && continue 2
435       done
436       if test $file = Makefile.am; then
437         copied=$copied${sep}$gnulib_mk; sep=$nl
438         remove_intl='/^[^#].*\/intl/s/^/#/;'"s!$bt_regex/!!g"
439         sed "$remove_intl" $1/$dir/$file | cmp -s - $dir/$gnulib_mk || {
440           echo "$0: Copying $1/$dir/$file to $dir/$gnulib_mk ..." &&
441           rm -f $dir/$gnulib_mk &&
442           sed "$remove_intl" $1/$dir/$file >$dir/$gnulib_mk
443         }
444       elif { test "${2+set}" = set && test -r $2/$dir/$file; } ||
445            version_controlled_file $dir $file; then
446         echo "$0: $dir/$file overrides $1/$dir/$file"
447       else
448         copied=$copied$sep$file; sep=$nl
449         if test $file = gettext.m4; then
450           echo "$0: patching m4/gettext.m4 to remove need for intl/* ..."
451           rm -f $dir/$file
452           sed '
453             /^AC_DEFUN(\[AM_INTL_SUBDIR],/,/^]/c\
454               AC_DEFUN([AM_INTL_SUBDIR], [
455             /^AC_DEFUN(\[gt_INTL_SUBDIR_CORE],/,/^]/c\
456               AC_DEFUN([gt_INTL_SUBDIR_CORE], [])
457             $a\
458               AC_DEFUN([gl_LOCK_EARLY], [])
459           ' $1/$dir/$file >$dir/$file
460         else
461           cp_mark_as_generated $1/$dir/$file $dir/$file
462         fi
463       fi || exit
464     done
465
466     for dot_ig in x $vc_ignore; do
467       test $dot_ig = x && continue
468       ig=$dir/$dot_ig
469       if test -n "$copied"; then
470         insert_sorted_if_absent $ig "$copied"
471         # If an ignored file name ends with _.h, then also add
472         # the name with just ".h".  Many gnulib headers are generated,
473         # e.g., stdint.in.h -> stdint.h, dirent.in.h ->..., etc.
474         # Likewise for .gperf -> .h, .y -> .c, and .sin -> .sed
475         f=`echo "$copied"|sed 's/\.in\.h$/.h/;s/\.sin$/.sed/;s/\.y$/.c/;s/\.gperf$/.h/'`
476         insert_sorted_if_absent $ig "$f"
477
478         # For files like sys_stat.in.h and sys_time.in.h, record as
479         # ignorable the directory we might eventually create: sys/.
480         f=`echo "$copied"|sed 's/sys_.*\.in\.h$/sys/'`
481         insert_sorted_if_absent $ig "$f"
482       fi
483     done
484   done
485 }
486
487
488 # Create boot temporary directories to import from gnulib and gettext.
489 rm -fr $bt $bt2 &&
490 mkdir $bt $bt2 || exit
491
492 # Import from gnulib.
493
494 gnulib_tool_options="\
495  --import\
496  --no-changelog\
497  --aux-dir $bt/$build_aux\
498  --doc-base $bt/doc\
499  --lib $gnulib_name\
500  --m4-base $bt/m4/\
501  --source-base $bt/lib/\
502  --tests-base $bt/tests\
503  --local-dir $local_gl_dir\
504 $gnulib_tool_option_extras\
505 "
506 echo "$0: $gnulib_tool $gnulib_tool_options --import ..."
507 $gnulib_tool $gnulib_tool_options --import $gnulib_modules &&
508 slurp $bt || exit
509
510 for file in $gnulib_files; do
511   symlink_to_dir "$GNULIB_SRCDIR" $file || exit
512 done
513
514
515 # Import from gettext.
516 with_gettext=yes
517 grep '^[         ]*AM_GNU_GETTEXT_VERSION(' configure.ac >/dev/null || \
518     with_gettext=no
519
520 if test $with_gettext = yes; then
521   echo "$0: (cd $bt2; autopoint) ..."
522   cp configure.ac $bt2 &&
523   (cd $bt2 && autopoint && rm configure.ac) &&
524   slurp $bt2 $bt || exit
525
526   rm -fr $bt $bt2 || exit
527 fi
528
529 # Coreutils is unusual in that it generates some of its test-related
530 # Makefile.am files.  That must be done before invoking automake.
531 mam_template=tests/Makefile.am.in
532 if test -f $mam_template; then
533   PERL=perl
534   for tool in cut head join pr sort tac tail test tr uniq wc; do
535     m=tests/$tool/Makefile.am
536     t=${m}t
537     rm -f $m $t
538     sed -n '1,/^##test-files-begin/p' $mam_template > $t
539     echo "x = $tool" >> $t
540     srcdir=tests/$tool
541     $PERL -I$srcdir -w -- tests/mk-script $srcdir --list >> $t
542     sed -n '/^##test-files-end/,$p' $mam_template >> $t
543     chmod -w $t
544     mv $t $m
545   done
546 fi
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 echo "$0: done.  Now you can run './configure'."