1#!/bin/bash
2
3#
4#    Copyright 2019 Google LLC. All Rights Reserved.
5#    Copyright 2014-2017 Nest Labs Inc. All Rights Reserved.
6#
7#    Licensed under the Apache License, Version 2.0 (the "License");
8#    you may not use this file except in compliance with the License.
9#    You may obtain a copy of the License at
10#
11#    http://www.apache.org/licenses/LICENSE-2.0
12#
13#    Unless required by applicable law or agreed to in writing, software
14#    distributed under the License is distributed on an "AS IS" BASIS,
15#    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16#    See the License for the specific language governing permissions and
17#    limitations under the License.
18#
19
20#
21#    Description:
22#      This file is a convenience script that will bootstrap the GNU
23#      autotools system for a project after any build system changes.
24#
25
26#
27# usage
28#
29# Display program usage.
30#
31usage() {
32    name=`basename $0`
33
34    echo "Usage: ${name} [ options ] [ -w <what> ]"
35
36    if [ $1 -ne 0 ]; then
37        echo "Try '${name} -h' for more information."
38    fi
39
40    if [ $1 -ne 1 ]; then
41        echo ""
42        echo "  -h, --help       Print this help, then exit."
43        echo "  -I DIR           Specify directory DIR as the root of the "
44        echo "                   nlbuild-autotools repository."
45        echo "  -v, --verbose    Verbosely report bootstrap progress."
46        echo "  -w, --what WHAT  Specify what part of the package should be "
47        echo "                   bootstrapped: all, config, make, or none "
48        echo "                   (default: all)."
49        echo ""
50    fi
51
52    exit $1
53}
54
55#
56# check_required_executable <path variable> <executable name>
57#
58# Check to ensure that the named executable with the path in the
59# provided variable exists and is executable by the current user.
60#
61check_required_executable() {
62    variable="${1}"
63    path="${!variable}"
64    name="${2}"
65    output="${3}"
66    stem="The required executable '${name}'"
67
68    if [ -z "${path}" ]; then
69        echo "${stem} could not be found."
70
71        eval "${output}"="no"
72
73        return 1
74    elif [ ! -e "${path}" ] || [ ! -x "${path}" ]; then
75        stem="${stem} at '${path}'"
76
77        if [ ! -e ${path} ]; then
78            echo "${stem} does not exist."
79        elif [ ! -x ${path} ]; then
80            echo "${stem} is not executable."
81        fi
82
83        echo "Please ensure '${name}' is available in PATH."
84
85	eval "${output}"="no"
86
87        return 1
88    fi
89
90    eval "${output}"="yes"
91
92    return 0
93}
94
95check_required_executables()
96{
97    check_required_executable ACLOCAL aclocal have_aclocal
98    check_required_executable AUTOCONF autoconf have_autoconf
99    check_required_executable AUTOHEADER autoheader have_autoheader
100    check_required_executable AUTOMAKE automake have_automake
101    check_required_executable LIBTOOLIZE libtoolize have_libtoolize
102    check_required_executable M4 m4 have_m4
103
104    if [ "${have_aclocal}" = "no" ] || [ "${have_autoconf}" = "no" ] || [ "${have_autoheader}" = "no" ] || [ "${have_automake}" = "no" ] || [ "${have_libtoolize}" = "no" ] || [ "${have_m4}" = "no" ]; then
105	cat << EOF
106--------------------------------------------------------------------------------
107Your build host system is missing one or more of the above executables required
108for bootstrapping this nlbuild-autotools-based package. You can either install
109these yourself using package management tools available and appropriate for your
110build host platform or you can build preselected versions of these executables
111from source for this package on this build host by invoking:
112
113    make -C ${nlbuild_autotools_dir} tools
114
115and then re-running this script which will use those executables.
116--------------------------------------------------------------------------------
117EOF
118
119      exit 1
120
121    fi
122}
123
124#
125# removetmp
126#
127# Remove temporary files and directories used during the run of this
128# script.
129#
130removetmp() {
131    if [ -n "${LIBTOOLIZE}"  ] && [ "${LIBTOOLIZE}" = "${BOOTSTRAP_TMPDIR}/libtoolize" ]; then
132        rm -f "${LIBTOOLIZE}"
133    fi
134
135    if [ -n "${AUTOM4TE_CFG}" ]; then
136        rm -f "${AUTOM4TE_CFG}"
137    fi
138
139    rm -r -f "${BOOTSTRAP_TMPDIR}"
140}
141
142what="all"
143verbose=
144nlbuild_autotools_dir=
145
146# Parse out any command line options
147
148while [ ${#} -gt 0 ]; do
149    case ${1} in
150    -h|--help)
151        usage 0
152        ;;
153
154    -I)
155        nlbuild_autotools_dir="${2}"
156        shift 2
157        ;;
158
159    -v|--verbose)
160        verbose="--verbose"
161        shift 1
162        ;;
163
164    -w|--what)
165        case "${2}" in
166
167        all|make*|conf*|none)
168            what="${2}"
169            shift 2
170            ;;
171
172        *)
173	    echo "Unknown what value '${2}'." >&2
174            usage 1
175            ;;
176
177        esac
178        ;;
179
180    *)
181        usage 1
182        ;;
183
184    esac
185done
186
187# Check to ensure that the location of the nlbuild-autotools directory
188# is sane.
189
190if [ -z "${nlbuild_autotools_dir}" ]; then
191    echo "$0: No -I option specified. Please provide the location of the nlbuild-autotools directory." >&2
192    exit 1
193
194elif [ ! -d "${nlbuild_autotools_dir}" ]; then
195    echo "$0: No such directory: ${nlbuild_autotools_dir}. Please provide a valid path to the nlbuild-autotools directory." >&2
196    exit 1
197
198fi
199
200# Establish some key directories
201
202srcdir=`dirname ${0}`
203abs_srcdir=`pwd`
204abs_top_srcdir="${abs_srcdir}"
205
206abs_top_hostdir="${nlbuild_autotools_dir}/tools/host"
207
208# Figure out what sort of build host we are running on, stripping off
209# any trailing version number information typically included on Darwin
210# / Mac OS X.
211
212host=`${nlbuild_autotools_dir}/third_party/autoconf/config.guess | sed -e 's/[[:digit:].]*$//g'`
213
214# If possible, attempt to be self-sufficient, relying on GNU autotools
215# executables installed along with the SDK itself.
216
217if [ -d "${abs_top_hostdir}/${host}/bin" ]; then
218    export PATH="${abs_top_hostdir}/${host}/bin:${PATH}"
219fi
220
221if [ -d "${abs_top_hostdir}/bin" ]; then
222    export PATH="${abs_top_hostdir}/bin:${PATH}"
223fi
224
225export ACLOCAL=`which aclocal`
226export AUTOCONF="`which autoconf`"
227export AUTOHEADER="`which autoheader`"
228export AUTOM4TE="`which autom4te`"
229export AUTOMAKE="`which automake`"
230export LIBTOOLIZE="`which libtoolize || which glibtoolize`"
231export M4=`which m4`
232
233# Establish, if necessary, some SDK-specific directories needed to
234# override various paths in GNU autotools that otherwise expect to be
235# absolute (e.g. /usr/share, etc.).
236
237if [ -d "${abs_top_hostdir}/share" ]; then
238    if [ -d "${abs_top_hostdir}/share/autoconf" ]; then
239        export AC_MACRODIR="${abs_top_hostdir}/share/autoconf"
240
241        export autom4te_perllibdir="${abs_top_hostdir}/share/autoconf"
242    fi
243
244    if [ -d "${abs_top_hostdir}/share/automake-1.14" ]; then
245        export PERL5LIB="${abs_top_hostdir}/share/automake-1.14:${PERL5LIB}"
246
247	make_action_options="--libdir ${abs_top_hostdir}/share/automake-1.14"
248    fi
249
250    if [ -d "${abs_top_hostdir}/share/aclocal-1.14" ]; then
251        local_action_options="--automake-acdir=${abs_top_hostdir}/share/aclocal-1.14 ${local_action_options}"
252    fi
253
254    if [ -d "${abs_top_hostdir}/share/aclocal" ]; then
255        local_action_options="--system-acdir=${abs_top_hostdir}/share/aclocal ${local_action_options}"
256    fi
257fi
258
259# Both autom4te.cfg and libtoolize, as installed from source, want to
260# use absolute file system paths that cannot be
261# overridden. Consequently, we create temporary, local versions of
262# these, patched up with SDK-specific paths.
263
264BOOTSTRAP_TMPDIR="`mktemp -d /tmp/tmp.bootstrapXXXXXX`"
265
266trap "removetmp" 1 2 3 9 15
267
268#
269# Generate any temporary files that need to be patched at run time
270# with the location of the SDK tree, including:
271#
272#   -  The autom4te configuration file
273#   -  The libtoolize executable script
274#
275
276if [ -r "${abs_top_hostdir}/share/autoconf/autom4te.cfg" ]; then
277    export AUTOM4TE_CFG="${BOOTSTRAP_TMPDIR}/autom4te.cfg"
278
279    sed -e "s,//share/autoconf,${abs_top_hostdir}/share/autoconf,g" < "${abs_top_hostdir}/share/autoconf/autom4te.cfg" > "${AUTOM4TE_CFG}"
280fi
281
282if [ -r "${abs_top_hostdir}/${host}/bin/libtoolize" ]; then
283    export LIBTOOLIZE="${BOOTSTRAP_TMPDIR}/libtoolize"
284
285    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}"
286
287    chmod 775 "${LIBTOOLIZE}"
288fi
289
290# Before we get much further, check to ensure that the required
291# executables are available and, if not, provide some actionable
292# guidance.
293
294check_required_executables
295
296if [ -n "${verbose}" ]; then
297    echo PATH="${PATH}"
298
299    echo ACLOCAL="${ACLOCAL}"
300    echo AUTOCONF="${AUTOCONF}"
301    echo AUTOHEADER="${AUTOHEADER}"
302    echo AUTOM4TE="${AUTOM4TE}"
303    echo AUTOMAKE="${AUTOMAKE}"
304    echo LIBTOOLIZE="${LIBTOOLIZE}"
305    echo M4="${M4}"
306
307    echo AC_MACRODIR="${AC_MACRODIR}"
308    echo AUTOM4TE_CFG="${AUTOM4TE_CFG}"
309    echo PERL5LIB="${PERL5LIB}"
310    echo autom4te_perllibdir="${autom4te_perllibdir}"
311
312    echo local_action_options="${local_action_options}"
313    echo make_action_options="${make_action_options}"
314fi
315
316# Set up the default actions for each bootstrap stage.
317
318local_action="${ACLOCAL} ${verbose} ${local_action_options}"
319header_action="${AUTOHEADER} ${verbose}"
320tool_action="${LIBTOOLIZE} ${verbose} --automake --copy --force"
321make_action="${AUTOMAKE} ${verbose} ${make_action_options} --add-missing --copy"
322config_action="${AUTOCONF} ${verbose}"
323
324# Determine what needs to be short-circuited based on the
325# user-specified "what".
326
327case "${what}" in
328
329    all)
330        ;;
331
332    conf*)
333        local_action=true
334        header_action=true
335        tool_action=true
336        make_action=true
337        ;;
338
339    make*)
340        local_action=true
341        header_action=true
342        config_action=true
343        ;;
344
345    none)
346        local_action=true
347        header_action=true
348        tool_action=true
349        make_action=true
350        config_action=true
351        ;;
352
353esac
354
355# Bootstrap the package.
356
357if [ -n "${verbose}" ]; then
358    echo "${local_action} && ${tool_action} && ${header_action} && ${make_action} && ${config_action}"
359fi
360
361${local_action} && ${tool_action} && ${header_action} && ${make_action} && ${config_action}
362
363# Clean up any temporary files created.
364
365removetmp
366