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