cargo.eclass: Sync with Gentoo

Signed-off-by: James Le Cuirot <jlecuirot@microsoft.com>
This commit is contained in:
James Le Cuirot 2024-07-25 09:26:53 +01:00
parent 626866adfa
commit d59e1a4eb6
No known key found for this signature in database
GPG Key ID: 1226415D00DD3137

View File

@ -109,7 +109,7 @@ ECARGO_VENDOR="${ECARGO_HOME}/gentoo"
#
# 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 of this eclass.
# other src_functions or cargo_env of this eclass.
# Note that cargo_gen_config is automatically called by cargo_src_unpack.
# @ECLASS_VARIABLE: myfeatures
@ -248,7 +248,7 @@ cargo_crate_uris() {
# @FUNCTION: cargo_gen_config
# @DESCRIPTION:
# Generate the $CARGO_HOME/config necessary to use our local registry and settings.
# Generate the $CARGO_HOME/config.toml necessary to use our local registry and settings.
# Cargo can also be configured through environment variables in addition to the TOML syntax below.
# For each configuration key below of the form foo.bar the environment variable CARGO_FOO_BAR
# can also be used to define the value.
@ -261,7 +261,7 @@ cargo_gen_config() {
mkdir -p "${ECARGO_HOME}" || die
cat > "${ECARGO_HOME}/config" <<- _EOF_ || die "Failed to create cargo config"
cat > "${ECARGO_HOME}/config.toml" <<- _EOF_ || die "Failed to create cargo config"
[source.gentoo]
directory = "${ECARGO_VENDOR}"
@ -324,9 +324,7 @@ _cargo_gen_git_config() {
# Return the directory within target that contains the build, e.g.
# target/aarch64-unknown-linux-gnu/release.
cargo_target_dir() {
local abi
tc-is-cross-compiler && abi=/$(rust_abi)
echo "${CARGO_TARGET_DIR:-target}${abi}/$(usex debug debug release)"
echo "${CARGO_TARGET_DIR:-target}/$(rust_abi)/$(usex debug debug release)"
}
# @FUNCTION: cargo_src_unpack
@ -523,36 +521,92 @@ cargo_src_configure() {
[[ ${ECARGO_ARGS[@]} ]] && einfo "Configured with: ${ECARGO_ARGS[@]}"
}
# @FUNCTION: cargo_env
# @USAGE: Command with its arguments
# @DESCRIPTION:
# Run the given command under an environment needed for performing tasks with
# Cargo such as building. RUSTFLAGS are appended to additional flags set here.
# Ensure these are set consistently between Cargo invocations, otherwise
# rebuilds will occur. Project-specific rustflags set against [build] will not
# take affect due to Cargo limitations, so add these to your ebuild's RUSTFLAGS
# if they seem important.
cargo_env() {
[[ ${_CARGO_GEN_CONFIG_HAS_RUN} ]] || \
die "FATAL: please call cargo_gen_config before using ${FUNCNAME}"
# Shadow flag variables so that filtering below remains local.
local flag
for flag in $(all-flag-vars); do
local -x "${flag}=${!flag}"
done
# Rust extensions are incompatible with C/C++ LTO compiler see e.g.
# https://bugs.gentoo.org/910220
filter-lto
tc-export AR CC CXX PKG_CONFIG
# Set vars for cc-rs crate.
local -x \
HOST_AR=$(tc-getBUILD_AR)
HOST_CC=$(tc-getBUILD_CC)
HOST_CXX=$(tc-getBUILD_CXX)
HOST_CFLAGS=${BUILD_CFLAGS}
HOST_CXXFLAGS=${BUILD_CXXFLAGS}
# Unfortunately, Cargo is *really* bad at handling flags. In short, it uses
# the first of the RUSTFLAGS env var, any target-specific config, and then
# any generic [build] config. It can merge within the latter two types from
# different sources, but it will not merge across these different types, so
# if a project sets flags under [target.'cfg(all())'], it will override any
# flags we set under [build] and vice-versa.
#
# It has been common for users and ebuilds to set RUSTFLAGS, which would
# have overridden whatever a project sets anyway, so the least-worst option
# is to include those RUSTFLAGS in target-specific config here, which will
# merge with any the project sets. Only flags in generic [build] config set
# by the project will be lost, and ebuilds will need to add those to
# RUSTFLAGS themselves if they are important.
#
# We could potentially inspect a project's generic [build] config and
# reapply those flags ourselves, but that would require a proper toml parser
# like tomlq, it might lead to confusion where projects also have
# target-specific config, and converting arrays to strings may not work
# well. Nightly features to inspect the config might help here in future.
#
# As of Rust 1.80, it is not possible to set separate flags for the build
# host and the target host when cross-compiling. The flags given are applied
# to the target host only with no flags being applied to the build host. The
# nightly host-config feature will improve this situation later.
#
# The default linker is "cc" so override by setting linker to CC in the
# RUSTFLAGS. The given linker cannot include any arguments, so split these
# into link-args along with LDFLAGS.
local -x CARGO_BUILD_TARGET=$(rust_abi)
local TRIPLE=${CARGO_BUILD_TARGET//-/_}
local TRIPLE=${TRIPLE^^} LD_A=( $(tc-getCC) ${LDFLAGS} )
local -x CARGO_TARGET_"${TRIPLE}"_RUSTFLAGS="-C strip=none -C linker=${LD_A[0]}"
[[ ${#LD_A[@]} -gt 1 ]] && local CARGO_TARGET_"${TRIPLE}"_RUSTFLAGS+="$(printf -- ' -C link-arg=%s' "${LD_A[@]:1}")"
local CARGO_TARGET_"${TRIPLE}"_RUSTFLAGS+=" ${RUSTFLAGS}"
(
# These variables will override the above, even if empty, so unset them
# locally. Do this in a subshell so that they remain set afterwards.
unset CARGO_BUILD_RUSTFLAGS CARGO_ENCODED_RUSTFLAGS RUSTFLAGS
"${@}"
)
}
# @FUNCTION: cargo_src_compile
# @DESCRIPTION:
# Build the package using cargo build.
cargo_src_compile() {
debug-print-function ${FUNCNAME} "$@"
[[ ${_CARGO_GEN_CONFIG_HAS_RUN} ]] || \
die "FATAL: please call cargo_gen_config before using ${FUNCNAME}"
filter-lto
tc-export AR CC CXX PKG_CONFIG
if tc-is-cross-compiler; then
export CARGO_BUILD_TARGET=$(rust_abi)
local TRIPLE=${CARGO_BUILD_TARGET//-/_}
export CARGO_TARGET_"${TRIPLE^^}"_LINKER=$(tc-getCC)
# Set vars for cc-rs crate.
tc-export_build_env
export \
HOST_AR=$(tc-getBUILD_AR)
HOST_CC=$(tc-getBUILD_CC)
HOST_CXX=$(tc-getBUILD_CXX)
HOST_CFLAGS=${BUILD_CFLAGS}
HOST_CXXFLAGS=${BUILD_CXXFLAGS}
fi
set -- cargo build $(usex debug "" --release) ${ECARGO_ARGS[@]} "$@"
einfo "${@}"
"${@}" || die "cargo build failed"
cargo_env "${@}" || die "cargo build failed"
}
# @FUNCTION: cargo_src_install
@ -564,16 +618,13 @@ cargo_src_compile() {
cargo_src_install() {
debug-print-function ${FUNCNAME} "$@"
[[ ${_CARGO_GEN_CONFIG_HAS_RUN} ]] || \
die "FATAL: please call cargo_gen_config before using ${FUNCNAME}"
set -- cargo install $(has --path ${@} || echo --path ./) \
--root "${ED}/usr" \
${GIT_CRATES[@]:+--frozen} \
$(usex debug --debug "") \
${ECARGO_ARGS[@]} "$@"
einfo "${@}"
"${@}" || die "cargo install failed"
cargo_env "${@}" || die "cargo install failed"
rm -f "${ED}/usr/.crates.toml" || die
rm -f "${ED}/usr/.crates2.json" || die
@ -585,12 +636,9 @@ cargo_src_install() {
cargo_src_test() {
debug-print-function ${FUNCNAME} "$@"
[[ ${_CARGO_GEN_CONFIG_HAS_RUN} ]] || \
die "FATAL: please call cargo_gen_config before using ${FUNCNAME}"
set -- cargo test $(usex debug "" --release) ${ECARGO_ARGS[@]} "$@"
einfo "${@}"
"${@}" || die "cargo test failed"
cargo_env "${@}" || die "cargo test failed"
}
fi