* build-aux/bootstrap (gnulib_name): New 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 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 grep '^[         ]*AC_CONFIG_AUX_DIR('$build_aux')' configure.ac >/dev/null ||
173   {
174     echo "$0: expected line not found in configure.ac. Add the following:" >&2
175     echo "  AC_CONFIG_AUX_DIR($build_aux)" >&2.
176   }
177
178 # If $build_aux doesn't exist, create it now, otherwise some bits
179 # below will malfunction.  If creating it, also mark it as ignored.
180 if test ! -d $build_aux; then
181   mkdir $build_aux
182   for ig in .cvsignore .gitignore; do
183     test -f $ig && insert_sorted_if_absent $ig $build_aux
184   done
185 fi
186
187 echo "$0: Bootstrapping from checked-out $package sources..."
188
189 cleanup_gnulib() {
190   status=$?
191   rm -fr gnulib
192   exit $status
193 }
194
195 # Get gnulib files.
196
197 case ${GNULIB_SRCDIR--} in
198 -)
199   if [ ! -d gnulib ]; then
200     echo "$0: getting gnulib files..."
201
202     case ${CVS_AUTH-pserver} in
203     pserver)
204       CVS_PREFIX=':pserver:anonymous@';;
205     ssh)
206       CVS_PREFIX="$CVS_USER${CVS_USER+@}";;
207     *)
208       echo "$0: $CVS_AUTH: Unknown CVS access method" >&2
209       exit 1;;
210     esac
211
212     case $CVS_RSH in
213     '') CVS_RSH=ssh; export CVS_RSH;;
214     esac
215
216     trap cleanup_gnulib 1 2 13 15
217
218     cvs -z3 -q -d ${CVS_PREFIX}cvs.savannah.gnu.org:/cvsroot/gnulib co gnulib ||
219       cleanup_gnulib
220
221     trap - 1 2 13 15
222   fi
223   GNULIB_SRCDIR=gnulib
224 esac
225
226 gnulib_tool=$GNULIB_SRCDIR/gnulib-tool
227 <$gnulib_tool || exit
228
229 # Get translations.
230
231 get_translations() {
232   subdir=$1
233   domain=$2
234
235   case $WGET_COMMAND in
236   '')
237     echo "$0: wget not available; skipping translations";;
238   ?*)
239     echo "$0: getting translations into $subdir for $domain..." &&
240
241     (cd $subdir && rm -f dummy `ls | sed -n '/\.gmo$/p; /\.po/p'`) &&
242     $WGET_COMMAND -O "$subdir/$domain.html" "$TP_URL$domain" &&
243
244     sed -n 's|.*"http://[^"]*/translation/teams/PO/\([^/"]*\)/'"$domain"'-\([^/"]*\)\.[^."]*\.po".*|\1.\2|p' <"$subdir/$domain.html" |
245     sort -k 1,1 -k 2,2n -k2,2 -k3,3n -k3,3 -k4,4n -k4,4 -k5,5n -k5.5 |
246     awk -F. '
247       { if (lang && $1 != lang) print lang, ver }
248       { lang = $1; ver = substr($0, index($0, ".") + 1) }
249       END { if (lang) print lang, ver }
250     ' | awk -v domain="$domain" -v subdir="$subdir" '
251       {
252         lang = $1
253         ver = $2
254         urlfmt = ""
255         printf "{ $WGET_COMMAND -O %s/%s.po '\'"$TP_PO_URL"'/%s/%s-%s.%s.po'\'' &&\n", subdir, lang, lang, domain, ver, lang
256         printf "  msgfmt -c -o /dev/null %s/%s.po || {\n", subdir, lang
257         printf "    echo >&2 '\'"$0"': omitting translation for %s'\''\n", lang
258         printf "    rm -f %s/%s.po; }; } &&\n", subdir, lang
259       }
260       END { print ":" }
261     ' | WGET_COMMAND="$WGET_COMMAND" sh;;
262   esac &&
263   ls "$subdir"/*.po 2>/dev/null |
264     sed 's|.*/||; s|\.po$||' >"$subdir/LINGUAS" &&
265   rm -f "$subdir/$domain.html"
266 }
267
268 case $SKIP_PO in
269 '')
270   case `wget --help` in
271   *'--no-cache'*)
272     WGET_COMMAND='wget -nv --no-cache';;
273   *'--cache=on/off'*)
274     WGET_COMMAND='wget -nv --cache=off';;
275   *'--non-verbose'*)
276     WGET_COMMAND='wget -nv';;
277   *)
278     WGET_COMMAND='';;
279   esac
280
281   if test -d po; then
282     get_translations po $package || exit
283   fi
284
285   if test -d runtime-po; then
286     get_translations runtime-po $package-runtime || exit
287   fi;;
288 esac
289
290 symlink_to_gnulib()
291 {
292   src=$GNULIB_SRCDIR/$1
293   dst=${2-$1}
294
295   test -f "$src" && {
296     if $copy; then
297       {
298         test ! -h "$dst" || {
299           echo "$0: rm -f $dst" &&
300           rm -f "$dst"
301         }
302       } &&
303       test -f "$dst" &&
304       cmp -s "$src" "$dst" || {
305         echo "$0: cp -fp $src $dst" &&
306         cp -fp "$src" "$dst"
307       }
308     else
309       test -h "$dst" &&
310       src_ls=`ls -diL "$src" 2>/dev/null` && set $src_ls && src_i=$1 &&
311       dst_ls=`ls -diL "$dst" 2>/dev/null` && set $dst_ls && dst_i=$1 &&
312       test "$src_i" = "$dst_i" || {
313         dot_dots=
314         case $src in
315         /*) ;;
316         *)
317           case /$dst/ in
318           *//* | */../* | */./* | /*/*/*/*/*/)
319              echo >&2 "$0: invalid symlink calculation: $src -> $dst"
320              exit 1;;
321           /*/*/*/*/)    dot_dots=../../../;;
322           /*/*/*/)      dot_dots=../../;;
323           /*/*/)        dot_dots=../;;
324           esac;;
325         esac
326
327         echo "$0: ln -fs $dot_dots$src $dst" &&
328         ln -fs "$dot_dots$src" "$dst"
329       }
330     fi
331   }
332 }
333
334 cp_mark_as_generated()
335 {
336   cp_src=$1
337   cp_dst=$2
338
339   if cmp -s "$cp_src" "$GNULIB_SRCDIR/$cp_dst"; then
340     symlink_to_gnulib "$cp_dst"
341   else
342     case $cp_dst in
343       *.[ch])             c1='/* '; c2=' */';;
344       *.texi)             c1='@c '; c2=     ;;
345       *.m4|*/Make*|Make*) c1='# ' ; c2=     ;;
346       *)                  c1=     ; c2=     ;;
347     esac
348
349     if test -z "$c1"; then
350       cmp -s "$cp_src" "$cp_dst" || {
351         echo "$0: cp -f $cp_src $cp_dst" &&
352         rm -f "$cp_dst" &&
353         sed "s!$bt_regex/!!g" "$cp_src" > "$cp_dst"
354       }
355     else
356       # Copy the file first to get proper permissions if it
357       # doesn't already exist.  Then overwrite the copy.
358       cp "$cp_src" "$cp_dst-t" &&
359       (
360         echo "$c1-*- buffer-read-only: t -*- vi: set ro:$c2" &&
361         echo "${c1}DO NOT EDIT! GENERATED AUTOMATICALLY!$c2" &&
362         sed "s!$bt_regex/!!g" "$cp_src"
363       ) > $cp_dst-t &&
364       if cmp -s "$cp_dst-t" "$cp_dst"; then
365         rm -f "$cp_dst-t"
366       else
367         echo "$0: cp $cp_src $cp_dst # with edits" &&
368         mv -f "$cp_dst-t" "$cp_dst"
369       fi
370     fi
371   fi
372 }
373
374 version_controlled_file() {
375   dir=$1
376   file=$2
377   found=no
378   if test -d CVS; then
379     grep -F "/$file/" $dir/CVS/Entries 2>/dev/null |
380              grep '^/[^/]*/[0-9]' > /dev/null && found=yes
381   elif test -d .git; then
382     git-rm -n "$dir/$file" > /dev/null 2>&1 && found=yes
383   else
384     echo "$0: no version control for $dir/$file?" >&2
385   fi
386   test $found = yes
387 }
388
389 slurp() {
390   for dir in . `(cd $1 && find * -type d -print)`; do
391     copied=
392     sep=
393     for file in `ls $1/$dir`; do
394       test -d $1/$dir/$file && continue
395       for excluded_file in $excluded_files; do
396         test "$dir/$file" = "$excluded_file" && continue 2
397       done
398       if test $file = Makefile.am; then
399         copied=$copied${sep}gnulib.mk; sep=$nl
400         remove_intl='/^[^#].*\/intl/s/^/#/;'"s!$bt_regex/!!g"
401         sed "$remove_intl" $1/$dir/$file | cmp -s - $dir/gnulib.mk || {
402           echo "$0: Copying $1/$dir/$file to $dir/gnulib.mk ..." &&
403           rm -f $dir/gnulib.mk &&
404           sed "$remove_intl" $1/$dir/$file >$dir/gnulib.mk
405         }
406       elif { test "${2+set}" = set && test -r $2/$dir/$file; } ||
407            version_controlled_file $dir $file; then
408         echo "$0: $dir/$file overrides $1/$dir/$file"
409       else
410         copied=$copied$sep$file; sep=$nl
411         if test $file = gettext.m4; then
412           echo "$0: patching m4/gettext.m4 to remove need for intl/* ..."
413           rm -f $dir/$file
414           sed '
415             /^AC_DEFUN(\[AM_INTL_SUBDIR],/,/^]/c\
416               AC_DEFUN([AM_INTL_SUBDIR], [
417             /^AC_DEFUN(\[gt_INTL_SUBDIR_CORE],/,/^]/c\
418               AC_DEFUN([gt_INTL_SUBDIR_CORE], [])
419             $a\
420               AC_DEFUN([gl_LOCK_EARLY], [])
421           ' $1/$dir/$file >$dir/$file
422         else
423           cp_mark_as_generated $1/$dir/$file $dir/$file
424         fi
425       fi || exit
426     done
427
428     for dot_ig in .cvsignore .gitignore; do
429       ig=$dir/$dot_ig
430       if test -n "$copied" && test -f $ig; then
431         insert_sorted_if_absent $ig "$copied"
432         # If an ignored file name ends with _.h, then also add
433         # the name with just ".h".  Many gnulib headers are generated,
434         # e.g., stdint_.h -> stdint.h, dirent_.h ->..., etc.
435         f=`echo "$copied"|sed 's/_\.h$/.h/'`
436         insert_sorted_if_absent $ig "$f"
437       fi
438     done
439   done
440 }
441
442
443 # Create boot temporary directories to import from gnulib and gettext.
444 rm -fr $bt $bt2 &&
445 mkdir $bt $bt2 || exit
446
447 # Import from gnulib.
448
449 gnulib_tool_options="\
450  --import\
451  --no-changelog\
452  --aux-dir $bt/$build_aux\
453  --doc-base $bt/doc\
454  --lib $gnulib_name\
455  --m4-base $bt/m4/\
456  --source-base $bt/lib/\
457  --tests-base $bt/tests\
458  --local-dir gl\
459 "
460 echo "$0: $gnulib_tool $gnulib_tool_options --import ..."
461 $gnulib_tool $gnulib_tool_options --import $gnulib_modules &&
462 slurp $bt || exit
463
464 for file in $gnulib_files; do
465   symlink_to_gnulib $file || exit
466 done
467
468
469 # Import from gettext.
470
471 echo "$0: (cd $bt2; autopoint) ..."
472 cp configure.ac $bt2 &&
473 (cd $bt2 && autopoint && rm configure.ac) &&
474 slurp $bt2 $bt || exit
475
476 rm -fr $bt $bt2 || exit
477
478
479 # Reconfigure, getting other files.
480
481 for command in \
482   libtool \
483   'aclocal --force -I m4' \
484   'autoconf --force' \
485   'autoheader --force' \
486   'automake --add-missing --copy --force-missing';
487 do
488   if test "$command" = libtool; then
489     grep '^[     ]*AM_PROG_LIBTOOL\>' configure.ac >/dev/null ||
490       continue
491     command='libtoolize -c -f'
492   fi
493   echo "$0: $command ..."
494   $command || exit
495 done
496
497
498 # Get some extra files from gnulib, overriding existing files.
499
500 for file in $gnulib_extra_files; do
501   case $file in
502   */INSTALL) dst=INSTALL;;
503   *) dst=$file;;
504   esac
505   symlink_to_gnulib $file $dst || exit
506 done
507
508
509 # Create gettext configuration.
510 echo "$0: Creating po/Makevars from po/Makevars.template ..."
511 rm -f po/Makevars
512 sed '
513   /^EXTRA_LOCALE_CATEGORIES *=/s/=.*/= '"$EXTRA_LOCALE_CATEGORIES"'/
514   /^MSGID_BUGS_ADDRESS *=/s/=.*/= bug-'"$package"'@gnu.org/
515   /^XGETTEXT_OPTIONS *=/{
516     s/$/ \\/
517     a\
518         '"$XGETTEXT_OPTIONS"' $${end_of_xgettext_options+}
519   }
520 ' po/Makevars.template >po/Makevars
521
522 if test -d runtime-po; then
523   # Similarly for runtime-po/Makevars, but not quite the same.
524   rm -f runtime-po/Makevars
525   sed '
526     /^DOMAIN *=.*/s/=.*/= '"$package"'-runtime/
527     /^subdir *=.*/s/=.*/= runtime-po/
528     /^MSGID_BUGS_ADDRESS *=/s/=.*/= bug-'"$package"'@gnu.org/
529     /^XGETTEXT_OPTIONS *=/{
530       s/$/ \\/
531       a\
532           '"$XGETTEXT_OPTIONS_RUNTIME"' $${end_of_xgettext_options+}
533     }
534   ' <po/Makevars.template >runtime-po/Makevars
535
536   # Copy identical files from po to runtime-po.
537   (cd po && cp -p Makefile.in.in *-quot *.header *.sed *.sin ../runtime-po)
538 fi
539
540 echo "$0: done.  Now you can run './configure'."