3294085057373b9d8a1146f48de8e39208b42286
[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 2, or (at your option)
10 # 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, write to the Free Software
19 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 # 02110-1301, USA.
21
22 # Written by Paul Eggert.
23
24 nl='
25 '
26
27 # Ensure file names are sorted consistently across platforms.
28 # Also, ensure diagnostics are in English, e.g., "wget --help" below.
29 LC_ALL=C
30 export LC_ALL
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 # List of gnulib modules needed.
65 gnulib_modules=
66
67 # Any gnulib files needed that are not in modules.
68 gnulib_files=
69
70 # Translation Project URL, for the registry of all projects
71 # and for the translation-team master directory.
72 TP_URL='http://www.iro.umontreal.ca/translation/registry.cgi?domain='
73 TP_PO_URL='http://www.iro.umontreal.ca/translation/teams/PO/'
74
75 extract_package_name='
76   /^AC_INIT(/{
77      /.*,.*,.*,/{
78        s///
79        s/[][]//g
80        p
81        q
82      }
83      s/AC_INIT(\[*//
84      s/]*,.*//
85      s/^GNU //
86      y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
87      s/[^A-Za-z0-9_]/-/g
88      p
89   }
90 '
91 package=`sed -n "$extract_package_name" configure.ac` || exit
92 gnulib_name=lib$package
93
94 build_aux=build-aux
95 # Extra files from gnulib, which override files from other sources.
96 gnulib_extra_files="
97         $build_aux/install-sh
98         $build_aux/missing
99         $build_aux/mdate-sh
100         $build_aux/texinfo.tex
101         $build_aux/depcomp
102         $build_aux/config.guess
103         $build_aux/config.sub
104         doc/INSTALL
105 "
106
107 # Other locale categories that need message catalogs.
108 EXTRA_LOCALE_CATEGORIES=
109
110 # Additional xgettext options to use.  Use "\\\newline" to break lines.
111 XGETTEXT_OPTIONS='\\\
112  --flag=_:1:pass-c-format\\\
113  --flag=N_:1:pass-c-format\\\
114  --flag=error:3:c-format --flag=error_at_line:5:c-format\\\
115 '
116
117 # Files we don't want to import.
118 excluded_files=
119
120 # File that should exist in the top directory of a checked out hierarchy,
121 # but not in a distribution tarball.
122 checkout_only_file=README-hacking
123
124 # Whether to use copies instead of symlinks.
125 copy=false
126
127 # Override the default configuration, if necessary.
128 test -r bootstrap.conf && . ./bootstrap.conf
129
130 # Translate configuration into internal form.
131
132 # Parse options.
133
134 for option
135 do
136   case $option in
137   --help)
138     usage
139     exit;;
140   --gnulib-srcdir=*)
141     GNULIB_SRCDIR=`expr "$option" : '--gnulib-srcdir=\(.*\)'`;;
142   --cvs-user=*)
143     CVS_USER=`expr "$option" : '--cvs-user=\(.*\)'`;;
144   --skip-po)
145     SKIP_PO=t;;
146   --force)
147     checkout_only_file=;;
148   --copy)
149     copy=true;;
150   *)
151     echo >&2 "$0: $option: unknown option"
152     exit 1;;
153   esac
154 done
155
156 if test -n "$checkout_only_file" && test ! -r "$checkout_only_file"; then
157   echo "$0: Bootstrapping from a non-checked-out distribution is risky." >&2
158   exit 1
159 fi
160
161 # If $STR is not already on a line by itself in $FILE, insert it,
162 # sorting the new contents of the file and replacing $FILE with the result.
163 insert_sorted_if_absent() {
164   file=$1
165   str=$2
166   echo "$str" | sort -u - $file | cmp -s - $file \
167     || echo "$str" | sort -u - $file -o $file \
168     || exit 1
169 }
170
171 # Die if there is no AC_CONFIG_AUX_DIR($build_aux) line in configure.ac.
172 found_aux_dir=no
173 grep '^[         ]*AC_CONFIG_AUX_DIR(\['"$build_aux"'\])' configure.ac \
174     >/dev/null && found_aux_dir=yes
175 grep '^[         ]*AC_CONFIG_AUX_DIR('"$build_aux"')' configure.ac \
176     >/dev/null && found_aux_dir=yes
177 if test $found_aux_dir = no; then
178   echo "$0: expected line not found in configure.ac. Add the following:" >&2
179   echo "  AC_CONFIG_AUX_DIR([$build_aux])" >&2.
180 fi
181
182 # If $build_aux doesn't exist, create it now, otherwise some bits
183 # below will malfunction.  If creating it, also mark it as ignored.
184 if test ! -d $build_aux; then
185   mkdir $build_aux
186   for ig in .cvsignore .gitignore; do
187     test -f $ig && insert_sorted_if_absent $ig $build_aux
188   done
189 fi
190
191 echo "$0: Bootstrapping from checked-out $package sources..."
192
193 cleanup_gnulib() {
194   status=$?
195   rm -fr gnulib
196   exit $status
197 }
198
199 # Get gnulib files.
200
201 case ${GNULIB_SRCDIR--} in
202 -)
203   if [ ! -d gnulib ]; then
204     echo "$0: getting gnulib files..."
205
206     case ${CVS_AUTH-pserver} in
207     pserver)
208       CVS_PREFIX=':pserver:anonymous@';;
209     ssh)
210       CVS_PREFIX="$CVS_USER${CVS_USER+@}";;
211     *)
212       echo "$0: $CVS_AUTH: Unknown CVS access method" >&2
213       exit 1;;
214     esac
215
216     case $CVS_RSH in
217     '') CVS_RSH=ssh; export CVS_RSH;;
218     esac
219
220     trap cleanup_gnulib 1 2 13 15
221
222     cvs -z3 -q -d ${CVS_PREFIX}cvs.savannah.gnu.org:/cvsroot/gnulib co gnulib ||
223       cleanup_gnulib
224
225     trap - 1 2 13 15
226   fi
227   GNULIB_SRCDIR=gnulib
228 esac
229
230 gnulib_tool=$GNULIB_SRCDIR/gnulib-tool
231 <$gnulib_tool || exit
232
233 # Get translations.
234
235 get_translations() {
236   subdir=$1
237   domain=$2
238
239   case $WGET_COMMAND in
240   '')
241     echo "$0: wget not available; skipping translations";;
242   ?*)
243     echo "$0: getting translations into $subdir for $domain..." &&
244
245     (cd $subdir && rm -f dummy `ls | sed -n '/\.gmo$/p; /\.po/p'`) &&
246     $WGET_COMMAND -O "$subdir/$domain.html" "$TP_URL$domain" &&
247
248     sed -n 's|.*"http://[^"]*/translation/teams/PO/\([^/"]*\)/'"$domain"'-\([^/"]*\)\.[^."]*\.po".*|\1.\2|p' <"$subdir/$domain.html" |
249     sort -k 1,1 -k 2,2n -k2,2 -k3,3n -k3,3 -k4,4n -k4,4 -k5,5n -k5.5 |
250     awk -F. '
251       { if (lang && $1 != lang) print lang, ver }
252       { lang = $1; ver = substr($0, index($0, ".") + 1) }
253       END { if (lang) print lang, ver }
254     ' | awk -v domain="$domain" -v subdir="$subdir" '
255       {
256         lang = $1
257         ver = $2
258         urlfmt = ""
259         printf "{ $WGET_COMMAND -O %s/%s.po '\'"$TP_PO_URL"'/%s/%s-%s.%s.po'\'' &&\n", subdir, lang, lang, domain, ver, lang
260         printf "  msgfmt -c -o /dev/null %s/%s.po || {\n", subdir, lang
261         printf "    echo >&2 '\'"$0"': omitting translation for %s'\''\n", lang
262         printf "    rm -f %s/%s.po; }; } &&\n", subdir, lang
263       }
264       END { print ":" }
265     ' | WGET_COMMAND="$WGET_COMMAND" sh;;
266   esac &&
267   ls "$subdir"/*.po 2>/dev/null |
268     sed 's|.*/||; s|\.po$||' >"$subdir/LINGUAS" &&
269   rm -f "$subdir/$domain.html"
270 }
271
272 case $SKIP_PO in
273 '')
274   case `wget --help` in
275   *'--no-cache'*)
276     WGET_COMMAND='wget -nv --no-cache';;
277   *'--cache=on/off'*)
278     WGET_COMMAND='wget -nv --cache=off';;
279   *'--non-verbose'*)
280     WGET_COMMAND='wget -nv';;
281   *)
282     WGET_COMMAND='';;
283   esac
284
285   if test -d po; then
286     get_translations po $package || exit
287   fi
288
289   if test -d runtime-po; then
290     get_translations runtime-po $package-runtime || exit
291   fi;;
292 esac
293
294 symlink_to_gnulib()
295 {
296   src=$GNULIB_SRCDIR/$1
297   dst=${2-$1}
298
299   test -f "$src" && {
300     if $copy; then
301       {
302         test ! -h "$dst" || {
303           echo "$0: rm -f $dst" &&
304           rm -f "$dst"
305         }
306       } &&
307       test -f "$dst" &&
308       cmp -s "$src" "$dst" || {
309         echo "$0: cp -fp $src $dst" &&
310         cp -fp "$src" "$dst"
311       }
312     else
313       test -h "$dst" &&
314       src_ls=`ls -diL "$src" 2>/dev/null` && set $src_ls && src_i=$1 &&
315       dst_ls=`ls -diL "$dst" 2>/dev/null` && set $dst_ls && dst_i=$1 &&
316       test "$src_i" = "$dst_i" || {
317         dot_dots=
318         case $src in
319         /*) ;;
320         *)
321           case /$dst/ in
322           *//* | */../* | */./* | /*/*/*/*/*/)
323              echo >&2 "$0: invalid symlink calculation: $src -> $dst"
324              exit 1;;
325           /*/*/*/*/)    dot_dots=../../../;;
326           /*/*/*/)      dot_dots=../../;;
327           /*/*/)        dot_dots=../;;
328           esac;;
329         esac
330
331         echo "$0: ln -fs $dot_dots$src $dst" &&
332         ln -fs "$dot_dots$src" "$dst"
333       }
334     fi
335   }
336 }
337
338 cp_mark_as_generated()
339 {
340   cp_src=$1
341   cp_dst=$2
342
343   if cmp -s "$cp_src" "$GNULIB_SRCDIR/$cp_dst"; then
344     symlink_to_gnulib "$cp_dst"
345   else
346     case $cp_dst in
347       *.[ch])             c1='/* '; c2=' */';;
348       *.texi)             c1='@c '; c2=     ;;
349       *.m4|*/Make*|Make*) c1='# ' ; c2=     ;;
350       *)                  c1=     ; c2=     ;;
351     esac
352
353     if test -z "$c1"; then
354       cmp -s "$cp_src" "$cp_dst" || {
355         echo "$0: cp -f $cp_src $cp_dst" &&
356         rm -f "$cp_dst" &&
357         sed "s!$bt_regex/!!g" "$cp_src" > "$cp_dst"
358       }
359     else
360       # Copy the file first to get proper permissions if it
361       # doesn't already exist.  Then overwrite the copy.
362       cp "$cp_src" "$cp_dst-t" &&
363       (
364         echo "$c1-*- buffer-read-only: t -*- vi: set ro:$c2" &&
365         echo "${c1}DO NOT EDIT! GENERATED AUTOMATICALLY!$c2" &&
366         sed "s!$bt_regex/!!g" "$cp_src"
367       ) > $cp_dst-t &&
368       if cmp -s "$cp_dst-t" "$cp_dst"; then
369         rm -f "$cp_dst-t"
370       else
371         echo "$0: cp $cp_src $cp_dst # with edits" &&
372         mv -f "$cp_dst-t" "$cp_dst"
373       fi
374     fi
375   fi
376 }
377
378 version_controlled_file() {
379   dir=$1
380   file=$2
381   found=no
382   if test -d CVS; then
383     grep -F "/$file/" $dir/CVS/Entries 2>/dev/null |
384              grep '^/[^/]*/[0-9]' > /dev/null && found=yes
385   elif test -d .git; then
386     git-rm -n "$dir/$file" > /dev/null 2>&1 && found=yes
387   else
388     echo "$0: no version control for $dir/$file?" >&2
389   fi
390   test $found = yes
391 }
392
393 slurp() {
394   for dir in . `(cd $1 && find * -type d -print)`; do
395     copied=
396     sep=
397     for file in `ls $1/$dir`; do
398       test -d $1/$dir/$file && continue
399       for excluded_file in $excluded_files; do
400         test "$dir/$file" = "$excluded_file" && continue 2
401       done
402       if test $file = Makefile.am; then
403         copied=$copied${sep}gnulib.mk; sep=$nl
404         remove_intl='/^[^#].*\/intl/s/^/#/;'"s!$bt_regex/!!g"
405         sed "$remove_intl" $1/$dir/$file | cmp -s - $dir/gnulib.mk || {
406           echo "$0: Copying $1/$dir/$file to $dir/gnulib.mk ..." &&
407           rm -f $dir/gnulib.mk &&
408           sed "$remove_intl" $1/$dir/$file >$dir/gnulib.mk
409         }
410       elif { test "${2+set}" = set && test -r $2/$dir/$file; } ||
411            version_controlled_file $dir $file; then
412         echo "$0: $dir/$file overrides $1/$dir/$file"
413       else
414         copied=$copied$sep$file; sep=$nl
415         if test $file = gettext.m4; then
416           echo "$0: patching m4/gettext.m4 to remove need for intl/* ..."
417           rm -f $dir/$file
418           sed '
419             /^AC_DEFUN(\[AM_INTL_SUBDIR],/,/^]/c\
420               AC_DEFUN([AM_INTL_SUBDIR], [
421             /^AC_DEFUN(\[gt_INTL_SUBDIR_CORE],/,/^]/c\
422               AC_DEFUN([gt_INTL_SUBDIR_CORE], [])
423             $a\
424               AC_DEFUN([gl_LOCK_EARLY], [])
425           ' $1/$dir/$file >$dir/$file
426         else
427           cp_mark_as_generated $1/$dir/$file $dir/$file
428         fi
429       fi || exit
430     done
431
432     for dot_ig in .cvsignore .gitignore; do
433       ig=$dir/$dot_ig
434       if test -n "$copied" && test -f $ig; then
435         insert_sorted_if_absent $ig "$copied"
436         # If an ignored file name ends with _.h, then also add
437         # the name with just ".h".  Many gnulib headers are generated,
438         # e.g., stdint_.h -> stdint.h, dirent_.h ->..., etc.
439         f=`echo "$copied"|sed 's/_\.h$/.h/'`
440         insert_sorted_if_absent $ig "$f"
441       fi
442     done
443   done
444 }
445
446
447 # Create boot temporary directories to import from gnulib and gettext.
448 rm -fr $bt $bt2 &&
449 mkdir $bt $bt2 || exit
450
451 # Import from gnulib.
452
453 gnulib_tool_options="\
454  --import\
455  --no-changelog\
456  --aux-dir $bt/$build_aux\
457  --doc-base $bt/doc\
458  --lib $gnulib_name\
459  --m4-base $bt/m4/\
460  --source-base $bt/lib/\
461  --tests-base $bt/tests\
462  --local-dir gl\
463 "
464 echo "$0: $gnulib_tool $gnulib_tool_options --import ..."
465 $gnulib_tool $gnulib_tool_options --import $gnulib_modules &&
466 slurp $bt || exit
467
468 for file in $gnulib_files; do
469   symlink_to_gnulib $file || exit
470 done
471
472
473 # Import from gettext.
474 with_gettext=yes
475 grep '^[         ]*AM_GNU_GETTEXT_VERSION(' configure.ac >/dev/null || \
476     with_gettext=no
477
478 if test $with_gettext = yes; then
479   echo "$0: (cd $bt2; autopoint) ..."
480   cp configure.ac $bt2 &&
481   (cd $bt2 && autopoint && rm configure.ac) &&
482   slurp $bt2 $bt || exit
483
484   rm -fr $bt $bt2 || exit
485 fi
486
487
488 # Reconfigure, getting other files.
489
490 for command in \
491   libtool \
492   'aclocal --force -I m4' \
493   'autoconf --force' \
494   'autoheader --force' \
495   'automake --add-missing --copy --force-missing';
496 do
497   if test "$command" = libtool; then
498     grep '^[     ]*AM_PROG_LIBTOOL\>' configure.ac >/dev/null ||
499       continue
500     command='libtoolize -c -f'
501   fi
502   echo "$0: $command ..."
503   $command || exit
504 done
505
506
507 # Get some extra files from gnulib, overriding existing files.
508
509 for file in $gnulib_extra_files; do
510   case $file in
511   */INSTALL) dst=INSTALL;;
512   *) dst=$file;;
513   esac
514   symlink_to_gnulib $file $dst || exit
515 done
516
517 if test $with_gettext = yes; then
518   # Create gettext configuration.
519   echo "$0: Creating po/Makevars from po/Makevars.template ..."
520   rm -f po/Makevars
521   sed '
522     /^EXTRA_LOCALE_CATEGORIES *=/s/=.*/= '"$EXTRA_LOCALE_CATEGORIES"'/
523     /^MSGID_BUGS_ADDRESS *=/s/=.*/= bug-'"$package"'@gnu.org/
524     /^XGETTEXT_OPTIONS *=/{
525       s/$/ \\/
526       a\
527           '"$XGETTEXT_OPTIONS"' $${end_of_xgettext_options+}
528     }
529   ' po/Makevars.template >po/Makevars
530
531   if test -d runtime-po; then
532     # Similarly for runtime-po/Makevars, but not quite the same.
533     rm -f runtime-po/Makevars
534     sed '
535       /^DOMAIN *=.*/s/=.*/= '"$package"'-runtime/
536       /^subdir *=.*/s/=.*/= runtime-po/
537       /^MSGID_BUGS_ADDRESS *=/s/=.*/= bug-'"$package"'@gnu.org/
538       /^XGETTEXT_OPTIONS *=/{
539         s/$/ \\/
540         a\
541             '"$XGETTEXT_OPTIONS_RUNTIME"' $${end_of_xgettext_options+}
542       }
543     ' <po/Makevars.template >runtime-po/Makevars
544
545     # Copy identical files from po to runtime-po.
546     (cd po && cp -p Makefile.in.in *-quot *.header *.sed *.sin ../runtime-po)
547   fi
548 fi
549
550 echo "$0: done.  Now you can run './configure'."