Gentoo Archives: gentoo-dev

From: Jason Zaman <perfinion@g.o>
To: gentoo-dev@l.g.o
Subject: [gentoo-dev] Bazel Build eclass
Date: Sat, 17 Nov 2018 19:37:52
Message-Id: 20181117193736.GA28471@baraddur.perfinion.com
1 Hey all,
2
3 I've been using Bazel (https://bazel.build/) to build TensorFlow for a
4 while now. Here is a bazel.eclass I'd like to commit to make it easier
5 for packages that use it to build. It's basically bits that I've
6 refactored out of the TensorFlow ebuild that would be useful to other
7 packages as well. I have a bump to sci-libs/tensorflow-1.12.0 prepared
8 that uses this eclass and have tested a full install.
9
10 -- Jason
11
12 # Copyright 1999-2018 Jason Zaman
13 # Distributed under the terms of the GNU General Public License v2
14
15 # @ECLASS: bazel.eclass
16 # @MAINTAINER:
17 # Jason Zaman <perfinion@g.o>
18 # @AUTHOR:
19 # Jason Zaman <perfinion@g.o>
20 # @BLURB: Utility functions for packages using Bazel Build
21 # @DESCRIPTION:
22 # A utility eclass providing functions to run the Bazel Build system.
23 #
24 # This eclass does not export any phase functions.
25
26 case "${EAPI:-0}" in
27 0|1|2|3|4|5|6)
28 die "Unsupported EAPI=${EAPI:-0} (too old) for ${ECLASS}"
29 ;;
30 7)
31 ;;
32 *)
33 die "Unsupported EAPI=${EAPI} (unknown) for ${ECLASS}"
34 ;;
35 esac
36
37 if [[ ! ${_BAZEL_ECLASS} ]]; then
38
39 inherit multiprocessing toolchain-funcs
40
41 BDEPEND=">=dev-util/bazel-0.19"
42
43 # @FUNCTION: bazel_get_flags
44 # @DESCRIPTION:
45 # Obtain and print the bazel flags for target and host *FLAGS.
46 #
47 # To add more flags to this, append the flags to the
48 # appropriate variable before calling this function
49 bazel_get_flags() {
50 local i fs=()
51 for i in ${CFLAGS}; do
52 fs+=( "--conlyopt=${i}" )
53 done
54 for i in ${BUILD_CFLAGS}; do
55 fs+=( "--host_conlyopt=${i}" )
56 done
57 for i in ${CXXFLAGS}; do
58 fs+=( "--cxxopt=${i}" )
59 done
60 for i in ${BUILD_CXXFLAGS}; do
61 fs+=( "--host_cxxopt=${i}" )
62 done
63 for i in ${CPPFLAGS}; do
64 fs+=( "--conlyopt=${i}" "--cxxopt=${i}" )
65 done
66 for i in ${BUILD_CPPFLAGS}; do
67 fs+=( "--host_conlyopt=${i}" "--host_cxxopt=${i}" )
68 done
69 for i in ${LDFLAGS}; do
70 fs+=( "--linkopt=${i}" )
71 done
72 for i in ${BUILD_LDFLAGS}; do
73 fs+=( "--host_linkopt=${i}" )
74 done
75 echo "${fs[*]}"
76 }
77
78 # @FUNCTION: bazel_setup_bazelrc
79 # @DESCRIPTION:
80 # Creates the bazelrc with common options that will be passed
81 # to bazel. This will be called by ebazel automatically so
82 # does not need to be called from the ebuild.
83 bazel_setup_bazelrc() {
84 if [[ -f "${T}/bazelrc" ]]; then
85 return
86 fi
87
88 # F: fopen_wr
89 # P: /proc/self/setgroups
90 # Even with standalone enabled, the Bazel sandbox binary is run for feature test:
91 # https://github.com/bazelbuild/bazel/blob/7b091c1397a82258e26ab5336df6c8dae1d97384/src/main/java/com/google/devtools/build/lib/sandbox/LinuxSandboxedSpawnRunner.java#L61
92 # https://github.com/bazelbuild/bazel/blob/76555482873ffcf1d32fb40106f89231b37f850a/src/main/tools/linux-sandbox-pid1.cc#L113
93 addpredict /proc
94
95 mkdir -p "${T}/bazel-cache" || die
96 mkdir -p "${T}/bazel-distdir" || die
97
98 cat > "${T}/bazelrc" <<-EOF || die
99 startup --batch
100
101 # dont strip HOME, portage sets a temp per-package dir
102 build --action_env HOME
103
104 # make bazel respect MAKEOPTS
105 build --jobs=$(makeopts_jobs)
106 build --compilation_mode=opt --host_compilation_mode=opt
107
108 # FLAGS
109 build $(bazel_get_flags)
110
111 # Use standalone strategy to deactivate the bazel sandbox, since it
112 # conflicts with FEATURES=sandbox.
113 build --spawn_strategy=standalone --genrule_strategy=standalone
114 test --spawn_strategy=standalone --genrule_strategy=standalone
115
116 build --strip=never
117 build --verbose_failures --noshow_loading_progress
118 test --verbose_test_summary --verbose_failures --noshow_loading_progress
119
120 # make bazel only fetch distfiles from the cache
121 fetch --repository_cache="${T}/bazel-cache/" --distdir="${T}/bazel-distdir/"
122 build --repository_cache="${T}/bazel-cache/" --distdir="${T}/bazel-distdir/"
123
124 build --define=PREFIX=${EPREFIX%/}/usr
125 build --define=LIBDIR=\$(PREFIX)/$(get_libdir)
126
127 EOF
128
129 tc-is-cross-compiler || \
130 echo "build --nodistinct_host_configuration" >> "${T}/bazelrc" || die
131 }
132
133 # @FUNCTION: ebazel
134 # @USAGE: [<args>...]
135 # @DESCRIPTION:
136 # Run bazel with the bazelrc and output_base.
137 #
138 # If $MULTIBUILD_VARIANT is set, this will make an output_base
139 # specific to that variant.
140 # bazel_setup_bazelrc will be called and the created bazelrc
141 # will be passed to bazel.
142 #
143 # Will automatically die if bazel does not exit cleanly.
144 ebazel() {
145 bazel_setup_bazelrc
146
147 # Use different build folders for each multibuild variant.
148 local base_suffix="${MULTIBUILD_VARIANT+-}${MULTIBUILD_VARIANT}"
149 local output_base="${WORKDIR}/bazel-base${base_suffix}"
150 mkdir -p "${output_base}" || die
151
152 einfo Running: bazel --output_base="${output_base}" "$@"
153 bazel --bazelrc="${T}/bazelrc" --output_base="${output_base}" $@ || die "ebazel $@"
154 }
155
156 # @FUNCTION: bazel_load_distfiles
157 # @USAGE: <distfiles>...
158 # @DESCRIPTION:
159 # Populate the bazel distdir to fetch from since it cannot use
160 # the network. Bazel looks in distdir but will only look for the
161 # original filename, not the possibly renamed one that portage
162 # downloaded. If the line has -> we to rename it back. This also
163 # handles use-conditionals that SRC_URI does.
164 #
165 # Example:
166 # @CODE
167 # bazel_external_uris="http://a/file-2.0.tgz
168 # python? ( http://b/1.0.tgz -> foo-1.0.tgz )"
169 # SRC_URI="http://c/${PV}.tgz
170 # ${bazel_external_uris}"
171 #
172 # src_unpack() {
173 # unpack ${PV}.tgz
174 # bazel_load_distfiles "${bazel_external_uris}"
175 # }
176 # @CODE
177 bazel_load_distfiles() {
178 local src dst uri rename
179
180 [[ "$@" ]] || die "Missing args"
181 mkdir -p "${T}/bazel-distdir" || die
182
183 while read uri rename dst; do
184 src="${uri##*/}"
185 [[ -z $src ]] && continue
186 if [[ "$rename" != "->" ]]; then
187 dst="${src}"
188 fi
189
190 [[ ${A} =~ ${dst} ]] || continue
191
192 if [[ "$dst" == "$src" ]]; then
193 einfo "Copying $dst to bazel distdir ..."
194 else
195 einfo "Copying $dst to bazel distdir $src ..."
196 fi
197 dst="$(readlink -f "${DISTDIR}/${dst}")"
198 ln -s "${dst}" "${T}/bazel-distdir/${src}" || die
199 done <<< "$(sed -re 's/!?[A-Za-z]+\?\s+\(\s*//g; s/\s+\)//g' <<< "$@")"
200 }
201
202 _BAZEL_ECLASS=1
203 fi

Replies

Subject Author
Re: [gentoo-dev] Bazel Build eclass "Michał Górny" <mgorny@g.o>