diff options
author | Jason Zaman <perfinion@gentoo.org> | 2018-11-17 23:33:49 +0800 |
---|---|---|
committer | Jason Zaman <perfinion@gentoo.org> | 2018-12-24 17:27:47 +0800 |
commit | 7a80ab92aa1025134d96252dc6d4e8d163910227 (patch) | |
tree | b1ef53ff04e2ccab78ffe2f27142080b847e52bc /eclass/bazel.eclass | |
parent | dev-util/bazel: bump 0.20.0 (diff) | |
download | gentoo-7a80ab92aa1025134d96252dc6d4e8d163910227.tar.gz gentoo-7a80ab92aa1025134d96252dc6d4e8d163910227.tar.bz2 gentoo-7a80ab92aa1025134d96252dc6d4e8d163910227.zip |
bazel.eclass: new eclass for bazel build
Signed-off-by: Jason Zaman <perfinion@gentoo.org>
Diffstat (limited to 'eclass/bazel.eclass')
-rw-r--r-- | eclass/bazel.eclass | 220 |
1 files changed, 220 insertions, 0 deletions
diff --git a/eclass/bazel.eclass b/eclass/bazel.eclass new file mode 100644 index 000000000000..ce80ea185e9c --- /dev/null +++ b/eclass/bazel.eclass @@ -0,0 +1,220 @@ +# Copyright 1999-2018 Jason Zaman +# Distributed under the terms of the GNU General Public License v2 + +# @ECLASS: bazel.eclass +# @MAINTAINER: +# Jason Zaman <perfinion@gentoo.org> +# @AUTHOR: +# Jason Zaman <perfinion@gentoo.org> +# @BLURB: Utility functions for packages using Bazel Build +# @DESCRIPTION: +# A utility eclass providing functions to run the Bazel Build system. +# +# This eclass does not export any phase functions. + +case "${EAPI:-0}" in + 0|1|2|3|4|5|6) + die "Unsupported EAPI=${EAPI:-0} (too old) for ${ECLASS}" + ;; + 7) + ;; + *) + die "Unsupported EAPI=${EAPI} (unknown) for ${ECLASS}" + ;; +esac + +if [[ ! ${_BAZEL_ECLASS} ]]; then + +inherit multiprocessing toolchain-funcs + +BDEPEND=">=dev-util/bazel-0.20" + +# @FUNCTION: bazel_get_flags +# @DESCRIPTION: +# Obtain and print the bazel flags for target and host *FLAGS. +# +# To add more flags to this, append the flags to the +# appropriate variable before calling this function +bazel_get_flags() { + local i fs=() + for i in ${CFLAGS}; do + fs+=( "--conlyopt=${i}" ) + done + for i in ${BUILD_CFLAGS}; do + fs+=( "--host_conlyopt=${i}" ) + done + for i in ${CXXFLAGS}; do + fs+=( "--cxxopt=${i}" ) + done + for i in ${BUILD_CXXFLAGS}; do + fs+=( "--host_cxxopt=${i}" ) + done + for i in ${CPPFLAGS}; do + fs+=( "--conlyopt=${i}" "--cxxopt=${i}" ) + done + for i in ${BUILD_CPPFLAGS}; do + fs+=( "--host_conlyopt=${i}" "--host_cxxopt=${i}" ) + done + for i in ${LDFLAGS}; do + fs+=( "--linkopt=${i}" ) + done + for i in ${BUILD_LDFLAGS}; do + fs+=( "--host_linkopt=${i}" ) + done + echo "${fs[*]}" +} + +# @FUNCTION: bazel_setup_bazelrc +# @DESCRIPTION: +# Creates the bazelrc with common options that will be passed +# to bazel. This will be called by ebazel automatically so +# does not need to be called from the ebuild. +bazel_setup_bazelrc() { + if [[ -f "${T}/bazelrc" ]]; then + return + fi + + # F: fopen_wr + # P: /proc/self/setgroups + # Even with standalone enabled, the Bazel sandbox binary is run for feature test: + # https://github.com/bazelbuild/bazel/blob/7b091c1397a82258e26ab5336df6c8dae1d97384/src/main/java/com/google/devtools/build/lib/sandbox/LinuxSandboxedSpawnRunner.java#L61 + # https://github.com/bazelbuild/bazel/blob/76555482873ffcf1d32fb40106f89231b37f850a/src/main/tools/linux-sandbox-pid1.cc#L113 + addpredict /proc + + mkdir -p "${T}/bazel-cache" || die + mkdir -p "${T}/bazel-distdir" || die + + cat > "${T}/bazelrc" <<-EOF || die + startup --batch + + # dont strip HOME, portage sets a temp per-package dir + build --action_env HOME + + # make bazel respect MAKEOPTS + build --jobs=$(makeopts_jobs) + build --compilation_mode=opt --host_compilation_mode=opt + + # FLAGS + build $(bazel_get_flags) + + # Use standalone strategy to deactivate the bazel sandbox, since it + # conflicts with FEATURES=sandbox. + build --spawn_strategy=standalone --genrule_strategy=standalone + test --spawn_strategy=standalone --genrule_strategy=standalone + + build --strip=never + build --verbose_failures --noshow_loading_progress + test --verbose_test_summary --verbose_failures --noshow_loading_progress + + # make bazel only fetch distfiles from the cache + fetch --repository_cache="${T}/bazel-cache/" --distdir="${T}/bazel-distdir/" + build --repository_cache="${T}/bazel-cache/" --distdir="${T}/bazel-distdir/" + + build --define=PREFIX=${EPREFIX%/}/usr + build --define=LIBDIR=\$(PREFIX)/$(get_libdir) + EOF + + if tc-is-cross-compiler; then + echo "build --nodistinct_host_configuration" >> "${T}/bazelrc" || die + fi +} + +# @FUNCTION: ebazel +# @USAGE: [<args>...] +# @DESCRIPTION: +# Run bazel with the bazelrc and output_base. +# +# output_base will be specific to $BUILD_DIR (if unset, $S). +# bazel_setup_bazelrc will be called and the created bazelrc +# will be passed to bazel. +# +# Will automatically die if bazel does not exit cleanly. +ebazel() { + bazel_setup_bazelrc + + # Use different build folders for each multibuild variant. + local output_base="${BUILD_DIR:-${S}}" + output_base="${output_base%/}-bazel-base" + mkdir -p "${output_base}" || die + + set -- bazel --bazelrc="${T}/bazelrc" --output_base="${output_base}" ${@} + echo "${*}" >&2 + "${@}" || die "ebazel failed" +} + +# @FUNCTION: bazel_load_distfiles +# @USAGE: <distfiles>... +# @DESCRIPTION: +# Populate the bazel distdir to fetch from since it cannot use +# the network. Bazel looks in distdir but will only look for the +# original filename, not the possibly renamed one that portage +# downloaded. If the line has -> we to rename it back. This also +# handles use-conditionals that SRC_URI does. +# +# Example: +# @CODE +# bazel_external_uris="http://a/file-2.0.tgz +# python? ( http://b/1.0.tgz -> foo-1.0.tgz )" +# SRC_URI="http://c/${PV}.tgz +# ${bazel_external_uris}" +# +# src_unpack() { +# unpack ${PV}.tgz +# bazel_load_distfiles "${bazel_external_uris}" +# } +# @CODE +bazel_load_distfiles() { + local file="" + local rename=0 + + [[ "${@}" ]] || die "Missing args" + mkdir -p "${T}/bazel-distdir" || die + + for word in ${@} + do + if [[ "${word}" == "->" ]]; then + # next word is a dest filename + rename=1 + elif [[ "${word}" == ")" ]]; then + # close conditional block + continue + elif [[ "${word}" == "(" ]]; then + # open conditional block + continue + elif [[ "${word}" == ?(\!)[A-Za-z0-9]*([A-Za-z0-9+_@-])\? ]]; then + # use-conditional block + # USE-flags can contain [A-Za-z0-9+_@-], and start with alphanum + # https://dev.gentoo.org/~ulm/pms/head/pms.html#x1-200003.1.4 + # ?(\!) matches zero-or-one !'s + # *(...) zero-or-more characters + # ends with a ? + continue + elif [[ ${rename} -eq 1 ]]; then + # Make sure the distfile is used + if [[ "${A}" == *"${word}"* ]]; then + echo "Copying ${file} to bazel distdir as ${word}" + ln -s "${DISTDIR}/${word}" "${T}/bazel-distdir/${file}" || die + fi + rename=0 + file="" + else + # another URL, current one may or may not be a rename + # if there was a previous one, its not renamed so copy it now + if [[ -n "${file}" && "${A}" == *"${file}"* ]]; then + echo "Copying ${file} to bazel distdir" + ln -s "${DISTDIR}/${file}" "${T}/bazel-distdir/${file}" || die + fi + # save the current URL, later we will find out if its a rename or not. + file="${word##*/}" + fi + done + + # handle last file + if [[ -n "${file}" ]]; then + echo "Copying ${file} to bazel distdir" + ln -s "${DISTDIR}/${file}" "${T}/bazel-distdir/${file}" || die + fi +} + +_BAZEL_ECLASS=1 +fi |