4 # Copyright (c) 2020 Project nlbuild-autotools Authors. All Rights Reserved.
5 # Copyright (c) 2018 Google LLC. All Rights Reserved.
6 # Copyright (c) 2014-2018 Nest Labs Inc. All Rights Reserved.
8 # Licensed under the Apache License, Version 2.0 (the "License");
9 # you may not use this file except in compliance with the License.
10 # You may obtain a copy of the License at
12 # http://www.apache.org/licenses/LICENSE-2.0
14 # Unless required by applicable law or agreed to in writing, software
15 # distributed under the License is distributed on an "AS IS" BASIS,
16 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 # See the License for the specific language governing permissions and
18 # limitations under the License.
23 # This file is a convenience script for building, for the current
24 # build host system, the minimal, core set of GNU autotools on
25 # which other projects' build systems depend.
28 EXTENSIONS="tar.gz tar.xz"
34 abs_top_srcdir=`echo ${abs_srcdir} | sed -e s,/${stem},,g`
36 abs_top_hostdir="${abs_top_srcdir}/tools/host"
41 # Display program usage.
46 echo "Usage: ${name} [ options ] [ -- <package> ... ]"
49 echo "Try '${name} -h' for more information."
54 echo " --arch ARCH Build the package for ARCH host architecture."
55 echo " -h, --help Print this help, then exit."
56 echo " --builddir DIR Build the packages in DIR."
57 echo " --destdir DIR Install the built tools to directory DIR."
58 echo " --srcdir DIR Find package, version, and URL metadata in DIR."
59 echo " -v, --verbose Enable verbose output."
69 # Display to standard error the specified arguments
78 # Display to standard error the specified arguments
87 # Display to standard error a log separator.
90 verbose "--------------------------------------------------------------------------------"
96 # Display to standard error a log trailer.
99 verbose "================================================================================"
103 # banner <message ...>
105 # Display to standard error a log banner with a message.
114 # subbanner <message ...>
116 # Display to standard error a log subbanner with a message.
125 # find_archive <subdir> <package> <extensions...>
127 # Attempt to find the specified package archive in the provided
128 # subdirectory matching one of the specified extensions.
137 for extension in ${*}; do
138 local maybe_archive="${subdir}/${package}.${extension}"
140 verbose " FIND ${maybe_archive}"
142 if [ -r "${maybe_archive}" ]; then
143 archive="${maybe_archive}"
152 # find_versioned_or_nonversioned_archive <subdir> <package> <version> <extensions...>
154 # Attempt to find the specified version-qualified or non-qualified
155 # package archive in the provided subdirectory matching one of the
156 # specified extensions.
158 find_versioned_or_nonverioned_archive() {
162 local fqpackage="${package}-${version}"
167 archive="`find_archive ${subdir} ${fqpackage} ${*}`"
169 if [ -z "${archive}" ]; then
170 archive="`find_archive ${subdir} ${package} ${*}`"
177 # fetch_url_with_command <fetchdir> <url> <command ...>
179 # Attempt to fetch the specified URL to the provided directory with
180 # the provided command.
182 fetch_url_with_command() {
183 local fetchdir="${1}"
185 local executable="`which ${3}`"
191 if [ -x "${executable}" ]; then
194 verbose " `echo ${1} | tr '[[:lower:]]' '[[:upper:]]'` ${url}"
200 if [ ${?} -ne 0 ]; then
201 error "Failed to fetch ${url} with ${1}."
211 # fetch_url <fetchdir> <url>
213 # Attempt to fetch the specified URL to the provided directory with
214 # either wget or curl.
217 local fetchdir="${1}"
220 # Try to fetch the package using wget or curl
222 fetch_url_with_command "${fetchdir}" "${url}" wget --tries 4 --no-check-certificate --quiet ||
223 fetch_url_with_command "${fetchdir}" "${url}" curl --retry 4 --insecure --silent --remote-name
227 # fetch_package <finddir> <fetchdir> <package> <version> <url>
229 # Attempt to fetch the specified package version to <fetchdir>, if a
230 # local archive does not already exist in <finddir> or <fetchdir>,
231 # from the provided URL.
235 local fetchdir="${2}"
239 local fqpackage="${package}-${version}"
241 # Check whether a local archive already exists in <finddir> or <fetchdir>.
243 archive="`find_versioned_or_nonverioned_archive ${finddir} ${package} ${version} ${EXTENSIONS}`"
245 if [ -z "${archive}" ]; then
246 archive="`find_versioned_or_nonverioned_archive ${fetchdir} ${package} ${version} ${EXTENSIONS}`"
249 # If no archive was found, attempt to fetch it.
251 if [ -z "${archive}" ]; then
252 verbose " FETCH ${url}"
254 fetch_url "${fetchdir}" "${url}"
257 error "No, found ${archive} locally."
265 # Remove temporary files and directories used during the run of this
269 if [ -O "${LIBTOOLIZE}" ]; then
270 rm -f "${LIBTOOLIZE}"
272 if [ -n "${AUTOM4TE_CFG}" ]; then
273 rm -f "${AUTOM4TE_CFG}"
280 # Returns a filename's extension, if any.
284 [[ $ext != $1 ]] || ext=
289 # patch_directory <directory> <patch arguments> <patch file> [ ... ]
291 # Patch the specified directory by applying the provided patched files
292 # using the specified patch arguments. The specified patch files may
293 # be uncompressed or compressed with any of bz2, gz, xz, compress, or
297 local directory="${1}"
298 local patchargs="${2}"
302 verbose " PATCH ${directory}"
304 for patch in "${*}"; do
305 verbose " PATCH ${patch}"
307 case $(file_extension "${patch}") in
310 uncompressor="bunzip2 -c"
314 uncompressor="gunzip -c"
318 uncompressor="xz -d -c"
322 uncompressor="uncompress -c"
326 uncompressor="unzip -p"
335 ${uncompressor} "${patch}" | patch ${patchargs} -d "${directory}" || exit 1;
341 # Determine the number of CPU threads available to this process
349 nthreads=$(sysctl -n hw.ncpu)
366 # build_package <package> <version> <host> <patchdir> <archivedir> <builddir> <destdir>
368 # Build the specified package version for <host> in <builddir> from
369 # the archive found in <archivedir>, after applying the patches in
370 # <patchdir> (if any), and install it into the specified destination
371 # directory, <destdir>.
377 local patchdir="${4}"
378 local archivedir="${5}"
379 local builddir="${6}"
381 local fqpackage="${package}-${version}"
386 verbose " CHECK ${package}"
388 archive="`find_versioned_or_nonverioned_archive ${archivedir} ${package} ${version} ${EXTENSIONS}`"
390 if [ -z "${archive}" ]; then
391 error "Could not find an archive for ${package}."
395 if [ ! -d "${archivedir}/${fqpackage}" ]; then
396 verbose " TAR ${archive}"
397 tar --directory "${archivedir}" -xf "${archive}" || exit ${?}
400 # If necessary, patch the expanded package.
402 if [ -d "${patchdir}" ]; then
403 patch_directory "${archivedir}/${fqpackage}" "-s -p1" ${patchdir}/*.patch*
406 # If possible, attempt to be self-sufficient, relying on GNU autotools
407 # executables installed along with the SDK itself.
409 if [ -d "${destdir}/${host}/bin" ]; then
410 export PATH="${destdir}/${host}/bin:${PATH}"
413 if [ -d "${destdir}/bin" ]; then
414 export PATH="${destdir}/bin:${PATH}"
417 export ACLOCAL=`which aclocal`
418 export AUTOCONF="`which autoconf`"
419 export AUTOHEADER="`which autoheader`"
420 export AUTOM4TE="`which autom4te`"
421 export AUTOMAKE="`which automake`"
422 export LIBTOOLIZE="`which libtoolize || which glibtoolize`"
425 # Establish, if necessary, some SDK-specific directories needed to
426 # override various paths in GNU autotools that otherwise expect to be
427 # absolute (e.g. /usr/share, etc.).
429 if [ -d "${destdir}/share" ]; then
430 if [ -d "${destdir}/share/autoconf" ]; then
431 export AC_MACRODIR="${destdir}/share/autoconf"
433 export autom4te_perllibdir="${destdir}/share/autoconf"
436 if [ -d "${destdir}/share/automake-1.14" ]; then
437 export PERL5LIB="${destdir}/share/automake-1.14:${PERL5LIB}"
441 trap "removetmp" 1 2 3 9 15
444 # Generate any temporary files that need to be patched at run time
445 # with the location of the SDK tree, including:
447 # - The autom4te configuration file
448 # - The libtoolize executable script
451 if [ -r "${destdir}/share/autoconf/autom4te.cfg" ]; then
452 export AUTOM4TE_CFG="${destdir}/autom4te.cfg"
454 sed -e "s,//share/autoconf,${destdir}/share/autoconf,g" < "${destdir}/share/autoconf/autom4te.cfg" > "${AUTOM4TE_CFG}"
457 if [ -r "${destdir}/${host}/bin/libtoolize" ]; then
458 export LIBTOOLIZE="${destdir}/libtoolize"
460 sed -e "s,//share/libtool,${destdir}/share/libtool,g" -e "s,//share/aclocal,${destdir}/share/aclocal,g" < "${destdir}/${host}/bin/libtoolize" > "${LIBTOOLIZE}"
462 chmod 775 "${LIBTOOLIZE}"
465 # Configure the package
467 if [ ${VERBOSE} -gt 0 ]; then
470 CONFIGURE_FLAGS="--quiet"
473 verbose " CONFIG ${package}"
477 ${archivedir}/${fqpackage}/configure ${CONFIGURE_FLAGS} --prefix=/ --exec-prefix=/${host} || exit ${?}
485 verbose " JOBS ${jobs}"
487 verbose " MAKE ${package}"
489 make -j ${jobs} V=${VERBOSE} -C "${builddir}" all || exit ${?}
491 # Install / stage the package
493 verbose " INSTALL ${package}"
495 make -j ${jobs} V=${VERBOSE} -C "${builddir}" DESTDIR="${destdir}" install || exit ${?}
497 # Remove any temporary files created.
502 # Parse out any command line options
504 while [ ${#} -gt 0 ]; do
546 # If the architecture is not specified, fail.
548 if [ -z "${ARCH}" ]; then
549 error "The host architecture was not specified via --arch."
554 # If the --builddir option wasn't specified, then provide a default.
556 if [ -z "${BUILDDIR}" ]; then
560 # If the --destdir option wasn't specified, then provide a default.
562 if [ -z "${DESTDIR}" ]; then
563 DESTDIR=${abs_top_hostdir}
566 # If the --srcdir option wasn't specified, then provide a default.
568 if [ -z "${SRCDIR}" ]; then
572 # Determine what packages to build
574 if [ ${#} -gt 0 ]; then
578 PACKAGES="`cat ${SRCDIR}/packages`"
584 banner "Building GNU autotools for ${ARCH}..."
586 for package in ${PACKAGES}; do
587 url="`cat ${SRCDIR}/${package}/${package}.url`"
588 version="`cat ${SRCDIR}/${package}/${package}.version`"
589 patchdir="${SRCDIR}/${package}/${package}.patches"
591 # Fetch, if necessary, the package from the canonical source location.
593 subbanner " CHECK ${package}"
595 fetch_package "${SRCDIR}/${package}" "${BUILDDIR}" "${package}" "${version}" "${url}"
597 # Build and install the package.
599 verbose " MKDIR ${BUILDDIR}/build/${ARCH}/${package}-${version}"
601 mkdir -p "${BUILDDIR}/build/${ARCH}/${package}-${version}" || exit ${?}
603 build_package "${package}" "${version}" "${ARCH}" "${patchdir}" "${BUILDDIR}" "${BUILDDIR}/build/${ARCH}/${package}-${version}" "${DESTDIR}"