| #!/usr/bin/env bash |
| |
| # |
| # Copyright 2019-2020 Google LLC. All Rights Reserved. |
| # Copyright 2014-2017 Nest Labs Inc. All Rights Reserved. |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); |
| # you may not use this file except in compliance with the License. |
| # You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| # |
| |
| # |
| # Description: |
| # This file is a convenience script that will bootstrap the GNU |
| # autotools system for a project after any build system changes. |
| # |
| |
| # |
| # usage |
| # |
| # Display program usage. |
| # |
| usage() { |
| name="$(basename "${0}")" |
| |
| echo "Usage: ${name} [ options ] [ -w <what> ]" |
| |
| if [ "${1}" -ne 0 ]; then |
| echo "Try '${name} -h' for more information." |
| fi |
| |
| if [ "${1}" -ne 1 ]; then |
| echo "" |
| echo " -h, --help Print this help, then exit." |
| echo " -I DIR Specify directory DIR as the root of the " |
| echo " nlbuild-autotools repository." |
| echo " -v, --verbose Verbosely report bootstrap progress." |
| echo " -w, --what WHAT Specify what part of the package should be " |
| echo " bootstrapped: all, config, make, or none " |
| echo " (default: all)." |
| echo "" |
| fi |
| |
| exit "${1}" |
| } |
| |
| # |
| # check_required_executable <path variable> <executable name> |
| # |
| # Check to ensure that the named executable with the path in the |
| # provided variable exists and is executable by the current user. |
| # |
| check_required_executable() { |
| variable="${1}" |
| path="${!variable}" |
| name="${2}" |
| output="${3}" |
| stem="The required executable '${name}'" |
| |
| if [ -z "${path}" ]; then |
| echo "${stem} could not be found." |
| |
| eval "${output}=no" |
| |
| return 1 |
| elif [ ! -e "${path}" ] || [ ! -x "${path}" ]; then |
| stem="${stem} at '${path}'" |
| |
| if [ ! -e "${path}" ]; then |
| echo "${stem} does not exist." |
| elif [ ! -x "${path}" ]; then |
| echo "${stem} is not executable." |
| fi |
| |
| echo "Please ensure '${name}' is available in PATH." |
| |
| eval "${output}=no" |
| |
| return 1 |
| fi |
| |
| eval "${output}=yes" |
| |
| return 0 |
| } |
| |
| check_required_executables() |
| { |
| local have_aclocal |
| local have_autoconf |
| local have_autoheader |
| local have_automake |
| local have_libtoolize |
| local have_m4 |
| |
| check_required_executable ACLOCAL aclocal have_aclocal |
| check_required_executable AUTOCONF autoconf have_autoconf |
| check_required_executable AUTOHEADER autoheader have_autoheader |
| check_required_executable AUTOMAKE automake have_automake |
| check_required_executable LIBTOOLIZE libtoolize have_libtoolize |
| check_required_executable M4 m4 have_m4 |
| |
| if [ "${have_aclocal}" = "no" ] || [ "${have_autoconf}" = "no" ] || [ "${have_autoheader}" = "no" ] || [ "${have_automake}" = "no" ] || [ "${have_libtoolize}" = "no" ] || [ "${have_m4}" = "no" ]; then |
| cat << EOF |
| -------------------------------------------------------------------------------- |
| Your build host system is missing one or more of the above executables required |
| for bootstrapping this nlbuild-autotools-based package. You can either install |
| these yourself using package management tools available and appropriate for your |
| build host platform or you can build preselected versions of these executables |
| from source for this package on this build host by invoking: |
| |
| make -C ${nlbuild_autotools_dir} tools |
| |
| and then re-running this script which will use those executables. |
| -------------------------------------------------------------------------------- |
| EOF |
| |
| exit 1 |
| |
| fi |
| } |
| |
| # |
| # removetmp |
| # |
| # Remove temporary files and directories used during the run of this |
| # script. |
| # |
| removetmp() { |
| if [ -n "${LIBTOOLIZE}" ] && [ "${LIBTOOLIZE}" = "${BOOTSTRAP_TMPDIR}/libtoolize" ]; then |
| rm -f "${LIBTOOLIZE}" |
| fi |
| |
| if [ -n "${AUTOM4TE_CFG}" ]; then |
| rm -f "${AUTOM4TE_CFG}" |
| fi |
| |
| rm -r -f "${BOOTSTRAP_TMPDIR}" |
| } |
| |
| # |
| # try_tool_action <tool executable> |
| # |
| # This attempts to run the specified build bootstrap tool, displaying |
| # the tool action to standard output if the verbose flag has been |
| # asserted. |
| # |
| # If the tool has failure status or if the verbose flag has been |
| # asserted, any error output from the tool is displayed to standard |
| # error. Likewise, if the tool has failure status, temporary files are |
| # removed and the script exits with that failed status. |
| # |
| try_tool_action() |
| { |
| local action |
| local errors |
| local status |
| |
| action="${1}" |
| |
| # If the verbose flag is asserted, display to standard output the |
| # tool action that will be run. |
| |
| if [[ -n "${verbose}" ]]; then |
| echo "${action}" |
| fi |
| |
| # Run the tool, capturing any errors and exit status. |
| |
| errors="$(${action} 2>&1)" |
| status="${?}" |
| |
| # If there was failed exit status or if the verbose flag is |
| # asserted and if there were errors captured, display them to |
| # standard error. |
| |
| if [[ ${status} -ne 0 ]] || [[ -n "${verbose}" ]]; then |
| if [[ -n "${errors}" ]]; then |
| echo "${errors}" >&2 |
| fi |
| fi |
| |
| # If there was failed exit status, clean up any temporary files |
| # and exit with the failed status. |
| |
| if [[ ${status} -ne 0 ]]; then |
| removetmp |
| |
| exit ${status} |
| fi |
| } |
| |
| what="all" |
| verbose= |
| nlbuild_autotools_dir= |
| |
| # Parse out any command line options |
| |
| while [ ${#} -gt 0 ]; do |
| case ${1} in |
| -h|--help) |
| usage 0 |
| ;; |
| |
| -I) |
| nlbuild_autotools_dir="${2}" |
| shift 2 |
| ;; |
| |
| -v|--verbose) |
| verbose="--verbose" |
| shift 1 |
| ;; |
| |
| -w|--what) |
| case "${2}" in |
| |
| all|make*|conf*|none) |
| what="${2}" |
| shift 2 |
| ;; |
| |
| *) |
| echo "Unknown what value '${2}'." >&2 |
| usage 1 |
| ;; |
| |
| esac |
| ;; |
| |
| *) |
| usage 1 |
| ;; |
| |
| esac |
| done |
| |
| # Check to ensure that the location of the nlbuild-autotools directory |
| # is sane. |
| |
| if [ -z "${nlbuild_autotools_dir}" ]; then |
| echo "$0: No -I option specified. Please provide the location of the nlbuild-autotools directory." >&2 |
| exit 1 |
| |
| elif [ ! -d "${nlbuild_autotools_dir}" ]; then |
| echo "$0: No such directory: ${nlbuild_autotools_dir}. Please provide a valid path to the nlbuild-autotools directory." >&2 |
| exit 1 |
| |
| fi |
| |
| # Establish some key directories |
| |
| abs_top_hostdir="${nlbuild_autotools_dir}/tools/host" |
| |
| # Figure out what sort of build host we are running on, stripping off |
| # any trailing version number information typically included on Darwin |
| # / Mac OS X. |
| |
| host="$("${nlbuild_autotools_dir}/third_party/autoconf/config.guess" | sed -e 's/[[:digit:].]*$//g')" |
| |
| # If possible, attempt to be self-sufficient, relying on GNU autotools |
| # executables installed along with the SDK itself. |
| |
| if [ -d "${abs_top_hostdir}/${host}/bin" ]; then |
| export PATH="${abs_top_hostdir}/${host}/bin:${PATH}" |
| fi |
| |
| if [ -d "${abs_top_hostdir}/bin" ]; then |
| export PATH="${abs_top_hostdir}/bin:${PATH}" |
| fi |
| |
| ACLOCAL="$(command -v aclocal)" |
| AUTOCONF="$(command -v autoconf)" |
| AUTOHEADER="$(command -v autoheader)" |
| AUTOM4TE="$(command -v autom4te)" |
| AUTOMAKE="$(command -v automake)" |
| LIBTOOLIZE="$(command -v libtoolize || command -v glibtoolize)" |
| M4="$(command -v m4)" |
| TRUE="$(command -v true)" |
| |
| export ACLOCAL |
| export AUTOCONF |
| export AUTOHEADER |
| export AUTOM4TE |
| export AUTOMAKE |
| export LIBTOOLIZE |
| export M4 |
| |
| # Establish, if necessary, some SDK-specific directories needed to |
| # override various paths in GNU autotools that otherwise expect to be |
| # absolute (e.g. /usr/share, etc.). |
| |
| if [ -d "${abs_top_hostdir}/share" ]; then |
| if [ -d "${abs_top_hostdir}/share/autoconf" ]; then |
| export AC_MACRODIR="${abs_top_hostdir}/share/autoconf" |
| |
| export autom4te_perllibdir="${abs_top_hostdir}/share/autoconf" |
| fi |
| |
| if [ -d "${abs_top_hostdir}/share/automake-1.14" ]; then |
| export PERL5LIB="${abs_top_hostdir}/share/automake-1.14:${PERL5LIB}" |
| |
| make_action_options="--libdir ${abs_top_hostdir}/share/automake-1.14" |
| fi |
| |
| if [ -d "${abs_top_hostdir}/share/aclocal-1.14" ]; then |
| local_action_options="--automake-acdir=${abs_top_hostdir}/share/aclocal-1.14 ${local_action_options}" |
| fi |
| |
| if [ -d "${abs_top_hostdir}/share/aclocal" ]; then |
| local_action_options="--system-acdir=${abs_top_hostdir}/share/aclocal ${local_action_options}" |
| fi |
| fi |
| |
| # Both autom4te.cfg and libtoolize, as installed from source, want to |
| # use absolute file system paths that cannot be |
| # overridden. Consequently, we create temporary, local versions of |
| # these, patched up with SDK-specific paths. |
| |
| BOOTSTRAP_TMPDIR="$(mktemp -d /tmp/tmp.bootstrapXXXXXX)" |
| |
| trap "removetmp" 1 2 3 15 |
| |
| # |
| # Generate any temporary files that need to be patched at run time |
| # with the location of the SDK tree, including: |
| # |
| # - The autom4te configuration file |
| # - The libtoolize executable script |
| # |
| |
| if [ -r "${abs_top_hostdir}/share/autoconf/autom4te.cfg" ]; then |
| export AUTOM4TE_CFG="${BOOTSTRAP_TMPDIR}/autom4te.cfg" |
| |
| sed -e "s,//share/autoconf,${abs_top_hostdir}/share/autoconf,g" < "${abs_top_hostdir}/share/autoconf/autom4te.cfg" > "${AUTOM4TE_CFG}" |
| fi |
| |
| if [ -r "${abs_top_hostdir}/${host}/bin/libtoolize" ]; then |
| export LIBTOOLIZE="${BOOTSTRAP_TMPDIR}/libtoolize" |
| |
| sed -e "s,//share/libtool,${abs_top_hostdir}/share/libtool,g" -e "s,//share/aclocal,${abs_top_hostdir}/share/aclocal,g" < "${abs_top_hostdir}/${host}/bin/libtoolize" > "${LIBTOOLIZE}" |
| |
| chmod 775 "${LIBTOOLIZE}" |
| fi |
| |
| # Before we get much further, check to ensure that the required |
| # executables are available and, if not, provide some actionable |
| # guidance. |
| |
| check_required_executables |
| |
| if [ -n "${verbose}" ]; then |
| echo PATH="${PATH}" |
| |
| echo ACLOCAL="${ACLOCAL}" |
| echo AUTOCONF="${AUTOCONF}" |
| echo AUTOHEADER="${AUTOHEADER}" |
| echo AUTOM4TE="${AUTOM4TE}" |
| echo AUTOMAKE="${AUTOMAKE}" |
| echo LIBTOOLIZE="${LIBTOOLIZE}" |
| echo M4="${M4}" |
| echo TRUE="${TRUE}" |
| |
| echo AC_MACRODIR="${AC_MACRODIR}" |
| echo AUTOM4TE_CFG="${AUTOM4TE_CFG}" |
| echo PERL5LIB="${PERL5LIB}" |
| echo autom4te_perllibdir="${autom4te_perllibdir}" |
| |
| echo local_action_options="${local_action_options}" |
| echo make_action_options="${make_action_options}" |
| fi |
| |
| # Set up the default actions for each bootstrap stage. |
| |
| local_action="${ACLOCAL} ${verbose} ${local_action_options}" |
| header_action="${AUTOHEADER} ${verbose}" |
| tool_action="${LIBTOOLIZE} ${verbose} --automake --copy --force" |
| make_action="${AUTOMAKE} ${verbose} ${make_action_options} --add-missing --copy" |
| config_action="${AUTOCONF} ${verbose}" |
| |
| # Determine what needs to be short-circuited based on the |
| # user-specified "what". |
| |
| case "${what}" in |
| |
| all) |
| ;; |
| |
| conf*) |
| local_action="${TRUE}" |
| header_action="${TRUE}" |
| tool_action="${TRUE}" |
| make_action="${TRUE}" |
| ;; |
| |
| make*) |
| local_action="${TRUE}" |
| header_action="${TRUE}" |
| config_action="${TRUE}" |
| ;; |
| |
| none) |
| local_action="${TRUE}" |
| header_action="${TRUE}" |
| tool_action="${TRUE}" |
| make_action="${TRUE}" |
| config_action="${TRUE}" |
| ;; |
| |
| esac |
| |
| # Bootstrap the package. |
| |
| try_tool_action "${local_action}" |
| try_tool_action "${tool_action}" |
| try_tool_action "${header_action}" |
| try_tool_action "${make_action}" |
| try_tool_action "${config_action}" |
| |
| # Clean up any temporary files created. |
| |
| removetmp |