• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
22nl='
23'
24
25# Ensure file names are sorted consistently across platforms.
26LC_ALL=C
27export LC_ALL
28
29local_gl_dir=gl
30
31# Temporary directory names.
32bt='._bootmp'
33bt_regex=`echo "$bt"| sed 's/\./[.]/g'`
34bt2=${bt}2
35
36usage() {
37  echo >&2 "\
38Usage: $0 [OPTION]...
39Bootstrap this package from the checked-out sources.
40
41Options:
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
52If the file $0.conf exists in the same directory as this script, its
53contents are read as shell variables to configure the bootstrap.
54
55Running without arguments will suffice in most cases.
56"
57}
58
59# Configuration.
60
61# Name of the Makefile.am
62gnulib_mk=gnulib.mk
63
64# List of gnulib modules needed.
65gnulib_modules=
66
67# Any gnulib files needed that are not in modules.
68gnulib_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.
75po_download_command_format=\
76"rsync -Lrtvz 'translationproject.org::tp/latest/%s/' '%s'"
77
78extract_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'
95package=`sed -n "$extract_package_name" configure.ac` || exit
96gnulib_name=lib$package
97
98build_aux=build-aux
99source_base=lib
100m4_base=m4
101doc_base=doc
102tests_base=tests
103
104# Extra files from gnulib, which override files from other sources.
105gnulib_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.
117gnulib_tool_option_extras=
118
119# Other locale categories that need message catalogs.
120EXTRA_LOCALE_CATEGORIES=
121
122# Additional xgettext options to use.  Use "\\\newline" to break lines.
123XGETTEXT_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
130MSGID_BUGS_ADDRESS=bug-$package@gnu.org
131
132# Files we don't want to import.
133excluded_files=
134
135# File that should exist in the top directory of a checked out hierarchy,
136# but not in a distribution tarball.
137checkout_only_file=README-hacking
138
139# Whether to use copies instead of symlinks.
140copy=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.
146vc_ignore=auto
147
148# Override the default configuration, if necessary.
149# Make sure that bootstrap.conf is sourced from the current directory
150# if we were invoked as "sh bootstrap".
151case "$0" in
152  */*) test -r "$0.conf" && . "$0.conf" ;;
153  *) test -r "$0.conf" && . ./"$0.conf" ;;
154esac
155
156
157if test "$vc_ignore" = auto; then
158  vc_ignore=
159  test -d .git && vc_ignore=.gitignore
160  test -d CVS && vc_ignore="$vc_ignore .cvsignore"
161fi
162
163# Translate configuration into internal form.
164
165# Parse options.
166
167for option
168do
169  case $option in
170  --help)
171    usage
172    exit;;
173  --gnulib-srcdir=*)
174    GNULIB_SRCDIR=`expr "X$option" : 'X--gnulib-srcdir=\(.*\)'`;;
175  --skip-po)
176    SKIP_PO=t;;
177  --force)
178    checkout_only_file=;;
179  --copy)
180    copy=true;;
181  *)
182    echo >&2 "$0: $option: unknown option"
183    exit 1;;
184  esac
185done
186
187if test -n "$checkout_only_file" && test ! -r "$checkout_only_file"; then
188  echo "$0: Bootstrapping from a non-checked-out distribution is risky." >&2
189  exit 1
190fi
191
192# If $STR is not already on a line by itself in $FILE, insert it,
193# sorting the new contents of the file and replacing $FILE with the result.
194insert_sorted_if_absent() {
195  file=$1
196  str=$2
197  test -f $file || touch $file
198  echo "$str" | sort -u - $file | cmp -s - $file \
199    || echo "$str" | sort -u - $file -o $file \
200    || exit 1
201}
202
203# Die if there is no AC_CONFIG_AUX_DIR($build_aux) line in configure.ac.
204found_aux_dir=no
205grep '^[	 ]*AC_CONFIG_AUX_DIR(\['"$build_aux"'\])' configure.ac \
206    >/dev/null && found_aux_dir=yes
207grep '^[	 ]*AC_CONFIG_AUX_DIR('"$build_aux"')' configure.ac \
208    >/dev/null && found_aux_dir=yes
209if test $found_aux_dir = no; then
210  echo "$0: expected line not found in configure.ac. Add the following:" >&2
211  echo "  AC_CONFIG_AUX_DIR([$build_aux])" >&2
212  exit 1
213fi
214
215# If $build_aux doesn't exist, create it now, otherwise some bits
216# below will malfunction.  If creating it, also mark it as ignored.
217if test ! -d $build_aux; then
218  mkdir $build_aux
219  for dot_ig in x $vc_ignore; do
220    test $dot_ig = x && continue
221    insert_sorted_if_absent $dot_ig $build_aux
222  done
223fi
224
225echo "$0: Bootstrapping from checked-out $package sources..."
226
227# See if we can use gnulib's git-merge-changelog merge driver.
228if test -d .git && (git --version) >/dev/null 2>/dev/null ; then
229  if git config merge.merge-changelog.driver >/dev/null ; then
230    :
231  elif (git-merge-changelog --version) >/dev/null 2>/dev/null ; then
232    echo "initializing git-merge-changelog driver"
233    git config merge.merge-changelog.name 'GNU-style ChangeLog merge driver'
234    git config merge.merge-changelog.driver 'git-merge-changelog %O %A %B'
235  else
236    echo "consider installing git-merge-changelog from gnulib"
237  fi
238fi
239
240
241cleanup_gnulib() {
242  status=$?
243  rm -fr gnulib
244  exit $status
245}
246
247git_modules_config () {
248  test -f .gitmodules && git config --file .gitmodules "$@"
249}
250
251# Get gnulib files.
252
253case ${GNULIB_SRCDIR--} in
254-)
255  if git_modules_config submodule.gnulib.url >/dev/null; then
256    echo "$0: getting gnulib files..."
257    git submodule init || exit $?
258    git submodule update || exit $?
259
260  elif [ ! -d gnulib ]; then
261    echo "$0: getting gnulib files..."
262
263    trap cleanup_gnulib 1 2 13 15
264
265    git clone --depth 2 git://git.sv.gnu.org/gnulib ||
266      cleanup_gnulib
267
268    trap - 1 2 13 15
269  fi
270  GNULIB_SRCDIR=gnulib
271  ;;
272*)
273  # Redirect the gnulib submodule to the directory on the command line
274  # if possible.
275  if test -d "$GNULIB_SRCDIR"/.git && \
276	git_modules_config submodule.gnulib.url >/dev/null; then
277    git submodule init
278    GNULIB_SRCDIR=`cd $GNULIB_SRCDIR && pwd`
279    git config --replace-all submodule.gnulib.url $GNULIB_SRCDIR
280    echo "$0: getting gnulib files..."
281    git submodule update || exit $?
282    GNULIB_SRCDIR=gnulib
283  fi
284  ;;
285esac
286
287gnulib_tool=$GNULIB_SRCDIR/gnulib-tool
288<$gnulib_tool || exit
289
290# Get translations.
291
292download_po_files() {
293  subdir=$1
294  domain=$2
295  echo "$0: getting translations into $subdir for $domain..."
296  cmd=`printf "$po_download_command_format" "$domain" "$subdir"`
297  eval "$cmd"
298}
299
300# Download .po files to $po_dir/.reference and copy only the new
301# or modified ones into $po_dir.  Also update $po_dir/LINGUAS.
302update_po_files() {
303  # Directory containing primary .po files.
304  # Overwrite them only when we're sure a .po file is new.
305  po_dir=$1
306  domain=$2
307
308  # Download *.po files into this dir.
309  # Usually contains *.s1 checksum files.
310  ref_po_dir="$po_dir/.reference"
311
312  test -d $ref_po_dir || mkdir $ref_po_dir || return
313  download_po_files $ref_po_dir $domain \
314    && ls "$ref_po_dir"/*.po 2>/dev/null |
315      sed 's|.*/||; s|\.po$||' > "$po_dir/LINGUAS"
316
317  langs=`cd $ref_po_dir && echo *.po|sed 's/\.po//g'`
318  test "$langs" = '*' && langs=x
319  for po in $langs; do
320    case $po in x) continue;; esac
321    new_po="$ref_po_dir/$po.po"
322    cksum_file="$ref_po_dir/$po.s1"
323    if ! test -f "$cksum_file" ||
324	! test -f "$po_dir/$po.po" ||
325	! sha1sum -c --status "$cksum_file" < "$new_po" > /dev/null; then
326      echo "updated $po_dir/$po.po..."
327      cp "$new_po" "$po_dir/$po.po" && sha1sum < "$new_po" > "$cksum_file"
328    fi
329  done
330}
331
332case $SKIP_PO in
333'')
334  if test -d po; then
335    update_po_files po $package || exit
336  fi
337
338  if test -d runtime-po; then
339    update_po_files runtime-po $package-runtime || exit
340  fi;;
341esac
342
343symlink_to_dir()
344{
345  src=$1/$2
346  dst=${3-$2}
347
348  test -f "$src" && {
349
350    # If the destination directory doesn't exist, create it.
351    # This is required at least for "lib/uniwidth/cjk.h".
352    dst_dir=`dirname "$dst"`
353    if ! test -d "$dst_dir"; then
354      mkdir -p "$dst_dir"
355
356      # If we've just created a directory like lib/uniwidth,
357      # tell version control system(s) it's ignorable.
358      # FIXME: for now, this does only one level
359      parent=`dirname "$dst_dir"`
360      for dot_ig in x $vc_ignore; do
361	test $dot_ig = x && continue
362	ig=$parent/$dot_ig
363	insert_sorted_if_absent $ig `echo "$dst_dir"|sed 's,.*/,,'`
364      done
365    fi
366
367    if $copy; then
368      {
369	test ! -h "$dst" || {
370	  echo "$0: rm -f $dst" &&
371	  rm -f "$dst"
372	}
373      } &&
374      test -f "$dst" &&
375      cmp -s "$src" "$dst" || {
376	echo "$0: cp -fp $src $dst" &&
377	cp -fp "$src" "$dst"
378      }
379    else
380      test -h "$dst" &&
381      src_ls=`ls -diL "$src" 2>/dev/null` && set $src_ls && src_i=$1 &&
382      dst_ls=`ls -diL "$dst" 2>/dev/null` && set $dst_ls && dst_i=$1 &&
383      test "$src_i" = "$dst_i" || {
384	dot_dots=
385	case $src in
386	/*) ;;
387	*)
388	  case /$dst/ in
389	  *//* | */../* | */./* | /*/*/*/*/*/)
390	     echo >&2 "$0: invalid symlink calculation: $src -> $dst"
391	     exit 1;;
392	  /*/*/*/*/)	dot_dots=../../../;;
393	  /*/*/*/)	dot_dots=../../;;
394	  /*/*/)	dot_dots=../;;
395	  esac;;
396	esac
397
398	echo "$0: ln -fs $dot_dots$src $dst" &&
399	ln -fs "$dot_dots$src" "$dst"
400      }
401    fi
402  }
403}
404
405cp_mark_as_generated()
406{
407  cp_src=$1
408  cp_dst=$2
409
410  if cmp -s "$cp_src" "$GNULIB_SRCDIR/$cp_dst"; then
411    symlink_to_dir "$GNULIB_SRCDIR" "$cp_dst"
412  elif cmp -s "$cp_src" "$local_gl_dir/$cp_dst"; then
413    symlink_to_dir $local_gl_dir "$cp_dst"
414  else
415    case $cp_dst in
416      *.[ch])             c1='/* '; c2=' */';;
417      *.texi)             c1='@c '; c2=     ;;
418      *.m4|*/Make*|Make*) c1='# ' ; c2=     ;;
419      *)                  c1=     ; c2=     ;;
420    esac
421
422    # If the destination directory doesn't exist, create it.
423    # This is required at least for "lib/uniwidth/cjk.h".
424    dst_dir=`dirname "$cp_dst"`
425    test -d "$dst_dir" || mkdir -p "$dst_dir"
426
427    if test -z "$c1"; then
428      cmp -s "$cp_src" "$cp_dst" || {
429	# Copy the file first to get proper permissions if it
430	# doesn't already exist.  Then overwrite the copy.
431	echo "$0: cp -f $cp_src $cp_dst" &&
432	rm -f "$cp_dst" &&
433	cp "$cp_src" "$cp_dst-t" &&
434	sed "s!$bt_regex/!!g" "$cp_src" > "$cp_dst-t" &&
435	mv -f "$cp_dst-t" "$cp_dst"
436      }
437    else
438      # Copy the file first to get proper permissions if it
439      # doesn't already exist.  Then overwrite the copy.
440      cp "$cp_src" "$cp_dst-t" &&
441      (
442	echo "$c1-*- buffer-read-only: t -*- vi: set ro:$c2" &&
443	echo "${c1}DO NOT EDIT! GENERATED AUTOMATICALLY!$c2" &&
444	sed "s!$bt_regex/!!g" "$cp_src"
445      ) > $cp_dst-t &&
446      if cmp -s "$cp_dst-t" "$cp_dst"; then
447	rm -f "$cp_dst-t"
448      else
449	echo "$0: cp $cp_src $cp_dst # with edits" &&
450	mv -f "$cp_dst-t" "$cp_dst"
451      fi
452    fi
453  fi
454}
455
456version_controlled_file() {
457  dir=$1
458  file=$2
459  found=no
460  if test -d CVS; then
461    grep -F "/$file/" $dir/CVS/Entries 2>/dev/null |
462	     grep '^/[^/]*/[0-9]' > /dev/null && found=yes
463  elif test -d .git; then
464    git rm -n "$dir/$file" > /dev/null 2>&1 && found=yes
465  elif test -d .svn; then
466    svn log -r HEAD "$dir/$file" > /dev/null 2>&1 && found=yes
467  else
468    echo "$0: no version control for $dir/$file?" >&2
469  fi
470  test $found = yes
471}
472
473slurp() {
474  for dir in . `(cd $1 && find * -type d -print)`; do
475    copied=
476    sep=
477    for file in `ls -a $1/$dir`; do
478      case $file in
479      .|..) continue;;
480      .*) continue;; # FIXME: should all file names starting with "." be ignored?
481      esac
482      test -d $1/$dir/$file && continue
483      for excluded_file in $excluded_files; do
484	test "$dir/$file" = "$excluded_file" && continue 2
485      done
486      if test $file = Makefile.am; then
487        copied=$copied${sep}$gnulib_mk; sep=$nl
488	remove_intl='/^[^#].*\/intl/s/^/#/;'"s!$bt_regex/!!g"
489        sed "$remove_intl" $1/$dir/$file | cmp -s - $dir/$gnulib_mk || {
490	  echo "$0: Copying $1/$dir/$file to $dir/$gnulib_mk ..." &&
491	  rm -f $dir/$gnulib_mk &&
492	  sed "$remove_intl" $1/$dir/$file >$dir/$gnulib_mk
493	}
494      elif { test "${2+set}" = set && test -r $2/$dir/$file; } ||
495	   version_controlled_file $dir $file; then
496	echo "$0: $dir/$file overrides $1/$dir/$file"
497      else
498	copied=$copied$sep$file; sep=$nl
499	if test $file = gettext.m4; then
500	  echo "$0: patching m4/gettext.m4 to remove need for intl/* ..."
501	  rm -f $dir/$file
502	  sed '
503	    /^AC_DEFUN(\[AM_INTL_SUBDIR],/,/^]/c\
504	      AC_DEFUN([AM_INTL_SUBDIR], [
505	    /^AC_DEFUN(\[gt_INTL_SUBDIR_CORE],/,/^]/c\
506	      AC_DEFUN([gt_INTL_SUBDIR_CORE], [])
507	    $a\
508	      AC_DEFUN([gl_LOCK_EARLY], [])
509	  ' $1/$dir/$file >$dir/$file
510	else
511	  cp_mark_as_generated $1/$dir/$file $dir/$file
512	fi
513      fi || exit
514    done
515
516    for dot_ig in x $vc_ignore; do
517      test $dot_ig = x && continue
518      ig=$dir/$dot_ig
519      if test -n "$copied"; then
520	insert_sorted_if_absent $ig "$copied"
521	# If an ignored file name ends with .in.h, then also add
522	# the name with just ".h".  Many gnulib headers are generated,
523	# e.g., stdint.in.h -> stdint.h, dirent.in.h ->..., etc.
524	# Likewise for .gperf -> .h, .y -> .c, and .sin -> .sed
525	f=`echo "$copied"|sed 's/\.in\.h$/.h/;s/\.sin$/.sed/;s/\.y$/.c/;s/\.gperf$/.h/'`
526	insert_sorted_if_absent $ig "$f"
527
528	# For files like sys_stat.in.h and sys_time.in.h, record as
529	# ignorable the directory we might eventually create: sys/.
530	f=`echo "$copied"|sed 's/sys_.*\.in\.h$/sys/'`
531	insert_sorted_if_absent $ig "$f"
532      fi
533    done
534  done
535}
536
537
538# Create boot temporary directories to import from gnulib and gettext.
539rm -fr $bt $bt2 &&
540mkdir $bt $bt2 || exit
541
542# Import from gnulib.
543
544gnulib_tool_options="\
545 --import\
546 --no-changelog\
547 --aux-dir $bt/$build_aux\
548 --doc-base $bt/$doc_base\
549 --lib $gnulib_name\
550 --m4-base $bt/$m4_base/\
551 --source-base $bt/$source_base/\
552 --tests-base $bt/$tests_base\
553 --local-dir $local_gl_dir\
554 $gnulib_tool_option_extras\
555"
556echo "$0: $gnulib_tool $gnulib_tool_options --import ..."
557$gnulib_tool $gnulib_tool_options --import $gnulib_modules &&
558slurp $bt || exit
559
560for file in $gnulib_files; do
561  symlink_to_dir "$GNULIB_SRCDIR" $file || exit
562done
563
564
565# Import from gettext.
566with_gettext=yes
567grep '^[	 ]*AM_GNU_GETTEXT_VERSION(' configure.ac >/dev/null || \
568    with_gettext=no
569
570if test $with_gettext = yes; then
571  echo "$0: (cd $bt2; autopoint) ..."
572  cp configure.ac $bt2 &&
573  (cd $bt2 && autopoint && rm configure.ac) &&
574  slurp $bt2 $bt || exit
575fi
576rm -fr $bt $bt2 || exit
577
578# Remove any dangling symlink matching "*.m4" or "*.[ch]" in some
579# gnulib-populated directories.  Such .m4 files would cause aclocal to fail.
580# The following requires GNU find 4.2.3 or newer.  Considering the usual
581# portability constraints of this script, that may seem a very demanding
582# requirement, but it should be ok.  Ignore any failure, which is fine,
583# since this is only a convenience to help developers avoid the relatively
584# unusual case in which a symlinked-to .m4 file is git-removed from gnulib
585# between successive runs of this script.
586find "$m4_base" "$source_base" \
587  -depth \( -name '*.m4' -o -name '*.[ch]' \) \
588  -type l -xtype l -delete > /dev/null 2>&1
589
590# Reconfigure, getting other files.
591
592for command in \
593  libtool \
594  'aclocal --force -I m4' \
595  'autoconf --force' \
596  'autoheader --force' \
597  'automake --add-missing --copy --force-missing';
598do
599  if test "$command" = libtool; then
600    grep '^[	 ]*AM_PROG_LIBTOOL\>' configure.ac >/dev/null ||
601      continue
602    command='libtoolize -c -f'
603  fi
604  echo "$0: $command ..."
605  $command || exit
606done
607
608
609# Get some extra files from gnulib, overriding existing files.
610for file in $gnulib_extra_files; do
611  case $file in
612  */INSTALL) dst=INSTALL;;
613  build-aux/*) dst=$build_aux/`expr "$file" : 'build-aux/\(.*\)'`;;
614  *) dst=$file;;
615  esac
616  symlink_to_dir "$GNULIB_SRCDIR" $file $dst || exit
617done
618
619if test $with_gettext = yes; then
620  # Create gettext configuration.
621  echo "$0: Creating po/Makevars from po/Makevars.template ..."
622  rm -f po/Makevars
623  sed '
624    /^EXTRA_LOCALE_CATEGORIES *=/s/=.*/= '"$EXTRA_LOCALE_CATEGORIES"'/
625    /^MSGID_BUGS_ADDRESS *=/s/=.*/= '"$MSGID_BUGS_ADDRESS"'/
626    /^XGETTEXT_OPTIONS *=/{
627      s/$/ \\/
628      a\
629	  '"$XGETTEXT_OPTIONS"' $${end_of_xgettext_options+}
630    }
631  ' po/Makevars.template >po/Makevars
632
633  if test -d runtime-po; then
634    # Similarly for runtime-po/Makevars, but not quite the same.
635    rm -f runtime-po/Makevars
636    sed '
637      /^DOMAIN *=.*/s/=.*/= '"$package"'-runtime/
638      /^subdir *=.*/s/=.*/= runtime-po/
639      /^MSGID_BUGS_ADDRESS *=/s/=.*/= bug-'"$package"'@gnu.org/
640      /^XGETTEXT_OPTIONS *=/{
641	s/$/ \\/
642	a\
643	    '"$XGETTEXT_OPTIONS_RUNTIME"' $${end_of_xgettext_options+}
644      }
645    ' <po/Makevars.template >runtime-po/Makevars
646
647    # Copy identical files from po to runtime-po.
648    (cd po && cp -p Makefile.in.in *-quot *.header *.sed *.sin ../runtime-po)
649  fi
650fi
651
652echo "$0: done.  Now you can run './configure'."
653