Port tests/rmdir/ignore away from GNU/Linux.
[coreutils/ericb.git] / bootstrap
blobe51cb08a95903d81dbf1d06c606b0b07ddd39d6b
1 #! /bin/sh
3 # Bootstrap this package from checked-out sources.
5 # Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
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.
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.
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/>.
20 # Written by Paul Eggert.
22 nl='
25 # Ensure file names are sorted consistently across platforms.
26 LC_ALL=C
27 export LC_ALL
29 local_gl_dir=gl
31 # Temporary directory names.
32 bt='._bootmp'
33 bt_regex=`echo "$bt"| sed 's/\./[.]/g'`
34 bt2=${bt}2
36 usage() {
37 echo >&2 "\
38 Usage: $0 [OPTION]...
39 Bootstrap this package from the checked-out sources.
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.
52 If the file bootstrap.conf exists in the current working directory, its
53 contents are read as shell variables to configure the bootstrap.
55 Running without arguments will suffice in most cases.
59 # Configuration.
61 # Name of the Makefile.am
62 gnulib_mk=gnulib.mk
64 # List of gnulib modules needed.
65 gnulib_modules=
67 # Any gnulib files needed that are not in modules.
68 gnulib_files=
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'"
78 extract_package_name='
79 /^AC_INIT(/{
80 /.*,.*,.*,/{
81 s///
82 s/[][]//g
86 s/AC_INIT(\[*//
87 s/]*,.*//
88 s/^GNU //
89 y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
90 s/[^A-Za-z0-9_]/-/g
94 package=`sed -n "$extract_package_name" configure.ac` || exit
95 gnulib_name=lib$package
97 build_aux=build-aux
98 # Extra files from gnulib, which override files from other sources.
99 gnulib_extra_files="
100 $build_aux/install-sh
101 $build_aux/missing
102 $build_aux/mdate-sh
103 $build_aux/texinfo.tex
104 $build_aux/depcomp
105 $build_aux/config.guess
106 $build_aux/config.sub
107 doc/INSTALL
110 # Additional gnulib-tool options to use. Use "\newline" to break lines.
111 gnulib_tool_option_extras=
113 # Other locale categories that need message catalogs.
114 EXTRA_LOCALE_CATEGORIES=
116 # Additional xgettext options to use. Use "\\\newline" to break lines.
117 XGETTEXT_OPTIONS='\\\
118 --flag=_:1:pass-c-format\\\
119 --flag=N_:1:pass-c-format\\\
120 --flag=error:3:c-format --flag=error_at_line:5:c-format\\\
123 # Files we don't want to import.
124 excluded_files=
126 # File that should exist in the top directory of a checked out hierarchy,
127 # but not in a distribution tarball.
128 checkout_only_file=README-hacking
130 # Whether to use copies instead of symlinks.
131 copy=false
133 # Set this to '.cvsignore .gitignore' in bootstrap.conf if you want
134 # those files to be generated in directories like lib/, m4/, and po/.
135 # Or set it to 'auto' to make this script select which to use based
136 # on which version control system (if any) is used in the source directory.
137 vc_ignore=auto
139 # Override the default configuration, if necessary.
140 test -r bootstrap.conf && . ./bootstrap.conf
142 if test "$vc_ignore" = auto; then
143 vc_ignore=
144 test -d .git && vc_ignore=.gitignore
145 test -d CVS && vc_ignore="$vc_ignore .cvsignore"
148 # Translate configuration into internal form.
150 # Parse options.
152 for option
154 case $option in
155 --help)
156 usage
157 exit;;
158 --gnulib-srcdir=*)
159 GNULIB_SRCDIR=`expr "$option" : '--gnulib-srcdir=\(.*\)'`;;
160 --skip-po)
161 SKIP_PO=t;;
162 --force)
163 checkout_only_file=;;
164 --copy)
165 copy=true;;
167 echo >&2 "$0: $option: unknown option"
168 exit 1;;
169 esac
170 done
172 if test -n "$checkout_only_file" && test ! -r "$checkout_only_file"; then
173 echo "$0: Bootstrapping from a non-checked-out distribution is risky." >&2
174 exit 1
177 # If $STR is not already on a line by itself in $FILE, insert it,
178 # sorting the new contents of the file and replacing $FILE with the result.
179 insert_sorted_if_absent() {
180 file=$1
181 str=$2
182 test -f $file || touch $file
183 echo "$str" | sort -u - $file | cmp -s - $file \
184 || echo "$str" | sort -u - $file -o $file \
185 || exit 1
188 # Die if there is no AC_CONFIG_AUX_DIR($build_aux) line in configure.ac.
189 found_aux_dir=no
190 grep '^[ ]*AC_CONFIG_AUX_DIR(\['"$build_aux"'\])' configure.ac \
191 >/dev/null && found_aux_dir=yes
192 grep '^[ ]*AC_CONFIG_AUX_DIR('"$build_aux"')' configure.ac \
193 >/dev/null && found_aux_dir=yes
194 if test $found_aux_dir = no; then
195 echo "$0: expected line not found in configure.ac. Add the following:" >&2
196 echo " AC_CONFIG_AUX_DIR([$build_aux])" >&2
197 exit 1
200 # If $build_aux doesn't exist, create it now, otherwise some bits
201 # below will malfunction. If creating it, also mark it as ignored.
202 if test ! -d $build_aux; then
203 mkdir $build_aux
204 for dot_ig in x $vc_ignore; do
205 test $dot_ig = x && continue
206 insert_sorted_if_absent $dot_ig $build_aux
207 done
210 echo "$0: Bootstrapping from checked-out $package sources..."
212 cleanup_gnulib() {
213 status=$?
214 rm -fr gnulib
215 exit $status
218 # Get gnulib files.
220 case ${GNULIB_SRCDIR--} in
222 if [ ! -d gnulib ]; then
223 echo "$0: getting gnulib files..."
225 trap cleanup_gnulib 1 2 13 15
227 git clone --depth 2 git://git.sv.gnu.org/gnulib ||
228 cleanup_gnulib
230 trap - 1 2 13 15
232 GNULIB_SRCDIR=gnulib
233 esac
235 gnulib_tool=$GNULIB_SRCDIR/gnulib-tool
236 <$gnulib_tool || exit
238 # Get translations.
240 download_po_files() {
241 subdir=$1
242 domain=$2
243 echo "$0: getting translations into $subdir for $domain..."
244 cmd=`printf "$po_download_command_format" "$domain" "$subdir"`
245 eval "$cmd"
248 # Download .po files to $po_dir/.reference and copy only the new
249 # or modified ones into $po_dir. Also update $po_dir/LINGUAS.
250 update_po_files() {
251 # Directory containing primary .po files.
252 # Overwrite them only when we're sure a .po file is new.
253 po_dir=$1
254 domain=$2
256 # Download *.po files into this dir.
257 # Usually contains *.s1 checksum files.
258 ref_po_dir="$po_dir/.reference"
260 test -d $ref_po_dir || mkdir $ref_po_dir || return
261 download_po_files $ref_po_dir $domain \
262 && ls "$ref_po_dir"/*.po 2>/dev/null |
263 sed 's|.*/||; s|\.po$||' > "$po_dir/LINGUAS"
265 langs=`cd $ref_po_dir && echo *.po|sed 's/\.po//g'`
266 test "$langs" = '*' && langs=x
267 for po in `cd $ref_po_dir && echo *.po|sed 's/\.po//g'`; do
268 case $po in x) continue;; esac
269 new_po="$ref_po_dir/$po.po"
270 cksum_file="$ref_po_dir/$po.s1"
271 if ! test -f "$cksum_file" ||
272 ! sha1sum -c --status "$cksum_file" < "$new_po" > /dev/null; then
273 echo "updated $po_dir/$po.po..."
274 cp "$new_po" "$po_dir/$po.po" && sha1sum < "$new_po" > "$cksum_file"
276 done
279 case $SKIP_PO in
281 if test -d po; then
282 update_po_files po $package || exit
285 if test -d runtime-po; then
286 update_po_files runtime-po $package-runtime || exit
287 fi;;
288 esac
290 symlink_to_dir()
292 src=$1/$2
293 dst=${3-$2}
295 test -f "$src" && {
297 # If the destination directory doesn't exist, create it.
298 # This is required at least for "lib/uniwidth/cjk.h".
299 dst_dir=`dirname "$dst"`
300 if ! test -d "$dst_dir"; then
301 mkdir -p "$dst_dir"
303 # If we've just created a directory like lib/uniwidth,
304 # tell version control system(s) it's ignorable.
305 # FIXME: for now, this does only one level
306 parent=`dirname "$dst_dir"`
307 for dot_ig in x $vc_ignore; do
308 test $dot_ig = x && continue
309 ig=$parent/$dot_ig
310 insert_sorted_if_absent $ig `echo "$dst_dir"|sed 's,.*/,,'`
311 done
314 if $copy; then
316 test ! -h "$dst" || {
317 echo "$0: rm -f $dst" &&
318 rm -f "$dst"
320 } &&
321 test -f "$dst" &&
322 cmp -s "$src" "$dst" || {
323 echo "$0: cp -fp $src $dst" &&
324 cp -fp "$src" "$dst"
326 else
327 test -h "$dst" &&
328 src_ls=`ls -diL "$src" 2>/dev/null` && set $src_ls && src_i=$1 &&
329 dst_ls=`ls -diL "$dst" 2>/dev/null` && set $dst_ls && dst_i=$1 &&
330 test "$src_i" = "$dst_i" || {
331 dot_dots=
332 case $src in
333 /*) ;;
335 case /$dst/ in
336 *//* | */../* | */./* | /*/*/*/*/*/)
337 echo >&2 "$0: invalid symlink calculation: $src -> $dst"
338 exit 1;;
339 /*/*/*/*/) dot_dots=../../../;;
340 /*/*/*/) dot_dots=../../;;
341 /*/*/) dot_dots=../;;
342 esac;;
343 esac
345 echo "$0: ln -fs $dot_dots$src $dst" &&
346 ln -fs "$dot_dots$src" "$dst"
352 cp_mark_as_generated()
354 cp_src=$1
355 cp_dst=$2
357 if cmp -s "$cp_src" "$GNULIB_SRCDIR/$cp_dst"; then
358 symlink_to_dir "$GNULIB_SRCDIR" "$cp_dst"
359 elif cmp -s "$cp_src" "$local_gl_dir/$cp_dst"; then
360 symlink_to_dir $local_gl_dir "$cp_dst"
361 else
362 case $cp_dst in
363 *.[ch]) c1='/* '; c2=' */';;
364 *.texi) c1='@c '; c2= ;;
365 *.m4|*/Make*|Make*) c1='# ' ; c2= ;;
366 *) c1= ; c2= ;;
367 esac
369 # If the destination directory doesn't exist, create it.
370 # This is required at least for "lib/uniwidth/cjk.h".
371 dst_dir=`dirname "$cp_dst"`
372 test -d "$dst_dir" || mkdir -p "$dst_dir"
374 if test -z "$c1"; then
375 cmp -s "$cp_src" "$cp_dst" || {
376 echo "$0: cp -f $cp_src $cp_dst" &&
377 rm -f "$cp_dst" &&
378 sed "s!$bt_regex/!!g" "$cp_src" > "$cp_dst"
380 else
381 # Copy the file first to get proper permissions if it
382 # doesn't already exist. Then overwrite the copy.
383 cp "$cp_src" "$cp_dst-t" &&
385 echo "$c1-*- buffer-read-only: t -*- vi: set ro:$c2" &&
386 echo "${c1}DO NOT EDIT! GENERATED AUTOMATICALLY!$c2" &&
387 sed "s!$bt_regex/!!g" "$cp_src"
388 ) > $cp_dst-t &&
389 if cmp -s "$cp_dst-t" "$cp_dst"; then
390 rm -f "$cp_dst-t"
391 else
392 echo "$0: cp $cp_src $cp_dst # with edits" &&
393 mv -f "$cp_dst-t" "$cp_dst"
399 version_controlled_file() {
400 dir=$1
401 file=$2
402 found=no
403 if test -d CVS; then
404 grep -F "/$file/" $dir/CVS/Entries 2>/dev/null |
405 grep '^/[^/]*/[0-9]' > /dev/null && found=yes
406 elif test -d .git; then
407 git-rm -n "$dir/$file" > /dev/null 2>&1 && found=yes
408 else
409 echo "$0: no version control for $dir/$file?" >&2
411 test $found = yes
414 slurp() {
415 for dir in . `(cd $1 && find * -type d -print)`; do
416 copied=
417 sep=
418 for file in `ls -a $1/$dir`; do
419 case $file in
420 .|..) continue;;
421 .*) continue;; # FIXME: should all file names starting with "." be ignored?
422 esac
423 test -d $1/$dir/$file && continue
424 for excluded_file in $excluded_files; do
425 test "$dir/$file" = "$excluded_file" && continue 2
426 done
427 if test $file = Makefile.am; then
428 copied=$copied${sep}$gnulib_mk; sep=$nl
429 remove_intl='/^[^#].*\/intl/s/^/#/;'"s!$bt_regex/!!g"
430 sed "$remove_intl" $1/$dir/$file | cmp -s - $dir/$gnulib_mk || {
431 echo "$0: Copying $1/$dir/$file to $dir/$gnulib_mk ..." &&
432 rm -f $dir/$gnulib_mk &&
433 sed "$remove_intl" $1/$dir/$file >$dir/$gnulib_mk
435 elif { test "${2+set}" = set && test -r $2/$dir/$file; } ||
436 version_controlled_file $dir $file; then
437 echo "$0: $dir/$file overrides $1/$dir/$file"
438 else
439 copied=$copied$sep$file; sep=$nl
440 if test $file = gettext.m4; then
441 echo "$0: patching m4/gettext.m4 to remove need for intl/* ..."
442 rm -f $dir/$file
443 sed '
444 /^AC_DEFUN(\[AM_INTL_SUBDIR],/,/^]/c\
445 AC_DEFUN([AM_INTL_SUBDIR], [
446 /^AC_DEFUN(\[gt_INTL_SUBDIR_CORE],/,/^]/c\
447 AC_DEFUN([gt_INTL_SUBDIR_CORE], [])
449 AC_DEFUN([gl_LOCK_EARLY], [])
450 ' $1/$dir/$file >$dir/$file
451 else
452 cp_mark_as_generated $1/$dir/$file $dir/$file
454 fi || exit
455 done
457 for dot_ig in x $vc_ignore; do
458 test $dot_ig = x && continue
459 ig=$dir/$dot_ig
460 if test -n "$copied"; then
461 insert_sorted_if_absent $ig "$copied"
462 # If an ignored file name ends with .in.h, then also add
463 # the name with just ".h". Many gnulib headers are generated,
464 # e.g., stdint.in.h -> stdint.h, dirent.in.h ->..., etc.
465 # Likewise for .gperf -> .h, .y -> .c, and .sin -> .sed
466 f=`echo "$copied"|sed 's/\.in\.h$/.h/;s/\.sin$/.sed/;s/\.y$/.c/;s/\.gperf$/.h/'`
467 insert_sorted_if_absent $ig "$f"
469 # For files like sys_stat.in.h and sys_time.in.h, record as
470 # ignorable the directory we might eventually create: sys/.
471 f=`echo "$copied"|sed 's/sys_.*\.in\.h$/sys/'`
472 insert_sorted_if_absent $ig "$f"
474 done
475 done
479 # Create boot temporary directories to import from gnulib and gettext.
480 rm -fr $bt $bt2 &&
481 mkdir $bt $bt2 || exit
483 # Import from gnulib.
485 gnulib_tool_options="\
486 --import\
487 --no-changelog\
488 --aux-dir $bt/$build_aux\
489 --doc-base $bt/doc\
490 --lib $gnulib_name\
491 --m4-base $bt/m4/\
492 --source-base $bt/lib/\
493 --tests-base $bt/tests\
494 --local-dir $local_gl_dir\
495 $gnulib_tool_option_extras\
497 echo "$0: $gnulib_tool $gnulib_tool_options --import ..."
498 $gnulib_tool $gnulib_tool_options --import $gnulib_modules &&
499 slurp $bt || exit
501 for file in $gnulib_files; do
502 symlink_to_dir "$GNULIB_SRCDIR" $file || exit
503 done
506 # Import from gettext.
507 with_gettext=yes
508 grep '^[ ]*AM_GNU_GETTEXT_VERSION(' configure.ac >/dev/null || \
509 with_gettext=no
511 if test $with_gettext = yes; then
512 echo "$0: (cd $bt2; autopoint) ..."
513 cp configure.ac $bt2 &&
514 (cd $bt2 && autopoint && rm configure.ac) &&
515 slurp $bt2 $bt || exit
517 rm -fr $bt $bt2 || exit
520 # Coreutils is unusual in that it generates some of its test-related
521 # Makefile.am files. That must be done before invoking automake.
522 mam_template=tests/Makefile.am.in
523 if test -f $mam_template; then
524 PERL=perl
525 for tool in cut head join pr sort tac tail test tr uniq wc; do
526 m=tests/$tool/Makefile.am
527 t=${m}t
528 rm -f $m $t
529 sed -n '1,/^##test-files-begin/p' $mam_template > $t
530 echo "x = $tool" >> $t
531 srcdir=tests/$tool
532 $PERL -I$srcdir -w -- tests/mk-script $srcdir --list >> $t
533 sed -n '/^##test-files-end/,$p' $mam_template >> $t
534 chmod -w $t
535 mv $t $m
536 done
539 # Reconfigure, getting other files.
541 for command in \
542 libtool \
543 'aclocal --force -I m4' \
544 'autoconf --force' \
545 'autoheader --force' \
546 'automake --add-missing --copy --force-missing';
548 if test "$command" = libtool; then
549 grep '^[ ]*AM_PROG_LIBTOOL\>' configure.ac >/dev/null ||
550 continue
551 command='libtoolize -c -f'
553 echo "$0: $command ..."
554 $command || exit
555 done
558 # Get some extra files from gnulib, overriding existing files.
559 for file in $gnulib_extra_files; do
560 case $file in
561 */INSTALL) dst=INSTALL;;
562 build-aux/*) dst=$build_aux/`expr "$file" : 'build-aux/\(.*\)'`;;
563 *) dst=$file;;
564 esac
565 symlink_to_dir "$GNULIB_SRCDIR" $file $dst || exit
566 done
568 if test $with_gettext = yes; then
569 # Create gettext configuration.
570 echo "$0: Creating po/Makevars from po/Makevars.template ..."
571 rm -f po/Makevars
572 sed '
573 /^EXTRA_LOCALE_CATEGORIES *=/s/=.*/= '"$EXTRA_LOCALE_CATEGORIES"'/
574 /^MSGID_BUGS_ADDRESS *=/s/=.*/= bug-'"$package"'@gnu.org/
575 /^XGETTEXT_OPTIONS *=/{
576 s/$/ \\/
578 '"$XGETTEXT_OPTIONS"' $${end_of_xgettext_options+}
580 ' po/Makevars.template >po/Makevars
582 if test -d runtime-po; then
583 # Similarly for runtime-po/Makevars, but not quite the same.
584 rm -f runtime-po/Makevars
585 sed '
586 /^DOMAIN *=.*/s/=.*/= '"$package"'-runtime/
587 /^subdir *=.*/s/=.*/= runtime-po/
588 /^MSGID_BUGS_ADDRESS *=/s/=.*/= bug-'"$package"'@gnu.org/
589 /^XGETTEXT_OPTIONS *=/{
590 s/$/ \\/
592 '"$XGETTEXT_OPTIONS_RUNTIME"' $${end_of_xgettext_options+}
594 ' <po/Makevars.template >runtime-po/Makevars
596 # Copy identical files from po to runtime-po.
597 (cd po && cp -p Makefile.in.in *-quot *.header *.sed *.sin ../runtime-po)
601 # Horrible, coreutils-specific kludges.
602 # Change paths in gnulib-tests/gnulib.mk from "../.." to "..".
603 m=gnulib-tests/gnulib.mk
604 sed 's,\.\./\.\.,..,g' $m > $m-t
605 mv -f $m-t $m
607 chmod a+x gnulib-tests/test-*.sh
609 echo "$0: done. Now you can run './configure'."