| # Copyright (c) 2012 The Native Client Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| # |
| # Environment variable NACL_ARCH should be set to one of the following |
| # values: i686 x86_64 pnacl arm |
| |
| |
| # NAMING CONVENTION |
| # ================= |
| # |
| # This file is source'd by the main naclports build script. Functions |
| # and variables defined here are available in the build script for |
| # individual ports. Only variables beginging with "NACL_" are intended |
| # to be used by those scripts. |
| |
| set -o nounset |
| set -o errexit |
| |
| unset MAKEFLAGS |
| |
| readonly TOOLS_DIR=$(cd "$(dirname "$BASH_SOURCE")" ; pwd) |
| readonly START_DIR=$PWD |
| readonly NACL_SRC=$(dirname ${TOOLS_DIR}) |
| readonly NACL_PACKAGES=${NACL_SRC} |
| |
| NACL_DEBUG=${NACL_DEBUG:-0} |
| |
| NACL_ENV_IMPORT=1 |
| . ${TOOLS_DIR}/nacl-env.sh |
| |
| # When run by a buildbot force all archives to come from the NaCl mirror |
| # rather than using upstream URL. |
| if [ -n ${BUILDBOT_BUILDERNAME:-""} ]; then |
| FORCE_MIRROR=${FORCE_MIRROR:-"yes"} |
| fi |
| |
| # sha1check python script |
| readonly SHA1CHECK=${TOOLS_DIR}/sha1check.py |
| |
| readonly NACLPORTS_INCLUDE=${NACL_PREFIX}/include |
| readonly NACLPORTS_LIBDIR=${NACL_PREFIX}/lib |
| readonly NACLPORTS_BIN=${NACL_PREFIX}/bin |
| |
| # The prefix used when configuring packages. Since we want to build re-usable |
| # re-locatable binary packages, we use a dummy value here and then modify |
| # at install time certain parts of package (e.g. pkgconfig .pc files) that |
| # embed this this information. |
| readonly PREFIX=/naclports-dummydir |
| |
| NACLPORTS_CFLAGS="" |
| NACLPORTS_CXXFLAGS="" |
| NACLPORTS_CPPFLAGS="${NACL_CPPFLAGS}" |
| |
| # For the library path we always explicly add to the link flags |
| # otherwise 'libtool' won't find the libraries correctly. This |
| # is because libtool uses 'gcc -print-search-dirs' which does |
| # not honor the external specs file. |
| NACLPORTS_LDFLAGS="$NACL_LDFLAGS" |
| NACLPORTS_LDFLAGS+=" -L${NACLPORTS_LIBDIR} -Wl,-rpath-link=${NACLPORTS_LIBDIR}" |
| |
| # The NaCl version of ARM gcc emits warnings about va_args that |
| # are not particularly useful |
| if [ $NACL_ARCH = "arm" ]; then |
| NACLPORTS_CFLAGS="${NACLPORTS_CFLAGS} -Wno-psabi" |
| NACLPORTS_CXXFLAGS="${NACLPORTS_CXXFLAGS} -Wno-psabi" |
| fi |
| |
| if [ "${NACL_ARCH}" = "emscripten" ]; then |
| NACLPORTS_CFLAGS+=" -Wno-warn-absolute-paths" |
| NACLPORTS_CXXFLAGS+=" -Wno-warn-absolute-paths" |
| fi |
| |
| # configure spec for if MMX/SSE/SSE2/Assembly should be enabled/disabled |
| # TODO: Currently only x86-32 will encourage MMX, SSE & SSE2 intrinsics |
| # and handcoded assembly. |
| if [ $NACL_ARCH = "i686" ]; then |
| readonly NACL_OPTION="enable" |
| else |
| readonly NACL_OPTION="disable" |
| fi |
| |
| # Set NACL_SHARED when we want to build shared libraries. |
| if [ "${NACL_LIBC}" = "glibc" -o "${NACL_LIBC}" = "bionic" ]; then |
| NACL_SHARED=1 |
| else |
| NACL_SHARED=0 |
| fi |
| |
| if [ ${NACL_DEBUG} = "1" ]; then |
| NACLPORTS_CFLAGS+=" -g -O0" |
| NACLPORTS_CXXFLAGS+=" -g -O0" |
| else |
| NACLPORTS_CFLAGS+=" -O2" |
| NACLPORTS_CXXFLAGS+=" -O2" |
| if [ ${NACL_ARCH} = "pnacl" ]; then |
| NACLPORTS_LDFLAGS+=" -O2" |
| fi |
| fi |
| |
| # libcli_main.a has a circular dependency which makes static link fail |
| # (cli_main => nacl_io => ppapi_cpp => cli_main). To break this loop, |
| # you should use this instead of -lcli_main. |
| export NACL_CLI_MAIN_LIB="-Wl,-uPSUserCreateInstance -lcli_main" |
| |
| # Python variables |
| NACL_PYSETUP_ARGS="" |
| NACL_BUILD_SUBDIR=build |
| NACL_INSTALL_SUBDIR=install |
| |
| # output directories |
| readonly NACL_PACKAGES_OUT=${NACL_SRC}/out |
| readonly NACL_PACKAGES_ROOT=${NACL_PACKAGES_OUT}/packages |
| readonly NACL_PACKAGES_BUILD=${NACL_PACKAGES_OUT}/build |
| readonly NACL_PACKAGES_PUBLISH=${NACL_PACKAGES_OUT}/publish |
| readonly NACL_PACKAGES_CACHE=${NACL_PACKAGES_OUT}/cache |
| readonly NACL_PACKAGES_STAMPDIR=${NACL_PACKAGES_OUT}/stamp |
| readonly NACL_HOST_PYROOT=${NACL_PACKAGES_BUILD}/host_python_root |
| readonly NACL_HOST_PYTHON=${NACL_HOST_PYROOT}/bin/python2.7 |
| readonly NACL_DEST_PYROOT=${NACL_PREFIX} |
| readonly SITE_PACKAGES="lib/python2.7/site-packages/" |
| |
| # The components of package names cannot contain underscore |
| # characters so use x86-64 rather then x86_64 for arch component. |
| if [ ${NACL_ARCH} = "x86_64" ]; then |
| PACKAGE_SUFFIX="_x86-64" |
| else |
| PACKAGE_SUFFIX="_${NACL_ARCH}" |
| fi |
| |
| if [ ${NACL_ARCH} != "pnacl" ]; then |
| PACKAGE_SUFFIX+=_${NACL_LIBC} |
| fi |
| |
| if [ ${NACL_DEBUG} = "1" ]; then |
| PACKAGE_SUFFIX+=_debug |
| fi |
| |
| NACL_BUILD_SUBDIR+=${PACKAGE_SUFFIX} |
| NACL_INSTALL_SUBDIR+=${PACKAGE_SUFFIX} |
| readonly DEST_PYTHON_OBJS=${NACL_PACKAGES_BUILD}/python-modules/${NACL_BUILD_SUBDIR} |
| PACKAGE_FILE=${NACL_PACKAGES_ROOT}/${NAME}_${VERSION}${PACKAGE_SUFFIX}.tar.bz2 |
| |
| # Don't support building with SDKs older than the current stable release |
| MIN_SDK_VERSION=${MIN_SDK_VERSION:-35} |
| |
| if [ $OS_NAME = "Darwin" ]; then |
| OS_JOBS=4 |
| elif [ $OS_NAME = "Linux" ]; then |
| OS_JOBS=`nproc` |
| else |
| OS_JOBS=1 |
| fi |
| |
| GomaTest() { |
| # test the goma compiler |
| if [ "${NACL_GOMA_FORCE:-}" = 1 ]; then |
| return 0 |
| fi |
| echo 'int foo = 4;' > goma_test.c |
| GOMA_USE_LOCAL=false GOMA_FALLBACK=false gomacc $1 -c \ |
| goma_test.c -o goma_test.o 2> /dev/null |
| local RTN=$? |
| rm -f goma_test.c |
| rm -f goma_test.o |
| return $RTN |
| } |
| |
| # If NACL_GOMA is defined then we check for goma and use it if its found. |
| if [ -n "${NACL_GOMA:-}" ]; then |
| if [ ${NACL_ARCH} != "pnacl" -a ${NACL_ARCH} != "arm" ]; then |
| # Assume that if CC is good then so is CXX since GomaTest is actually |
| # quite slow |
| if GomaTest ${NACLCC}; then |
| NACLCC="gomacc ${NACLCC}" |
| NACLCXX="gomacc ${NACLCXX}" |
| # There is a bug in goma right now where the i686 compiler wrapper script |
| # is not correcly handled and gets confiused with the x86_64 version. |
| # We need to pass a redunant -m32, to force it to compiler for i686. |
| if [ "$NACL_ARCH" = "i686" ]; then |
| NACLPORTS_CFLAGS+=" -m32" |
| NACLPORTS_CXXFLAGS+=" -m32" |
| fi |
| OS_JOBS=100 |
| echo "Using GOMA!" |
| fi |
| fi |
| fi |
| |
| if [ "${NACL_DEBUG}" = "1" ]; then |
| NACL_CONFIG=Debug |
| else |
| NACL_CONFIG=Release |
| fi |
| |
| # ARCHIVE_ROOT (the folder contained within that archive) defaults to |
| # the NAME-VERSION. Packages with non-standard contents can override |
| # this before including common.sh |
| PACKAGE_NAME=${NAME} |
| ARCHIVE_ROOT=${ARCHIVE_ROOT:-${NAME}-${VERSION}} |
| WORK_DIR=${NACL_PACKAGES_BUILD}/${NAME} |
| SRC_DIR=${WORK_DIR}/${ARCHIVE_ROOT} |
| DEFAULT_BUILD_DIR=${WORK_DIR}/${NACL_BUILD_SUBDIR} |
| BUILD_DIR=${NACL_BUILD_DIR:-${DEFAULT_BUILD_DIR}} |
| INSTALL_DIR=${WORK_DIR}/${NACL_INSTALL_SUBDIR} |
| |
| # DESTDIR is where the headers, libraries, etc. will be installed |
| # Default to the usr folder within the SDK. |
| if [ -z "${DESTDIR:-}" ]; then |
| readonly DEFAULT_DESTDIR=1 |
| DESTDIR=${INSTALL_DIR} |
| fi |
| |
| DESTDIR_LIB=${DESTDIR}/${PREFIX}/lib |
| DESTDIR_INCLUDE=${DESTDIR}/${PREFIX}/include |
| |
| PUBLISH_DIR="${NACL_PACKAGES_PUBLISH}/${PACKAGE_NAME}" |
| if [ "${NACL_ARCH}" = "pnacl" ]; then |
| PUBLISH_DIR+=/pnacl |
| else |
| PUBLISH_DIR+=/${NACL_LIBC} |
| fi |
| |
| if [ "${NACL_ARCH}" != "pnacl" -a -z "${NACL_SEL_LDR:-}" ]; then |
| SKIP_SEL_LDR_TESTS=1 |
| else |
| SKIP_SEL_LDR_TESTS=0 |
| fi |
| |
| |
| ###################################################################### |
| # Always run |
| ###################################################################### |
| |
| CheckPatchVersion() { |
| # refuse patch 2.6 |
| if ! which patch > /dev/null; then |
| echo 'patch command not found, please install and try again.' |
| exit 1 |
| fi |
| if [ "`patch --version 2> /dev/null | sed q`" = "patch 2.6" ]; then |
| echo "patch 2.6 is incompatible with these scripts." |
| echo "Please install either version 2.5.9 (or earlier)" |
| echo "or version 2.6.1 (or later.)" |
| exit -1 |
| fi |
| } |
| |
| |
| CheckToolchain() { |
| if [ -n "${LIBC:-}" ]; then |
| if [ "${LIBC}" == "glibc" ]; then |
| if [ "${NACL_LIBC}" != "glibc" ]; then |
| echo "This package must be built with glibc (\$TOOLCHAIN=glibc)" |
| exit 1 |
| fi |
| elif [ "${LIBC}" == "newlib" ]; then |
| if [ "${NACL_LIBC}" != "newlib" ]; then |
| echo "This package must be built with newlib (\$TOOLCHAIN=newlib)" |
| exit 1 |
| fi |
| fi |
| fi |
| } |
| |
| |
| InstallConfigSite() { |
| CONFIG_SITE=${NACL_PREFIX}/share/config.site |
| mkdir -p ${NACL_PREFIX}/share |
| echo "ac_cv_exeext=${NACL_EXEEXT}" > ${CONFIG_SITE} |
| } |
| |
| |
| # When configure checks for system headers is doesn't pass CFLAGS |
| # to the compiler. This means that any includes that live in paths added |
| # with -I are not found. Here we push the additional newlib headers |
| # into the toolchain itself from $NACL_SDK_ROOT/include/<toolchain>. |
| InjectSystemHeaders() { |
| local TC_INCLUDES=${NACL_SDK_ROOT}/include/${TOOLCHAIN} |
| if [ ! -d "${TC_INCLUDES}" ]; then |
| return |
| fi |
| |
| MakeDir ${NACLPORTS_INCLUDE} |
| for INC in $(find ${TC_INCLUDES} -type f); do |
| INC=${INC#${TC_INCLUDES}} |
| if ! cmp ${TC_INCLUDES}${INC} ${NACLPORTS_INCLUDE}${INC} > /dev/null; then |
| MakeDir $(dirname ${NACLPORTS_INCLUDE}${INC}) |
| LogExecute cp ${TC_INCLUDES}${INC} ${NACLPORTS_INCLUDE}${INC} |
| fi |
| done |
| } |
| |
| |
| PatchSpecFile() { |
| # Temporary PNaCl toolchain hack to add usr/local/lib to the library |
| # path. TODO(sbc): remove this once this change makes it into pepper_canary: |
| # https://codereview.chromium.org/299273002/ |
| if [ "${NACL_ARCH}" = "pnacl" ]; then |
| local LD=${NACL_TOOLCHAIN_ROOT}/bin/pydir/pnacl-ld.py |
| if ! grep -q "local\/lib" "$LD"; then |
| sed -i.bak \ |
| "s:\${BASE_USR}/lib/:\${BASE_USR}/local/lib/ \${BASE_USR}/lib/:" "$LD" |
| fi |
| fi |
| |
| #if [ "${NACL_ARCH}" = "pnacl" -o "${NACL_ARCH}" = "arm" -o \ |
| if [ "${NACL_ARCH}" = "pnacl" -o \ |
| "${NACL_ARCH}" = "emscripten" ]; then |
| # The arm compiler doesn't currently need a patched specs file |
| # as it ships with the correct paths. As does the pnacl toolchain. |
| return |
| fi |
| |
| # SPECS_FILE is where nacl-gcc 'specs' file will be installed |
| if [ "${NACL_ARCH}" = "arm" ]; then |
| local SPECS_FILE=${NACL_TOOLCHAIN_ROOT}/lib/gcc/arm-nacl/4.8.3/specs |
| else |
| local SPECS_FILE=${NACL_TOOLCHAIN_ROOT}/lib/gcc/x86_64-nacl/4.4.3/specs |
| fi |
| |
| # NACL_SDK_MULITARCH_USR is a version of NACL_TOOLCHAIN_ROOT that gets passed |
| # into the gcc specs file. It has a gcc spec-file conditional for |
| # ${NACL_ARCH} |
| local NACL_SDK_MULTIARCH_USR=${NACL_TOOLCHAIN_ROOT}/\%\(nacl_arch\)/usr |
| local NACL_SDK_MULTIARCH_USR_INCLUDE=${NACL_SDK_MULTIARCH_USR}/include |
| local NACL_SDK_MULTIARCH_USR_LIB=${NACL_SDK_MULTIARCH_USR}/lib |
| local ERROR_MSG="Shared libraries are not supported by newlib toolchain" |
| |
| # fix up spaces so gcc sees entire path |
| local SED_SAFE_SPACES_USR_INCLUDE=${NACL_SDK_MULTIARCH_USR_INCLUDE/ /\ /} |
| local SED_SAFE_SPACES_USR_LIB=${NACL_SDK_MULTIARCH_USR_LIB/ /\ /} |
| |
| if [ "${NACL_ARCH}" = "arm" ]; then |
| local ARCH_SUBST='/\*cpp:/ { \ |
| printf("*nacl_arch:\narm-nacl\n\n", $1); } \ |
| { print $0; }' |
| else |
| local ARCH_SUBST='/\*cpp:/ { \ |
| printf("*nacl_arch:\n%%{m64:x86_64-nacl; m32:i686-nacl; :x86_64-nacl}\n\n", $1); } \ |
| { print $0; }' |
| fi |
| |
| # have nacl-gcc dump specs file & add include & lib search paths |
| ${NACLCC} -dumpspecs |\ |
| awk "${ARCH_SUBST}" |\ |
| sed "/*cpp:/{ |
| N |
| s|$| -isystem ${SED_SAFE_SPACES_USR_INCLUDE}| |
| }" |\ |
| sed "/*link_libgcc:/{ |
| N |
| s|$| -rpath-link=${SED_SAFE_SPACES_USR_LIB} -L${SED_SAFE_SPACES_USR_LIB}| |
| }" > ${SPECS_FILE} |
| |
| # For newlib toolchain, modify the specs file to give an error when attempting |
| # to create a shared object. |
| if [ "${NACL_LIBC}" = "newlib" ]; then |
| sed -i.bak "s/%{shared:-shared/%{shared:%e${ERROR_MSG}/" "${SPECS_FILE}" |
| fi |
| } |
| |
| |
| CheckSDKVersion() { |
| if [ -z "${MIN_SDK_VERSION:-}" ]; then |
| return |
| fi |
| local GETOS=${NACL_SDK_ROOT}/tools/getos.py |
| local RESULT=$(${GETOS} --check-version=${MIN_SDK_VERSION} 2>&1) |
| if [ -n "${RESULT:-}" ]; then |
| echo "The SDK in \$NACL_SDK_ROOT is too old to build ${PACKAGE_NAME}." |
| echo ${RESULT} |
| exit -1 |
| fi |
| } |
| |
| |
| ###################################################################### |
| # Helper functions |
| ###################################################################### |
| |
| Banner() { |
| echo "######################################################################" |
| echo $* |
| echo "######################################################################" |
| } |
| |
| |
| # echo a command to stdout and then execute it. |
| LogExecute() { |
| echo $* |
| $* |
| } |
| |
| |
| # Set the ARCHIVE_NAME variable to the nacl of the upstream |
| # tarball. If ${URL} is not define (when there is no upstream) |
| # then leave ARCHIVE_NAME unset. |
| ArchiveName() { |
| if [ -z "${ARCHIVE_NAME:-}" -a -n "${URL:-}" ]; then |
| ARCHIVE_NAME=${URL_FILENAME:-$(basename ${URL})} |
| fi |
| } |
| |
| |
| # Is this a git repo? |
| IsGitRepo() { |
| if [ -z "${URL:-}" ]; then |
| return 1; |
| fi |
| |
| local GIT_URL=${URL%@*} |
| |
| if [[ "${#GIT_URL}" -ge "4" ]] && [[ "${GIT_URL:(-4)}" == ".git" ]]; then |
| return 0; |
| else |
| return 1; |
| fi |
| } |
| |
| |
| # |
| # Attempt to download a file from a given URL |
| # $1 - URL to fetch |
| # $2 - Filename to write to. |
| # |
| TryFetch() { |
| local URL=$1 |
| local FILENAME=$2 |
| Banner "Fetching ${PACKAGE_NAME} (${FILENAME})" |
| # Send curl's status messages to stdout rather then stderr |
| CURL_ARGS="--fail --location --stderr -" |
| if [ -t 1 ]; then |
| # Add --progress-bar but only if stdout is a TTY device. |
| CURL_ARGS+=" --progress-bar" |
| else |
| # otherwise suppress all status output, since curl always |
| # assumes a TTY and writes \r and \b characters. |
| CURL_ARGS+=" --silent" |
| fi |
| if which curl > /dev/null ; then |
| curl ${CURL_ARGS} -o ${FILENAME} ${URL} |
| else |
| Banner "ERROR: could not find 'curl' in your PATH" |
| exit 1 |
| fi |
| } |
| |
| |
| # |
| # Download a file from a given URL |
| # $1 - URL to fetch |
| # $2 - Filename to write to. |
| # |
| Fetch() { |
| local URL=$1 |
| local FILENAME=$2 |
| local MIRROR_URL=http://storage.googleapis.com/naclports/mirror |
| if echo ${URL} | grep -qv http://storage.googleapis.com &> /dev/null; then |
| set +o errexit |
| # Try mirrored version first |
| local BASENAME=${URL_FILENAME:-$(basename ${URL})} |
| TryFetch ${MIRROR_URL}/${BASENAME} ${FILENAME} |
| if [ $? != 0 -a ${FORCE_MIRROR:-no} = "no" ]; then |
| # Fall back to original URL |
| TryFetch ${URL} ${FILENAME} |
| fi |
| set -o errexit |
| else |
| # The URL is already on Google Clound Storage do just download it |
| TryFetch ${URL} ${FILENAME} |
| fi |
| |
| if [ ! -s ${FILENAME} ]; then |
| echo "ERROR: failed to download ${FILENAME}" |
| exit -1 |
| fi |
| } |
| |
| |
| Check() { |
| # verify sha1 checksum for tarball |
| if echo "${SHA1} *${ARCHIVE_NAME}" | ${SHA1CHECK}; then |
| return 0 |
| else |
| return 1 |
| fi |
| } |
| |
| |
| DefaultDownloadStep() { |
| if [ -z "${ARCHIVE_NAME:-}" ]; then |
| return |
| fi |
| |
| cd ${NACL_PACKAGES_CACHE} |
| # if matching tarball already exists, don't download again |
| if ! Check ; then |
| Fetch ${URL} ${ARCHIVE_NAME} |
| if ! Check ; then |
| Banner "${PACKAGE_NAME} failed checksum!" |
| exit -1 |
| fi |
| fi |
| } |
| |
| |
| GitCloneStep() { |
| if [ -d ${SRC_DIR} ]; then |
| if CheckKeyStamp clone "$URL" ; then |
| Banner "Skipping git clone step" |
| return |
| fi |
| |
| echo "Upstream archive or patch has changed." |
| echo "Please remove existing checkout to continue: '${SRC_DIR}'" |
| exit 1 |
| fi |
| |
| local GIT_URL=${URL%@*} |
| local COMMIT=${URL#*@} |
| |
| # Clone upstream git repo into local mirror, or update the existing |
| # mirror. |
| local GIT_MIRROR=${GIT_URL##*://} |
| GIT_MIRROR=${GIT_MIRROR//\//_} |
| cd "${NACL_PACKAGES_CACHE}" |
| if [ -e "${GIT_MIRROR}" ]; then |
| cd ${GIT_MIRROR} |
| if git rev-parse ${COMMIT} > /dev/null 2>&1; then |
| echo "git mirror up-to-date: ${GIT_MIRROR}" |
| else |
| echo "Updating git mirror: ${GIT_MIRROR}" |
| LogExecute git remote update --prune |
| fi |
| cd "${NACL_PACKAGES_CACHE}" |
| else |
| LogExecute git clone --mirror ${GIT_URL} ${GIT_MIRROR} |
| fi |
| |
| # Clone from the local mirror. |
| LogExecute git clone ${GIT_MIRROR} ${SRC_DIR} |
| ChangeDir ${SRC_DIR} |
| LogExecute git reset --hard ${COMMIT} |
| |
| # Set the origing to the original URL so it is possible to push directly |
| # from the build tree. |
| git remote set-url origin ${GIT_URL} |
| |
| TouchKeyStamp clone "$URL" |
| |
| # make sure the patch step is applied |
| rm -f ${NACL_PACKAGES_STAMPDIR}/${PACKAGE_NAME}/patch |
| } |
| |
| |
| Patch() { |
| local LOCAL_PATCH_FILE=$1 |
| if [ -e "${START_DIR}/${LOCAL_PATCH_FILE}" ]; then |
| Banner "Patching $(basename ${PWD})" |
| #git apply ${START_DIR}/${LOCAL_PATCH_FILE} |
| patch -p1 -g0 --no-backup-if-mismatch < ${START_DIR}/${LOCAL_PATCH_FILE} |
| git add . |
| git commit -m "Apply naclports patch" |
| fi |
| } |
| |
| |
| VerifyPath() { |
| # make sure path isn't all slashes (possibly from an unset variable) |
| local PATH=$1 |
| local TRIM=${PATH##/} |
| if [ ${#TRIM} -ne 0 ]; then |
| return 0 |
| else |
| return 1 |
| fi |
| } |
| |
| |
| ChangeDir() { |
| local NAME=$1 |
| if VerifyPath ${NAME}; then |
| echo "chdir ${NAME}" |
| cd ${NAME} |
| else |
| echo "ChangeDir called with bad path." |
| exit -1 |
| fi |
| } |
| |
| |
| Remove() { |
| local NAME=$1 |
| if VerifyPath ${NAME}; then |
| rm -rf ${NAME} |
| else |
| echo "Remove called with bad path." |
| exit -1 |
| fi |
| } |
| |
| |
| MakeDir() { |
| local NAME=$1 |
| if VerifyPath ${NAME}; then |
| mkdir -p ${NAME} |
| else |
| echo "MakeDir called with bad path." |
| exit -1 |
| fi |
| } |
| |
| |
| DefaultPreInstallStep() { |
| MakeDir ${NACL_PACKAGES_ROOT} |
| MakeDir ${NACL_PACKAGES_BUILD} |
| # If 'tarballs' directory exists then rename it to the new name: 'cache'. |
| # TODO(sbc): remove this once the new name as been in existence for |
| # a few months. |
| if [ ! -d ${NACL_PACKAGES_CACHE} -a -d ${NACL_PACKAGES_OUT}/tarballs ]; then |
| mv ${NACL_PACKAGES_OUT}/tarballs ${NACL_PACKAGES_CACHE} |
| fi |
| MakeDir ${NACL_PACKAGES_CACHE} |
| MakeDir ${NACL_PACKAGES_PUBLISH} |
| MakeDir ${WORK_DIR} |
| } |
| |
| |
| PublishByArchForDevEnv() { |
| MakeDir ${PUBLISH_DIR} |
| local ARCH_DIR=${PUBLISH_DIR}/${NACL_ARCH} |
| MakeDir ${ARCH_DIR} |
| # -executable is not supported on BSD and -perm +nn is not |
| # supported on linux |
| if [ ${OS_NAME} != "Darwin" ]; then |
| local EXECUTABLES=$(find . -type f -executable) |
| else |
| local EXECUTABLES=$(find . -type f -perm +u+x) |
| fi |
| for nexe in ${EXECUTABLES}; do |
| local name=$(basename ${nexe}) |
| name=${name/%.nexe/} |
| name=${name/%.pexe/} |
| LogExecute cp ${nexe} ${ARCH_DIR}/${name} |
| # TODO(bradnelson): Do something prettier. |
| if [ "$(head -c 2 ${nexe})" != "#!" ]; then |
| # Strip non-scripts |
| LogExecute ${NACLSTRIP} ${ARCH_DIR}/${name} |
| |
| # Run create_nmf for non-scripts. |
| # Stage libraries for toolchains that support dynamic linking. |
| if [[ "${TOOLCHAIN}" = "glibc" || "${TOOLCHAIN}" = "bionic" ]]; then |
| pushd ${ARCH_DIR} |
| # Create a temporary name ending in .nexe so create_nmf does the right |
| # thing. |
| LogExecute cp ${name} tmp.nexe |
| LogExecute python ${NACL_SDK_ROOT}/tools/create_nmf.py \ |
| tmp.nexe -s . -o tmp.nmf |
| LogExecute rm tmp.nexe |
| LogExecute rm tmp.nmf |
| popd |
| fi |
| fi |
| done |
| ChangeDir ${ARCH_DIR} |
| LogExecute rm -f ${ARCH_DIR}.zip |
| LogExecute zip -r ${ARCH_DIR}.zip . |
| } |
| |
| |
| InitGitRepo() { |
| if [ -d .git ]; then |
| local PREEXISTING_REPO=1 |
| else |
| local PREEXISTING_REPO=0 |
| fi |
| |
| if [ ${PREEXISTING_REPO} = 0 ]; then |
| LogExecute git init |
| fi |
| |
| # Setup git username and email in case there is not a system |
| # wide one already (git will error out on commit if it is missing). |
| if [ -n "${BUILDBOT_BUILDERNAME:-}" ]; then |
| if [ -z "$(git config user.email)" ]; then |
| git config user.email "naclports_buildbot" |
| fi |
| if [ -z "$(git config user.name)" ]; then |
| git config user.name "naclports buildbot" |
| fi |
| fi |
| |
| # Ignore the nacl build directories so that are preserved |
| # across calls to git clean. |
| echo "/build-nacl-*" >> .gitignore |
| |
| # Ensure that the repo has an upstream and a master branch properly set up. |
| if [ ${PREEXISTING_REPO} = 1 ]; then |
| git checkout -b placeholder |
| git show-ref refs/heads/upstream > /dev/null && git branch -D upstream |
| git checkout -b upstream |
| git show-ref refs/heads/master > /dev/null && git branch -D master |
| git checkout -b master |
| git branch -D placeholder |
| else |
| git add -f . |
| git commit -m "Upstream version" > /dev/null |
| git checkout -b upstream |
| git checkout master |
| fi |
| } |
| |
| |
| CheckStamp() { |
| local STAMP_DIR="${NACL_PACKAGES_STAMPDIR}/${PACKAGE_NAME}" |
| local STAMP_FILE="${STAMP_DIR}/$1" |
| # check the stamp file exists and is newer and dependency |
| if [ ! -f "${STAMP_FILE}" ]; then |
| return 1 |
| fi |
| shift |
| while (( "$#" )) ; do |
| if [ "$1" -nt "${STAMP_FILE}" ]; then |
| return 1 |
| fi |
| shift |
| done |
| return 0 |
| } |
| |
| |
| TouchStamp() { |
| local STAMP_DIR=${NACL_PACKAGES_STAMPDIR}/${PACKAGE_NAME} |
| mkdir -p ${STAMP_DIR} |
| touch ${STAMP_DIR}/$1 |
| } |
| |
| |
| # |
| # KeyStamp: just like a stamp, but it puts a value in the file |
| # and checks to make sure it's the same when you check it. |
| # The value must be the second argument, subsequent arguments |
| # can be dependencies, just like stamp. |
| # |
| CheckKeyStamp() { |
| local STAMP_DIR="${NACL_PACKAGES_STAMPDIR}/${PACKAGE_NAME}" |
| local STAMP_FILE="${STAMP_DIR}/$1" |
| # check the stamp file exists, contains the key, and is newer |
| # than dependencies. |
| if [ ! -f "${STAMP_FILE}" ]; then |
| return 1 |
| fi |
| |
| if [ ! `cat ${STAMP_FILE}` = $2 ]; then |
| return 1 |
| fi |
| |
| shift |
| shift |
| while (( "$#" )) ; do |
| if [ "$1" -nt "${STAMP_FILE}" ]; then |
| return 1 |
| fi |
| shift |
| done |
| return 0 |
| } |
| |
| |
| TouchKeyStamp() { |
| local STAMP_DIR=${NACL_PACKAGES_STAMPDIR}/${PACKAGE_NAME} |
| mkdir -p ${STAMP_DIR} |
| echo $2 > ${STAMP_DIR}/$1 |
| } |
| |
| |
| InstallNaClTerm() { |
| local INSTALL_DIR=$1 |
| local CHROMEAPPS=${NACL_SRC}/third_party/libapps/ |
| local LIB_DOT=${CHROMEAPPS}/libdot |
| local NASSH=${CHROMEAPPS}/nassh |
| local HTERM=${CHROMEAPPS}/hterm |
| LIBDOT_SEARCH_PATH=${CHROMEAPPS} LogExecute ${LIB_DOT}/bin/concat.sh \ |
| -i ${HTERM}/concat/hterm_deps.concat -o ${INSTALL_DIR}/hterm.concat.js |
| LIBDOT_SEARCH_PATH=${CHROMEAPPS} LogExecute ${LIB_DOT}/bin/concat.sh \ |
| -i ${HTERM}/concat/hterm.concat -o ${INSTALL_DIR}/hterm2.js |
| chmod +w ${INSTALL_DIR}/hterm.concat.js ${INSTALL_DIR}/hterm2.js |
| cat ${INSTALL_DIR}/hterm2.js >> ${INSTALL_DIR}/hterm.concat.js |
| rm ${INSTALL_DIR}/hterm2.js |
| |
| LogExecute cp ${TOOLS_DIR}/naclterm.js ${INSTALL_DIR} |
| LogExecute cp ${TOOLS_DIR}/pipeserver.js ${INSTALL_DIR} |
| if [ ${NACL_ARCH} = "pnacl" ] ; then |
| sed 's/x-nacl/x-pnacl/' \ |
| ${TOOLS_DIR}/naclprocess.js > ${INSTALL_DIR}/naclprocess.js |
| else |
| LogExecute cp ${TOOLS_DIR}/naclprocess.js ${INSTALL_DIR} |
| fi |
| } |
| |
| |
| # |
| # Build step for projects based on the NaCl SDK build |
| # system (common.mk). |
| # |
| SetupSDKBuildSystem() { |
| # We override $(OUTBASE) to force the build system to put |
| # all its artifacts in ${SRC_DIR} rather than alongside |
| # the Makefile. |
| export OUTBASE=${SRC_DIR} |
| export CFLAGS="${NACLPORTS_CPPFLAGS} ${NACLPORTS_CFLAGS}" |
| export CXXFLAGS="${NACLPORTS_CPPFLAGS} ${NACLPORTS_CXXFLAGS}" |
| export LDFLAGS=${NACLPORTS_LDFLAGS} |
| export NACL_PREFIX |
| export NACL_PACKAGES_PUBLISH |
| export NACL_SRC |
| export NACLPORTS_INCLUDE |
| export NACLPORTS_REVISION=${REVISION} |
| export PKG_CONFIG_LIBDIR="${NACLPORTS_LIBDIR}/pkgconfig" |
| export ENABLE_BIONIC=1 |
| # By default PKG_CONFIG_PATH is set to <libdir>/pkgconfig:<datadir>/pkgconfig. |
| # While PKG_CONFIG_LIBDIR overrides <libdir>, <datadir> (/usr/share/) can only |
| # be overridden individually when pkg-config is built. |
| # Setting PKG_CONFIG_PATH instead to compensate. |
| export PKG_CONFIG_PATH="${NACLPORTS_LIBDIR}/pkgconfig" |
| PKG_CONFIG_PATH+=":${NACLPORTS_LIBDIR}/../share/pkgconfig" |
| |
| MAKEFLAGS+=" TOOLCHAIN=${TOOLCHAIN}" |
| MAKEFLAGS+=" NACL_ARCH=${NACL_ARCH_ALT}" |
| if [ "${NACL_DEBUG}" = "1" ]; then |
| MAKEFLAGS+=" CONFIG=Debug" |
| else |
| MAKEFLAGS+=" CONFIG=Release" |
| fi |
| if [ "${VERBOSE:-}" = "1" ]; then |
| MAKEFLAGS+=" V=1" |
| fi |
| export MAKEFLAGS |
| |
| BUILD_DIR=${START_DIR} |
| } |
| |
| |
| SetupCrossEnvironment() { |
| # export the nacl tools |
| export CONFIG_SITE |
| export EXEEXT=${NACL_EXEEXT} |
| export CC=${NACLCC} |
| export CXX=${NACLCXX} |
| export AR=${NACLAR} |
| export RANLIB=${NACLRANLIB} |
| export READELF=${NACLREADELF} |
| export STRIP=${NACLSTRIP} |
| export PKG_CONFIG_LIBDIR="${NACLPORTS_LIBDIR}/pkgconfig" |
| # By default PKG_CONFIG_PATH is set to <libdir>/pkgconfig:<datadir>/pkgconfig. |
| # While PKG_CONFIG_LIBDIR overrides <libdir>, <datadir> (/usr/share/) can only |
| # be overridden individually when pkg-config is built. |
| # Setting PKG_CONFIG_PATH instead to compensate. |
| export PKG_CONFIG_PATH="${NACLPORTS_LIBDIR}/pkgconfig" |
| PKG_CONFIG_PATH+=":${NACLPORTS_LIBDIR}/../share/pkgconfig" |
| export CFLAGS=${NACLPORTS_CFLAGS} |
| export CPPFLAGS=${NACLPORTS_CPPFLAGS} |
| export CXXFLAGS=${NACLPORTS_CXXFLAGS} |
| export LDFLAGS=${NACLPORTS_LDFLAGS} |
| export AR_FLAGS=cr |
| |
| export SDL_CONFIG=${NACLPORTS_BIN}/sdl-config |
| export FREETYPE_CONFIG=${NACLPORTS_BIN}/freetype-config |
| export PATH=${NACL_BIN_PATH}:${NACLPORTS_BIN}:${PATH} |
| |
| echo "CPPFLAGS=${CPPFLAGS}" |
| echo "CFLAGS=${CFLAGS}" |
| echo "CXXFLAGS=${CXXFLAGS}" |
| echo "LDFLAGS=${LDFLAGS}" |
| } |
| |
| |
| GetRevision() { |
| cd ${NACL_SRC} |
| if [ -d .git ]; then |
| # TODO(sbc): find a replacement for git number. It seems that its not |
| # designed for normal use like this. 'git describe' would work but |
| # requires a tag in the git repo which we currently don't have. |
| if ! git config user.name > /dev/null; then |
| echo "setting user.name" |
| git config user.name local_bot |
| fi |
| if ! git config user.email > /dev/null; then |
| echo "setting user.email" |
| git config user.email local_bot@example.com |
| fi |
| REV_RAW=$(CHROME_HEADLESS=1 git number) |
| else |
| REV_RAW=$(svnversion) |
| fi |
| cd - > /dev/null |
| # The svn revision can have a trailing M when there are modifications, such |
| # as during a try run. Remove it so we get a valid extension version. |
| REVISION=${REV_RAW/M/} |
| } |
| |
| |
| GenerateManifest() { |
| local SOURCE_FILE=$1 |
| shift |
| local TARGET_DIR=$1 |
| shift |
| local TEMPLATE_EXPAND="${START_DIR}/../../build_tools/template_expand.py" |
| |
| # TODO(sbc): deal with versions greater than 16bit. |
| if (( ${REVISION} >= 65536 )); then |
| echo "Version too great to store in revision field on manifest.json" |
| exit 1 |
| fi |
| |
| if [ $# -gt 0 ]; then |
| local KEY="$(cat $1)" |
| else |
| local KEY="" |
| fi |
| echo "Expanding ${SOURCE_FILE} > ${TARGET_DIR}/manifest.json" |
| # Generate a manifest.json |
| ${TEMPLATE_EXPAND} ${SOURCE_FILE} \ |
| version=${REVISION} key="${KEY}" > ${TARGET_DIR}/manifest.json |
| } |
| |
| |
| ###################################################################### |
| # Build Steps |
| ###################################################################### |
| DefaultExtractStep() { |
| if [ -z "${ARCHIVE_NAME:-}" ]; then |
| return |
| fi |
| |
| local ARCHIVE="${NACL_PACKAGES_CACHE}/${ARCHIVE_NAME}" |
| if [ -d ${SRC_DIR} ]; then |
| local PATCH="${START_DIR}/${PATCH_FILE:-nacl.patch}" |
| |
| if CheckStamp extract "${ARCHIVE}" "${PATCH}" ; then |
| Banner "Skipping extract step" |
| return |
| fi |
| fi |
| |
| Banner "Extracting ${ARCHIVE_NAME}" |
| if [ -d ${SRC_DIR} ]; then |
| echo "Upstream archive or patch has changed." |
| echo "Please remove existing workspace to continue: '${SRC_DIR}'" |
| exit 1 |
| fi |
| Remove ${SRC_DIR} |
| |
| # make sure the patch step is applied |
| rm -f ${NACL_PACKAGES_STAMPDIR}/${PACKAGE_NAME}/patch |
| local EXTENSION="${ARCHIVE_NAME##*.}" |
| PARENT_DIR=$(dirname ${SRC_DIR}) |
| MakeDir ${PARENT_DIR} |
| ChangeDir ${PARENT_DIR} |
| if [ ${EXTENSION} = "zip" ]; then |
| unzip -q ${ARCHIVE} |
| else |
| if [ $OS_SUBDIR = "win" ]; then |
| tar --no-same-owner -xf ${ARCHIVE} |
| else |
| tar xf ${ARCHIVE} |
| fi |
| fi |
| |
| MakeDir ${BUILD_DIR} |
| TouchStamp extract |
| } |
| |
| |
| PatchConfigSub() { |
| # Replace the package's config.sub one with an up-do-date copy |
| # that includes nacl support. We only do this if the string |
| # 'nacl)' is not already contained in the file. |
| CONFIG_SUB=${CONFIG_SUB:-config.sub} |
| if [ ! -f $CONFIG_SUB ]; then |
| CONFIG_SUB=$(find "${SRC_DIR}" -name config.sub -print) |
| fi |
| |
| for sub in $CONFIG_SUB; do |
| if grep -q 'nacl)' $sub /dev/null; then |
| echo "$CONFIG_SUB supports NaCl" |
| else |
| echo "Patching $sub" |
| /bin/cp -f ${TOOLS_DIR}/config.sub $sub |
| fi |
| done |
| } |
| |
| |
| PatchConfigure() { |
| if [ -f configure ]; then |
| Banner "Patching configure" |
| ${TOOLS_DIR}/patch_configure.py configure |
| fi |
| } |
| |
| |
| DefaultPatchStep() { |
| if [ -z "${ARCHIVE_NAME:-}" ] && ! IsGitRepo; then |
| return |
| fi |
| |
| ChangeDir ${SRC_DIR} |
| |
| if CheckStamp patch ; then |
| Banner "Skipping patch step (cleaning source tree)" |
| git clean -f -d |
| return |
| fi |
| |
| InitGitRepo |
| Patch ${PATCH_FILE:-nacl.patch} |
| PatchConfigure |
| PatchConfigSub |
| if [ -n "$(git diff --no-ext-diff)" ]; then |
| git add -u |
| git commit -m "Automatic patch generated by naclports" |
| fi |
| |
| TouchStamp patch |
| } |
| |
| |
| DefaultConfigureStep() { |
| local CONFIGURE=${NACL_CONFIGURE_PATH:-${SRC_DIR}/configure} |
| |
| if [ -n "${CONFIGURE_SENTINEL:-}" -a -f "${CONFIGURE_SENTINEL:-}" ]; then |
| return |
| fi |
| |
| if [ -f "${CONFIGURE}" ]; then |
| ConfigureStep_Autotools |
| elif [ -f "${SRC_DIR}/CMakeLists.txt" ]; then |
| ConfigureStep_CMake |
| else |
| echo "No configure or CMakeLists.txt script found in ${SRC_DIR}" |
| fi |
| } |
| |
| |
| ConfigureStep_Autotools() { |
| conf_build=$(/bin/sh ${SCRIPT_DIR}/config.guess) |
| |
| SetupCrossEnvironment |
| |
| local CONFIGURE=${NACL_CONFIGURE_PATH:-${SRC_DIR}/configure} |
| local conf_host=${NACL_CROSS_PREFIX} |
| if [ "${NACL_ARCH}" = "pnacl" -o "${NACL_ARCH}" = "emscripten" ]; then |
| # The PNaCl tools use "pnacl-" as the prefix, but config.sub |
| # does not know about "pnacl". It only knows about "le32-nacl". |
| # Unfortunately, most of the config.subs here are so old that |
| # it doesn't know about that "le32" either. So we just say "nacl". |
| conf_host="nacl" |
| fi |
| |
| # Inject a shim that speed up pnacl invocations for configure. |
| if [ "${NACL_ARCH}" = "pnacl" ]; then |
| local PNACL_CONF_SHIM="${TOOLS_DIR}/pnacl-configure-shim.py" |
| CC="${PNACL_CONF_SHIM} ${CC}" |
| fi |
| |
| # Specify both --build and --host options. This forces autoconf into cross |
| # compile mode. This is useful since the autodection doesn't always works. |
| # For example a trivial PNaCl binary can sometimes run on the linux host if |
| # it has the correct LLVM bimfmt support. What is more, autoconf will |
| # generate a warning if only --host is specified. |
| LogExecute ${CONFIGURE} \ |
| --build=${conf_build} \ |
| --host=${conf_host} \ |
| --prefix=${PREFIX} \ |
| --with-http=no \ |
| --with-html=no \ |
| --with-ftp=no \ |
| --${NACL_OPTION}-mmx \ |
| --${NACL_OPTION}-sse \ |
| --${NACL_OPTION}-sse2 \ |
| --${NACL_OPTION}-asm \ |
| --with-x=no \ |
| ${EXTRA_CONFIGURE_ARGS:-} |
| } |
| |
| |
| ConfigureStep_CMake() { |
| if [ "${CMAKE_USE_NINJA:-}" = "1" ]; then |
| EXTRA_CMAKE_ARGS+=" -GNinja" |
| fi |
| |
| EXTRA_CMAKE_ARGS=${EXTRA_CMAKE_ARGS:-} |
| if [ "${NACL_LIBC}" = "newlib" ]; then |
| EXTRA_CMAKE_ARGS+=" -DEXTRA_INCLUDE=${NACLPORTS_INCLUDE}/glibc-compat" |
| fi |
| |
| CC="${NACLCC}" CXX="${NACLCXX}" LogExecute cmake ${SRC_DIR} \ |
| -DCMAKE_TOOLCHAIN_FILE=${TOOLS_DIR}/XCompile-nacl.cmake \ |
| -DNACLAR=${NACLAR} \ |
| -DNACLLD=${NACLLD} \ |
| -DNACL_CROSS_PREFIX=${NACL_CROSS_PREFIX} \ |
| -DNACL_SDK_ROOT=${NACL_SDK_ROOT} \ |
| -DNACL_TOOLCHAIN_ROOT=${NACL_TOOLCHAIN_ROOT} \ |
| -DCMAKE_PREFIX_PATH=${NACL_PREFIX} \ |
| -DCMAKE_INSTALL_PREFIX=${PREFIX} \ |
| -DCMAKE_BUILD_TYPE=RELEASE ${EXTRA_CMAKE_ARGS} |
| } |
| |
| |
| DefaultBuildStep() { |
| if [ "${CMAKE_USE_NINJA:-}" = "1" ]; then |
| if [ "${VERBOSE:-}" = "1" ]; then |
| NINJA_ARGS="-v" |
| fi |
| LogExecute ninja ${NINJA_ARGS:-} ${MAKE_TARGETS:-} |
| return |
| fi |
| |
| # Build ${MAKE_TARGETS} or default target if it is not defined |
| if [ -n "${MAKEFLAGS:-}" ]; then |
| echo "MAKEFLAGS=${MAKEFLAGS}" |
| export MAKEFLAGS |
| fi |
| if [ "${VERBOSE:-}" = "1" ]; then |
| MAKE_TARGETS+=" VERBOSE=1 V=1" |
| fi |
| export PATH=${NACL_BIN_PATH}:${PATH} |
| LogExecute make -j${OS_JOBS} ${MAKE_TARGETS:-} |
| } |
| |
| |
| DefaultPythonModuleBuildStep() { |
| SetupCrossEnvironment |
| Banner "Build ${PACKAGE_NAME} python module" |
| ChangeDir ${SRC_DIR} |
| LogExecute rm -rf build dist |
| MakeDir "${NACL_DEST_PYROOT}/${SITE_PACKAGES}" |
| export PYTHONPATH="${NACL_HOST_PYROOT}/${SITE_PACKAGES}" |
| export PYTHONPATH="${PYTHONPATH}:${NACL_DEST_PYROOT}/${SITE_PACKAGES}" |
| export NACL_PORT_BUILD=${1:-dest} |
| export NACL_BUILD_TREE=${NACL_DEST_PYROOT} |
| export CFLAGS="${NACLPORTS_CPPFLAGS} ${NACLPORTS_CFLAGS}" |
| export CXXFLAGS="${NACLPORTS_CPPFLAGS} ${NACLPORTS_CXXFLAGS}" |
| export LDFLAGS=${NACLPORTS_LDFLAGS} |
| LogExecute ${NACL_HOST_PYTHON} setup.py \ |
| ${NACL_PYSETUP_ARGS:-} \ |
| install --prefix=${NACL_DEST_PYROOT} |
| MakeDir ${DEST_PYTHON_OBJS}/${PACKAGE_NAME} |
| LogExecute find build -name "*.o" -execdir cp -v {} \ |
| ${DEST_PYTHON_OBJS}/${PACKAGE_NAME}/{} \; |
| } |
| |
| |
| DefaultTestStep() { |
| echo "No tests defined for ${PACKAGE_NAME}" |
| } |
| |
| |
| DefaultPostInstallTestStep() { |
| echo "No post-packaging tests defined for ${PACKAGE_NAME}" |
| } |
| |
| |
| DefaultInstallStep() { |
| INSTALL_TARGETS=${INSTALL_TARGETS:-install} |
| |
| if [ "${CMAKE_USE_NINJA:-}" = "1" ]; then |
| DESTDIR=${DESTDIR} LogExecute ninja ${INSTALL_TARGETS} |
| return |
| fi |
| |
| # assumes pwd has makefile |
| if [ -n "${MAKEFLAGS:-}" ]; then |
| echo "MAKEFLAGS=${MAKEFLAGS}" |
| export MAKEFLAGS |
| fi |
| export PATH=${NACL_BIN_PATH}:${PATH} |
| LogExecute make ${INSTALL_TARGETS} DESTDIR=${DESTDIR} |
| } |
| |
| |
| DefaultPythonModuleInstallStep() { |
| Banner "Installing ${PACKAGE_NAME}" |
| # We've installed already previously. We just need to collect our modules. |
| MakeDir ${NACL_HOST_PYROOT}/python_modules/ |
| if [ -e ${START_DIR}/modules.list ] ; then |
| LogExecute cp ${START_DIR}/modules.list \ |
| ${DEST_PYTHON_OBJS}/${PACKAGE_NAME}.list |
| fi |
| if [ -e ${START_DIR}/modules.libs ] ; then |
| LogExecute cp ${START_DIR}/modules.libs \ |
| ${DEST_PYTHON_OBJS}/${PACKAGE_NAME}.libs |
| fi |
| } |
| |
| |
| # |
| # echo a command before exexuting it under 'time' |
| # |
| TimeCommand() { |
| echo "$@" |
| time "$@" |
| } |
| |
| |
| # |
| # Validate a given NaCl executable (.nexe file) |
| # $1 - Execuatable file (.nexe) |
| # |
| Validate() { |
| if [ "${NACL_ARCH}" = "pnacl" -o "${NACL_ARCH}" = "emscripten" ]; then |
| return |
| fi |
| |
| # new SDKs have a single validator called ncval whereas older (<= 28) |
| # have a different validator for each arch. |
| if [ -f ${NACL_SDK_ROOT}/tools/ncval ]; then |
| NACL_VALIDATE=${NACL_SDK_ROOT}/tools/ncval |
| elif [ ${NACL_ARCH} = "arm" ]; then |
| NACL_VALIDATE=${NACL_SDK_ROOT}/tools/ncval_arm |
| elif [ ${NACL_ARCH} = "x86_64" ]; then |
| NACL_VALIDATE="${NACL_SDK_ROOT}/tools/ncval_x86_64 --errors" |
| else |
| NACL_VALIDATE=${NACL_SDK_ROOT}/tools/ncval_x86_32 |
| fi |
| LogExecute ${NACL_VALIDATE} $@ |
| if [ $? != 0 ]; then |
| exit 1 |
| fi |
| } |
| |
| |
| # |
| # PostBuildStep by default will validae (using ncval) any executables |
| # specified in the $EXECUTABLES as well as create wrapper scripts |
| # for running them in sel_ldr. |
| # |
| DefaultPostBuildStep() { |
| if [ "${NACL_ARCH}" = "emscripten" ]; then |
| return; |
| fi |
| |
| if [ -z "${EXECUTABLES:-}" ]; then |
| return |
| fi |
| |
| if [ "${NACL_ARCH}" = "pnacl" ]; then |
| for pexe in ${EXECUTABLES} ; do |
| FinalizePexe ${pexe} |
| done |
| for pexe in ${EXECUTABLES} ; do |
| TranslatePexe ${pexe} |
| done |
| return |
| fi |
| |
| for nexe in $EXECUTABLES ; do |
| Validate ${nexe} |
| # Create a script which will run the executable in sel_ldr. The name |
| # of the script is the same as the name of the executable, either without |
| # any extension or with the .sh extension. |
| if [[ ${nexe} == *${NACL_EXEEXT} && ! -d ${nexe%%${NACL_EXEEXT}} ]]; then |
| WriteSelLdrScript ${nexe%%${NACL_EXEEXT}} $(basename ${nexe}) |
| else |
| WriteSelLdrScript $nexe.sh $(basename ${nexe}) |
| fi |
| done |
| } |
| |
| |
| # |
| # Run an executable with under sel_ldr. |
| # $1 - Executable (.nexe) name |
| # |
| RunSelLdrCommand() { |
| if [ "${SKIP_SEL_LDR_TESTS}" = "1" ]; then |
| return |
| fi |
| |
| if [ "${NACL_ARCH}" = "pnacl" ]; then |
| # For PNaCl we translate to each arch where we have sel_ldr, then run it. |
| local PEXE=$1 |
| local NEXE_32=$1_32.nexe |
| local NEXE_64=$1_64.nexe |
| local SCRIPT_32=$1_32.sh |
| local SCRIPT_64=$1_64.sh |
| shift |
| TranslateAndWriteSelLdrScript ${PEXE} x86-32 ${NEXE_32} ${SCRIPT_32} |
| echo "[sel_ldr x86-32] $@" |
| time ./${SCRIPT_32} $* |
| if [ -f ${NACL_SEL_LDR_X8664} ]; then |
| TranslateAndWriteSelLdrScript ${PEXE} x86-64 ${NEXE_64} ${SCRIPT_64} |
| echo "[sel_ldr x86-64] $@" |
| time ./${SCRIPT_64} $* |
| else |
| echo "WARNING: ${NACL_SEL_LDR_X8664} not found, skipping tests." |
| fi |
| else |
| # Normal NaCl. |
| local NEXE=$(basename $1) |
| local SCRIPT=$1.sh |
| if [ -f ${NACL_SEL_LDR} ]; then |
| WriteSelLdrScript ${SCRIPT} ${NEXE} |
| echo "[sel_ldr] $@" |
| shift |
| time ./${SCRIPT} $* |
| else |
| echo "WARNING: ${NACL_SEL_LDR} not found, skipping tests." |
| fi |
| fi |
| } |
| |
| |
| # |
| # Write a wrapper script that will run a nexe under sel_ldr |
| # $1 - Script name |
| # $2 - Nexe name |
| # |
| WriteSelLdrScript() { |
| if [ "${SKIP_SEL_LDR_TESTS}" = "1" ]; then |
| return |
| fi |
| |
| if [ ${OS_NAME} = "Cygwin" ]; then |
| local LOGFILE=nul |
| local NACL_IRT_PATH=`cygpath -m ${NACL_IRT}` |
| else |
| local LOGFILE=/dev/null |
| local NACL_IRT_PATH=${NACL_IRT} |
| fi |
| |
| if [ "${NACL_LIBC}" = "glibc" ]; then |
| cat > $1 <<HERE |
| #!/bin/bash |
| export NACLLOG=${LOGFILE} |
| |
| SCRIPT_DIR=\$(dirname "\${BASH_SOURCE[0]}") |
| SEL_LDR=${NACL_SEL_LDR} |
| IRT=${NACL_IRT_PATH} |
| NACL_SDK_LIB=${NACL_SDK_LIB} |
| LIB_PATH_DEFAULT=${NACL_SDK_LIBDIR}:${NACLPORTS_LIBDIR} |
| LIB_PATH_DEFAULT=\${LIB_PATH_DEFAULT}:\${NACL_SDK_LIB}:\${SCRIPT_DIR} |
| SEL_LDR_LIB_PATH=\${SEL_LDR_LIB_PATH}:\${LIB_PATH_DEFAULT} |
| |
| "\${SEL_LDR}" -a -B "\${IRT}" -- \\ |
| "\${NACL_SDK_LIB}/runnable-ld.so" --library-path "\${SEL_LDR_LIB_PATH}" \\ |
| "\${SCRIPT_DIR}/$2" "\$@" |
| HERE |
| else |
| cat > $1 <<HERE |
| #!/bin/bash |
| export NACLLOG=${LOGFILE} |
| |
| SCRIPT_DIR=\$(dirname "\${BASH_SOURCE[0]}") |
| if [ \$(uname -s) = CYGWIN* ]; then |
| SCRIPT_DIR=\$(cygpath -m \${SCRIPT_DIR}) |
| fi |
| SEL_LDR=${NACL_SEL_LDR} |
| IRT=${NACL_IRT_PATH} |
| |
| "\${SEL_LDR}" -a -B "\${IRT}" -- "\${SCRIPT_DIR}/$2" "\$@" |
| HERE |
| fi |
| chmod 750 $1 |
| echo "Wrote script $1 -> $2" |
| } |
| |
| |
| TranslateAndWriteSelLdrScript() { |
| local PEXE=$1 |
| local PEXE_FINAL=$1_final.pexe |
| local ARCH=$2 |
| local NEXE=$3 |
| local SCRIPT=$4 |
| # Finalize the pexe to make sure it is finalizeable. |
| TimeCommand ${PNACLFINALIZE} ${PEXE} -o ${PEXE_FINAL} |
| # Translate to the appropriate version. |
| TimeCommand ${TRANSLATOR} ${PEXE_FINAL} -arch ${ARCH} -o ${NEXE} |
| WriteSelLdrScriptForPNaCl ${SCRIPT} ${NEXE} ${ARCH} |
| } |
| |
| |
| # |
| # Write a wrapper script that will run a nexe under sel_ldr, for PNaCl |
| # $1 - Script name |
| # $2 - Nexe name |
| # $3 - sel_ldr architecture |
| # |
| WriteSelLdrScriptForPNaCl() { |
| local script_name=$1 |
| local nexe_name=$2 |
| local arch=$3 |
| local nacl_sel_ldr="no-sel-ldr" |
| local irt_core="no-irt-core" |
| case ${arch} in |
| x86-32) |
| nacl_sel_ldr=${NACL_SEL_LDR_X8632} |
| irt_core=${NACL_IRT_X8632} |
| ;; |
| x86-64) |
| nacl_sel_ldr=${NACL_SEL_LDR_X8664} |
| irt_core=${NACL_IRT_X8664} |
| ;; |
| *) |
| echo "No sel_ldr for ${arch}" |
| exit 1 |
| esac |
| cat > ${script_name} <<HERE |
| #!/bin/bash |
| export NACLLOG=/dev/null |
| |
| SCRIPT_DIR=\$(dirname "\${BASH_SOURCE[0]}") |
| SEL_LDR=${nacl_sel_ldr} |
| IRT=${irt_core} |
| |
| "\${SEL_LDR}" -a -B "\${IRT}" -- "\${SCRIPT_DIR}/${nexe_name}" "\$@" |
| HERE |
| chmod 750 ${script_name} |
| echo "Wrote script $PWD/${script_name}" |
| } |
| |
| |
| FinalizePexe() { |
| local pexe=$1 |
| Banner "Finalizing ${pexe}" |
| TimeCommand ${PNACLFINALIZE} ${pexe} |
| } |
| |
| |
| # |
| # Translate a PNaCl executable (.pexe) into one or more |
| # native NaCl executables (.nexe). |
| # $1 - pexe file |
| # |
| TranslatePexe() { |
| local pexe=$1 |
| local basename="${pexe%.*}" |
| local arches="arm x86-32 x86-64" |
| Banner "Translating ${pexe}" |
| |
| for a in ${arches} ; do |
| echo "translating pexe [$a]" |
| nexe=${basename}.$a.nexe |
| TimeCommand ${TRANSLATOR} -O0 -arch $a ${pexe} -o ${nexe} |
| done |
| |
| # Now the same spiel with -O2 |
| |
| for a in ${arches} ; do |
| echo "translating pexe [$a]" |
| nexe=${basename}.opt.$a.nexe |
| TimeCommand ${TRANSLATOR} -O2 -arch $a ${pexe} -o ${nexe} |
| done |
| |
| ls -l $(dirname ${pexe})/*.nexe ${pexe} |
| } |
| |
| |
| PackageStep() { |
| Banner "Packaging $(basename ${PACKAGE_FILE})" |
| Remove ${PACKAGE_FILE} |
| if [ -d ${INSTALL_DIR}${PREFIX} ]; then |
| mv ${INSTALL_DIR}${PREFIX} ${INSTALL_DIR}/payload |
| fi |
| LogExecute cp ${START_DIR}/pkg_info ${INSTALL_DIR} |
| if [ ${NACL_DEBUG} = "1" ]; then |
| echo "BUILD_CONFIG=debug" >> ${INSTALL_DIR}/pkg_info |
| else |
| echo "BUILD_CONFIG=release" >> ${INSTALL_DIR}/pkg_info |
| fi |
| echo "BUILD_ARCH=${NACL_ARCH}" >> ${INSTALL_DIR}/pkg_info |
| echo "BUILD_TOOLCHAIN=${TOOLCHAIN}" >> ${INSTALL_DIR}/pkg_info |
| echo "BUILD_SDK_VERSION=${NACL_SDK_VERSION}" >> ${INSTALL_DIR}/pkg_info |
| echo "BUILD_NACLPORTS_REVISION=${REVISION}" >> ${INSTALL_DIR}/pkg_info |
| LogExecute tar cjf ${PACKAGE_FILE} -C ${INSTALL_DIR} . |
| } |
| |
| |
| ZipPublishDir() { |
| # If something exists in the publish directory, zip it for download by mingn. |
| if [ -d "${PUBLISH_DIR}" ]; then |
| # Remove existing zip as it may contain only some architectures. |
| LogExecute rm -f ${PUBLISH_DIR}.zip |
| pushd ${PUBLISH_DIR} |
| LogExecute zip -rq ${PUBLISH_DIR}.zip ./ |
| popd |
| fi |
| } |
| |
| |
| DefaultPackageInstall() { |
| RunPreInstallStep |
| if IsGitRepo; then |
| RunGitCloneStep |
| else |
| RunDownloadStep |
| RunExtractStep |
| fi |
| RunPatchStep |
| RunConfigureStep |
| RunBuildStep |
| RunPostBuildStep |
| RunTestStep |
| RunInstallStep |
| RunPostInstallTestStep |
| ZipPublishDir |
| PackageStep |
| } |
| |
| |
| NaclportsMain() { |
| local COMMAND=PackageInstall |
| if [[ $# -gt 0 ]]; then |
| COMMAND=Run$1 |
| fi |
| if [ -d "${BUILD_DIR}" ]; then |
| ChangeDir ${BUILD_DIR} |
| fi |
| ${COMMAND} |
| } |
| |
| |
| RunStep() { |
| local STEP_FUNCTION=$1 |
| local DIR='' |
| shift |
| if [ $# -gt 0 ]; then |
| local TITLE=$1 |
| shift |
| Banner "${TITLE} ${PACKAGE_NAME}" |
| fi |
| if [ $# -gt 0 ]; then |
| DIR=$1 |
| shift |
| fi |
| if [ -n "${DIR}" ]; then |
| if [ ! -d ${DIR} ]; then |
| MakeDir ${DIR} |
| fi |
| ChangeDir ${DIR} |
| fi |
| ArchiveName |
| # Step functions are run in sub-shell so that they are independent |
| # from each other. |
| ( ${STEP_FUNCTION} ) |
| } |
| |
| |
| # Function entry points that packages should override in order |
| # to customize the build process. |
| PreInstallStep() { DefaultPreInstallStep; } |
| DownloadStep() { DefaultDownloadStep; } |
| ExtractStep() { DefaultExtractStep; } |
| PatchStep() { DefaultPatchStep; } |
| ConfigureStep() { DefaultConfigureStep; } |
| BuildStep() { DefaultBuildStep; } |
| PostBuildStep() { DefaultPostBuildStep; } |
| TestStep() { DefaultTestStep; } |
| InstallStep() { DefaultInstallStep; } |
| PostInstallTestStep() { DefaultPostInstallTestStep; } |
| PackageInstall() { DefaultPackageInstall; } |
| |
| RunPreInstallStep() { RunStep PreInstallStep; } |
| RunDownloadStep() { RunStep DownloadStep; } |
| RunGitCloneStep() { RunStep GitCloneStep; } |
| RunExtractStep() { RunStep ExtractStep; } |
| RunPatchStep() { RunStep PatchStep; } |
| RunConfigureStep() { |
| RunStep ConfigureStep "Configuring" ${BUILD_DIR}; |
| } |
| RunBuildStep() { RunStep BuildStep "Building" ${BUILD_DIR}; } |
| RunPostBuildStep() { RunStep PostBuildStep "PostBuild" ${BUILD_DIR}; } |
| RunTestStep() { |
| if [ "${SKIP_SEL_LDR_TESTS}" = "1" ]; then |
| return; |
| fi |
| RunStep TestStep "Testing" ${BUILD_DIR} |
| } |
| |
| |
| RunPostInstallTestStep() { |
| RunStep PostInstallTestStep "Testing (post-install)" |
| } |
| |
| |
| RunInstallStep() { |
| Remove ${INSTALL_DIR} |
| MakeDir ${INSTALL_DIR} |
| RunStep InstallStep "Installing" ${BUILD_DIR}; |
| } |
| |
| |
| ###################################################################### |
| # Always run |
| # These functions are called when this script is imported to do |
| # any essential checking/setup operations. |
| ###################################################################### |
| CheckToolchain |
| CheckPatchVersion |
| CheckSDKVersion |
| PatchSpecFile |
| InjectSystemHeaders |
| InstallConfigSite |
| GetRevision |