1 |
it's needed to be present in all ebuilds for |
2 |
crate auditing tools to work properly. |
3 |
|
4 |
Signed-off-by: Georgy Yakovlev <gyakovlev@g.o> |
5 |
--- |
6 |
eclass/cargo.eclass | 17 +++++++++++++++++ |
7 |
1 file changed, 17 insertions(+) |
8 |
|
9 |
diff --git a/eclass/cargo.eclass b/eclass/cargo.eclass |
10 |
index 9923b1c9deb2..50237d302ce6 100644 |
11 |
--- a/eclass/cargo.eclass |
12 |
+++ b/eclass/cargo.eclass |
13 |
@@ -1,409 +1,426 @@ |
14 |
# Copyright 1999-2021 Gentoo Authors |
15 |
# Distributed under the terms of the GNU General Public License v2 |
16 |
|
17 |
# @ECLASS: cargo.eclass |
18 |
# @MAINTAINER: |
19 |
# rust@g.o |
20 |
# @AUTHOR: |
21 |
# Doug Goldstein <cardoe@g.o> |
22 |
# Georgy Yakovlev <gyakovlev@×××××××.org> |
23 |
# @SUPPORTED_EAPIS: 7 8 |
24 |
# @BLURB: common functions and variables for cargo builds |
25 |
|
26 |
if [[ -z ${_CARGO_ECLASS} ]]; then |
27 |
_CARGO_ECLASS=1 |
28 |
|
29 |
# check and document RUST_DEPEND and options we need below in case conditions. |
30 |
# https://github.com/rust-lang/cargo/blob/master/CHANGELOG.md |
31 |
RUST_DEPEND="virtual/rust" |
32 |
|
33 |
case "${EAPI:-0}" in |
34 |
0|1|2|3|4|5|6) |
35 |
die "Unsupported EAPI=${EAPI:-0} (too old) for ${ECLASS}" |
36 |
;; |
37 |
7) |
38 |
# 1.37 added 'cargo vendor' subcommand and net.offline config knob |
39 |
RUST_DEPEND=">=virtual/rust-1.37.0" |
40 |
;; |
41 |
|
42 |
8) |
43 |
# 1.39 added --workspace |
44 |
# 1.46 added --target dir |
45 |
# 1.48 added term.progress config option |
46 |
# 1.51 added split-debuginfo profile option |
47 |
# 1.52 may need setting RUSTC_BOOTSTRAP envvar for some crates |
48 |
# 1.53 added cargo update --offline, can be used to update vulnerable crates from pre-fetched registry without editing toml |
49 |
RUST_DEPEND=">=virtual/rust-1.53" |
50 |
;; |
51 |
*) |
52 |
die "Unsupported EAPI=${EAPI} (unknown) for ${ECLASS}" |
53 |
;; |
54 |
esac |
55 |
|
56 |
inherit multiprocessing toolchain-funcs |
57 |
|
58 |
if [[ ! ${CARGO_OPTIONAL} ]]; then |
59 |
BDEPEND="${RUST_DEPEND}" |
60 |
EXPORT_FUNCTIONS src_unpack src_configure src_compile src_install src_test |
61 |
fi |
62 |
|
63 |
IUSE="${IUSE} debug" |
64 |
|
65 |
ECARGO_HOME="${WORKDIR}/cargo_home" |
66 |
ECARGO_VENDOR="${ECARGO_HOME}/gentoo" |
67 |
|
68 |
+# @ECLASS-VARIABLE: CRATES |
69 |
+# @DEFAULT_UNSET |
70 |
+# @DESCRIPTION: |
71 |
+# bash string containing all crates package wants to download |
72 |
+# used by cargo_crate_uris() |
73 |
+# Example: |
74 |
+# @CODE |
75 |
+# CRATES=" |
76 |
+# metal-1.2.3 |
77 |
+# bar-4.5.6 |
78 |
+# iron_oxide-0.0.1 |
79 |
+# " |
80 |
+# inherit cargo |
81 |
+# ... |
82 |
+# SRC_URI="$(cargo_crate_uris ${CRATES})" |
83 |
+# @CODE |
84 |
+ |
85 |
# @ECLASS-VARIABLE: CARGO_OPTIONAL |
86 |
# @DEFAULT_UNSET |
87 |
# @PRE_INHERIT |
88 |
# @DESCRIPTION: |
89 |
# If set to a non-null value, before inherit cargo part of the ebuild will |
90 |
# be considered optional. No dependencies will be added and no phase |
91 |
# functions will be exported. |
92 |
# |
93 |
# If you enable CARGO_OPTIONAL, you have to set BDEPEND on virtual/rust |
94 |
# for your package and call at least cargo_gen_config manually before using |
95 |
# other src_ functions of this eclass. |
96 |
# note that cargo_gen_config is automatically called by cargo_src_unpack. |
97 |
|
98 |
# @ECLASS_VARIABLE: myfeatures |
99 |
# @DEFAULT_UNSET |
100 |
# @DESCRIPTION: |
101 |
# Optional cargo features defined as bash array. |
102 |
# Should be defined before calling cargo_src_configure(). |
103 |
# |
104 |
# Example package that has x11 and wayland as features, and disables default. |
105 |
# @CODE |
106 |
# src_configure() { |
107 |
# local myfeatures=( |
108 |
# $(usex X x11 '') |
109 |
# $(usev wayland) |
110 |
# ) |
111 |
# cargo_src_configure --no-default-features |
112 |
# } |
113 |
# @CODE |
114 |
|
115 |
# @ECLASS-VARIABLE: ECARGO_REGISTRY_DIR |
116 |
# @USER_VARIABLE |
117 |
# @DEFAULT_UNSET |
118 |
# @DESCRIPTION: |
119 |
# Storage directory for cargo registry. |
120 |
# Used by cargo_live_src_unpack to cache downloads. |
121 |
# This is intended to be set by users. |
122 |
# Ebuilds must not set it. |
123 |
# |
124 |
# Defaults to "${DISTDIR}/cargo-registry" it not set. |
125 |
|
126 |
# @ECLASS-VARIABLE: ECARGO_OFFLINE |
127 |
# @USER_VARIABLE |
128 |
# @DEFAULT_UNSET |
129 |
# @DESCRIPTION: |
130 |
# If non-empty, this variable prevents online operations in |
131 |
# cargo_live_src_unpack. |
132 |
# Inherits value of EVCS_OFFLINE if not set explicitly. |
133 |
|
134 |
# @ECLASS-VARIABLE: EVCS_UMASK |
135 |
# @USER_VARIABLE |
136 |
# @DEFAULT_UNSET |
137 |
# @DESCRIPTION: |
138 |
# Set this variable to a custom umask. This is intended to be set by |
139 |
# users. By setting this to something like 002, it can make life easier |
140 |
# for people who use cargo in a home directory, but are in the portage |
141 |
# group, and then switch over to building with FEATURES=userpriv. |
142 |
# Or vice-versa. |
143 |
|
144 |
# @FUNCTION: cargo_crate_uris |
145 |
# @DESCRIPTION: |
146 |
# Generates the URIs to put in SRC_URI to help fetch dependencies. |
147 |
cargo_crate_uris() { |
148 |
local -r regex='^([a-zA-Z0-9_\-]+)-([0-9]+\.[0-9]+\.[0-9]+.*)$' |
149 |
local crate |
150 |
for crate in "$@"; do |
151 |
local name version url |
152 |
[[ $crate =~ $regex ]] || die "Could not parse name and version from crate: $crate" |
153 |
name="${BASH_REMATCH[1]}" |
154 |
version="${BASH_REMATCH[2]}" |
155 |
url="https://crates.io/api/v1/crates/${name}/${version}/download -> ${crate}.crate" |
156 |
echo "${url}" |
157 |
done |
158 |
} |
159 |
|
160 |
# @FUNCTION: cargo_gen_config |
161 |
# @DESCRIPTION: |
162 |
# Generate the $CARGO_HOME/config necessary to use our local registry and settings. |
163 |
# Cargo can also be configured through environment variables in addition to the TOML syntax below. |
164 |
# For each configuration key below of the form foo.bar the environment variable CARGO_FOO_BAR |
165 |
# can also be used to define the value. |
166 |
# Environment variables will take precedence over TOML configuration, |
167 |
# and currently only integer, boolean, and string keys are supported. |
168 |
# For example the build.jobs key can also be defined by CARGO_BUILD_JOBS. |
169 |
# Or setting CARGO_TERM_VERBOSE=false in make.conf will make build quieter. |
170 |
cargo_gen_config() { |
171 |
debug-print-function ${FUNCNAME} "$@" |
172 |
|
173 |
mkdir -p "${ECARGO_HOME}" || die |
174 |
|
175 |
cat > "${ECARGO_HOME}/config" <<- _EOF_ || die "Failed to create cargo config" |
176 |
[source.gentoo] |
177 |
directory = "${ECARGO_VENDOR}" |
178 |
|
179 |
[source.crates-io] |
180 |
replace-with = "gentoo" |
181 |
local-registry = "/nonexistant" |
182 |
|
183 |
[net] |
184 |
offline = true |
185 |
|
186 |
[build] |
187 |
jobs = $(makeopts_jobs) |
188 |
incremental = false |
189 |
|
190 |
[term] |
191 |
verbose = true |
192 |
$([[ "${NOCOLOR}" = true || "${NOCOLOR}" = yes ]] && echo "color = 'never'") |
193 |
_EOF_ |
194 |
|
195 |
export CARGO_HOME="${ECARGO_HOME}" |
196 |
_CARGO_GEN_CONFIG_HAS_RUN=1 |
197 |
} |
198 |
|
199 |
# @FUNCTION: cargo_src_unpack |
200 |
# @DESCRIPTION: |
201 |
# Unpacks the package and the cargo registry |
202 |
cargo_src_unpack() { |
203 |
debug-print-function ${FUNCNAME} "$@" |
204 |
|
205 |
mkdir -p "${ECARGO_VENDOR}" || die |
206 |
mkdir -p "${S}" || die |
207 |
|
208 |
local archive shasum pkg |
209 |
for archive in ${A}; do |
210 |
case "${archive}" in |
211 |
*.crate) |
212 |
ebegin "Loading ${archive} into Cargo registry" |
213 |
tar -xf "${DISTDIR}"/${archive} -C "${ECARGO_VENDOR}/" || die |
214 |
# generate sha256sum of the crate itself as cargo needs this |
215 |
shasum=$(sha256sum "${DISTDIR}"/${archive} | cut -d ' ' -f 1) |
216 |
pkg=$(basename ${archive} .crate) |
217 |
cat <<- EOF > ${ECARGO_VENDOR}/${pkg}/.cargo-checksum.json |
218 |
{ |
219 |
"package": "${shasum}", |
220 |
"files": {} |
221 |
} |
222 |
EOF |
223 |
# if this is our target package we need it in ${WORKDIR} too |
224 |
# to make ${S} (and handle any revisions too) |
225 |
if [[ ${P} == ${pkg}* ]]; then |
226 |
tar -xf "${DISTDIR}"/${archive} -C "${WORKDIR}" || die |
227 |
fi |
228 |
eend $? |
229 |
;; |
230 |
*) |
231 |
unpack ${archive} |
232 |
;; |
233 |
esac |
234 |
done |
235 |
|
236 |
cargo_gen_config |
237 |
} |
238 |
|
239 |
# @FUNCTION: cargo_live_src_unpack |
240 |
# @DESCRIPTION: |
241 |
# Runs 'cargo fetch' and vendors downloaded crates for offline use, used in live ebuilds |
242 |
cargo_live_src_unpack() { |
243 |
debug-print-function ${FUNCNAME} "$@" |
244 |
|
245 |
[[ "${PV}" == *9999* ]] || die "${FUNCNAME} only allowed in live/9999 ebuilds" |
246 |
[[ "${EBUILD_PHASE}" == unpack ]] || die "${FUNCNAME} only allowed in src_unpack" |
247 |
|
248 |
mkdir -p "${S}" || die |
249 |
mkdir -p "${ECARGO_VENDOR}" || die |
250 |
mkdir -p "${ECARGO_HOME}" || die |
251 |
|
252 |
local distdir=${PORTAGE_ACTUAL_DISTDIR:-${DISTDIR}} |
253 |
: ${ECARGO_REGISTRY_DIR:=${distdir}/cargo-registry} |
254 |
|
255 |
local offline="${ECARGO_OFFLINE:-${EVCS_OFFLINE}}" |
256 |
|
257 |
if [[ ! -d ${ECARGO_REGISTRY_DIR} && ! ${offline} ]]; then |
258 |
( |
259 |
addwrite "${ECARGO_REGISTRY_DIR}" |
260 |
mkdir -p "${ECARGO_REGISTRY_DIR}" |
261 |
) || die "Unable to create ${ECARGO_REGISTRY_DIR}" |
262 |
fi |
263 |
|
264 |
if [[ ${offline} ]]; then |
265 |
local subdir |
266 |
for subdir in cache index src; do |
267 |
if [[ ! -d ${ECARGO_REGISTRY_DIR}/registry/${subdir} ]]; then |
268 |
eerror "Networking activity has been disabled via ECARGO_OFFLINE or EVCS_OFFLINE" |
269 |
eerror "However, no valid cargo registry available at ${ECARGO_REGISTRY_DIR}" |
270 |
die "Unable to proceed with ECARGO_OFFLINE/EVCS_OFFLINE." |
271 |
fi |
272 |
done |
273 |
fi |
274 |
|
275 |
if [[ ${EVCS_UMASK} ]]; then |
276 |
local saved_umask=$(umask) |
277 |
umask "${EVCS_UMASK}" || die "Bad options to umask: ${EVCS_UMASK}" |
278 |
fi |
279 |
|
280 |
pushd "${S}" > /dev/null || die |
281 |
|
282 |
# Respect user settings befire cargo_gen_config is called. |
283 |
if [[ ! ${CARGO_TERM_COLOR} ]]; then |
284 |
[[ "${NOCOLOR}" = true || "${NOCOLOR}" = yes ]] && export CARGO_TERM_COLOR=never |
285 |
local unset_color=true |
286 |
fi |
287 |
if [[ ! ${CARGO_TERM_VERBOSE} ]]; then |
288 |
export CARGO_TERM_VERBOSE=true |
289 |
local unset_verbose=true |
290 |
fi |
291 |
|
292 |
# Let cargo fetch to system-wide location. |
293 |
# It will keep directory organized by itself. |
294 |
addwrite "${ECARGO_REGISTRY_DIR}" |
295 |
export CARGO_HOME="${ECARGO_REGISTRY_DIR}" |
296 |
|
297 |
# Absence of quotes around offline arg is intentional, as cargo bails out if it encounters '' |
298 |
einfo "cargo fetch ${offline:+--offline}" |
299 |
cargo fetch ${offline:+--offline} || die #nowarn |
300 |
|
301 |
# Let cargo copy all required crates to "${WORKDIR}" for offline use in later phases. |
302 |
einfo "cargo vendor ${offline:+--offline} ${ECARGO_VENDOR}" |
303 |
cargo vendor ${offline:+--offline} "${ECARGO_VENDOR}" || die #nowarn |
304 |
|
305 |
# Users may have git checkouts made by cargo. |
306 |
# While cargo vendors the sources, it still needs git checkout to be present. |
307 |
# Copying full dir is an overkill, so just symlink it. |
308 |
if [[ -d ${ECARGO_REGISTRY_DIR}/git ]]; then |
309 |
ln -sv "${ECARGO_REGISTRY_DIR}/git" "${ECARGO_HOME}/git" || die |
310 |
fi |
311 |
|
312 |
popd > /dev/null || die |
313 |
|
314 |
# Restore settings if needed. |
315 |
[[ ${unset_color} ]] && unset CARGO_TERM_COLOR |
316 |
[[ ${unset_verbose} ]] && unset CARGO_TERM_VERBOSE |
317 |
if [[ ${saved_umask} ]]; then |
318 |
umask "${saved_umask}" || die |
319 |
fi |
320 |
|
321 |
# After following calls, cargo will no longer use ${ECARGO_REGISTRY_DIR} as CARGO_HOME |
322 |
# It will be forced into offline mode to prevent network access. |
323 |
# But since we already vendored crates and symlinked git, it has all it needs to build. |
324 |
unset CARGO_HOME |
325 |
cargo_gen_config |
326 |
} |
327 |
|
328 |
# @FUNCTION: cargo_src_configure |
329 |
# @DESCRIPTION: |
330 |
# Configure cargo package features and arguments. |
331 |
# Extra positional arguments supplied to this function |
332 |
# will be passed to cargo in all phases. |
333 |
# Make sure all cargo subcommands support flags passed here. |
334 |
# |
335 |
# Example for package that explicitly builds only 'baz' binary and |
336 |
# enables 'barfeature' and optional 'foo' feature. |
337 |
# will pass '--features barfeature --features foo --bin baz' |
338 |
# in src_{compile,test,install} |
339 |
# |
340 |
# @CODE |
341 |
# src_configure() { |
342 |
# local myfeatures=( |
343 |
# barfeature |
344 |
# $(usev foo) |
345 |
# ) |
346 |
# cargo_src_configure --bin baz |
347 |
# } |
348 |
# @CODE |
349 |
# |
350 |
# In some cases crates may need '--no-default-features' option, |
351 |
# as there is no way to disable single feature, except disabling all. |
352 |
# It can be passed directly to cargo_src_configure(). |
353 |
cargo_src_configure() { |
354 |
debug-print-function ${FUNCNAME} "$@" |
355 |
|
356 |
[[ -z ${myfeatures} ]] && declare -a myfeatures=() |
357 |
local myfeaturestype=$(declare -p myfeatures 2>&-) |
358 |
if [[ "${myfeaturestype}" != "declare -a myfeatures="* ]]; then |
359 |
die "myfeatures must be declared as array" |
360 |
fi |
361 |
|
362 |
# transform array from simple feature list |
363 |
# to multiple cargo args: |
364 |
# --features feature1 --features feature2 ... |
365 |
# this format is chosen because 2 other methods of |
366 |
# listing features (space OR comma separated) require |
367 |
# more fiddling with strings we'd like to avoid here. |
368 |
myfeatures=( ${myfeatures[@]/#/--features } ) |
369 |
|
370 |
readonly ECARGO_ARGS=( ${myfeatures[@]} ${@} ${ECARGO_EXTRA_ARGS} ) |
371 |
|
372 |
[[ ${ECARGO_ARGS[@]} ]] && einfo "Configured with: ${ECARGO_ARGS[@]}" |
373 |
} |
374 |
|
375 |
# @FUNCTION: cargo_src_compile |
376 |
# @DESCRIPTION: |
377 |
# Build the package using cargo build |
378 |
cargo_src_compile() { |
379 |
debug-print-function ${FUNCNAME} "$@" |
380 |
|
381 |
[[ ${_CARGO_GEN_CONFIG_HAS_RUN} ]] || \ |
382 |
die "FATAL: please call cargo_gen_config before using ${FUNCNAME}" |
383 |
|
384 |
tc-export AR CC CXX PKG_CONFIG |
385 |
|
386 |
set -- cargo build $(usex debug "" --release) ${ECARGO_ARGS[@]} "$@" |
387 |
einfo "${@}" |
388 |
"${@}" || die "cargo build failed" |
389 |
} |
390 |
|
391 |
# @FUNCTION: cargo_src_install |
392 |
# @DESCRIPTION: |
393 |
# Installs the binaries generated by cargo |
394 |
# In come case workspaces need alternative --path parameter |
395 |
# default is '--path ./' if nothing specified. |
396 |
# '--path ./somedir' can be passed directly to cargo_src_install() |
397 |
cargo_src_install() { |
398 |
debug-print-function ${FUNCNAME} "$@" |
399 |
|
400 |
[[ ${_CARGO_GEN_CONFIG_HAS_RUN} ]] || \ |
401 |
die "FATAL: please call cargo_gen_config before using ${FUNCNAME}" |
402 |
|
403 |
set -- cargo install $(has --path ${@} || echo --path ./) \ |
404 |
--root "${ED}/usr" \ |
405 |
$(usex debug --debug "") \ |
406 |
${ECARGO_ARGS[@]} "$@" |
407 |
einfo "${@}" |
408 |
"${@}" || die "cargo install failed" |
409 |
|
410 |
rm -f "${ED}/usr/.crates.toml" || die |
411 |
rm -f "${ED}/usr/.crates2.json" || die |
412 |
|
413 |
# it turned out to be non-standard dir, so get rid of it future EAPI |
414 |
# and only run for EAPI=7 |
415 |
# https://bugs.gentoo.org/715890 |
416 |
case ${EAPI:-0} in |
417 |
7) |
418 |
if [ -d "${S}/man" ]; then |
419 |
doman "${S}/man" || return 0 |
420 |
fi |
421 |
;; |
422 |
esac |
423 |
} |
424 |
|
425 |
# @FUNCTION: cargo_src_test |
426 |
# @DESCRIPTION: |
427 |
# Test the package using cargo test |
428 |
cargo_src_test() { |
429 |
debug-print-function ${FUNCNAME} "$@" |
430 |
|
431 |
[[ ${_CARGO_GEN_CONFIG_HAS_RUN} ]] || \ |
432 |
die "FATAL: please call cargo_gen_config before using ${FUNCNAME}" |
433 |
|
434 |
set -- cargo test $(usex debug "" --release) ${ECARGO_ARGS[@]} "$@" |
435 |
einfo "${@}" |
436 |
"${@}" || die "cargo test failed" |
437 |
} |
438 |
|
439 |
fi |
440 |
-- |
441 |
2.32.0 |