| # Copyright 2017 The ChromiumOS Authors |
| # Distributed under the terms of the GNU General Public License v2. |
| |
| # @ECLASS: cros-llvm.eclass |
| # @MAINTAINER: |
| # ChromeOS toolchain team.<chromeos-toolchain@google.com> |
| |
| # @DESCRIPTION: |
| # Functions to set the right toolchains and install prefix for llvm |
| # related libraries in crossdev stages. |
| |
| inherit multilib |
| |
| IUSE="continue-on-patch-failure python_targets_python3_6" |
| |
| BDEPEND="python_targets_python3_6? ( dev-python/dataclasses )" |
| if [[ ${CATEGORY} == cross-* ]] ; then |
| DEPEND=" |
| ${CATEGORY}/binutils |
| sys-devel/llvm |
| " |
| fi |
| |
| export CBUILD=${CBUILD:-${CHOST}} |
| export CTARGET=${CTARGET:-${CHOST}} |
| |
| if [[ "${CTARGET}" = "${CHOST}" ]] ; then |
| if [[ "${CATEGORY/cross-}" != "${CATEGORY}" ]] ; then |
| export CTARGET=${CATEGORY/cross-} |
| fi |
| fi |
| |
| setup_cross_toolchain() { |
| export CC="${CBUILD}-clang" |
| export CXX="${CBUILD}-clang++" |
| export PREFIX="/usr" |
| |
| if [[ ${CATEGORY} == cross-* ]] ; then |
| export CC="${CTARGET}-clang" |
| export CXX="${CTARGET}-clang++" |
| export PREFIX="/usr/${CTARGET}/usr" |
| export AS="$(tc-getAS "${CTARGET}")" |
| export STRIP="$(tc-getSTRIP "${CTARGET}")" |
| export OBJCOPY="$(tc-getOBJCOPY "${CTARGET}")" |
| elif [[ "${CTARGET}" != "${CBUILD}" ]] ; then |
| export CC="${CTARGET}-clang" |
| export CXX="${CTARGET}-clang++" |
| fi |
| unset ABI MULTILIB_ABIS DEFAULT_ABI |
| multilib_env "${CTARGET}" |
| } |
| |
| # @FUNCTION: prepare_patches |
| # @USAGE: <SVN Revision> |
| # @DESCRIPTION: |
| # Applies the LLVM patches to the LLVM source at `$S`. If the SVN revision |
| # is not passed in, then it will be extracted from the `$PV` for non-9999 / |
| # non-llvm-{next,tot} ebuilds. Otherwise it will inspect the .git directory |
| # to compute the SVN revision. |
| prepare_patches() { |
| local failure_mode |
| failure_mode="$(usex continue-on-patch-failure continue fail)" |
| |
| local revision |
| if [[ $# -ge 1 ]]; then |
| revision="$1" |
| else |
| revision="$(cros-llvm_get_most_recent_revision)" |
| fi |
| |
| "${FILESDIR}"/patch_manager/patch_manager.py \ |
| --svn_version "${revision}" \ |
| --patch_metadata_file "${FILESDIR}"/PATCHES.json \ |
| --failure_mode "${failure_mode}" \ |
| --src_path "${S}" || die |
| } |
| |
| # @FUNCTION cros-llvm_get_most_recent_revision |
| # @USAGE: <optional LLVM directory> |
| # @DESCRIPTION: |
| # Returns the revision number (e.g., 12345) for the currently checked out LLVM |
| # revision. Respects the result of running `cros-llvm_default_preclone_hook`, if |
| # its been run, and caches the result for future use. |
| # |
| # shellcheck disable=SC2120 |
| cros-llvm_get_most_recent_revision() { |
| # b/293822345 - Don't depend on the .git repo for versioned builds. |
| if [[ "${PV}" != "9999" ]]; then |
| # 17.0_pre496208 -> 496208 |
| ver_cut 4 |
| return |
| fi |
| |
| if [[ -f "${T}/llvm-rev" ]]; then |
| # If this file exists, it was set by the unpack stage. |
| cat "${T}/llvm-rev" |
| return |
| fi |
| |
| local subdir="${1:-"${S}/llvm"}" |
| # Tries to get the revision ID of the most recent commit |
| local rev current_git_head |
| current_git_head="$(git -C "${subdir}" rev-parse HEAD)" || die |
| rev="$("${FILESDIR}"/patch_manager/git_llvm_rev.py --llvm_dir "${subdir}" --sha="${current_git_head}")" || die "failed to get most recent llvm revision from ${subdir}" |
| rev="$(cut -d 'r' -f 2 <<< "${rev}")" |
| echo "${rev}" > "${T}/llvm-rev" |
| echo "${rev}" |
| } |
| |
| is_baremetal_abi() { |
| # ABIs like armv7m-cros-eabi or arm-none-eabi. |
| if [[ "${CTARGET}" == *-eabi ]]; then |
| return 0 |
| fi |
| return 1 |
| } |
| |
| # @FUNCTION cros-llvm_default_preclone_hook |
| # @DESCRIPTION: |
| # A function that takes in a global variable "path", to determine the |
| # location of the llvm-project git, and writes it to a tempfile ${T}/llvm-rev. |
| # This is useful when we need to get the svn revision number but we don't |
| # have access to this information from the ebuild itself. |
| # |
| # Used for cros-workon live ebuild support (PV=9999). |
| cros-llvm_default_preclone_hook() { |
| # "path" is defined as a global in the cros-workon.eclass |
| # shellcheck disable=SC2154 |
| local project_path="${path[0]}" |
| if [[ -d "${project_path}" ]]; then |
| # Note that cros-llvm_get_most_recent_revision caches its |
| # result, so discarding the result here is fine. |
| cros-llvm_get_most_recent_revision "${project_path}" > /dev/null |
| fi |
| } |
| |
| # @FUNCTION _cros-llvm_ensure_patches_stamp_exists |
| # @DESCRIPTION: |
| # Dies with an informative error message if the `patches_applied` stamp doesn't |
| # exist for the current package. |
| _cros-llvm_ensure_patches_stamp_exists() { |
| local f="${S}/.ebuild/stamps/patches_applied/${CATEGORY}/${PN}" |
| [[ -e "${f}" ]] || \ |
| die "No patches-applied stamp found at ${f}. Did you run src/third_party/toolchain-utils/llvm_tools/setup_for_workon.py?" |
| } |
| |
| # @FUNCTION _cros-llvm_apply_patch_manager_patches |
| # @DESCRIPTION: |
| # Runs `patch_manager` to apply patches. |
| _cros-llvm_apply_patch_manager_patches() { |
| local failure_mode |
| failure_mode="$(usex continue-on-patch-failure continue fail)" |
| "${FILESDIR}/patch_manager/patch_manager.py" \ |
| --svn_version="$(cros-llvm_get_most_recent_revision)" \ |
| --patch_metadata_file="${FILESDIR}/PATCHES.json" \ |
| --failure_mode="${failure_mode}" \ |
| --src_path="${S}" || die |
| } |
| |
| # @FUNCTION cros-llvm_ensure_patches_applied |
| # @DESCRIPTION: |
| # Ensures that patches are applied, by either applying them (in non-9999 |
| # ebuilds), or checking for a stamp that verifies that the patches were applied |
| # (in 9999 ebuilds). |
| cros-llvm_ensure_patches_applied() { |
| if [[ "${PV}" == "9999" ]]; then |
| # Use live sources if we're using the cros-workon ebuild. In |
| # this case, patches must already be applied. |
| _cros-llvm_ensure_patches_stamp_exists |
| else |
| _cros-llvm_apply_patch_manager_patches |
| fi |
| } |