blob: d1684a161e091c3955afdb7b65e9e7e79d48ba9d [file] [log] [blame]
# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
# Distributed under the terms of the GNU General Public License v2
# @ECLASS: cros-workon.eclass
# @MAINTAINER:
# ChromiumOS Build Team
# @BUGREPORTS:
# Please report bugs via http://crbug.com/new (with label Build)
# @VCSURL: https://chromium.googlesource.com/chromiumos/overlays/chromiumos-overlay/+/master/eclass/@ECLASS@
# @BLURB: helper eclass for building ChromiumOS packages from git
# @DESCRIPTION:
# A lot of ChromiumOS packages (src/platform/ and src/third_party/) are
# managed in the same way. You've got a git tree and you want to build
# it. This automates a lot of that common stuff in one place.
inherit cros-constants
# Array variables. All of the following variables can contain multiple items
# with the restriction being that all of them have to have either:
# - the same number of items globally
# - one item as default for all
# - no items as the cros-workon default
# The exception is CROS_WORKON_PROJECT which has to have all items specified.
ARRAY_VARIABLES=(
CROS_WORKON_{SUBDIR,REPO,PROJECT,LOCALNAME,DESTDIR,COMMIT,TREE,SRCPATH} )
# @ECLASS-VARIABLE: CROS_WORKON_SUBDIR
# @DESCRIPTION:
# Sub-directory which is added to create full source checkout path
: ${CROS_WORKON_SUBDIR:=}
# @ECLASS-VARIABLE: CROS_WORKON_REPO
# @DESCRIPTION:
# Git URL which is prefixed to CROS_WORKON_PROJECT
: ${CROS_WORKON_REPO:=${CROS_GIT_HOST_URL}}
# @ECLASS-VARIABLE: CROS_WORKON_PROJECT
# @DESCRIPTION:
# Git project name which is suffixed to CROS_WORKON_REPO
: ${CROS_WORKON_PROJECT:=}
# @ECLASS-VARIABLE: CROS_WORKON_LOCALNAME
# @DESCRIPTION:
# Temporary local name in third_party
: ${CROS_WORKON_LOCALNAME:=${PN}}
# @ECLASS-VARIABLE: CROS_WORKON_DESTDIR
# @DESCRIPTION:
# Destination directory in ${WORKDIR} for checkout.
# Note that the default is ${S}, but is only referenced in src_unpack for
# ebuilds that would like to override it.
: ${CROS_WORKON_DESTDIR:=}
# @ECLASS-VARIABLE: CROS_WORKON_COMMIT
# @DESCRIPTION:
# Git commit to checkout to
: ${CROS_WORKON_COMMIT:=master}
# @ECLASS-VARIABLE: CROS_WORKON_TREE
# @DESCRIPTION:
# SHA1 of the contents of the repository. This is used for verifying the
# correctness of prebuilts. Unlike the commit hash, this SHA1 is unaffected
# by the history of the repository, or by commit messages.
: ${CROS_WORKON_TREE:=}
# Scalar variables. These variables modify the behaviour of the eclass.
# @ECLASS-VARIABLE: CROS_WORKON_SUBDIRS_TO_COPY
# @DESCRIPTION:
# Make cros-workon operate exclusively with the subtrees given by this array.
# NOTE: This only speeds up local_cp builds. Inplace/local_git builds are unaffected.
# It will also be disabled by using project arrays, rather than a single project.
: ${CROS_WORKON_SUBDIRS_TO_COPY:=/}
# @ECLASS-VARIABLE: CROS_WORKON_SUBDIRS_BLACKLIST
# @DESCRIPTION:
# Array of directories in the source tree to explicitly ignore and not even copy
# them over. This is intended, for example, for blocking infamous bloated and
# generated content that is unwanted during the build.
: ${CROS_WORKON_SUBDIRS_BLACKLIST:=}
# @ECLASS-VARIABLE: CROS_WORKON_SRCROOT
# @DESCRIPTION:
# Directory where chrome third party and platform sources are located (formerly CHROMEOS_ROOT)
: ${CROS_WORKON_SRCROOT:="${CHROOT_SOURCE_ROOT}"}
# @ECLASS-VARIABLE: CROS_WORKON_INPLACE
# @DESCRIPTION:
# Build the sources in place. Don't copy them to a temp dir.
: ${CROS_WORKON_INPLACE:=}
# @ECLASS-VARIABLE: CROS_WORKON_USE_VCSID
# @DESCRIPTION:
# Export VCSID into the project
: ${CROS_WORKON_USE_VCSID:=}
# @ECLASS-VARIABLE: CROS_WORKON_GIT_SUFFIX
# @DESCRIPTION:
# The git eclass does not do locking on its repo. That means
# multiple ebuilds that use the same git repo cannot safely be
# emerged at the same time. Until we can get that sorted out,
# allow ebuilds that know they'll conflict to declare a unique
# path for storing the local clone.
: ${CROS_WORKON_GIT_SUFFIX:=}
# @ECLASS-VARIABLE: CROS_WORKON_OUTOFTREE_BUILD
# @DESCRIPTION:
# Do not copy the source tree to $S; instead set $S to the
# source tree and store compiled objects and build state
# in $WORKDIR. The ebuild is responsible for ensuring
# the build output goes to $WORKDIR, e.g. setting
# O=${WORKDIR}/${P}/build/${board} when compiling the kernel.
: ${CROS_WORKON_OUTOFTREE_BUILD:=}
# @ECLASS-VARIABLE: CROS_WORKON_INCREMENTAL_BUILD
# @DESCRIPTION:
# If set to "1", store output objects in a location that is not wiped
# between emerges. If disabled, objects will be written to ${WORKDIR}
# like normal.
: ${CROS_WORKON_INCREMENTAL_BUILD:=}
# @ECLASS-VARIABLE: CROS_WORKON_BLACKLIST
# @DESCRIPTION:
# If set to "1", the cros-workon uprev system on the bots will not automatically
# revbump your package when changes are made. This is useful if you want more
# direct control over when updates to the source git repo make it into the
# ebuild, or if the git repo you're using is not part of the official manifest.
# e.g. If you set CROS_WORKON_REPO or EGIT_REPO_URI to an external (to Google)
# site, set this to "1".
: ${CROS_WORKON_BLACKLIST:=}
# @ECLASS-VARIABLE: CROS_WORKON_CLANG
# @DESCRIPTION:
# If set to "1", for target board packages, build with -clang-syntax.
# This is a flag our compiler wrapper uses, not the real gcc. If you want to
# disable this feature, set this to "0".
: ${CROS_WORKON_CLANG:=1}
# @ECLASS-VARIABLE: CROS_WORKON_MAKE_COMPILE_ARGS
# @DESCRIPTION:
# Args to pass to `make` when running src_compile. Not intended for ebuilds
# to set, just to respect. Used by `cros_workon_make` and friends.
# @ECLASS-VARIABLE: CROS_WORKON_EGIT_BRANCH
# @DESCRIPTION:
# This branch is used as EGIT_BRANCH when falling back to git-2. Leaving this
# as the default value of space will cause git-2 to fetch all branches with
# the special refspec ":". Since we don't know which branch CROS_WORKON_COMMIT
# is in, fetching all branches is a safe bet. However, if the git branch being
# updated can't be fast-forwarded (e.g. linux-next master), the branch needs to
# be specified because the special refspec excludes non-FF branches in fetches.
: ${CROS_WORKON_EGIT_BRANCH:=}
# @ECLASS-VARIABLE: CROS_WORKON_ALWAYS_LIVE
# @DESCRIPTION:
# If set to "1", don't try to do a local fetch for 9999 ebuilds.
: ${CROS_WORKON_ALWAYS_LIVE:=}
# @ECLASS-VARIABLE: CROS_WORKON_SRCPATH
# @DESCRIPTION:
# Location of the source directory relative to the brick source root. This is
# used for locally sourced packages and, if defined, takes precedence over
# Chrome OS specific source locations.
: ${CROS_WORKON_SRCPATH:=}
# Join the tree commits to produce a unique identifier
CROS_WORKON_TREE_COMPOSITE=$(IFS="_"; echo "${CROS_WORKON_TREE[*]}")
IUSE="cros_host cros_workon_tree_$CROS_WORKON_TREE_COMPOSITE profiling"
inherit flag-o-matic toolchain-funcs
# We need git-2 only for packages that define CROS_WORKON_PROJECT. Otherwise,
# there's no dependence on git and we don't want it pulled in.
if [[ -n "${CROS_WORKON_PROJECT[*]}" ]]; then
inherit git-2
fi
# Sanitize all variables, autocomplete where necessary.
# This function possibly modifies all CROS_WORKON_ variables inplace. It also
# provides a global project_count variable which contains the number of
# projects.
array_vars_autocomplete() {
# CROS_WORKON_{PROJECT,SRCPATH} must have all values explicitly filled in.
# They have to be of the same length, or one may be undefined (length <= 1
# and empty).
project_count=${#CROS_WORKON_PROJECT[@]}
local srcpath_count=${#CROS_WORKON_SRCPATH[@]}
if [[ ${project_count} -lt ${srcpath_count} ]]; then
if [[ ${project_count} -gt 1 ]] || [[ -n "${CROS_WORKON_PROJECT[@]}" ]]; then
die "CROS_WORKON_PROJECT has fewer values than _SRCPATH"
fi
project_count=${srcpath_count}
elif [[ ${project_count} -gt ${srcpath_count} ]]; then
if [[ ${srcpath_count} -gt 1 ]] || [[ -n "${CROS_WORKON_SRCPATH[@]}" ]]; then
die "CROS_WORKON_SRCPATH has fewer values than _PROJECT"
fi
fi
# No project_count is really bad.
if [[ ${project_count} -eq 0 ]]; then
die "Must have at least one value in CROS_WORKON_{PROJECT,SRCPATH}"
fi
# For one value, defaults will suffice, unless it's blank (likely undefined).
if [[ ${project_count} -eq 1 ]]; then
if [[ -z "${CROS_WORKON_SRCPATH[@]}" ]] && [[ -z "${CROS_WORKON_PROJECT[@]}" ]]; then
die "Undefined CROS_WORKON_{PROJECT,SRCPATH}"
fi
return
fi
[[ ${CROS_WORKON_OUTOFTREE_BUILD} == "1" ]] && die "Out of Tree Build not compatible with multi-project ebuilds"
local count var
for var in "${ARRAY_VARIABLES[@]}"; do
eval count=\${#${var}\[@\]}
if [[ ${count} -ne ${project_count} ]] && [[ ${count} -ne 1 ]]; then
die "${var} has ${count} projects. ${project_count} or one default expected."
fi
# Invariably, ${project_count} is at least 2 here. All variables also either
# have all items or the first serves as default (or isn't needed if
# empty). By looking at the second item, determine if we need to
# autocomplete.
local i
if [[ ${count} -ne ${project_count} ]]; then
for (( i = 1; i < project_count; ++i )); do
eval ${var}\[i\]=\${${var}\[0\]}
done
fi
eval einfo "${var}: \${${var}[@]}"
done
}
# Calculate path where code should be checked out.
# Result passed through global variable "path" to preserve proper array quoting.
get_paths() {
local pathbase srcbase
pathbase="${CROS_WORKON_SRCROOT}"
if [[ "${CATEGORY}" == "chromeos-base" ||
"${CATEGORY}" == "brillo-base" ]] ; then
pathbase+=/src
else
pathbase+=/src/third_party
fi
srcbase="$(dirname "$(dirname "$(dirname "$(dirname "${EBUILD}")")")")/src"
path=()
local pathelement i
for (( i = 0; i < project_count; ++i )); do
if [[ -n "${CROS_WORKON_SRCPATH[i]}" ]]; then
pathelement="${srcbase}/${CROS_WORKON_SRCPATH[i]}"
else
pathelement="${pathbase}/${CROS_WORKON_LOCALNAME[i]}"
if [[ ! -d "${pathelement}" ]]; then
pathelement="${pathbase}/platform/${CROS_WORKON_LOCALNAME[i]}"
fi
fi
if [[ -n "${CROS_WORKON_SUBDIR[i]}" ]]; then
pathelement+="/${CROS_WORKON_SUBDIR[i]}"
fi
path+=( "${pathelement}" )
done
}
local_copy_cp() {
local src="${1}"
local dst="${2}"
einfo "Copying sources from ${src}"
local blacklist=( "${CROS_WORKON_SUBDIR_BLACKLIST[@]/#/--exclude=}" "--exclude=*.pyc" )
local sl
for sl in "${CROS_WORKON_SUBDIRS_TO_COPY[@]}"; do
if [[ -d "${src}/${sl}" ]]; then
mkdir -p "${dst}/${sl}"
rsync -a "${blacklist[@]}" "${src}/${sl}"/* "${dst}/${sl}" || \
die "rsync -a ${blacklist[@]} ${src}/${sl}/* ${dst}/${sl}"
fi
done
}
symlink_in_place() {
local src="${1}"
local dst="${2}"
einfo "Using experimental inplace build in ${src}."
SBOX_TMP=":${SANDBOX_WRITE}:"
if [ "${SBOX_TMP/:$CROS_WORKON_SRCROOT://}" == "${SBOX_TMP}" ]; then
ewarn "For inplace build you need to modify the sandbox"
ewarn "Set SANDBOX_WRITE=${CROS_WORKON_SRCROOT} in your env."
fi
mkdir -p "${dst%/*}"
ln -sf "${src}" "${dst}"
}
local_copy() {
# Local vars used by all called functions.
local src="${1}"
local dst="${2}"
# If we want to use git, and the source actually is a git repo
if [ "${CROS_WORKON_INPLACE}" == "1" ]; then
symlink_in_place "${src}" "${dst}"
elif [ "${CROS_WORKON_OUTOFTREE_BUILD}" == "1" ]; then
S="${src}"
else
local_copy_cp "${src}" "${dst}"
fi
}
set_vcsid() {
export VCSID="${PVR}-${1}"
if [ "${CROS_WORKON_USE_VCSID}" = "1" ]; then
append-cppflags -DVCSID=\'\"${VCSID}\"\'
MAKEOPTS+=" VCSID=${VCSID}"
# When working with multiple projects, keep from adding the same
# flags many many times.
CROS_WORKON_USE_VCSID="2"
fi
}
get_rev() {
GIT_DIR="$1" git rev-parse HEAD
}
using_common_mk() {
[[ -n $(find -H "${S}" -name common.mk -exec grep -l 'The authoritative common.mk is located in' {} +) ]]
}
cros-workon_src_unpack() {
local fetch_method # local|git
# Sanity check. We cannot have S set to WORKDIR because if/when we try
# to check out repos, git will die if it tries to check out into a dir
# that already exists. Some packages might try this when out-of-tree
# builds are enabled, and they'll work fine most of the time because
# they'll be using a full manifest and will just re-use the existing
# checkout in src/platform/*. But if the code detects that it has to
# make its own checkout, things fall apart. For out-of-tree builds,
# the initial $S doesn't even matter because it resets it below to the
# repo in src/platform/.
if [[ ${S} == "${WORKDIR}" ]]; then
die "Sorry, but \$S cannot be set to \$WORKDIR"
fi
# Set the default of CROS_WORKON_DESTDIR. This is done here because S is
# sometimes overridden in ebuilds and we cannot rely on the global state
# (and therefore ordering of eclass inherits and local ebuild overrides).
: ${CROS_WORKON_DESTDIR:=${S}}
# Fix array variables
array_vars_autocomplete
if [[ "${PV}" == "9999" && "${CROS_WORKON_ALWAYS_LIVE}" != "1" ]] || [[ -z "${CROS_WORKON_PROJECT[*]}" ]]; then
# Live / non-repo packages
fetch_method=local
elif [[ "${PV}" != "9999" && "${CROS_WORKON_ALWAYS_LIVE}" == "1" ]]; then
die "CROS_WORKON_ALWAYS_LIVE is set for non-9999 ebuild"
else
fetch_method=git
fi
# Hack
# TODO(msb): remove once we've resolved the include path issue
# http://groups.google.com/a/chromium.org/group/chromium-os-dev/browse_thread/thread/5e85f28f551eeda/3ae57db97ae327ae
local p i
for p in "${CROS_WORKON_LOCALNAME[@]/#/${WORKDIR}/}"; do
ln -s "${S}" "${p}" &> /dev/null
done
local repo=( "${CROS_WORKON_REPO[@]}" )
local project=( "${CROS_WORKON_PROJECT[@]}" )
local destdir=( "${CROS_WORKON_DESTDIR[@]}" )
get_paths
# Automatically build out-of-tree for common.mk packages.
# TODO(vapier): Enable this once all common.mk packages have converted.
#if [[ -e ${path}/common.mk ]] ; then
# : ${CROS_WORKON_OUTOFTREE_BUILD:=1}
#fi
if [[ ${fetch_method} == "git" && ${CROS_WORKON_OUTOFTREE_BUILD} == "1" ]] ; then
# See if the local repo exists, is unmodified, and is checked out to
# the right rev. This will be the common case, so support it to make
# builds a bit faster.
if [[ -d ${path} ]] ; then
if [[ ${CROS_WORKON_COMMIT} == "$(get_rev "${path}/.git")" ]] ; then
local changes=$(
cd "${path}"
# Needed as `git status` likes to grab a repo lock.
addpredict "${PWD}"
# Ignore untracked files as they (should) be ignored by the build too.
git status --porcelain | grep -v '^[?][?]'
)
if [[ -z ${changes} ]] ; then
fetch_method=local
else
# Assume that if the dev has changes, they want it that way.
: #ewarn "${path} contains changes"
fi
else
ewarn "${path} is not at rev ${CROS_WORKON_COMMIT}"
fi
else
# This will hit minilayout users a lot, and rarely non-minilayout
# users. So don't bother warning here.
: #ewarn "${path} does not exist"
fi
fi
if [[ "${fetch_method}" == "git" ]] ; then
all_local() {
local p
for p in "${path[@]}"; do
[[ -d ${p} ]] || return 1
done
return 0
}
local fetched=0
if all_local; then
for (( i = 0; i < project_count; ++i )); do
# Looks like we already have a local copy of all repositories.
# Let's use these and checkout ${CROS_WORKON_COMMIT}.
# -s: For speed, share objects between ${path} and ${S}.
# -n: Don't checkout any files from the repository yet. We'll
# checkout the source separately.
#
# We don't use git clone to checkout the source because the -b
# option for clone defaults to HEAD if it can't find the
# revision you requested. On the other hand, git checkout fails
# if it can't find the revision you requested, so we use that
# instead.
# Destination directory. If we have one project, it's simply
# ${CROS_WORKON_DESTDIR}. More projects either specify an array or go to
# ${S}/${project}.
if [[ "${CROS_WORKON_COMMIT[i]}" == "master" ]]; then
# Since we don't have a CROS_WORKON_COMMIT revision specified,
# we don't know what revision the ebuild wants. Let's take the
# version of the code that the user has checked out.
#
# This almost replicates the pre-cros-workon behavior, where
# the code you had in your source tree was used to build
# things. One difference here, however, is that only committed
# changes are included.
#
# TODO(davidjames): We should fix the preflight buildbot to
# specify CROS_WORKON_COMMIT for all ebuilds, and update this
# code path to fail and explain the problem.
git clone -s "${path[i]}" "${destdir[i]}" || \
die "Can't clone ${path[i]}."
: $(( ++fetched ))
else
git clone -sn "${path[i]}" "${destdir[i]}" || \
die "Can't clone ${path[i]}."
if ! ( cd ${destdir[i]} && git checkout -q ${CROS_WORKON_COMMIT[i]} ) ; then
ewarn "Cannot run git checkout ${CROS_WORKON_COMMIT[i]} in ${destdir[i]}."
ewarn "Is ${path[i]} up to date? Try running repo sync."
rm -rf "${destdir[i]}/.git"
else
: $(( ++fetched ))
fi
fi
done
if [[ ${fetched} -eq ${project_count} ]]; then
# TODO: Id of all repos?
set_vcsid "$(get_rev "${path[0]}/.git")"
return
else
ewarn "Falling back to git.eclass..."
fi
fi
EGIT_BRANCH="${CROS_WORKON_EGIT_BRANCH}"
# Always pull all branches, if we are pulling source via git.
EGIT_ALL_BRANCH="1"
for (( i = 0; i < project_count; ++i )); do
EGIT_REPO_URI="${repo[i]}/${project[i]}.git"
EGIT_PROJECT="${project[i]}${CROS_WORKON_GIT_SUFFIX}"
EGIT_SOURCEDIR="${destdir[i]}"
EGIT_COMMIT="${CROS_WORKON_COMMIT[i]}"
# Clones to /var, copies src tree to the /build/<board>/tmp.
# Make sure git-2 does not run `unpack` for us automatically.
# The normal cros-workon flow above doesn't do it, so don't
# let git-2 do it either. http://crosbug.com/38342
EGIT_NOUNPACK=true git-2_src_unpack
# TODO(zbehan): Support multiple projects for vcsid?
done
set_vcsid "${CROS_WORKON_COMMIT[0]}"
return
fi
einfo "Using local source dir(s): ${path[*]}"
# Clone from the git host + repository path specified by
# CROS_WORKON_REPO + CROS_WORKON_PROJECT. Checkout source from
# the branch specified by CROS_WORKON_COMMIT into the workspace path.
# If the repository exists just punt and let it be copied off for build.
if [[ "${fetch_method}" == "local" && ! -d ${path} ]] ; then
ewarn "Sources are missing in ${path}"
ewarn "You need to cros_workon and repo sync your project. For example if you are working on the platform2 ebuild and shill repository:"
ewarn "cros_workon start --board=x86-generic platform2"
ewarn "repo sync shill"
fi
einfo "path: ${path[*]}"
einfo "destdir: ${destdir[*]}"
# Copy source tree to /build/<board>/tmp for building
for (( i = 0; i < project_count; ++i )); do
local_copy "${path[i]}" "${destdir[i]}" || \
die "Cannot create a local copy"
done
if [[ -n "${CROS_WORKON_PROJECT[*]}" ]]; then
set_vcsid "$(get_rev "${path[0]}/.git")"
fi
}
cros-workon_get_build_dir() {
local dir
if [[ ${CROS_WORKON_INCREMENTAL_BUILD} == "1" ]]; then
dir="${SYSROOT}/var/cache/portage/${CATEGORY}/${PN}"
[[ ${SLOT:-0} != "0" ]] && dir+=":${SLOT}"
else
dir="${WORKDIR}/build"
fi
echo "${dir}"
}
cros-workon_pkg_setup() {
if [[ ${MERGE_TYPE} != "binary" && ${CROS_WORKON_INCREMENTAL_BUILD} == "1" ]]; then
local out=$(cros-workon_get_build_dir)
addwrite "${out}"
mkdir -p -m 755 "${out}"
chown ${PORTAGE_USERNAME}:${PORTAGE_GRPNAME} "${out}" "${out%/*}"
fi
}
cros-workon_src_prepare() {
local out="$(cros-workon_get_build_dir)"
[[ ${CROS_WORKON_INCREMENTAL_BUILD} != "1" ]] && mkdir -p "${out}"
if using_common_mk ; then
: ${OUT=${out}}
export OUT
fi
}
cros-workon_src_configure() {
cros-workon_check_clang_syntax
if [[ $(type -t cros-debug-add-NDEBUG) == "function" ]] ; then
# Only run this if we've inherited cros-debug.eclass.
cros-debug-add-NDEBUG
fi
if using_common_mk ; then
# We somewhat overshoot here, but it isn't harmful,
# and catches all the packages we care about.
tc-export CC CXX AR RANLIB LD NM PKG_CONFIG
# Portage takes care of this for us.
export SPLITDEBUG=0
export MODE=$(usex profiling profiling opt)
elif [[ -x ${ECONF_SOURCE:-.}/configure ]]; then
econf "$@"
else
default
fi
}
cros-workon_check_clang_syntax() {
if ! use cros_host && [[ ${CROS_WORKON_CLANG} == "1" ]]; then
# For target board packages, build with -clang-syntax. This is a flag our
# compiler wrapper uses, not the real gcc.
append-flags -clang-syntax
fi
}
cw_emake() {
local dir=$(cros-workon_get_build_dir)
# Clean up a previous build dir if it exists. Use sudo in case some
# files happened to be owned by root or are otherwise marked a-w.
# The sandbox/preload magic is to turn off the sandbox before the sudo.
SANDBOX_ON=0 env -u LD_PRELOAD sudo rm -rf "${dir}%failed"
if ! nonfatal emake "$@" ; then
# If things failed, move the incremental dir out of the way --
# we don't know why exactly it failed as it could be due to
# corruption. Don't throw it away immediately in case the the
# developer wants to poke around.
# http://crosbug.com/35958
if [[ ${CROS_WORKON_INCREMENTAL_BUILD} == "1" ]] ; then
if [[ $(hostname -d) == "golo.chromium.org" ]] ; then
eerror "The build failed. Output has been retained at:"
eerror " ${dir}%failed/"
eerror "It will be cleaned up automatically next emerge."
wait # wait for the `rm` to finish.
mv "${dir}" "${dir}%failed"
else
ewarn "If this failure is due to build-dir corruption, run:"
ewarn " sudo rm -rf '${dir}'"
fi
fi
die "command: emake $*"
fi
}
cros-workon_src_compile() {
if using_common_mk ; then
cw_emake ${CROS_WORKON_MAKE_COMPILE_ARGS}
else
default
fi
}
cros-workon_src_test() {
if using_common_mk ; then
emake \
VALGRIND=$(use_if_iuse valgrind && echo 1) \
tests
else
default
fi
}
cros-workon_src_install() {
# common.mk supports coverage analysis, but only generates data when
# the tests have been run as part of the build process. Thus this code
# needs to test of the analysis output is present before trying to
# install it.
if using_common_mk ; then
if use profiling; then
LCOV_DIR=$(find "${WORKDIR}" -name "lcov-html")
if [[ $(echo "${LCOV_DIR}" | wc -l) -gt 1 ]] ; then
die "More then one instance of lcov-html " \
"found! The instances are ${LCOV_DIR}. " \
"It is unclear which version to use, " \
"failing install."
fi
if [[ -d "${LCOV_DIR}" ]] ; then
local dir="${PN}"
[[ ${SLOT} != "0" ]] && dir+=":${SLOT}"
insinto "/usr/share/profiling/${dir}/lcov"
doins -r "${LCOV_DIR}"/*
fi
fi
else
default
fi
}
cros-workon_pkg_info() {
print_quoted_array() { printf '"%s"\n' "$@"; }
array_vars_autocomplete > /dev/null
get_paths
CROS_WORKON_SRCDIR=("${path[@]}")
local val var
for var in CROS_WORKON_SRCDIR CROS_WORKON_PROJECT ; do
eval val=(\"\${${var}\[@\]}\")
echo ${var}=\($(print_quoted_array "${val[@]}")\)
done
}
EXPORT_FUNCTIONS pkg_setup src_unpack pkg_info