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