53f3817d362bcf9b38fadca742635c05ddb3f27b
[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 "X$option" : 'X--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 git_modules_config () {
228   GIT_CONFIG_LOCAL=.gitmodules git config "$@"
229 }
230
231 # Get gnulib files.
232
233 case ${GNULIB_SRCDIR--} in
234 -)
235   if git_modules_config submodule.gnulib.url >/dev/null; then
236     echo "$0: getting gnulib files..."
237     git submodule init || exit $?
238     git submodule update || exit $?
239
240   elif [ ! -d gnulib ]; then
241     echo "$0: getting gnulib files..."
242
243     trap cleanup_gnulib 1 2 13 15
244
245     git clone --depth 2 git://git.sv.gnu.org/gnulib ||
246       cleanup_gnulib
247
248     trap - 1 2 13 15
249   fi
250   GNULIB_SRCDIR=gnulib
251   ;;
252 *)
253   # Redirect the gnulib submodule to the directory on the command line
254   # if possible.
255   if test -d "$GNULIB_SRCDIR"/.git && \
256         git_modules_config submodule.gnulib.url >/dev/null; then
257     git submodule init
258     GNULIB_SRCDIR=`cd $GNULIB_SRCDIR && pwd`
259     git config --replace-all submodule.gnulib.url $GNULIB_SRCDIR
260     echo "$0: getting gnulib files..."
261     git submodule update || exit $?
262     GNULIB_SRCDIR=gnulib
263   fi
264   ;;
265 esac
266
267 gnulib_tool=$GNULIB_SRCDIR/gnulib-tool
268 <$gnulib_tool || exit
269
270 # Get translations.
271
272 download_po_files() {
273   subdir=$1
274   domain=$2
275   echo "$0: getting translations into $subdir for $domain..."
276   cmd=`printf "$po_download_command_format" "$domain" "$subdir"`
277   eval "$cmd"
278 }
279
280 # Download .po files to $po_dir/.reference and copy only the new
281 # or modified ones into $po_dir.  Also update $po_dir/LINGUAS.
282 update_po_files() {
283   # Directory containing primary .po files.
284   # Overwrite them only when we're sure a .po file is new.
285   po_dir=$1
286   domain=$2
287
288   # Download *.po files into this dir.
289   # Usually contains *.s1 checksum files.
290   ref_po_dir="$po_dir/.reference"
291
292   test -d $ref_po_dir || mkdir $ref_po_dir || return
293   download_po_files $ref_po_dir $domain \
294     && ls "$ref_po_dir"/*.po 2>/dev/null |
295       sed 's|.*/||; s|\.po$||' > "$po_dir/LINGUAS"
296
297   langs=`cd $ref_po_dir && echo *.po|sed 's/\.po//g'`
298   test "$langs" = '*' && langs=x
299   for po in $langs; do
300     case $po in x) continue;; esac
301     new_po="$ref_po_dir/$po.po"
302     cksum_file="$ref_po_dir/$po.s1"
303     if ! test -f "$cksum_file" ||
304         ! test -f "$po_dir/$po.po" ||
305         ! sha1sum -c --status "$cksum_file" < "$new_po" > /dev/null; then
306       echo "updated $po_dir/$po.po..."
307       cp "$new_po" "$po_dir/$po.po" && sha1sum < "$new_po" > "$cksum_file"
308     fi
309   done
310 }
311
312 case $SKIP_PO in
313 '')
314   if test -d po; then
315     update_po_files po $package || exit
316   fi
317
318   if test -d runtime-po; then
319     update_po_files runtime-po $package-runtime || exit
320   fi;;
321 esac
322
323 symlink_to_dir()
324 {
325   src=$1/$2
326   dst=${3-$2}
327
328   test -f "$src" && {
329
330     # If the destination directory doesn't exist, create it.
331     # This is required at least for "lib/uniwidth/cjk.h".
332     dst_dir=`dirname "$dst"`
333     if ! test -d "$dst_dir"; then
334       mkdir -p "$dst_dir"
335
336       # If we've just created a directory like lib/uniwidth,
337       # tell version control system(s) it's ignorable.
338       # FIXME: for now, this does only one level
339       parent=`dirname "$dst_dir"`
340       for dot_ig in x $vc_ignore; do
341         test $dot_ig = x && continue
342         ig=$parent/$dot_ig
343         insert_sorted_if_absent $ig `echo "$dst_dir"|sed 's,.*/,,'`
344       done
345     fi
346
347     if $copy; then
348       {
349         test ! -h "$dst" || {
350           echo "$0: rm -f $dst" &&
351           rm -f "$dst"
352         }
353       } &&
354       test -f "$dst" &&
355       cmp -s "$src" "$dst" || {
356         echo "$0: cp -fp $src $dst" &&
357         cp -fp "$src" "$dst"
358       }
359     else
360       test -h "$dst" &&
361       src_ls=`ls -diL "$src" 2>/dev/null` && set $src_ls && src_i=$1 &&
362       dst_ls=`ls -diL "$dst" 2>/dev/null` && set $dst_ls && dst_i=$1 &&
363       test "$src_i" = "$dst_i" || {
364         dot_dots=
365         case $src in
366         /*) ;;
367         *)
368           case /$dst/ in
369           *//* | */../* | */./* | /*/*/*/*/*/)
370              echo >&2 "$0: invalid symlink calculation: $src -> $dst"
371              exit 1;;
372           /*/*/*/*/)    dot_dots=../../../;;
373           /*/*/*/)      dot_dots=../../;;
374           /*/*/)        dot_dots=../;;
375           esac;;
376         esac
377
378         echo "$0: ln -fs $dot_dots$src $dst" &&
379         ln -fs "$dot_dots$src" "$dst"
380       }
381     fi
382   }
383 }
384
385 cp_mark_as_generated()
386 {
387   cp_src=$1
388   cp_dst=$2
389
390   if cmp -s "$cp_src" "$GNULIB_SRCDIR/$cp_dst"; then
391     symlink_to_dir "$GNULIB_SRCDIR" "$cp_dst"
392   elif cmp -s "$cp_src" "$local_gl_dir/$cp_dst"; then
393     symlink_to_dir $local_gl_dir "$cp_dst"
394   else
395     case $cp_dst in
396       *.[ch])             c1='/* '; c2=' */';;
397       *.texi)             c1='@c '; c2=     ;;
398       *.m4|*/Make*|Make*) c1='# ' ; c2=     ;;
399       *)                  c1=     ; c2=     ;;
400     esac
401
402     # If the destination directory doesn't exist, create it.
403     # This is required at least for "lib/uniwidth/cjk.h".
404     dst_dir=`dirname "$cp_dst"`
405     test -d "$dst_dir" || mkdir -p "$dst_dir"
406
407     if test -z "$c1"; then
408       cmp -s "$cp_src" "$cp_dst" || {
409         # Copy the file first to get proper permissions if it
410         # doesn't already exist.  Then overwrite the copy.
411         echo "$0: cp -f $cp_src $cp_dst" &&
412         rm -f "$cp_dst" &&
413         cp "$cp_src" "$cp_dst-t" &&
414         sed "s!$bt_regex/!!g" "$cp_src" > "$cp_dst-t" &&
415         mv -f "$cp_dst-t" "$cp_dst"
416       }
417     else
418       # Copy the file first to get proper permissions if it
419       # doesn't already exist.  Then overwrite the copy.
420       cp "$cp_src" "$cp_dst-t" &&
421       (
422         echo "$c1-*- buffer-read-only: t -*- vi: set ro:$c2" &&
423         echo "${c1}DO NOT EDIT! GENERATED AUTOMATICALLY!$c2" &&
424         sed "s!$bt_regex/!!g" "$cp_src"
425       ) > $cp_dst-t &&
426       if cmp -s "$cp_dst-t" "$cp_dst"; then
427         rm -f "$cp_dst-t"
428       else
429         echo "$0: cp $cp_src $cp_dst # with edits" &&
430         mv -f "$cp_dst-t" "$cp_dst"
431       fi
432     fi
433   fi
434 }
435
436 version_controlled_file() {
437   dir=$1
438   file=$2
439   found=no
440   if test -d CVS; then
441     grep -F "/$file/" $dir/CVS/Entries 2>/dev/null |
442              grep '^/[^/]*/[0-9]' > /dev/null && found=yes
443   elif test -d .git; then
444     git rm -n "$dir/$file" > /dev/null 2>&1 && found=yes
445   elif test -d .svn; then
446     svn log -r HEAD "$dir/$file" > /dev/null 2>&1 && found=yes
447   else
448     echo "$0: no version control for $dir/$file?" >&2
449   fi
450   test $found = yes
451 }
452
453 slurp() {
454   for dir in . `(cd $1 && find * -type d -print)`; do
455     copied=
456     sep=
457     for file in `ls -a $1/$dir`; do
458       case $file in
459       .|..) continue;;
460       .*) continue;; # FIXME: should all file names starting with "." be ignored?
461       esac
462       test -d $1/$dir/$file && continue
463       for excluded_file in $excluded_files; do
464         test "$dir/$file" = "$excluded_file" && continue 2
465       done
466       if test $file = Makefile.am; then
467         copied=$copied${sep}$gnulib_mk; sep=$nl
468         remove_intl='/^[^#].*\/intl/s/^/#/;'"s!$bt_regex/!!g"
469         sed "$remove_intl" $1/$dir/$file | cmp -s - $dir/$gnulib_mk || {
470           echo "$0: Copying $1/$dir/$file to $dir/$gnulib_mk ..." &&
471           rm -f $dir/$gnulib_mk &&
472           sed "$remove_intl" $1/$dir/$file >$dir/$gnulib_mk
473         }
474       elif { test "${2+set}" = set && test -r $2/$dir/$file; } ||
475            version_controlled_file $dir $file; then
476         echo "$0: $dir/$file overrides $1/$dir/$file"
477       else
478         copied=$copied$sep$file; sep=$nl
479         if test $file = gettext.m4; then
480           echo "$0: patching m4/gettext.m4 to remove need for intl/* ..."
481           rm -f $dir/$file
482           sed '
483             /^AC_DEFUN(\[AM_INTL_SUBDIR],/,/^]/c\
484               AC_DEFUN([AM_INTL_SUBDIR], [
485             /^AC_DEFUN(\[gt_INTL_SUBDIR_CORE],/,/^]/c\
486               AC_DEFUN([gt_INTL_SUBDIR_CORE], [])
487             $a\
488               AC_DEFUN([gl_LOCK_EARLY], [])
489           ' $1/$dir/$file >$dir/$file
490         else
491           cp_mark_as_generated $1/$dir/$file $dir/$file
492         fi
493       fi || exit
494     done
495
496     for dot_ig in x $vc_ignore; do
497       test $dot_ig = x && continue
498       ig=$dir/$dot_ig
499       if test -n "$copied"; then
500         insert_sorted_if_absent $ig "$copied"
501         # If an ignored file name ends with .in.h, then also add
502         # the name with just ".h".  Many gnulib headers are generated,
503         # e.g., stdint.in.h -> stdint.h, dirent.in.h ->..., etc.
504         # Likewise for .gperf -> .h, .y -> .c, and .sin -> .sed
505         f=`echo "$copied"|sed 's/\.in\.h$/.h/;s/\.sin$/.sed/;s/\.y$/.c/;s/\.gperf$/.h/'`
506         insert_sorted_if_absent $ig "$f"
507
508         # For files like sys_stat.in.h and sys_time.in.h, record as
509         # ignorable the directory we might eventually create: sys/.
510         f=`echo "$copied"|sed 's/sys_.*\.in\.h$/sys/'`
511         insert_sorted_if_absent $ig "$f"
512       fi
513     done
514   done
515 }
516
517
518 # Create boot temporary directories to import from gnulib and gettext.
519 rm -fr $bt $bt2 &&
520 mkdir $bt $bt2 || exit
521
522 # Import from gnulib.
523
524 gnulib_tool_options="\
525  --import\
526  --no-changelog\
527  --aux-dir $bt/$build_aux\
528  --doc-base $bt/$doc_base\
529  --lib $gnulib_name\
530  --m4-base $bt/$m4_base/\
531  --source-base $bt/$source_base/\
532  --tests-base $bt/$tests_base\
533  --local-dir $local_gl_dir\
534  $gnulib_tool_option_extras\
535 "
536 echo "$0: $gnulib_tool $gnulib_tool_options --import ..."
537 $gnulib_tool $gnulib_tool_options --import $gnulib_modules &&
538 slurp $bt || exit
539
540 for file in $gnulib_files; do
541   symlink_to_dir "$GNULIB_SRCDIR" $file || exit
542 done
543
544
545 # Import from gettext.
546 with_gettext=yes
547 grep '^[         ]*AM_GNU_GETTEXT_VERSION(' configure.ac >/dev/null || \
548     with_gettext=no
549
550 if test $with_gettext = yes; then
551   echo "$0: (cd $bt2; autopoint) ..."
552   cp configure.ac $bt2 &&
553   (cd $bt2 && autopoint && rm configure.ac) &&
554   slurp $bt2 $bt || exit
555 fi
556 rm -fr $bt $bt2 || exit
557
558 # Remove any dangling symlink matching "*.m4" or "*.[ch]" in some
559 # gnulib-populated directories.  Such .m4 files would cause aclocal to fail.
560 # The following requires GNU find 4.2.3 or newer.  Considering the usual
561 # portability constraints of this script, that may seem a very demanding
562 # requirement, but it should be ok.  Ignore any failure, which is fine,
563 # since this is only a convenience to help developers avoid the relatively
564 # unusual case in which a symlinked-to .m4 file is git-removed from gnulib
565 # between successive runs of this script.
566 find "$m4_base" "$source_base" \
567   -depth \( -name '*.m4' -o -name '*.[ch]' \) \
568   -type l -xtype l -delete > /dev/null 2>&1
569
570 # Reconfigure, getting other files.
571
572 for command in \
573   libtool \
574   'aclocal --force -I m4' \
575   'autoconf --force' \
576   'autoheader --force' \
577   'automake --add-missing --copy --force-missing';
578 do
579   if test "$command" = libtool; then
580     grep '^[     ]*AM_PROG_LIBTOOL\>' configure.ac >/dev/null ||
581       continue
582     command='libtoolize -c -f'
583   fi
584   echo "$0: $command ..."
585   $command || exit
586 done
587
588
589 # Get some extra files from gnulib, overriding existing files.
590 for file in $gnulib_extra_files; do
591   case $file in
592   */INSTALL) dst=INSTALL;;
593   build-aux/*) dst=$build_aux/`expr "$file" : 'build-aux/\(.*\)'`;;
594   *) dst=$file;;
595   esac
596   symlink_to_dir "$GNULIB_SRCDIR" $file $dst || exit
597 done
598
599 if test $with_gettext = yes; then
600   # Create gettext configuration.
601   echo "$0: Creating po/Makevars from po/Makevars.template ..."
602   rm -f po/Makevars
603   sed '
604     /^EXTRA_LOCALE_CATEGORIES *=/s/=.*/= '"$EXTRA_LOCALE_CATEGORIES"'/
605     /^MSGID_BUGS_ADDRESS *=/s/=.*/= '"$MSGID_BUGS_ADDRESS"'/
606     /^XGETTEXT_OPTIONS *=/{
607       s/$/ \\/
608       a\
609           '"$XGETTEXT_OPTIONS"' $${end_of_xgettext_options+}
610     }
611   ' po/Makevars.template >po/Makevars
612
613   if test -d runtime-po; then
614     # Similarly for runtime-po/Makevars, but not quite the same.
615     rm -f runtime-po/Makevars
616     sed '
617       /^DOMAIN *=.*/s/=.*/= '"$package"'-runtime/
618       /^subdir *=.*/s/=.*/= runtime-po/
619       /^MSGID_BUGS_ADDRESS *=/s/=.*/= bug-'"$package"'@gnu.org/
620       /^XGETTEXT_OPTIONS *=/{
621         s/$/ \\/
622         a\
623             '"$XGETTEXT_OPTIONS_RUNTIME"' $${end_of_xgettext_options+}
624       }
625     ' <po/Makevars.template >runtime-po/Makevars
626
627     # Copy identical files from po to runtime-po.
628     (cd po && cp -p Makefile.in.in *-quot *.header *.sed *.sin ../runtime-po)
629   fi
630 fi
631
632 echo "$0: done.  Now you can run './configure'."