summaryrefslogtreecommitdiff
path: root/eclass
diff options
context:
space:
mode:
authorV3n3RiX <venerix@koprulu.sector>2024-11-10 03:03:09 +0000
committerV3n3RiX <venerix@koprulu.sector>2024-11-10 03:03:09 +0000
commitbe94ae04eee564451203d45977c2ef7c7ace1580 (patch)
tree616ffc0ad9aee18dc7d5e9e62bf62394e8e520ba /eclass
parent2be329ae14bbf99f0fc4de7567e2386bbb529fdc (diff)
gentoo auto-resync : 10:11:2024 - 03:03:09
Diffstat (limited to 'eclass')
-rw-r--r--eclass/Manifest.gzbin38869 -> 39020 bytes
-rw-r--r--eclass/cargo.eclass59
-rw-r--r--eclass/rust.eclass464
-rw-r--r--eclass/toolchain.eclass8
4 files changed, 511 insertions, 20 deletions
diff --git a/eclass/Manifest.gz b/eclass/Manifest.gz
index a2049ecec127..1bd42ac7b11e 100644
--- a/eclass/Manifest.gz
+++ b/eclass/Manifest.gz
Binary files differ
diff --git a/eclass/cargo.eclass b/eclass/cargo.eclass
index 499fe5498c96..855692b72ec7 100644
--- a/eclass/cargo.eclass
+++ b/eclass/cargo.eclass
@@ -8,6 +8,7 @@
# Doug Goldstein <cardoe@gentoo.org>
# Georgy Yakovlev <gyakovlev@gentoo.org>
# @SUPPORTED_EAPIS: 8
+# @PROVIDES: rust
# @BLURB: common functions and variables for cargo builds
case ${EAPI} in
@@ -18,25 +19,36 @@ esac
if [[ -z ${_CARGO_ECLASS} ]]; then
_CARGO_ECLASS=1
-# check and document RUST_DEPEND and options we need below in case conditions.
+if [[ -n ${RUST_NEEDS_LLVM} ]]; then
+ if [[ -z ${_LLVM_R1_ECLASS} ]]; then
+ die "Please inherit llvm-r1.eclass before cargo.eclass when using RUST_NEEDS_LLVM"
+ fi
+fi
+
+if [[ -n ${CARGO_OPTIONAL} ]]; then
+ RUST_OPTIONAL=1
+fi
+
+# Either the lowest slot supported by rust.eclass _or_
+# reference the changelog for a particular feature requirement
# https://github.com/rust-lang/cargo/blob/master/CHANGELOG.md
-RUST_DEPEND="virtual/rust"
+_CARGO_ECLASS_RUST_MIN_VER="1.71.1"
case ${EAPI} in
8)
- # 1.39 added --workspace
- # 1.46 added --target dir
- # 1.48 added term.progress config option
- # 1.51 added split-debuginfo profile option
- # 1.52 may need setting RUSTC_BOOTSTRAP envvar for some crates
- # 1.53 added cargo update --offline, can be used to update vulnerable crates from pre-fetched registry without editing toml
- RUST_DEPEND=">=virtual/rust-1.53"
+ if [[ -n ${RUST_MIN_VER} ]]; then
+ # This is _very_ unlikely given that we leverage the rust eclass but just in case cargo requires a newer version
+ # than the oldest in-tree in future.
+ if ver_test "${RUST_MIN_VER}" -lt "${_CARGO_ECLASS_RUST_MIN_VER}"; then
+ die "RUST_MIN_VERSION must be at least ${_CARGO_ECLASS_RUST_MIN_VER}"
+ fi
+ else
+ RUST_MIN_VER="${_CARGO_ECLASS_RUST_MIN_VER}"
+ fi
;;
esac
-inherit flag-o-matic multiprocessing rust-toolchain toolchain-funcs
-
-[[ ! ${CARGO_OPTIONAL} ]] && BDEPEND="${RUST_DEPEND}"
+inherit flag-o-matic multiprocessing rust rust-toolchain toolchain-funcs
IUSE="${IUSE} debug"
@@ -107,9 +119,8 @@ ECARGO_VENDOR="${ECARGO_HOME}/gentoo"
# be considered optional. No dependencies will be added and no phase
# functions will be exported.
#
-# If you enable CARGO_OPTIONAL, you have to set BDEPEND on virtual/rust
-# for your package and call at least cargo_gen_config manually before using
-# other src_functions or cargo_env of this eclass.
+# If you enable CARGO_OPTIONAL call at least cargo_gen_config manually
+# before using other src_functions or cargo_env of this eclass.
# Note that cargo_gen_config is automatically called by cargo_src_unpack.
# @ECLASS_VARIABLE: myfeatures
@@ -129,6 +140,11 @@ ECARGO_VENDOR="${ECARGO_HOME}/gentoo"
# }
# @CODE
+# @ECLASS_VARIABLE: ECARGO_HOME
+# @OUTPUT_VARIABLE
+# @DESCRIPTION:
+# Location of the cargo home directory.
+
# @ECLASS_VARIABLE: ECARGO_REGISTRY_DIR
# @USER_VARIABLE
# @DEFAULT_UNSET
@@ -148,6 +164,11 @@ ECARGO_VENDOR="${ECARGO_HOME}/gentoo"
# cargo_live_src_unpack.
# Inherits value of EVCS_OFFLINE if not set explicitly.
+# @ECLASS_VARIABLE: ECARGO_VENDOR
+# @OUTPUT_VARIABLE
+# @DESCRIPTION:
+# Location of the cargo vendor directory.
+
# @ECLASS_VARIABLE: EVCS_UMASK
# @USER_VARIABLE
# @DEFAULT_UNSET
@@ -531,6 +552,8 @@ cargo_src_configure() {
# take affect due to Cargo limitations, so add these to your ebuild's RUSTFLAGS
# if they seem important.
cargo_env() {
+ debug-print-function ${FUNCNAME} "$@"
+
[[ ${_CARGO_GEN_CONFIG_HAS_RUN} ]] || \
die "FATAL: please call cargo_gen_config before using ${FUNCNAME}"
@@ -604,7 +627,7 @@ cargo_env() {
cargo_src_compile() {
debug-print-function ${FUNCNAME} "$@"
- set -- cargo build $(usex debug "" --release) ${ECARGO_ARGS[@]} "$@"
+ set -- ${CARGO} build $(usex debug "" --release) ${ECARGO_ARGS[@]} "$@"
einfo "${@}"
cargo_env "${@}" || die "cargo build failed"
}
@@ -618,7 +641,7 @@ cargo_src_compile() {
cargo_src_install() {
debug-print-function ${FUNCNAME} "$@"
- set -- cargo install $(has --path ${@} || echo --path ./) \
+ set -- ${CARGO} install $(has --path ${@} || echo --path ./) \
--root "${ED}/usr" \
${GIT_CRATES[@]:+--frozen} \
$(usex debug --debug "") \
@@ -636,7 +659,7 @@ cargo_src_install() {
cargo_src_test() {
debug-print-function ${FUNCNAME} "$@"
- set -- cargo test $(usex debug "" --release) ${ECARGO_ARGS[@]} "$@"
+ set -- ${CARGO} test $(usex debug "" --release) ${ECARGO_ARGS[@]} "$@"
einfo "${@}"
cargo_env "${@}" || die "cargo test failed"
}
diff --git a/eclass/rust.eclass b/eclass/rust.eclass
new file mode 100644
index 000000000000..ca71c6535061
--- /dev/null
+++ b/eclass/rust.eclass
@@ -0,0 +1,464 @@
+# Copyright 2024 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+# @ECLASS: rust.eclass
+# @MAINTAINER:
+# Matt Jolly <kangie@gentoo.org>
+# @AUTHOR:
+# Matt Jolly <kangie@gentoo.org>
+# @SUPPORTED_EAPIS: 8
+# @BLURB: Utility functions to build against slotted Rust
+# @DESCRIPTION:
+# An eclass to reliably depend on a Rust or Rust/LLVM combination for
+# a given Rust slot. To use the eclass:
+#
+# 1. If required, set RUST_{MAX,MIN}_SLOT to the range of supported slots.
+# 2. If rust is optional, set RUST_OPTIONAL to a non-empty value then
+# appropriately gate ${RUST_DEPEND}
+# 3. Use rust_pkg_setup, get_rust_prefix or RUST_SLOT.
+
+# Example use for a package supporting Rust 1.72.0 to 1.82.0:
+# @CODE
+#
+# RUST_MAX_VER="1.82.0"
+# RUST_MIN_VER="1.72.0"
+#
+# inherit meson rust
+#
+# # only if you need to define one explicitly
+# pkg_setup() {
+# rust_pkg_setup
+# do-something-else
+# }
+# @CODE
+#
+# Example for a package needing Rust w/ a specific target:
+# @CODE
+# RUST_USEDEP='clippy,${MULTILIB_USEDEP}'
+#
+# inherit multilib-minimal meson rust
+#
+# @CODE
+
+case ${EAPI} in
+ 8) ;;
+ *) die "${ECLASS}: EAPI ${EAPI:-0} not supported" ;;
+esac
+
+if [[ -z ${_RUST_ECLASS} ]]; then
+_RUST_ECLASS=1
+
+if [[ -n ${RUST_NEEDS_LLVM} ]]; then
+ if [[ -z ${_LLVM_R1_ECLASS} ]]; then
+ die "Please inherit llvm-r1.eclass before rust.eclass when using RUST_NEEDS_LLVM"
+ fi
+fi
+
+# == internal control knobs ==
+
+# @ECLASS_VARIABLE: _RUST_LLVM_MAP
+# @INTERNAL
+# @DESCRIPTION:
+# Definitive list of Rust slots and the associated LLVM slot, newest first.
+declare -A -g -r _RUST_LLVM_MAP=(
+ ["1.82.0"]=19
+ ["1.81.0"]=18
+ ["1.80.1"]=18
+ ["1.79.0"]=18
+ ["1.77.1"]=17
+ ["1.75.0"]=17
+ ["1.74.1"]=17
+ ["1.71.1"]=16
+)
+
+# @ECLASS_VARIABLE: _RUST_SLOTS_ORDERED
+# @INTERNAL
+# @DESCRIPTION:
+# Array of Rust slots, newest first.
+# While _RUST_LLVM_MAP stores useful info about the relationship between Rust and LLVM slots,
+# this array is used to store the Rust slots in a more convenient order for iteration.
+declare -a -g -r _RUST_SLOTS_ORDERED=(
+ "1.82.0"
+ "1.81.0"
+ "1.80.1"
+ "1.79.0"
+ "1.77.1"
+ "1.75.0"
+ "1.74.1"
+ "1.71.1"
+)
+
+# == control variables ==
+
+# @ECLASS_VARIABLE: RUST_MAX_VER
+# @DEFAULT_UNSET
+# @DESCRIPTION:
+# Highest Rust slot supported by the package. Needs to be set before
+# rust_pkg_setup is called. If unset, no upper bound is assumed.
+
+# @ECLASS_VARIABLE: RUST_MIN_VER
+# @DEFAULT_UNSET
+# @DESCRIPTION:
+# Lowest Rust slot supported by the package. Needs to be set before
+# rust_pkg_setup is called. If unset, no lower bound is assumed.
+
+# @eclass-variable: RUST_NEEDS_LLVM
+# @DEFAULT_UNSET
+# @DESCRIPTION:
+# If set to a non-empty value generate a llvm_slot_${llvm_slot}? gated
+# dependency block for rust slots in LLVM_COMPAT. This is useful for
+# packages that need a tight coupling between Rust and LLVM but don't
+# really care _which_ version of Rust is selected. Combine with
+# RUST_MAX_VER and RUST_MIN_VER to limit the range of Rust versions
+# that are acceptable. Will `die` if llvm-r1 is not inherited or
+# an invalid combination of RUST and LLVM slots is detected; this probably
+# means that a LLVM slot in LLVM_COMPAT has had all of its Rust slots filtered.
+
+# @ECLASS_VARIABLE: RUST_DEPEND
+# @OUTPUT_VARIABLE
+# @DESCRIPTION:
+# This is an eclass-generated Rust dependency string, filtered by
+# RUST_MAX_VER and RUST_MIN_VER. If RUST_NEEDS_LLVM is set, this
+# is gropeda and gated by an appropriate `llvm_slot_x` USE for all
+# implementations listed in LLVM_COMPAT.
+
+# @ECLASS_VARIABLE: RUST_OPTIONAL
+# @DEFAULT_UNSET
+# @DESCRIPTION:
+# If set to a non-empty value, the Rust dependency will not be added
+# to BDEPEND. This is useful for where packages need to gate rust behind
+# certain USE themselves.
+
+# @ECLASS_VARIABLE: RUST_USEDEP
+# @DEFAULT_UNSET
+# @DESCRIPTION:
+# Additional USE-dependencies to be added to the Rust dependency.
+# This is useful for packages that need to depend on specific Rust
+# features, like clippy or rustfmt. The variable is expanded before
+# being used in the Rust dependency.
+
+# == global metadata ==
+
+_rust_set_globals() {
+ debug-print-function ${FUNCNAME} "$@"
+
+ # If RUST_MIN_VER is older than our oldest slot we'll just set it to that
+ # internally so we don't have to worry about it later.
+ if ver_test "${_RUST_SLOTS_ORDERED[-1]}" -gt "${RUST_MIN_VER:-0}"; then
+ RUST_MIN_VER="${_RUST_SLOTS_ORDERED[-1]}"
+ fi
+
+ # and if it falls between slots we'll set it to the next highest slot
+ # We can skip this we match a slot exactly.
+ if ! [[ "${_RUST_SLOTS_ORDERED[@]}" == *"${RUST_MIN_VER}"* ]]; then
+ local i
+ for (( i=${#_RUST_SLOTS_ORDERED[@]}-1 ; i>=0 ; i-- )); do
+ if ver_test "${_RUST_SLOTS_ORDERED[$i]}" -gt "${RUST_MIN_VER}"; then
+ RUST_MIN_VER="${_RUST_SLOTS_ORDERED[$i]}"
+ break
+ fi
+ done
+ fi
+
+ if [[ -n "${RUST_MAX_VER}" && -n "${RUST_MIN_VER}" ]]; then
+ if ! ver_test "${RUST_MAX_VER}" -ge "${RUST_MIN_VER}"; then
+ die "RUST_MAX_VER must not be older than RUST_MIN_VER"
+ fi
+ fi
+
+ local slot
+ # Try to keep this in order of newest to oldest
+ for slot in "${_RUST_SLOTS_ORDERED[@]}"; do
+ if ver_test "${slot}" -le "${RUST_MAX_VER:-9999}" && \
+ ver_test "${slot}" -ge "${RUST_MIN_VER:-0}"; then
+ _RUST_SLOTS+=( "${slot}" )
+ fi
+ done
+
+ _RUST_SLOTS=( "${_RUST_SLOTS[@]}" )
+
+ # We may have been passed a variable like ${MULTILIB_USEDEP}; expand it.
+ if [[ -n "${RUST_USEDEP}" ]]; then
+ eval $(echo RUST_USEDEP="${RUST_USEDEP}")
+ [[ -z "${RUST_USEDEP}" ]] && die "When evaluated, RUST_USEDEP is empty"
+ fi
+
+ readonly _RUST_SLOTS
+
+ local rust_dep=()
+ local llvm_slot
+ local rust_slot
+ local usedep
+
+ # If we're not using LLVM, we can just generate a simple Rust dependency
+ if [[ -z "${RUST_NEEDS_LLVM}" ]]; then
+ rust_dep=( "|| (" )
+ for slot in "${_RUST_SLOTS[@]}"; do
+ usedep="${RUST_USEDEP+[${RUST_USEDEP}]}"
+ rust_dep+=(
+ "dev-lang/rust-bin:${slot}${usedep}"
+ "dev-lang/rust:${slot}${usedep}"
+ )
+ done
+ rust_dep+=( ")" )
+ RUST_DEPEND="${rust_dep[*]}"
+ else
+ for llvm_slot in "${LLVM_COMPAT[@]}"; do
+ # Quick sanity check to make sure that the llvm slot is valid for Rust.
+ if [[ "${_RUST_LLVM_MAP[@]}" == *"${llvm_slot}"* ]]; then
+ # We're working a bit backwards here; iterate over _RUST_LLVM_MAP, check the
+ # LLVM slot, and if it matches add this to a new array because it may (and likely will)
+ # match multiple Rust slots. We already filtered Rust max/min slots.
+ # We always have a usedep for the LLVM slot, append `,RUST_USEDEP` if it's set
+ usedep="[llvm_slot_${llvm_slot}${RUST_USEDEP+,${RUST_USEDEP}}]"
+ local slot_dep_content=()
+ for rust_slot in "${_RUST_SLOTS[@]}"; do
+ if [[ "${_RUST_LLVM_MAP[${rust_slot}]}" == "${llvm_slot}" ]]; then
+ slot_dep_content+=(
+ "dev-lang/rust-bin:${rust_slot}${usedep}"
+ "dev-lang/rust:${rust_slot}${usedep}"
+ )
+ fi
+ done
+ if [ ${#slot_dep_content[@]} -ne 0 ]; then
+ rust_dep+=( "llvm_slot_${llvm_slot}? ( || ( ${slot_dep_content[*]} ) )" )
+ else
+ die "${FUNCNAME}: no Rust slots found for LLVM slot ${llvm_slot}"
+ fi
+ fi
+ done
+ RUST_DEPEND="${rust_dep[*]}"
+ fi
+
+ readonly RUST_DEPEND
+ if [[ -z ${RUST_OPTIONAL} ]]; then
+ BDEPEND="${RUST_DEPEND}"
+ fi
+}
+_rust_set_globals
+unset -f _rust_set_globals
+
+# == ebuild helpers ==
+
+# @FUNCTION: get_rust_slot
+# @USAGE: [-b|-d]
+# @DESCRIPTION:
+# Find the newest Rust install that is acceptable for the package,
+# and print its version number (i.e. SLOT) and type (source or bin[ary]).
+#
+# If -b is specified, the checks are performed relative to BROOT,
+# and BROOT-path is returned.
+#
+# If -d is specified, the checks are performed relative to ESYSROOT,
+# and ESYSROOT-path is returned. -d is the default.
+#
+# If RUST_M{AX,IN}_SLOT is non-zero, then only Rust versions that
+# are not newer or older than the specified slot(s) will be considered.
+# Otherwise, all Rust versions are be considered acceptable.
+#
+# If the `rust_check_deps()` function is defined within the ebuild, it
+# will be called to verify whether a particular slot is accepable.
+# Within the function scope, RUST_SLOT and LLVM_SLOT will be defined.
+#
+# The function should return a true status if the slot is acceptable,
+# false otherwise. If rust_check_deps() is not defined, the function
+# defaults to checking whether a suitable Rust package is installed.
+get_rust_slot() {
+ debug-print-function ${FUNCNAME} "$@"
+
+ local hv_switch=-d
+ while [[ ${1} == -* ]]; do
+ case ${1} in
+ -b|-d) hv_switch="${1}";;
+ *) break;;
+ esac
+ shift
+ done
+
+ local max_slot
+ if [[ -z "${RUST_MAX_VER}" ]]; then
+ max_slot=
+ else
+ max_slot="${RUST_MAX_VER}"
+ fi
+ local slot
+ local llvm_slot
+
+ if [[ -n "${RUST_NEEDS_LLVM}" ]]; then
+ local unique_slots=()
+ local llvm_r1_slot
+ # Associative array keys are unique, so let's use that to our advantage
+ for llvm_slot in "${_RUST_LLVM_MAP[@]}"; do
+ unique_slots["${llvm_slot}"]="1"
+ done
+ for llvm_slot in "${!unique_slots[@]}"; do
+ if [[ "${LLVM_COMPAT[@]}" == *"${llvm_slot}"* ]]; then
+ # We can check for the USE
+ use "llvm_slot_${llvm_slot}" && llvm_r1_slot="${llvm_slot}"
+ else
+ continue
+ fi
+ done
+ if [[ -z "${llvm_r1_slot}" ]]; then
+ die "${FUNCNAME}: no LLVM slot found"
+ fi
+ fi
+
+ # iterate over known slots, newest first
+ for slot in "${_RUST_SLOTS_ORDERED[@]}"; do
+ llvm_slot="${_RUST_LLVM_MAP[${slot}]}"
+ # skip higher slots
+ if [[ -n "${max_slot}" ]]; then
+ if ver_test "${slot}" -eq "${max_slot}"; then
+ max_slot=
+ elif ver_test "${slot}" -gt "${max_slot}"; then
+ continue
+ fi
+ fi
+
+ # If we're in LLVM mode we can skip any slots that don't match the selected USE
+ if [[ -n "${RUST_NEEDS_LLVM}" ]]; then
+ if [[ "${llvm_slot}" != "${llvm_r1_slot}" ]]; then
+ continue
+ fi
+ fi
+
+ if declare -f rust_check_deps >/dev/null; then
+ local RUST_SLOT="${slot}"
+ local LLVM_SLOT="${_RUST_LLVM_MAP[${slot}]}"
+ rust_check_deps && return
+ else
+ local rust_usedep="${RUST_USEDEP+[${RUST_USEDEP}]}"
+ # When checking for installed packages prefer the non `-bin` package
+ # if effort was put into building it we should use it.
+ local rust_pkgs=(
+ "dev-lang/rust:${slot}${rust_usedep}"
+ "dev-lang/rust-bin:${slot}${rust_usedep}"
+ )
+ local _pkg
+ for _pkg in "${rust_pkgs[@]}"
+ do
+ if has_version "${hv_switch}" "${_pkg}"; then
+ echo "${slot}"
+ if [[ "${_pkg}" == "dev-lang/rust:${slot}${rust_usedep}" ]]; then
+ echo source
+ else
+ echo binary
+ fi
+ return
+ fi
+ done
+ fi
+
+ # We want to process the slot before escaping the loop if we've hit the minimum slot
+ if ver_test "${slot}" -eq "${RUST_MIN_VER}"; then
+ break
+ fi
+
+ done
+
+ # max_slot should have been unset in the iteration
+ if [[ -n "${max_slot}" ]]; then
+ die "${FUNCNAME}: invalid max_slot=${max_slot}"
+ fi
+
+ die "No Rust slot${1:+ <= ${1}} satisfying the package's dependencies found installed!"
+}
+
+# @FUNCTION: get_rust_path
+# @USAGE: prefix slot rust_type
+# @DESCRIPTION:
+# Given argument of slot and rust_type, return an appropriate path
+# for the Rust install. The rust_type should be either "source"
+# or "binary". If the rust_type is not one of these, the function
+# will die.
+get_rust_path() {
+ debug-print-function ${FUNCNAME} "$@"
+
+ local prefix="${1}"
+ local slot="${2}"
+ local rust_type="${3}"
+
+ if [[ ${#} -ne 3 ]]; then
+ die "${FUNCNAME}: invalid number of arguments"
+ fi
+
+ if [[ "${rust_type}" != "source" && "${rust_type}" != "binary" ]]; then
+ die "${FUNCNAME}: invalid rust_type=${rust_type}"
+ fi
+
+ if [[ "${rust_type}" == "source" ]]; then
+ echo "${prefix}/usr/lib/rust/${slot}/"
+ else
+ echo "${prefix}/opt/rust-bin-${slot}/"
+ fi
+}
+
+# @FUNCTION: get_rust_prefix
+# @USAGE: [-b|-d]
+# @DESCRIPTION:
+# Find the newest Rust install that is acceptable for the package,
+# and print an absolute path to it. If both -bin and regular Rust
+# are installed, the regular Rust is preferred.
+#
+# The options and behavior are the same as get_rust_slot.
+get_rust_prefix() {
+ debug-print-function ${FUNCNAME} "$@"
+
+ local prefix=${BROOT}
+ [[ ${1} == -d ]] && prefix=${ESYSROOT}
+
+ local slot rust_type
+ { read -r slot; read -r rust_type; } <<< $(get_rust_slot)
+ echo $(get_rust_path "${prefix}" "${slot}" "${rust_type}")
+}
+
+# @FUNCTION: rust_prepend_path
+# @USAGE: <slot> <type>
+# @DESCRIPTION:
+# Prepend the path to the specified Rust to PATH and re-export it.
+rust_prepend_path() {
+ debug-print-function ${FUNCNAME} "$@"
+
+ [[ ${#} -ne 2 ]] && die "Usage: ${FUNCNAME} <slot> <type>"
+ local slot="${1}"
+ local type="${2}"
+ export PATH="$(get_rust_path "${BROOT}" "${slot}" "${type}")/bin:${PATH}"
+}
+
+# @FUNCTION: rust_pkg_setup
+# @DESCRIPTION:
+# Prepend the appropriate executable directory for the newest
+# acceptable Rust slot to the PATH. If used with LLVM, an appropriate
+# `llvm_pkg_setup` call should be made in addition to this function.
+# For path determination logic, please see the get_rust_prefix documentation.
+#
+# The highest acceptable Rust slot can be set in RUST_MAX_VER variable.
+# If it is unset or empty, any slot is acceptable.
+#
+# The lowest acceptable Rust slot can be set in RUST_MIN_VER variable.
+# If it is unset or empty, any slot is acceptable.
+#
+# `CARGO` and `RUSTC` variables are set for the selected slot and exported.
+#
+# The PATH manipulation is only done for source builds. The function
+# is a no-op when installing a binary package.
+#
+# If any other behavior is desired, the contents of the function
+# should be inlined into the ebuild and modified as necessary.
+rust_pkg_setup() {
+ debug-print-function ${FUNCNAME} "$@"
+
+ if [[ ${MERGE_TYPE} != binary ]]; then
+ { read -r RUST_SLOT; read -r RUST_TYPE; } <<< $(get_rust_slot)
+ rust_prepend_path "${RUST_SLOT}" "${RUST_TYPE}"
+ CARGO="$(get_rust_prefix)bin/cargo"
+ RUSTC="$(get_rust_prefix)bin/rustc"
+ export CARGO RUSTC
+ einfo "Using Rust ${RUST_SLOT} (${RUST_TYPE})"
+ fi
+}
+
+fi
+
+EXPORT_FUNCTIONS pkg_setup
diff --git a/eclass/toolchain.eclass b/eclass/toolchain.eclass
index b25c5dcf0929..4d5973bb4959 100644
--- a/eclass/toolchain.eclass
+++ b/eclass/toolchain.eclass
@@ -14,6 +14,8 @@
if [[ -z ${_TOOLCHAIN_ECLASS} ]]; then
_TOOLCHAIN_ECLASS=1
+RUST_OPTIONAL="1"
+
case ${EAPI} in
7|8) ;;
*) die "${ECLASS}: EAPI ${EAPI:-0} not supported" ;;
@@ -22,7 +24,7 @@ esac
DESCRIPTION="The GNU Compiler Collection"
HOMEPAGE="https://gcc.gnu.org/"
-inherit edo flag-o-matic gnuconfig libtool multilib pax-utils toolchain-funcs prefix
+inherit edo flag-o-matic gnuconfig libtool multilib pax-utils rust toolchain-funcs prefix
[[ -n ${TOOLCHAIN_HAS_TESTS} ]] && inherit python-any-r1
@@ -427,7 +429,7 @@ fi
if tc_has_feature rust && tc_version_is_at_least 14.0.0_pre20230421 ; then
# This was added upstream in r14-9968-g3e1e73fc995844 as a temporary measure.
# See https://inbox.sourceware.org/gcc/34fec7ea-8762-4cac-a1c8-ff54e20e31ed@embecosm.com/
- BDEPEND+=" rust? ( virtual/rust )"
+ BDEPEND+=" rust? ( ${RUST_DEPEND} )"
fi
PDEPEND=">=sys-devel/gcc-config-2.11"
@@ -593,6 +595,8 @@ toolchain_pkg_setup() {
MAKEOPTS="--output-sync=line ${MAKEOPTS}"
[[ -n ${TOOLCHAIN_HAS_TESTS} ]] && use test && python-any-r1_pkg_setup
+
+ _tc_use_if_iuse rust && rust_pkg_setup
}
#---->> src_unpack <<----