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