#! /bin/sh # Print a version string. scriptversion=2010-09-21.05; # UTC # Bootstrap this package from checked-out sources. # Written by Gary V. Vaughan, 2010 # Copyright (C) 2010 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # Originally written by Paul Eggert. The canonical version of this # script is maintained as build-aux/bootstrap in gnulib, however, to # be useful to your project, you should place a copy of it under # version control in the top-level directory of your project. The # intent is that all customization can be done with a bootstrap.conf # file also maintained in your version control; gnulib comes with a # template build-aux/bootstrap.conf to get you started. # Please report bugs or propose patches to address@hidden README=' ## ================================================================== ## ## ## ## DO NOT EDIT THIS FILE, CUSTOMIZE IT USING A BOOTSTRAP.CONF ## ## ## ## ================================================================== ## 1. Customisation ================ There are four ways to customize the functionality of this script, all requiring creation of a `bootstrap.conf` file in the same directory as this file: 1.1. Configuration Variables ---------------------------- For all but the most complex customisations, you can change (or alter) the value of any of the shell variables described in the "Configuration" section of this file by setting them to whatever value is most appropriate to your package in your `bootstrap.conf` file. vc_ignore=".gitignore" 1.2 Require Variables --------------------- Many of the functions in this script should not be executed more than once, which is achieved by initially storing the name of that function in a variable initially, so that it is called with: $require_gnulib_tool At this stage, the value of the variable is interpreted as a function call by the shell, and the named function then runs. Under normal circumstances, functions that are called in this way always set their associated variable name to simply `:` so that subsequent occurrences of `$require_gnulib_tool` have no effect. That means you can easily skip any functions that are called like this by unconditionally setting the require variable to `:` in your `bootstrap.conf`. So, for example, if your package makes no use of `gnulib-tool`, you can add the following to you `bootstrap.conf`: require_gnulib_tool=: You should be aware, however, that the function calls managed by this mechanism are designed to be called one time to ensure that some resource is available for use by the rest of any function that uses a $require_some_resource. Be careful to ensure that you remove any code paths that try to use that resource if you have effectively disabled it by setting its variable to `:` early on. 1.3. Hook Functions ------------------- Many of the key functions in this script will run one or more hook functions before they return. Essentially, all this script does is to define a lot of functions (some of which will run hooks), then source the contents of your `bootstrap.conf` customizations, and then run the `func_bootstrap` function. Look at the doc-comments above `func_bootstrap` and the functions that it calls to find where you can hook your own functions to be called during the normal execution of this script. my_silent_option () { $debug_cmd case $1 in --silent|-s) opt_silent=:; shift ;; esac # return modified option list func_quote_for_eval ${1+"$@"} func_run_hooks_result="$func_quote_for_eval_result" } func_add_hook func_parse_options my_silent_option 1.4. Function Replacement ------------------------- With some complex packages, you might find that some selection of functions called during the normal execution of this script are wholly inappropriate for your project, and disabling "$require_some_resource" functions and hooking in additional code is not enough to avoid or radically alter the parts of "bootstrap" you do not like. In that case you can simply rewrite a new implementation of whatever function(s) you want to replace in your `bootstrap.conf`, so that by the time "func_bootstrap" is called at the end of this script your new implementation is in place. func_echo () { # respect new --silent option $opt_silent || echo "$progname: $*" } 2. Usage Patterns ================= There are two ways to incorporate gnulib into your package, which are both supported by this script. Be sure that everyone working on your package is using the same usage pattern, or things will be bad! 2.1 Configuration all kept in `bootstrap.conf` ---------------------------------------------- All the parameters for running `gnulib-tool` and others are maintained in `bootstrap.conf`. This is the default usage pattern. In order for this to work, when you wish to add or remove a gnulib module from your package, amend the value of `gnulib_modules` in `bootstrap.conf` (and similarly for any other parameters) and rerun `bootstrap` to import everything anew. To avoid things getting out of sync, you should never run `gnulib-tool` directly. 2.2 Gnulib configuration stored in `gnulib-cache.m4` ---------------------------------------------------- To implement this usage pattern, leave the value of `gnulib_modules` and the `gl_xxx` empty in `bootstrap.conf` and call `gnulib-tool --import ...` from your shell and check that `gnulib-cache.m4` reflects the values you wanted. From now on you can either call `gnulib-tool --update` or rerun `bootstrap` whenever you want to resync the package modules with your local gnulib checkout. If you wish to add or remove a gnulib module from your package, call `gnulib-tool --import-add ...` or `gnulib-tool --import- remove` respectively. 3. Known Bugs ============= * gnulib-tool has no `--force` option, so sometimes symlinks are left pointing to an old gnulib tree (even with `./bootstrap --force`): $ ./bootstrap --skip-git --gnulib-srcdir=../gnulib $ ./bootstrap --gnulib-srcdir=../gnulib --force note that plenty of symlinks still point to ../gnulib instead of having being retargeted to the submodule in ./gnulib. ' ## ------------------------------- ## ## User overridable command paths. ## ## ------------------------------- ## # All uppercase denotes values stored in the environment. These # variables should generally be overridden by the user - however, we do # set them to `true' in some parts of this script to prevent them being # called at the wrong time by other tools that we call (`autoreconf', # for example). # # We also allow `LIBTOOLIZE' and `M4' to be overridden, and export the # result for child processes, but they are handled by the function # `func_find_tool' and not defaulted in this section. : "${ACLOCAL=aclocal}" : "${AUTOCONF=autoconf}" : "${AUTOHEADER=autoheader}" : "${AUTOM4TE=autom4te}" : "${AUTOHEADER=autoheader}" : "${AUTOMAKE=automake}" : "${AUTOPOINT=autopoint}" : "${AUTORECONF=autoreconf}" : "${CMP=cmp}" : "${CONFIG_SHELL=/bin/sh}" : "${EGREP=egrep}" : "${FGREP=fgrep}" : "${GIT=git}" : "${GREP=grep}" : "${LN_S=ln -s}" : "${RM=rm}" : "${SED=sed}" export ACLOCAL export AUTOCONF export AUTOHEADER export AUTOM4TE export AUTOHEADER export AUTOMAKE export AUTOPOINT export AUTORECONF ## -------------- ## ## Configuration. ## ## -------------- ## # Short help message in response to `-h'. Add to this in `bootstrap.conf' # if you accept any additional options. usage_message="Bootstrap this package from the checked-out sources. Common Bootstrap Options: -c, --copy copy files instead of creating symbolic links. --debug enable verbose shell tracing -n, --dry-run print commands rather than running them -f, --force attempt to bootstrap even if the sources seem not to have been checked out. --gnulib-srcdir=DIRNAME specify a local directory where gnulib sources reside. Use this if you already have the gnulib sources on your machine, and don't want to waste your bandwidth downloading them again. Defaults to \$GNULIB_SRCDIR. --skip-git do not fetch files from remote repositories --skip-po do not download po files. -v, --verbose verbosely report processing --version print version information and exit -W, --warnings=CATEGORY report the warnings falling in CATEGORY [all] -h, --help print short or long help message and exit " # Warning categories used by `bootstrap', append others if you use them # in your `bootstrap.conf'. warning_categories="recommend settings upgrade" # Additional text appended to `usage_message' in response to `--help'. long_help_message=" Warning categories include: \`all' show all warnings \`none' turn off all the warnings \`error' warnings are treated as fatal errors \`recommend' show warnings about missing recommended packages \`settings' show warnings about missing \`bootstrap.conf' settings \`upgrade' show warnings about out-dated files If the file $progpath.conf exists in the same directory as this script, its contents are read as shell variables to configure the bootstrap. For build prerequisites, environment variables like \$AUTOCONF and \$AMTAR are honored. Running without arguments will suffice in most cases. " # A newline delimited list of triples of programs (that respond to # --version), the minimum version numbers required (or just `-' in the # version field if any version will be sufficient) and homepage URLs # to help locate missing packages. buildreq= # Name of a file containing instructions on installing missing packages # required in `buildreq'. buildreq_readme=README-hacking # These are extracted from AC_INIT in configure.ac, though you can # override those values in `bootstrap.conf' if you prefer. build_aux= macro_dir= package= package_name= package_version= package_bugreport= # These are extracted from `gnulib-cache.m4', or else fall-back # automatically on the gnulib defaults; unless you set the values # manually in `bootstrap.conf'. doc_base= gnulib_mk= gnulib_name= local_gl_dir= source_base= tests_base= # The list of gnulib modules required at `gnulib-tool' time. If you # check `gnulib-cache.m4' into your repository, then this list will be # extracted automatically. gnulib_modules= # Any gnulib files needed that are not in modules. gnulib_files= # Extra gnulib files that are not in modules, which override files of # the same name installed by other bootstrap tools. gnulib_non_module_files=" build-aux/compile build-aux/install-sh build-aux/missing build-aux/mdate-sh build-aux/texinfo.tex build-aux/depcomp build-aux/config.guess build-aux/config.sub doc/INSTALL " # Relative path to the local gnulib submodule, and url to the upstream # git repository. If you have a gnulib entry in your .gitmodules file, # these values are ignored. gnulib_path= gnulib_url= # Additional gnulib-tool options to use. gnulib_tool_options=" --no-changelog " # bootstrap removes any macro-files that are not included by aclocal.m4, # except for files listed in this variable which are always kept. gnulib_precious=" gnulib-tool.m4 " # When truncating long commands for display, always allow at least this # many characters before truncating. min_cmd_len=160 # The command to download all .po files for a specified domain into # a specified directory. Fill in the first %s is the domain name, and # the second with the destination directory. Use rsync's -L and -r # options because the latest/%s directory and the .po files within are # all symlinks. po_download_command_format=\ "rsync --delete --exclude '*.s1' -Lrtvz \ 'translationproject.org::tp/latest/%s/' '%s'" # Other locale categories that need message catalogs. extra_locale_categories= # Additional xgettext options to use. Gnulib might provide you with an # extensive list of additional options to append to this, but gettext # 0.16.1 and newer appends them automaticaly, so you can safely ignore # the complaints from `gnulib-tool' if your $configure_ac states: # # AM_GNU_GETTEXT_VERSION([0.16.1]) xgettext_options=" --flag=_:1:pass-c-format --flag=N_:1:pass-c-format " # Package copyright holder for gettext files. Defaults to FSF if unset. copyright_holder= # File that should exist in the top directory of a checked out hierarchy, # but not in a distribution tarball. checkout_only_file= # Whether to use copies instead of symlinks by default (if set to true, # the --copy option has no effect). copy=false # Set this to ".cvsignore .gitignore" in `bootstrap.conf' if you want # those files to be generated in directories like `lib/', `m4/', and `po/', # or set it to "auto" to make this script select which to use based # on which version control system (if any) is used in the source directory. # Or set it to "none" to ignore VCS ignore files entirely. Default is # "auto". vc_ignore= ## -------------------- ## ## Shell normalisation. ## ## -------------------- ## # NLS nuisances. LANGUAGE=C export LANGUAGE # Ensure file names are sorted consistently across platforms. LC_ALL=C export LC_ALL # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH ## ------------------------- ## ## Hook function management. ## ## ------------------------- ## # This section contains functions for adding, removing, and running hooks # to the main code. A hook is just a named list of of function, that can # be run in order later on. # func_append VAR VALUE # --------------------- # Append VALUE onto the existing contents of VAR. if (eval 'x=a; x+=" b"; test "x$x" = "xa b"') 2>/dev/null then # This is an XSI compatible shell, allowing a faster implementation... eval 'func_append () { $debug_cmd eval "$1+=\$2" }' else # ...otherwise fall back to using expr, which is often a shell builtin. func_append () { $debug_cmd eval "$1=\$$1\$2" } fi # func_hookable FUNC_NAME # ----------------------- # Declare that FUNC_NAME will run hooks added with # `func_add_hook FUNC_NAME ...'. func_hookable () { $debug_cmd func_append hookable_funcs " $1" } # func_add_hook FUNC_NAME HOOK_FUNC # --------------------------------- # Request that FUNC_NAME call HOOK_FUNC before it returns. FUNC_NAME must # first have been declared "hookable" by a coll to `func_hookable'. func_add_hook () { $debug_cmd case " $hookable_funcs " in *" $1 "*) ;; *) func_fatal_error "Error: \`$1' does not accept hook functions." ;; esac eval func_append ${1}_hooks '" $2"' } # func_remove_hook FUNC_NAME HOOK_FUNC # ------------------------------------ # Remove HOOK_FUNC from the list of functions called by FUNC_NAME. func_remove_hook () { $debug_cmd eval ${1}_hooks='`echo "\$'$1'_hooks" |$SED "s| '$2'||"`' } # func_run_hooks FUNC_NAME [ARG]... # --------------------------------- # Run all hook functions registered to FUNC_NAME. func_run_hooks () { $debug_cmd case " $hookable_funcs " in *" $1 "*) ;; *) func_fatal_error "Error: \`$1' does not support hook funcions.n" ;; esac eval hook_funcs="\$$1_hooks" # shift away the first argument (FUNC_NAME) shift func_run_hooks_result=${1+"$@"} for hook_func in $hook_funcs; do eval $hook_func '"$@"' # store returned options list back into positional # parameters for next `cmd' execution. eval set dummy "$func_run_hooks_result"; shift done } ## ------------------- ## ## Hookable functions. ## ## ------------------- ## # After `bootstrap.conf' has been sourced, execution proceeds by calling # `func_bootstrap'. Where a function is decorated with `func_hookable # func_name', you will find a matching `func_run_hooks func_name' which # executes all functions added with `func_add_hook func_name my_func'. # # You might notice that many of these functions begin with a series of # `$require_foo' lines. See the docu-comments at the start of the # `Resource management' section for a description of what these are. # func_bootstrap [ARG]... # ----------------------- # All the functions called inside func_bootstrap are hookable. See the # the individual implementations for details. func_bootstrap () { $debug_cmd # Save the current positional parameters to prevent them being # corrupted by calls to `set' in `func_init'. func_quote_for_eval ${1+"$@"} my_saved_positional_parameters="$func_quote_for_eval_result" # initialisation func_init # option processing eval func_options "$my_saved_positional_parameters" # post-option preparation func_prep # reconfigure the package func_reconfigure # finalisation func_fini } # func_init # --------- # Any early initialisations can be hooked to this function. Consider # whether you can hook onto `func_prep' instead, because if you hook # any slow to execute code in here, it will also add to the time before # `./bootstrap --version' can respond. func_hookable func_init func_init () { $debug_cmd func_run_hooks func_init } # func_options [ARG]... # --------------------- # All the functions called inside func_options are hookable. See the # individual implementations for details. func_hookable func_options func_options () { $debug_cmd func_options_prep ${1+"$@"} eval func_parse_options \ ${func_options_prep_result+"$func_options_prep_result"} eval func_validate_options \ ${func_parse_options+"$func_parse_options_result"} eval func_run_hooks func_options \ ${func_validate_options_result+"$func_validate_options_result"} # save modified positional parameters for caller func_options_result="$func_run_hooks_result" } # func_options_prep [ARG]... # -------------------------- # All initialisations required before starting the option parse loop. # Note that when calling hook functions, we pass through the list of # positional parameters. If a hook function modifies that list, and # needs to propogate that back to rest of this script, then the complete # modified list must be put in `func_run_hooks_result' before # returning. func_hookable func_options_prep func_options_prep () { $debug_cmd warning_func=func_error # Option defaults: opt_copy=${copy-false} opt_dry_run=false opt_force=false opt_gnulib_srcdir="$GNULIB_SRCDIR" opt_skip_git=false opt_skip_po=false opt_warning= opt_verbose=false func_run_hooks func_options_prep ${1+"$@"} # save modified positional parameters for caller func_options_prep_result="$func_run_hooks_result" } # func_parse_options [ARG]... # --------------------------- # The main option parsing loop. # # In order to add your own option parsing hooks, you must accept the # full positional parameter list in your hook function, remove any # options that you action, and then pass back the remaining unprocessed # options in `func_run_hooks_result', escaped suitably for `eval'. Like # this: # # my_silent_option () # { # $debug_cmd # # case $1 in # --silent|-s) opt_silent=:; shift ;; # esac # # func_quote_for_eval ${1+"$@"} # func_run_hooks_result="$func_quote_for_eval_result" # } # func_add_hook func_parse_options my_silent_option # func_hookable func_parse_options func_parse_options () { $debug_cmd func_parse_options_result= # this just eases exit handling while test $# -gt 0; do # Defer to hook functions for initial option parsing, so they # get priority in the event of reusing an option name. func_run_hooks func_parse_options ${1+"$@"} # Adjust func_parse_options positional parameters to match eval set dummy "$func_run_hooks_result"; shift opt="$1" shift case $opt in --debug|-x) debug_cmd='set -x' func_echo "enabling shell trace mode" $debug_cmd ;; --dry-run|--dryrun|-n) opt_dry_run=: ;; --copy|-c) opt_copy=: ;; --force|-f) opt_force=: ;; --gnulib-srcdir) test $# = 0 && func_missing_arg $opt && break opt_gnulib_srcdir="$1" shift ;; --skip-git) opt_skip_git=: ;; --skip-po) opt_skip_po=: ;; --verbose|-v) opt_verbose=: ;; --warnings|--warning|-W) test $# = 0 && func_missing_arg $opt && break case " $1 " in " all ") opt_warning=" $warning_categories" ;; " none ") opt_warning=" none" warning_func=: ;; " error ") warning_func=func_fatal_error ;; *" $warning_categories "*) func_append_u opt_warning " $1" ;; *) func_fatal_error \ "Error: unsupported warning category: \`$1'" ;; esac shift ;; --version) func_version ;; -\?|-h) func_usage ;; --help) func_help ;; # Separate optargs to long options: --*=*) func_split_equals "$opt" set dummy "$func_split_equals_lhs" \ "$func_split_equals_rhs" ${1+"$@"} shift ;; # Separate optargs to short options: -W*) func_split_short_opt "$opt" set dummy "$func_split_short_opt_name" \ "$func_split_short_opt_arg" ${1+"$@"} shift ;; # Separate non-argument short options: -\?*|-h*|-c*|-f*|-n*|-v*|-x*) func_split_short_opt "$opt" set dummy "$func_split_short_opt_name" \ "-$func_split_short_opt_arg" ${1+"$@"} shift ;; --) set dummy "$opt"; shift; break ;; -*) func_fatal_help "unrecognised option: \`$opt'" ;; *) set dummy "$opt"; shift; break ;; esac done # save modified positional parameters for caller func_quote_for_eval ${1+"$@"} func_parse_options_result="$func_quote_for_eval_result" } # func_validate_options [ARG]... # ------------------------------ # Perform any sanity checks on option settings and/or unconsumed # arguments. func_hookable func_validate_options func_validate_options () { $debug_cmd # display all warnings if -W was not given test -n "$opt_warning" || opt_warning="$warning_categories" func_run_hooks func_validate_options ${1+"$@"} # Validate options. test $# -gt 0 \ && func_fatal_help "too many arguments" # Bail if the options were screwed! $exit_cmd $EXIT_FAILURE # save modified positional parameters for caller func_quote_for_eval ${1+"$@"} func_validate_options_result="$func_quote_for_eval_result" } # func_prep # --------- # Function to perform preparation for remaining bootstrap process. If # your hooked code relies on the outcome of `func_options' hook it here # rather than to `func_init'. # # All the functions called inside func_prep are hookable. See the # individual implementations for details. func_hookable func_prep func_prep () { $debug_cmd $require_bootstrap_uptodate $require_buildtools_uptodate $require_gnulib_merge_changelog # fetch update files from the translation project func_update_translations func_run_hooks func_prep } # func_update_translations # ------------------------ # Update package po files and translations. func_hookable func_update_translations func_update_translations () { $debug_cmd $opt_skip_po || { test -d po && { $require_package func_update_po_files po $package || exit $? } func_run_hooks func_update_translations } } # func_reconfigure # ---------------- # Reconfigure the current package by running the appropriate autotools in a # suitable order. func_hookable func_reconfigure func_reconfigure () { $debug_cmd # Released `autopoint' has the tendency to install macros that have # been obsoleted in current `gnulib., so run this before `gnulib-tool'. func_autopoint # Autoreconf runs `aclocal' before `libtoolize', which causes spurious # warnings if the initial `aclocal' is confused by the libtoolized # (or worse: out-of-date) macro directory. func_libtoolize # If you need to do anything after `gnulib-tool' is done, but before # `autoreconf' runs, you don't need to override this whole function, # because `func_gnulib_tool' is hookable. func_gnulib_tool func_autoreconf func_run_hooks func_reconfigure } # func_gnulib_tool # ---------------- # Run `gnulib-tool' to fetch gnulib modules into the current package. # To avoid conflics between `autopoint', `libtoolize' and `gnulib-tool', # this default implementation first tricks `gnulib-tool' into copying # the modules into a temporary directory, and then mangles the contents # as they copied to their final destination. # # It's assumed that since you are using gnulib's `bootstrap' script, # you're also using gnulib elsewhere in your package. If not, then # replace this function in `bootstrap.conf' with: # # func_gnulib_tool () { :; } # func_hookable func_gnulib_tool func_gnulib_tool () { $debug_cmd $require_gnulib_tool $require_libtoolize test true = "$gnulib_tool" || { if test -n "$gnulib_modules"; then $require_gnulib_cache $require_build_aux $require_macro_dir # Try not to pick up any stale values from `gnulib-cache.m4'. rm -f "$gnulib_cache" gnulib_mode="--import" # `gnulib_modules' and others are maintained in `bootstrap.conf`: # Use `gnulib --import` to fetch gnulib modules. test -n "$build_aux" \ && func_append_u gnulib_tool_options " --aux-dir=$build_aux" test -n "$macro_dir" \ && func_append_u gnulib_tool_options " --m4-base=$macro_dir" test -n "$doc_base" \ && func_append_u gnulib_tool_options " --doc-base=$doc_base" test -n "$gnulib_name" \ && func_append_u gnulib_tool_options " --lib=$gnulib_name" test -n "$local_gl_dir" \ && func_append_u gnulib_tool_options " --local-dir=$local_gl_dir" test -n "$source_base" \ && func_append_u gnulib_tool_options " --source-base=$source_base" test -n "$gnulib_mk" \ && func_append_u gnulib_tool_options " --makefile-name=$gnulib_mk" test -n "$tests_base" && { func_append_u gnulib_tool_options " --tests-base=$tests_base" func_append_u gnulib_tool_options " --with-tests" } else # `gnulib_modules' and others are cached in `gnulib-cache.m4': # Use `gnulib --update' to fetch gnulib modules. gnulib_mode="--update" fi # Add a sensible default libtool option to gnulib_tool_options. case " $gnulib_tool_options " in *" --no-libtool "*|*" --libtool "*) ;; *) if true = "$LIBTOOLIZE"; then func_append_u gnulib_tool_options " --no-libtool" else func_append_u gnulib_tool_options " --libtool" fi ;; esac $opt_copy || func_append_u gnulib_tool_options " --symbolic" func_append_u gnulib_tool_options " $gnulib_mode" func_append gnulib_tool_options " $gnulib_modules" # The embeded echo is to squash whitespace before display. gnulib_cmd=`echo $gnulib_tool $gnulib_tool_options` func_show_eval "$gnulib_cmd" 'exit $?' } func_run_hooks func_gnulib_tool } # func_fini # --------- # Function to perform all finalisation for the bootstrap process. func_hookable func_fini func_fini () { $debug_cmd func_install_gnulib_non_module_files func_gettext_configuration func_clean_dangling_symlinks func_clean_unused_macros func_skip_po_recommendation func_run_hooks func_fini func_echo "Done. Now you can run './configure'." } # func_gettext_configuration # -------------------------- # Edit configuration values into po/Makevars. func_hookable func_gettext_configuration func_gettext_configuration () { $debug_cmd $require_autopoint test true = "$AUTOPOINT" || { $require_copyright_holder $require_extra_locale_categories $require_package_bugreport # Escape xgettext options for sed Makevars generation below. # We have to delete blank lines in a separate script so that we don't # append \\\ to the penultimate line, and then delete the last empty # line, which messes up the variable substitution later in this # function. Note that adding a literal \\\ requires double escaping # here, once for the execution subshell, and again for the assignment, # which is why there are actually 12 (!!) backslashes in the script. my_xgettext_options=`echo "$xgettext_options$nl" |$SED '/^$/d' |$SED ' $b s|$| \\\\\\\\\\\\|'` # Create gettext configuration. func_echo "Creating po/Makevars from po/Makevars.template ..." $RM -f po/Makevars $SED ' /^EXTRA_LOCALE_CATEGORIES *=/s|=.*|= '"$extra_locale_categories"'| /^COPYRIGHT_HOLDER *=/s|=.*|= '"$copyright_holder"'| /^MSGID_BUGS_ADDRESS *=/s|=.*|= '"$package_bugreport"'| /^XGETTEXT_OPTIONS *=/{ s|$| \\| a\ '"$my_xgettext_options"' \\\ $${end_of_xgettext_options+} } ' po/Makevars.template >po/Makevars || exit 1 } func_run_hooks func_gettext_configuration } ## --------------- ## ## Core functions. ## ## --------------- ## # This section contains the main functions called from the `Hookable # functions' (shown above), and are the ones you're most likely # to want to replace with your own implementations in `bootstrap.conf'. # func_autopoint # -------------- # If this package uses gettext, then run `autopoint'. func_autopoint () { $debug_cmd $require_autopoint test true = "$AUTOPOINT" \ || func_show_eval "$AUTOPOINT --force" 'exit $?' } # func_libtoolize # --------------- # If this package uses libtool, then run `libtoolize'. func_libtoolize () { $debug_cmd $require_libtoolize test true = "$LIBTOOLIZE" || { my_libtoolize_options= $opt_copy && func_append my_libtoolize_options " --copy" $opt_force && func_append my_libtoolize_options " --force" $opt_verbose || func_append my_libtoolize_options " --quiet" func_show_eval "$LIBTOOLIZE$my_libtoolize_options" 'exit $?' } } # func_autoreconf # --------------- # Being careful not to re-run `autopoint' or `libtoolize', and not to # try to run `autopoint', `libtoolize' or `autoheader' on packages that # don't use them, defer to `autoreconf' for execution of the remaining # autotools to bootstrap this package. func_autoreconf () { $debug_cmd $require_autoheader $require_build_aux # automake and others put files in here $require_macro_dir # aclocal and others put files in here # We ran these manually already, and autoreconf won't exec `:' save_AUTOPOINT="$AUTOPOINT"; AUTOPOINT=true save_LIBTOOLIZE="$LIBTOOLIZE"; LIBTOOLIZE=true my_autoreconf_options= $opt_copy || func_append my_autoreconf_options " --symlink" $opt_force && func_append my_autoreconf_options " --force" $opt_verbose && func_append my_autoreconf_options " --verbose" func_show_eval "$AUTORECONF$my_autoreconf_options --install" 'exit $?' AUTOPOINT="$save_AUTOPOINT" LIBTOOLIZE="$save_LIBTOOLIZE" } # func_install_gnulib_non_module_files # ------------------------------------ # Get additional non-module files from gnulib, overriding existing files. func_install_gnulib_non_module_files () { $debug_cmd $require_build_aux $require_gnulib_path test -n "$gnulib_non_module_files" && { if test -n "$gnulib_path"; then maybe_exit_cmd=: for file in $gnulib_non_module_files; do case $file in */INSTALL) dest=INSTALL;; build-aux/*) dest=$build_aux/`expr "$file" : 'build-aux/\(.*\)'`;; *) dest=$file;; esac # Be sure to show all copying errors before bailing out if test -f "$gnulib_path/$file"; then func_symlink_to_dir "$gnulib_path" $file $dest else func_error "Error: \`$gnulib_path/$file' does not exist" maybe_exit_cmd="exit $EXIT_FAILURE" fi done $maybe_exit_cmd else func_warning recommend "\ Unable to link \`\$gnulib_non_module_files', please provide the locationof a complete \`gnulib' tree by setting \`gnulib_path' in your \`bootstrap.conf' or with the \`--gnulib-srcdir' option - or else specify the location of your \`git' binary by setting \`GIT' in the environment so that a fresh \`gnulib' submodule can be cloned." fi } } # func_check_configuration VARNAME [CONFIGURE_MACRO] # -------------------------------------------------- func_check_configuration () { $debug_cmd $require_configure_ac eval 'test -n "$'$1'"' || { my_error_msg="Error: please set \`$1' in \`bootstrap.conf'" test -n "$2" \ && func_append my_error_msg " or add the following (or similar) to your \`$configure_ac': $2" func_fatal_error "$my_error_msg" } } # func_clean_dangling_symlinks # ---------------------------- # Remove any dangling symlink matching "*.m4" or "*.[ch]" in some # gnulib-populated directories. Such .m4 files would cause aclocal to # fail. The following requires GNU find 4.2.3 or newer. Considering # the usual portability constraints of this script, that may seem a very # demanding requirement, but it should be ok. Ignore any failure, # which is fine, since this is only a convenience to help developers # avoid the relatively unusual case in which a symlinked-to .m4 file is # git-removed from gnulib between successive runs of this script. func_clean_dangling_symlinks () { $debug_cmd $require_macro_dir $require_source_base func_verbose "cleaning dangling symlinks" find "$macro_dir" "$source_base" \ -depth \( -name '*.m4' -o -name '*.[ch]' \) \ -type l -xtype l -delete > /dev/null 2>&1 } # func_clean_unused_macros # ------------------------ # Autopoint can result in over-zealously adding macros into $macro_dir # even though they are not actually used, for example tests to help # build the `intl' directory even though you have specified # `AM_GNU_GETTEXT([external])' in your configure.ac. This function # looks removes any macro files that can be found in gnulib, but # are not `m4_include'd by `aclocal.m4'. func_clean_unused_macros () { $debug_cmd $require_gnulib_path $require_macro_dir test -n "$gnulib_path" && test -f aclocal.m4 && { aclocal_m4s=`find . -name aclocal.m4 -print` # We use `ls|grep' instead of `ls *.m4' to avoid exceeding # command line length limits in some shells. for file in `cd $macro_dir && ls -1 |grep '\.m4$'`; do # Remove a macro file when aclocal.m4 does not m4_include it... func_grep_q 'm4_include([[]'$macro_dir/$file'])' $aclocal_m4s \ || test ! -f $gnulib_path/m4/$file || { # ...and there is an identical file in gnulib... if func_cmp_s $gnulib_path/m4/$file $macro_dir/$file; then # ...and it's not in the precious list (`echo' is needed # here to squash whitespace for the match expression). case " "`echo $gnulib_precious`" " in *" $file "*) ;; *) rm -f $macro_dir/$file func_verbose \ "removing unused gnulib file \`$macro_dir/$file'" esac fi } done } } # func_skip_po_recommendation # --------------------------- # If there is a po directory, and `--skip-po' wasn't passed, let the # user know that they can use `--skip-po' on subsequent invocations. func_skip_po_recommendation () { test ! -d po \ || $opt_skip_po \ || func_warning recommend "\ If your pofiles are up-to-date, you can rerun bootstrap as \`$progname --skip-po' to avoid redownloading." } ## -------------------- ## ## Resource management. ## ## -------------------- ## # This section contains definitions for functions that each ensure a # particular resource (a file, or a non-empty configuration variable for # example) is available, and if appropriate to extract default values # from pertinent package files. Where a variable already has a non- # empty value (as set by the package's `bootstrap.conf'), that value is # used in preference to deriving the default. Call them using their # associated `require_*' variable to ensure that they are executed, at # most, once. # require_aclocal_amflags # ----------------------- # Ensure `$aclocal_amflags' has a sensible default, extracted from # `Makefile.am' if necessary. require_aclocal_amflags=func_require_aclocal_amflags func_require_aclocal_amflags () { $debug_cmd $require_makefile_am my_sed_extract_aclocal_amflags='s|#.*$|| /^[ ]*ACLOCAL_AMFLAGS[ ]*=/ { s|^.*=[ ]*\(.*\)|aclocal_amflags="\1"| p }' my_aclocal_flags_cmd=`$SED -n "$my_sed_extract_aclocal_amflags" \ "$makefile_am"` eval "$my_aclocal_flags_cmd" func_verbose "ACLOCAL_AMFLAGS='$aclocal_amflags'" require_aclocal_amflags=: } # require_autobuild_buildreq # -------------------------- # Try to find whether the bootstrap requires autobuild. require_autobuild_buildreq=func_require_autobuild_buildreq func_require_autobuild_buildreq () { $debug_cmd printf "$buildreq"| func_grep_q '^[ ]*autobuild' || { $require_configure_ac func_extract_trace AB_INIT test -n "$func_extract_trace_result" && { func_append buildreq 'autobuild - http://josefsson.org/autobuild/ ' func_verbose "auto-adding \`autobuild' to build requirements" } } require_autobuild_buildreq=: } # require_autoconf_buildreq # require_gettext_buildreq # require_libtoolize_buildreq # --------------------------- # Try to find the minimum compatible version of autoconf/libtool # required to bootstrap successfully, and add it to `$buildreq'. for tool in autoconf libtoolize gettext; do b=$tool v=require_${tool}_buildreq f=func_$v case $tool in autoconf) m=AC_PREREQ ;; libtoolize) m=LT_PREREQ; b=libtool ;; gettext) m=AM_GNU_GETTEXT_VERSION ;; esac eval $v'='$f' '$f' () { $debug_cmd # The following is ignored if undefined, but might be necessary # in order for `func_find_tool` to run. ${require_'$tool'-:} printf "$buildreq" | func_grep_q '\''^[ ]*'$tool\'' || { $require_configure_ac func_extract_trace '$m' my_version="$func_extract_trace_result" test -n "$my_version" && { func_append buildreq "\ '$tool' $my_version http://www.gnu.org/software/'$b' " func_verbose \ "auto-adding \`'$tool'-$my_version'\'' to build requirements" } } '$v'=: } ' done # require_autoheader # ------------------ # Skip autoheader if it's not needed. require_autoheader=func_require_autoheader func_require_autoheader () { $debug_cmd test true = "$AUTOHEADER" || { func_extract_trace AC_CONFIG_HEADERS test -n "$func_extract_trace_result" || { AUTOHEADER=true func_verbose "export AUTOHEADER='$AUTOHEADER'" # Make sure the search result is visible to subshells export AUTOHEADER } } require_autoheader=: } # require_automake_buildreq # ------------------------- # Try to find the minimum compatible version of automake required to # bootstrap successfully, and add it to `$buildreq'. require_automake_buildreq=func_require_automake_buildreq func_require_automake_buildreq () { $debug_cmd # if automake is not already listed in $buildreq... printf "$buildreq"| func_grep_q automake || { func_extract_trace AM_INIT_AUTOMAKE # ...and AM_INIT_AUTOMAKE is declared... test -n "$func_extract_trace_result" && { automake_version=`echo "$func_extract_trace_result" \ |$SED 's|[^0-9]*||; s| .*$||'` test -n "$automake_version" || automake_version="-" func_append buildreq "\ automake $automake_version http://www.gnu.org/software/automake " func_verbose \ "auto-adding \`automake-$automake_version' to build requirements" } } require_automake_buildreq=: } # require_autopoint # ----------------- # Skip autopoint if it's not needed. require_autopoint=func_require_autopoint func_require_autopoint () { $debug_cmd test true = "$AUTOPOINT" || { func_extract_trace AM_GNU_GETTEXT_VERSION test -n "$func_extract_trace_result" || { AUTOPOINT=true func_verbose "export AUTOPOINT='$AUTOPOINT'" # Make sure the search result is visible to subshells export AUTOPOINT } } require_autopoint=: } # func_require_bootstrap_uptodate # ------------------------------- # Complain if the version of bootstrap in the gnulib directory differs # from the one we are running. require_bootstrap_uptodate=func_require_bootstrap_uptodate func_require_bootstrap_uptodate () { $debug_cmd $require_gnulib_path test x = x"$gnulib_path" \ || func_cmp_s $progpath $gnulib_path/build-aux/bootstrap \ || func_warning upgrade "\ \`$progpath' differs from \`./$gnulib_path/build-aux/bootstrap', please consider adopting the canonical version from gnulib." require_bootstrap_uptodate=: } # require_build_aux # ----------------- # Ensure that `$build_aux' is set, and if it doesn't already point to an # existing directory, create one. require_build_aux=func_require_build_aux func_require_build_aux () { $debug_cmd test -n "$build_aux" || { $require_configure_ac func_extract_trace AC_CONFIG_AUX_DIR build_aux="$func_extract_trace_result" func_check_configuration build_aux \ "AC_CONFIG_AUX_DIR([name of a directory for build scripts])" func_verbose "build_aux='$build_aux'" } $require_vc_ignore_files # If the build_aux directory doesn't exist, create it now, and mark it # as ignored for the VCS. if test ! -d "$build_aux"; then func_show_eval "mkdir '$build_aux'" test -n "$vc_ignore_files" \ || func_insert_sorted_if_absent "$build_aux" $vc_ignore_files fi require_build_aux=: } # func_require_buildtools_uptodate # -------------------------------- # Ensure all the packages listed in BUILDREQS are available on the build # machine at the minimum versions or better. require_buildtools_uptodate=func_require_buildtools_uptodate func_require_buildtools_uptodate () { $debug_cmd $require_autobuild_buildreq $require_autoconf_buildreq $require_automake_buildreq $require_libtoolize_buildreq $require_gettext_buildreq test -n "$buildreq" && { func_check_versions $buildreq $func_check_versions_result || { test -n "$buildreq_readme" \ && test -f "$buildreq_readme" \ && func_error "\ Error: $buildreq_readme explains how to obtain these prerequisite programs: " func_strtable 7 11 12 36 \ "Program" "Min_version" "Homepage" $buildreq func_fatal_error "$func_strtable_result" } } require_buildtools_uptodate=: } # require_configure_ac # -------------------- # Ensure that there is a `configure.ac' or `configure.in' file in the # current directory, and that `$configure_ac' contains its name. require_configure_ac=func_require_configure_ac func_require_configure_ac () { $debug_cmd test -n "$configure_ac" || { for configure_ac in configure.ac configure.in; do test -f $configure_ac && break done <$configure_ac } func_verbose "found \`$configure_ac'" require_configure_ac=: } # require_copyright_holder # ------------------------ # Ensure there is a sensible non-empty default value in `$copyright_holder'. require_copyright_holder=func_require_copyright_holder func_require_copyright_holder () { $debug_cmd test -n "$copyright_holder" || { copyright_holder='Free Software Foundation, Inc.' func_warning settings "\ Please set copyright_holder explicitly in \`bootstrap.conf'; defaulting to \`$copyright_holder'." } require_copyright_holder=: } # require_dotgitmodules # --------------------- # Ensure we have a `.gitmodules' file, with appropriate `gnulib' settings. require_dotgitmodules=func_require_dotgitmodules func_require_dotgitmodules () { $debug_cmd $require_git test true = "$GIT" || { # A gnulib entry in .gitmodules always takes precedence. my_path="`$GIT config --file .gitmodules submodule.gnulib.path 2>/dev/null`" test -n "$my_path" || { $require_vc_ignore_files func_verbose "creating \`.gitmodules'" # If the .gitmodules file doesn't exist, create it now, and mark # it as ignored for the VCS. test -n "$gnulib_path" || gnulib_path=gnulib test -n "$gnulib_url" || gnulib_url=git://git.sv.gnu.org/gnulib { echo '[submodule "gnulib"]' echo " path = $gnulib_path" echo " url = $gnulib_url" } >> .gitmodules test -n "$vc_ignore_files" \ || func_instert_sorted_if_absent ".gitmodules" $vc_ignore_files } } require_dotgitmodules=: } # require_extra_locale_categories # ------------------------------- # Ensure there is a default value in `$extra_locale_categories' require_extra_locale_categories=func_require_extra_locale_categories func_require_extra_locale_categories () { $debug_cmd # Defaults to empty, so run with whatever value may have been set in # `bootstrap.conf'. require_extra_locale_categories=: } # require_git # ----------- # Ignore git if it's not available, or we're not in a git checkout tree. require_git=func_require_git func_require_git () { $debug_cmd $opt_skip_git && GIT=true test true = "$GIT" || { if test -d .git && ($GIT --version) >/dev/null 2>&1; then :; else GIT=true fi } func_verbose "GIT='$GIT'" require_git=: } # require_gnu_m4 # -------------- # Search for GNU M4, and export it in $M4. require_gnu_m4=func_require_gnu_m4 func_require_gnu_m4 () { $debug_cmd test -n "$M4" || { # Find the first m4 binary that responds to --version. func_find_tool M4 gm4 gnum4 m4 } test -n "$M4" || func_fatal_error "\ Error: Please install GNU M4, or \`export M4=/path/to/gnu/m4'." func_verbose "export M4='$M4'" # Make sure the search result is visible to subshells export M4 require_gnu_m4=: } # require_gnulib_cache # -------------------- # Ensure there is a non-empty default for `$gnulib_cache', and that it # names an existing file. require_gnulib_cache=func_require_gnulib_cache func_require_gnulib_cache () { $debug_cmd $require_macro_dir test -n "$gnulib_cache" \ || gnulib_cache="$macro_dir/gnulib-cache.m4" func_verbose "found \`$gnulib_cache'" require_gnulib_cache=: } # require_gnulib_files_already_present # ------------------------------------ # If we have no means to update imported gnulib files, then try to # ensure at least that this tree already has files from a previous # `gnulib-tool' run. require_gnulib_files_already_present=func_require_gnulib_files_already_present func_require_gnulib_files_already_present () { $debug_cmd $require_build_aux $require_macro_dir $require_gnulib_mk $require_source_base # As a heuristic, only bail out if any of the following # are missing. my_gnulib_files_already_present=" $build_aux/install-sh $macro_dir/00gnulib.m4 $source_base/$gnulib_mk " $opt_dry_run || { for my_file in $my_gnulib_files_already_present; do test -f "$my_file" || func_fatal_error "\ Error: Can't find, copy or download required gnulib files, please provide the location of a complete \`gnulib' tree by setting \`gnulib_path' in your \`bootstrap.conf' or with the \`--gnulib-srcdir' option - or else specify the location of your \`git' binary by setting \`GIT' in the environment so that a fresh \`gnulib' submodule can be cloned." done } require_gnulib_files_already_present=: } # require_gnulib_merge_changelog # ------------------------------ # See if we can use gnulib's git-merge-changelog merge driver. require_gnulib_merge_changelog=func_require_gnulib_merge_changelog func_require_gnulib_merge_changelog () { $debug_cmd $require_git test true = "$GIT" || { if $GIT config merge.merge-changelog.driver >/dev/null ; then : elif (git-merge-changelog --version) >/dev/null 2>&1 ; then func_echo "initializing git-merge-changelog driver" $GIT config merge.merge-changelog.name 'GNU-style ChangeLog merge driver' $GIT config merge.merge-changelog.driver 'git-merge-changelog %O %A %B' else func_warning recommend \ "Consider installing git-merge-changelog from gnulib." fi } require_gnulib_merge_changelog=: } # require_gnulib_mk # ----------------- # Ensure gnulib_mk has a sensible value, extracted from `gnulib-cache.m4' # if possible, otherwise letting `gnulib-tool' pick a default. require_gnulib_mk=func_require_gnulib_mk func_require_gnulib_mk () { $debug_cmd test -n "$gnulib_mk" || { $require_gnulib_cache $require_macro_dir func_extract_trace "gl_MAKEFILE_NAME" "$gnulib_cache" gnulib_mk="$func_extract_trace_result" test -n "$gnulib_mk" && func_verbose "gnulib_mk='$gnulib_mk'" } require_gnulib_mk=: } # require_gnulib_path # require_gnulib_url # ------------------- # Ensure `gnulib_path' and `gnulib_url' are set. require_gnulib_path=func_require_dotgitmodules_parameters require_gnulib_url=func_require_dotgitmodules_parameters func_require_dotgitmodules_parameters () { $debug_cmd $require_git if test true = "$GIT"; then # If we can't find git (or if the user specified `--skip-git'), # then use an existing gnulib directory specified with # `--gnulib-srcdir' if possible. test -n "$gnulib_path" \ || test ! -x "$opt_gnulib_srcdir/gnulib-tool" \ || gnulib_path="$opt_gnulib_srcdir" else $require_dotgitmodules # Extract the parameters with calls to git config. test -n "$gnulib_path" \ || gnulib_path="`$GIT config --file .gitmodules submodule.gnulib.path`" test -n "$gnulib_url" \ || gnulib_url="`$GIT config --file .gitmodules submodule.gnulib.url`" fi func_verbose "gnulib_path='$gnulib_path'" func_verbose "gnulib_url='$gnulib_url'" require_gnulib_path=: require_gnulib_url=: } # require_gnulib_submodule # ------------------------ # Ensure that there is a current gnulib submodule at `$gnulib_path'. require_gnulib_submodule=func_require_gnulib_submodule func_require_gnulib_submodule () { $debug_cmd $require_git if test true = "$GIT"; then func_warning recommend \ "No \`git' found; imported gnulib modules may be outdated." else $require_gnulib_path $require_gnulib_url if test -f "$gnulib_path/gnulib-tool"; then func_show_eval "$GIT submodule update" \ 'func_fatal_error "Error: Unable to update gnulib submodule."' elif test -n "$opt_gnulib_srcdir"; then # Older git can't clone into an empty directory. rmdir "$gnulib_path" 2>/dev/null func_show_eval "$GIT clone --reference '$opt_gnulib_srcdir' \ '$gnulib_url' '$gnulib_path'" \ && func_show_eval "$GIT submodule init" \ && func_show_eval "$GIT submodule update" \ || func_fatal_error "Error: Unable to fetch gnulib submodule." # Without --gnulib-srcdir, and no existing checked out submodule, we # create a new shallow clone of the remote gnulib repository. else trap func_cleanup_gnulib 1 2 13 15 shallow= $GIT clone -h 2>&1 |func_grep_q -- --depth \ && shallow='--depth 2' func_show_eval "$GIT clone $shallow '$gnulib_url' '$gnulib_path'" \ func_cleanup_gnulib trap - 1 2 13 15 fi fi require_gnulib_submodule=: } # require_gnulib_tool # ------------------- # Ensure that `$gnulib_tool' is set, and points to an executable file, # or else fall back to using the binary `true' if the main gnulib # files appear to have been imported already. require_gnulib_tool=func_require_gnulib_tool func_require_gnulib_tool () { $debug_cmd $require_gnulib_submodule test true = "$gnulib_tool" || { test -n "$gnulib_tool" \ || gnulib_tool="$gnulib_path/gnulib-tool" test -x "$gnulib_tool" || { $require_gnulib_files_already_present gnulib_tool=true func_warning recommend \ "No \`gnulib-tool' found; gnulib modules may be missing." } test true = "$gnulib_tool" \ || func_verbose "found \`$gnulib_tool'" } require_gnulib_tool=: } # require_libtoolize # ------------------ # Skip libtoolize if it's not needed. require_libtoolize=func_require_libtoolize func_require_libtoolize () { $debug_cmd # Unless we're not searching for libtool use by this package, set # LIBTOOLIZE to true if none of `LT_INIT', `AC_PROG_LIBTOOL' and # `AM_PROG_LIBTOOL' are used in configure. test true = "$LIBTOOLIZE" || { func_extract_trace LT_INIT test -n "$func_extract_trace_result"||func_extract_trace AC_PROG_LIBTOOL test -n "$func_extract_trace_result"||func_extract_trace AM_PROG_LIBTOOL test -n "$func_extract_trace_result"||LIBTOOLIZE=true } test -n "$LIBTOOLIZE" || { # Find libtoolize, named glibtoolize in Mac Ports, but prefer # user-installed libtoolize to ancient glibtoolize shipped by # Apple with Mac OS X when Mac Ports is not installed. func_find_tool LIBTOOLIZE libtoolize glibtoolize } func_verbose "export LIBTOOLIZE='$LIBTOOLIZE'" # Make sure the search result is visible to subshells export LIBTOOLIZE require_libtoolize=: } # require_macro_dir # ----------------- # Ensure that `$macro_dir' is set, and if it doesn't already point to an # existing directory, create one. require_macro_dir=func_require_macro_dir func_require_macro_dir () { $debug_cmd # Sometimes this is stored in `configure.ac'. test -n "$macro_dir" || { func_extract_trace AC_CONFIG_MACRO_DIR macro_dir="$func_extract_trace_result" } # Otherwise we might find it in `Makefile.am'. test -n "$macro_dir" || { $require_aclocal_amflags my_sed_scan='s|^.*-I[ ]*\([^ ]*\) .*|\1|' # Trailing space in echo is required by the sed script. macro_dir=`echo "$aclocal_amflags " |$SED "$my_sed_scan"` } func_verbose "macro_dir='$macro_dir'" func_check_configuration macro_dir \ "AC_CONFIG_MACRO_DIR([name of a directory for configure m4 files])" $require_vc_ignore_files # If the macro_dir directory doesn't exist, create it now, and mark it # as ignored for the VCS. if test ! -d "$macro_dir"; then mkdir "$macro_dir" || func_permissions_error "$macro_dir" test -n "$vc_ignore_files" \ || func_insert_sorted_if_absent "$macro_dir" $vc_ignore_files fi require_macro_dir=: } # require_makefile_am # ------------------- # Ensure there is a `Makefile.am' in the current directory. # names an existing file. require_makefile_am=func_require_makefile_am func_require_makefile_am () { $debug_cmd test -n "$makefile_am" \ || makefile_am="Makefile.am" <"$makefile_am" func_verbose "found \`$makefile_am'" require_makefile_am=: } # require_package # --------------- # Ensure that `$package' contains a sensible default value. require_package=func_require_package func_require_package () { $debug_cmd test -n "$package" || { $require_package_name package=`echo "$package_name" \ |$SED 's/GNU //;y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'` } func_verbose "package='$package'" require_package=: } # require_package_bugreport # ------------------------- # Ensure that this has a sensible value, extracted from `configure.ac' # if appropriate (and possible!). require_package_bugreport=func_require_package_bugreport func_require_package_bugreport () { $debug_cmd func_extract_trace AC_INIT save_ifs="$IFS" IFS=: set dummy $func_extract_trace_result IFS="$save_ifs" shift test -n "$package_bugreport" || package_bugreport="$3" func_check_configuration package_bugreport \ "AC_INIT([$package_name], [$package_version], address@hidden)" func_verbose "package_bugreport='$package_bugreport'" require_package_bugreport=: } # require_package_name # -------------------- # Ensure that this has a sensible value, extracted from `configure.ac' # if appropriate (and possible!). require_package_name=func_require_package_name func_require_package_name () { $debug_cmd func_extract_trace AC_INIT save_ifs="$IFS" IFS=: set dummy $func_extract_trace_result IFS="$save_ifs" shift test -n "$package_name" || package_name="$1" func_check_configuration package_name \ "AC_INIT([name of your package], [package version number])" func_verbose "package_name='$package_name'" require_package_name=: } # require_package_version # ----------------------- # Ensure that this has a sensible value, extracted from `configure.ac' # if appropriate (and possible!). While we might have set all the # parameters extracted from AC_INIT at once, `package_version' in # particular is not necessarily available as early as the others, since # `git-version-gen' is often involved, and until then we can't rely on # getting a correct version number from an AC_INIT extraction. require_package_version=func_require_package_version func_require_package_version () { $debug_cmd func_extract_trace AC_INIT save_ifs="$IFS" IFS=: set dummy $func_extract_trace_result IFS="$save_ifs" shift test -n "$package_version" || package_version="$2" func_check_configuration package_version \ "AC_INIT([$package_name], [package version number])" func_verbose "package_version='$package_version'" require_package_version=: } # require_source_base # ------------------- # Ensure that source_base has a sensible value, extracted from # `gnulib-cache.m4' if possible. require_source_base=func_require_source_base func_require_source_base () { $debug_cmd $require_gnulib_cache test -f "$gnulib_cache" && test x = "x$source_base" && { $require_macro_dir func_extract_trace "gl_SOURCE_BASE" "$gnulib_cache" source_base="$func_extract_trace_result" func_verbose "source_base='$source_base'" } # Only prevent repeated calls if we found something... # gnulib-cache.m4 might arrive before the next call. test -n "$source_base" && require_source_base=: } # require_vc_ignore_files # ----------------------- # Ensure that `$vc_ignore' has been processed to list VCS ignore files # in `$vc_ignore_files' require_vc_ignore_files=func_require_vc_ignore_files func_require_vc_ignore_files () { $debug_cmd test -n "$vc_ignore" || vc_ignore=auto if test auto = "$vc_ignore" && test x = x"$vc_ignore_files"; then vc_ignore_files= test -d .git && vc_ignore_files=.gitignore test -d CVS && vc_ignore_files="$vc_ignore_files .cvsignore" else vc_ignore_files="$vc_ignore" fi func_verbose "vc_ignore_files='$vc_ignore_files'" require_vc_ignore_files=: } ## ------------------## ## Helper functions. ## ## ------------------## # This section contains the helper functions used by the rest of `bootstrap'. # func_len STRING # --------------- # STRING may not start with a hyphen. if (eval 'x=123; test x${#x} = "x3"') 2>/dev/null then # This is an XSI compatible shell, allowing a faster implementation... eval 'func_len () { $debug_cmd func_len_result=${#1} }' else # ...otherwise fall back to using expr, which is often a shell builtin. func_len () { $debug_cmd func_len_result=`expr "$1" : ".*" 2>/dev/null || echo 0` } fi # func_unset VAR # -------------- # Portably unset VAR. func_unset () { { eval $1=; unset $1; } } unset=func_unset # func_cmp_s FILE1 FILE2 # ---------------------- # Return non-zero exit status unless FILE1 and FILE2 are identical, without # output. func_cmp_s () { $debug_cmd # This function relies on non-zero exit status, which will cause the # program to exit when running in `set -e' mode. $CMP "$@" >/dev/null 2>&1 } # func_grep_q EXPRESSION [FILENAME..]. # ------------------------------------ # Check whether EXPRESSION matches any line of any listed FILENAME, # without output. func_grep_q () { $debug_cmd # This function relies on non-zero exit status, which will cause the # program to exit when running in `set -e' mode. $GREP "$@" >/dev/null 2>&1 } # func_append_u VAR VALUE # ----------------------- # Append unique VALUE onto the existing contents of VAR, assuming # entries are delimited by the first character of VALUE. For example: # # func_append_u options " --another-option option-argument" # # will only append to $options if " --another-option option-argument " # is not already present somewhere in $options already (note spaces at # each end implied by leading space in second argument). func_append_u () { $debug_cmd eval my_current_value='`echo $'$1'`' my_delim=`expr "$2" : '\(.\)'` case $my_delim$my_current_value$my_delim in *"$2$my_delim"*) ;; *) func_append "$@" ;; esac } # func_strpad STR WIDTH CHAR # -------------------------- # Trim STR, or pad with CHAR to force a total length of WIDTH. func_strpad () { $debug_cmd my_width=`expr "$2" - 1` func_strpad_result=`echo "$1" |$SED ' :a s|^.\{0,'"$my_width"'\}$|&'"$3"'| ta '` } # func_strrpad STR WIDTH CHAR # --------------------------- # Trim STR, or right-justify-pad with CHAR to force a total length of # WIDTH. func_strrpad () { $debug_cmd my_width=`expr "$2" - 1` func_strrpad_result=`echo "$1" |$SED ' :a s|^.\{0,'"$my_width"'\}$|'"$3"'&| ta '` } # func_strrow INDENT FIELD WIDTH [FIELDn WIDTHn]... # ------------------------------------------------- # Return a string containing each FIELD left justified to WIDTH, with # the whole thing indented by INDENT spaces. This function is used to # render one row of aligned columns for a table by func_strtable(). func_strrow () { $debug_cmd func_strrow_linelen="$1"; shift my_row= while test $# -gt 0; do func_strrow_linelen=`expr $func_strrow_linelen + $2` func_strpad "$1" $2 " " func_append my_row "$func_strpad_result" shift; shift done func_strrpad "$my_row" $func_strrow_linelen " " func_strrow_result="$func_strrpad_result" } # func_strtable INDENT WIDTH1...WIDTHn HEADER1...HEADERn FIELD1...FIELDn # ---------------------------------------------------------------------- # Generate a string of newline-separated rows arranged in lined-up # columns of the given WIDTHs, with the entire table indented by INDENT # spaces. The number of columns is determined by the number of integer # valued WIDTH arguments following INDENT. The next set (i.e. a number # of arguments equal to the number of WIDTH arguments) of fields are # treated as the table's column HEADERs, and are separated from the # remainder of the table by an indented row of `-' characters. Remaining # arguments are each aligned below the next available header, wrapping # to a new row as necessary. Finally another row of `-' characters is # added to mark the end of the table. # # For example an unindented 3 column table with 2 rows of data would be # generated by this call: # # func_strtable 3 20 10 25 \ # Header1 Header2 Header3 \ # Row1Col1 Row1Col2 Row1Col3 \ # Row2Col1 Row2Col2 Row2Col3 # # returning the following string: # # " Header1 Header2 Header3 # ------------------------------------------------------- # Row1Col1 Row1Col2 Row1Col3 # Row2Col1 Row2Col2 Row2Col3 # -------------------------------------------------------" func_strtable () { $debug_cmd # Save the indent value, we'll need it for each row we render. my_indent="$1"; shift # Collect remaining numeric args into a list for reuse between # members of each row when we call func_strrow later. my_widths="$1"; shift while test 0 -lt `expr "$1" : '[1-9][0-9]*$'`; do func_append my_widths " $1"; shift done # Extract the same number of positional parameters as there are # width elements - we'll do the header rows separately so that # we can insert a divider line. my_header="$my_indent" for my_width in $my_widths; do func_append my_header " $1 $my_width"; shift done func_strrow $my_header # Strip off the indent, and make a divider with `-' chars, then # reindent. my_divider=`echo "$func_strrow_result" \ |$SED 's|[^ ]|-|g :a s|- |--|g ta '` # Append the header and divider to the running result. func_append func_strtable_result "\ $func_strrow_result $my_divider " # The remaining rows are zipped between the width values we # unwound earlier just like the header row above. while test $# -gt 0; do my_row="$my_indent" for my_width in $my_widths; do func_append my_row " $1 $my_width"; shift done func_strrow $my_row func_append func_strtable_result "\ $func_strrow_result " done # Mark the end of the table with a final divider line. func_append func_strtable_result "$my_divider" } # func_echo ARG... # ---------------- # Echo program name prefixed message, taking newlines into account. func_echo () { my_message="$*" save_IFS="$IFS" IFS="$nl" for my_line in $my_message; do IFS="$save_IFS" echo "$progname: $my_line" done IFS="$save_IFS" } # func_verbose ARG... # ------------------- # Echo program name prefixed message in verbose mode only. func_verbose () { $opt_verbose && func_echo ${1+"$@"} } # func_error ARG... # ----------------- # Echo program name prefixed message to standard error. func_error () { my_message="$*" save_IFS="$IFS" IFS="$nl" for my_line in $my_message; do IFS="$save_IFS" echo "$progname: $bold_on$my_line$bold_off" 1>&2 done IFS="$save_IFS" } # Allow display of bold text on xterms if case "$TERM" in xterm*) test -t 1;; *) false;; esac; then # Assume xterm compatible escape sequences. bold_on=`printf '\x1b[1m'` bold_off=`printf '\x1b[0m'` else bold_on= bold_off= fi # func_fatal_error ARG... # ----------------------- # Echo program name prefixed message to standard error, and exit. func_fatal_error () { func_error ${1+"$@"} exit $EXIT_FAILURE } # func_internal_error ARG... # -------------------------- # Echo program name prefixed message to standard error, and exit. func_internal_error () { func_fatal_error "INTERNAL ERROR: " ${1+"$@"} " Please report this bug to address@hidden' in as much detail as possible." } # func_permissions_error FILE-OR-DIRECTORY # ---------------------------------------- # Echo program name prefixed permissions error message to standard # error, and exit. func_permissions_error () { $debug_cmd func_fatal_error "Error: Failed to create \`$1', check permissions." } # func_warning CATEGORY ARG... # ---------------------------- # Echo program name prefixed warning message to standard error. Warning # messages can be filtered according to CATEGORY. func_warning () { $debug_cmd case " $warning_categories " in *" $1 "*) ;; *) func_internal_error "invalid warning category \`$1'" ;; esac my_category="$1" shift case " $opt_warning " in *" $my_category "*) $warning_func ${1+"$@"} ;; esac } # func_fatal_help ARG... # ---------------------- # Echo program name prefixed message to standard error, followed by # a help hint, and exit. func_fatal_help () { $debug_cmd func_error ${1+"$@"} func_fatal_error "$fatal_help" } fatal_help="Try \`$progname --help' for more information." ## default # func_version # ------------ # Echo version message to standard output and exit. func_version () { $debug_cmd cat </dev/null then # This is an XSI compatible shell, allowing a faster implementation... eval 'func_split_short_opt () { $debug_cmd func_split_short_opt_arg=${1#??} func_split_short_opt_name=${1%"$func_split_short_opt_arg"} }' else # ...otherwise fall back to using expr, which is often a shell builtin. func_split_short_opt () { $debug_cmd func_split_short_opt_name=`expr "x$1" : 'x-\(.\)'` func_split_short_opt_arg=`expr "x$1" : 'x-.\(.*\)$'` } fi #func_split_short_opt # func_split_equals STRING # ------------------------ # Set func_split_equals_lhs and func_split_equals_rhs shell variables after # splitting STRING at the `=' sign. if (eval 'x='--ab=cd'; y=${x#*=}; z=${x%%=*}; test x$y$z = xcd--ab') 2>/dev/null then # This is an XSI compatible shell, allowing a faster implementation... eval 'func_split_equals () { $debug_cmd func_split_equals_lhs=${1%%=*} func_split_equals_rhs=${1#*=} test "x$func_split_equals_lhs" = "x$1" \ && func_split_equals_rhs="" }' else # ...otherwise fall back to using expr, which is often a shell builtin. func_split_equals () { $debug_cmd func_split_equals_lhs=`expr "x$1" : 'x\([^=]*)'` func_split_equals_rhs="" test "x$func_split_equals_lhs" = "x$1" \ || func_split_equals_rhs=`expr "x$1" : 'x[^=]*=\(.*\)$'` } fi #func_split_equals # func_quote_for_eval ARG... # -------------------------- # Aesthetically quote ARGs to be evaled later. # This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT # is double-quoted, suitable for a subsequent eval, whereas # FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters # which are still active within double quotes backslashified. sed_quote_subst='s|\([`"$\\]\)|\\\1|g' func_quote_for_eval () { $debug_cmd func_quote_for_eval_result= while test $# -gt 0; do case $1 in *[\\\`\"\$]*) my_unquoted_arg=`printf "$1" | $SED "$sed_quote_subst"` ;; *) my_unquoted_arg="$1" ;; esac case $my_unquoted_arg in # Double-quote args containing shell metacharacters to delay # word splitting, command substitution and and variable # expansion for a subsequent eval. # Many Bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") my_quoted_arg="\"$my_unquoted_arg\"" ;; *) my_quoted_arg="$my_unquoted_arg" ;; esac test -n "$func_quote_for_eval_result" \ && func_append func_quote_for_eval_result " " func_append func_quote_for_eval_result "$my_quoted_arg" shift done } # func_show_eval CMD [FAIL_EXP] # ----------------------------- # Unless opt_silent is true, then output CMD. Then, if opt_dryrun is # not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP # is given, then evaluate it. func_show_eval () { $debug_cmd my_cmd="$1" my_fail_exp="${2-:}" ${opt_silent-false} || { func_quote_for_eval $my_cmd eval func_truncate_cmd $func_quote_for_eval_result func_echo "running: $func_truncate_cmd_result" } if ${opt_dry_run-false}; then :; else eval "$my_cmd" my_status=$? if test "$my_status" -eq 0; then :; else eval "(exit $my_status); $my_fail_exp" fi fi } # func_truncate_cmd CMD [ARG]... # ------------------------------ # For unreasonably long commands (such as a gnulib-tool invocation with # the full module list for import), truncate CMD after the second non- # option ARG. func_truncate_cmd () { $debug_cmd my_last_arg_opt_p=false func_truncate_cmd_result= set dummy "$@"; shift while test $# -gt 0; do my_opt="$1"; shift test -n "$func_truncate_cmd_result" \ && func_append func_truncate_cmd_result ' ' func_append func_truncate_cmd_result "$my_opt" func_len "x$func_truncate_cmd_result" case $my_opt in -*) my_last_arg_opt_p=: ;; *) $my_last_arg_opt_p \ || test $min_cmd_len -gt $func_len_result \ || break my_last_arg_opt_p=false ;; esac done test $# -gt 0 && func_append func_truncate_cmd_result "..." } # func_extract_trace MACRO_NAME [FILENAME]... # ------------------------------------------- # set `$func_extract_trace_result' to a colon delimited list of # arguments to MACRO_NAME in FILENAME. If no FILENAME is not given, # then `configure.ac' is assumed. func_extract_trace () { $debug_cmd $require_configure_ac $require_gnu_m4 my_macro="$1"; shift test $# -gt 0 || { set dummy $configure_ac shift } # Generate an error if the first file is missing <"$1" # Sadly, we can't use `autom4te' tracing to extract macro # arguments, because it complains about things we want to # ignore at bootstrap time - like missing m4_include files; # AC_PREREQ being newer than the installed autoconf; and # returns nothing when tracing `AM_INIT_AUTOMAKE' when # aclocal hasn't been generated yet. # # The following tries to emulate a less persnickety version # of (and due to not having to wait for Perl startup on # every invocation, it's probably faster too): # # autom4te --language=Autoconf --trace=$my_macro:\$% "$@" # # First we give a minimal set of macro declarations to M4 # to prime it for reading Autoconf macros, while still # providing some of the functionality generally used at # m4-time to supply dynamic arguments to Autocof functions, # but without following `m4_s?include' files. # # We discard M4's stdout, but the M4 trace output from reading # our "autoconf.mini" followed by any other files passed to # this function is then scanned by sed to transform it into # a colon delimited argument list assigned to a shell variable. # # Finally, we `eval' the sed generated assignment to get # the result back into this script for further use by callers # of this function. func_extract_trace_result= eval `echo ' # Initialisation. m4_changequote([,]) m4_define([m4_copy], [m4_define([$2], m4_defn([$1]))]) m4_define([m4_rename], [m4_copy([$1], [$2])m4_undefine([$1])]) # Disable these macros. m4_undefine([m4_dnl]) m4_undefine([m4_include]) m4_undefine([m4_m4exit]) m4_undefine([m4_m4wrap]) m4_undefine([m4_maketemp]) # Copy and rename macros not handled by "m4 --prefix". m4_define([dnl], [m4_builtin([dnl])]) m4_copy([m4_define], [m4_defun]) m4_rename([m4_ifelse], [m4_if]) m4_ifdef([m4_mkstemp], [m4_undefine([m4_mkstemp])]) m4_rename([m4_patsubst], [m4_bpatsubst]) m4_rename([m4_regexp], [m4_bregexp]) # "m4sugar.mini" - useful m4-time macros for dynamic arguments. # If we discover packages that need more m4 macros defined in # order to bootstrap correctly, add them here: m4_define([m4_bmatch], [m4_if([$#], 0, [], [$#], 1, [], [$#], 2, [$2], [m4_if(m4_bregexp([$1], [$2]), -1, [$0([$1], m4_shift3($@))], [$3])])]) m4_define([m4_ifndef], [m4_ifdef([$1], [$3], [$2])]) m4_define([m4_ifset], [m4_ifdef([$1], [m4_ifval(m4_defn([$1]), [$2], [$3])], [$3])]) m4_define([m4_require], [$1]) m4_define([m4_shift3], [m4_shift(m4shift(m4shift($@)))]) # "autoconf.mini" - things from autoconf macros we care about. m4_copy([m4_defun], [AC_DEFUN]) # Dummy definition for the macro we want to trace. # AM_INIT_AUTOMAKE at least produces no trace without this. AC_DEFUN(['"$my_macro"'])' \ |$M4 -daq --prefix --trace="$my_macro" - "$@" 2>&1 1>/dev/null \ |$SED -n 's|#.*$|| /^m4trace: -1- '"$my_macro"'/ { s|^m4trace: -1- '"$my_macro"'([[]|func_extract_trace_result='\''| s|], [[]|:|g s|])$|'\''| s|[^'\'']$|\&'\''| p }'` } # func_insert_sorted_if_absent STR FILE... # ---------------------------------------- # If $STR is not already on a line by itself in $FILE, insert it, # sorting the new contents of the file and replacing $FILE with the result. func_insert_sorted_if_absent () { $debug_cmd str=$1 shift for file do test -f $file || touch $file func_grep_q "$str" "$file" \ && func_verbose "inserting \`$str' into \`$file'" echo "$str" | sort -u - $file | func_cmp_s - $file \ || echo "$str" | sort -u - $file -o $file \ || func_permissions_error "$file" done } # func_sort_ver VER1 VER2 # ----------------------- # Note this deviates from the version comparison in automake # in that it treats 1.5 < 1.5.0, and treats 1.4.4a < 1.4-p3a # but this should suffice as we won't be specifying old # version formats or redundant trailing .0 in bootstrap.conf. # If we did want full compatibility then we should probably # use m4_version_compare from autoconf. func_sort_ver () # sort -V is not generally available { $debug_cmd ver1="$1" ver2="$2" # split on '.' and compare each component i=1 while : ; do p1=`echo "$ver1" | cut -d. -f$i` p2=`echo "$ver2" | cut -d. -f$i` if test ! "$p1"; then echo "$1 $2" break elif test ! "$p2"; then echo "$2 $1" break elif test ! "$p1" = "$p2"; then if test "$p1" -gt "$p2" 2>/dev/null; then # numeric comparison echo "$2 $1" elif test "$p2" -gt "$p1" 2>/dev/null; then # numeric comparison echo "$1 $2" else # numeric, then lexicographic comparison lp=`printf "$p1\n$p2\n" | sort -n | tail -n1` if test "$lp" = "$p2"; then echo "$1 $2" else echo "$2 $1" fi fi break fi i=`expr $i + 1` done } # func_get_version APP # -------------------- # echo the version number (if any) of APP, which is looked up along your # PATH. func_get_version () { $debug_cmd app=$1 $app --version >/dev/null 2>&1 || return 1 $app --version 2>&1 | $SED -n '# extract version within line s|.*[v ]\{1,\}\([0-9]\{1,\}\.[.a-z0-9-]*\).*|\1| t done # extract version at start of line s|^\([0-9]\{1,\}\.[.a-z0-9-]*\).*|\1| t done d :done #the following essentially does s|5.005|5.5| s|\.0*\([1-9]\)|.\1|g p q' } # func_check_versions APP1 VER1 URL1 ...[APPN VERN URLN] # ------------------------------------------------------ func_check_versions () { $debug_cmd func_check_versions_result=: while test $# -gt 0; do my_app="$1"; shift my_reqver="$1"; shift my_url="$1"; shift # Honor $APP variables ($TAR, $AUTOCONF, etc.) my_appvar=`echo $my_app | tr '[a-z]' '[A-Z]'` test "$my_appvar" = TAR && my_appvar=AMTAR eval "my_app=\${$my_appvar-$my_app}" my_instver=`func_get_version $my_app` test ! "$my_instver" \ || func_verbose "found \`$my_app' version $my_instver" # Fail if --version didn't work. if test ! "$my_instver"; then func_error "Error: \`$my_app' not found" func_check_versions_result=false # Fail if a new version than what we have is required. elif test ! "$my_reqver" = "-"; then my_newer=`func_sort_ver $my_reqver $my_instver | cut -d' ' -f2` test ! "$my_newer" = "$my_instver" && { func_error "\ Error: \`$my_app' version == $my_instver is too old \`$my_app' version >= $my_reqver is required" func_check_versions_result=false } fi done } # func_cleanup_gnulib # ------------------- # Recursively delete everything below the path in the global variable # GNULIB_PATH. func_cleanup_gnulib () { $debug_cmd status=$? $RM -fr "$gnulib_path" exit $status } # func_symlink_to_dir SRCDIR FILENAME [DEST_FILENAME] # --------------------------------------------------- # Make a symlink from FILENAME in SRCDIR to the current directory, # optionally calling the symlink DEST_FILENAME. func_symlink_to_dir () { $debug_cmd $require_vc_ignore_files src=$1/$2 dst=${3-$2} test -f "$src" && { # If the destination directory doesn't exist, create it. # This is required at least for "lib/uniwidth/cjk.h". dst_dir=`dirname "$dst"` if ! test -d "$dst_dir"; then mkdir -p "$dst_dir" # If we've just created a directory like lib/uniwidth, # tell version control system(s) it's ignorable. # FIXME: for now, this does only one level parent=`dirname "$dst_dir"` for dot_ig in x $vc_ignore_files; do test $dot_ig = x && continue ig=$parent/$dot_ig func_insert_sorted_if_absent `echo "$dst_dir" |$SED 's|.*/||'` $ig done fi if $opt_copy; then { test ! -h "$dst" \ || func_show_eval "$RM -f '$dst'" } \ && test -f "$dst" \ && func_cmp_s "$src" "$dst" \ && func_echo "copying file \`$src'" \ && cp -fp "$src" "$dst" else test -h "$dst" \ && src_ls=`ls -diL "$src" 2>/dev/null` \ && set $src_ls && src_i=$1 \ && dst_ls=`ls -diL "$dst" 2>/dev/null` \ && set $dst_ls && dst_i=$1 \ && test "$src_i" = "$dst_i" \ || { dot_dots= case $src in /*) ;; *) case /$dst/ in *//* | */../* | */./* | /*/*/*/*/*/) func_fatal_error "\ Error: Invalid symlink calculation: $src -> $dst" ;; /*/*/*/*/) dot_dots=../../../;; /*/*/*/) dot_dots=../../;; /*/*/) dot_dots=../;; esac ;; esac func_echo "linking file \`$src'" ln -fs "$dot_dots$src" "$dst" } fi } } # func_download_po_files SUBDIR DOMAIN # ------------------------------------ func_download_po_files () { $debug_cmd func_echo "getting translations into $1 for $2..." cmd=`printf "$po_download_command_format" "$2" "$1"` eval "$cmd" } # func_find_tool ENVVAR NAMES... # ------------------------------ # Search for a required program. Use the value of ENVVAR, if set, # otherwise find the first of the NAMES that can be run (i.e., # supports --version). If found, set ENVVAR to the program name, # die otherwise. func_find_tool () { $debug_cmd find_tool_envvar=$1 shift find_tool_names=$@ eval "find_tool_res=\$$find_tool_envvar" if test x"$find_tool_res" = x; then for i do if ($i --version /dev/null 2>&1; then find_tool_res=$i break fi done else find_tool_error_prefix="\$$find_tool_envvar: " fi test x"$find_tool_res" = x && func_fatal_error "\ Error: One of these is required: $find_tool_names" ($find_tool_res --version /dev/null 2>&1 \ || func_fatal_error "\ Error: ${find_tool_error_prefix}Cannot run \`$find_tool_res --version'" eval "$find_tool_envvar=\$find_tool_res" eval "export $find_tool_envvar" } # func_update_po_files PO_DIR DOMAIN # ---------------------------------- # Mirror .po files to $po_dir/.reference and copy only the new # or modified ones into $po_dir. Also update $po_dir/LINGUAS. # Note po files that exist locally only are left in $po_dir but will # not be included in LINGUAS and hence will not be distributed. func_update_po_files () { $debug_cmd # Directory containing primary .po files. # Overwrite them only when we're sure a .po file is new. po_dir=$1 domain=$2 # Mirror *.po files into this dir. # Usually contains *.s1 checksum files. ref_po_dir="$po_dir/.reference" test -d $ref_po_dir || mkdir $ref_po_dir || return func_download_po_files $ref_po_dir $domain \ && ls "$ref_po_dir"/*.po 2>/dev/null | $SED 's|.*/||; s|\.po$||' > "$po_dir/LINGUAS" || return # Find sha1sum, named gsha1sum on MacPorts, and shasum on MacOS 10.6. func_find_tool SHA1SUM sha1sum gsha1sum shasum langs=`cd $ref_po_dir && echo *.po|$SED 's|\.po||g'` test "$langs" = '*' && langs=x for po in $langs; do case $po in x) continue;; esac new_po="$ref_po_dir/$po.po" cksum_file="$ref_po_dir/$po.s1" if ! test -f "$cksum_file" || ! test -f "$po_dir/$po.po" || ! $SHA1SUM -c --status "$cksum_file" \ < "$new_po" > /dev/null; then echo "updated $po_dir/$po.po..." cp "$new_po" "$po_dir/$po.po" \ && $SHA1SUM < "$new_po" > "$cksum_file" fi done } ## ----------------- ## ## Global variables. ## ## ----------------- ## EXIT_SUCCESS=0 EXIT_FAILURE=1 EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. exit_status=$EXIT_SUCCESS # Allow overriding, eg to get a function call trace: # debug_cmd='eval echo "${FUNCNAME[0]} $*" >&2' bash bootstrap debug_cmd="${debug_cmd-:}" exit_cmd=: dirname='s|/[^/]*$||' basename='s|^.*/||' nl=' ' # Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh # is ksh but when the shell is invoked as "sh" and the current value of # the _XPG environment variable is not equal to 1 (one), the special # positional parameter $0, within a function call, is the name of the # function. progpath="$0" # The name of this program: progname=`echo "$progpath" |$SED "$basename"` ## -------------------------------------------------- ## ## Source package customisations in `bootstrap.conf'. ## ## -------------------------------------------------- ## # Override the default configuration, if necessary. # Make sure that bootstrap.conf is sourced from the current directory # if we were invoked as "sh bootstrap". case "$0" in */*) test -r "$0.conf" && . "$0.conf" ;; *) test -r "$0.conf" && . ./"$0.conf" ;; esac # Bail out if this package only bootstraps properly from a repository # checkout. test -n "$checkout_only_file" && test ! -f "$checkout_only_file" \ && func_fatal_error "\ Error: Bootstrapping from a non-checked-out distribution is risky." ## ------------------------------- ## ## Actually perform the bootstrap. ## ## ------------------------------- ## func_bootstrap ${1+"$@"} # The End. exit $exit_status # Local variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: