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 $0.conf exists in the same directory as this script, 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 # Make sure that bootstrap.conf is sourced from the current directory 150 # if we were invoked as "sh bootstrap". 151 case "$0" in 152 */*) test -r "$0.conf" && . "$0.conf" ;; 153 *) test -r "$0.conf" && . ./"$0.conf" ;; 154 esac 155 156 157 if test "$vc_ignore" = auto; then 158 vc_ignore= 159 test -d .git && vc_ignore=.gitignore 160 test -d CVS && vc_ignore="$vc_ignore .cvsignore" 161 fi 162 163 # Translate configuration into internal form. 164 165 # Parse options. 166 167 for option 168 do 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 185 done 186 187 if 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 190 fi 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. 194 insert_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. 204 found_aux_dir=no 205 grep '^[ ]*AC_CONFIG_AUX_DIR(\['"$build_aux"'\])' configure.ac \ 206 >/dev/null && found_aux_dir=yes 207 grep '^[ ]*AC_CONFIG_AUX_DIR('"$build_aux"')' configure.ac \ 208 >/dev/null && found_aux_dir=yes 209 if 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 213 fi 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. 217 if 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 223 fi 224 225 echo "$0: Bootstrapping from checked-out $package sources..." 226 227 # See if we can use gnulib's git-merge-changelog merge driver. 228 if 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 238 fi 239 240 241 cleanup_gnulib() { 242 status=$? 243 rm -fr gnulib 244 exit $status 245 } 246 247 git_modules_config () { 248 test -f .gitmodules && git config --file .gitmodules "$@" 249 } 250 251 # Get gnulib files. 252 253 case ${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 ;; 285 esac 286 287 gnulib_tool=$GNULIB_SRCDIR/gnulib-tool 288 <$gnulib_tool || exit 289 290 # Get translations. 291 292 download_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. 302 update_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 332 case $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;; 341 esac 342 343 symlink_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 405 cp_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 456 version_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 473 slurp() { 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. 539 rm -fr $bt $bt2 && 540 mkdir $bt $bt2 || exit 541 542 # Import from gnulib. 543 544 gnulib_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 " 556 echo "$0: $gnulib_tool $gnulib_tool_options --import ..." 557 $gnulib_tool $gnulib_tool_options --import $gnulib_modules && 558 slurp $bt || exit 559 560 for file in $gnulib_files; do 561 symlink_to_dir "$GNULIB_SRCDIR" $file || exit 562 done 563 564 565 # Import from gettext. 566 with_gettext=yes 567 grep '^[ ]*AM_GNU_GETTEXT_VERSION(' configure.ac >/dev/null || \ 568 with_gettext=no 569 570 if 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 575 fi 576 rm -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. 586 find "$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 592 for command in \ 593 libtool \ 594 'aclocal --force -I m4' \ 595 'autoconf --force' \ 596 'autoheader --force' \ 597 'automake --add-missing --copy --force-missing'; 598 do 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 606 done 607 608 609 # Get some extra files from gnulib, overriding existing files. 610 for 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 617 done 618 619 if 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 650 fi 651 652 echo "$0: done. Now you can run './configure'." 653