From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from lists.gentoo.org (pigeon.gentoo.org [208.92.234.80]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by finch.gentoo.org (Postfix) with ESMTPS id C05D7159C9B for ; Thu, 8 Aug 2024 09:00:55 +0000 (UTC) Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id EF921E2C7B; Thu, 8 Aug 2024 09:00:54 +0000 (UTC) Received: from smtp.gentoo.org (woodpecker.gentoo.org [IPv6:2001:470:ea4a:1:5054:ff:fec7:86e4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by pigeon.gentoo.org (Postfix) with ESMTPS id CBEFAE2C7B for ; Thu, 8 Aug 2024 09:00:54 +0000 (UTC) Received: from oystercatcher.gentoo.org (oystercatcher.gentoo.org [148.251.78.52]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by smtp.gentoo.org (Postfix) with ESMTPS id A82EF34308C for ; Thu, 8 Aug 2024 09:00:53 +0000 (UTC) Received: from localhost.localdomain (localhost [IPv6:::1]) by oystercatcher.gentoo.org (Postfix) with ESMTP id 0FBC31B9A for ; Thu, 8 Aug 2024 09:00:52 +0000 (UTC) From: "James Le Cuirot" To: gentoo-commits@lists.gentoo.org Content-Transfer-Encoding: 8bit Content-type: text/plain; charset=UTF-8 Reply-To: gentoo-dev@lists.gentoo.org, "James Le Cuirot" Message-ID: <1723107608.27d469a2114b4ad0b3e682854c50c806753eb472.chewi@gentoo> Subject: [gentoo-commits] repo/gentoo:master commit in: eclass/ X-VCS-Repository: repo/gentoo X-VCS-Files: eclass/cargo.eclass X-VCS-Directories: eclass/ X-VCS-Committer: chewi X-VCS-Committer-Name: James Le Cuirot X-VCS-Revision: 27d469a2114b4ad0b3e682854c50c806753eb472 X-VCS-Branch: master Date: Thu, 8 Aug 2024 09:00:52 +0000 (UTC) Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-commits@lists.gentoo.org X-Auto-Response-Suppress: DR, RN, NRN, OOF, AutoReply X-Archives-Salt: b3f73cb5-e3ee-42be-b835-d016bec1d8ba X-Archives-Hash: f7e5da86849e55f388a891f02102ae0e commit: 27d469a2114b4ad0b3e682854c50c806753eb472 Author: James Le Cuirot gentoo org> AuthorDate: Wed Aug 7 14:27:36 2024 +0000 Commit: James Le Cuirot gentoo org> CommitDate: Thu Aug 8 09:00:08 2024 +0000 URL: https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=27d469a2 cargo.eclass: Change RUSTFLAGS approach following recent build failures Cargo turned out to be even worse at handling flags than I thought. Target-specific flags set by projects were overriding our own, and Cargo was bailing out when faced with merging a string of flags with an array of flags. After weighing up the poor set of options, I've found that it is better to always set flags via a target-specific environment variable for reasons set out in comments added here. This approach was previously just used for cross-compiling, but now we do it unconditionally. It has the downside of overriding generic [build] flags set by projects, but these were already being overridden by users and ebuilds setting RUSTFLAGS themselves. Closes: https://bugs.gentoo.org/937453 Closes: https://bugs.gentoo.org/937470 Signed-off-by: James Le Cuirot gentoo.org> eclass/cargo.eclass | 65 ++++++++++++++++++++++++++++++++--------------------- 1 file changed, 39 insertions(+), 26 deletions(-) diff --git a/eclass/cargo.eclass b/eclass/cargo.eclass index c360c2a6c419..6d4cf1b425eb 100644 --- a/eclass/cargo.eclass +++ b/eclass/cargo.eclass @@ -259,19 +259,6 @@ cargo_crate_uris() { cargo_gen_config() { debug-print-function ${FUNCNAME} "$@" - # 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. Also include external RUSTFLAGS. - # Note that as of Rust 1.80, the build host RUSTFLAGS are ignored when - # cross-compiling unless you use the unstable host-config feature available - # with USE=nightly. There is no simple way around this. - tc-export_build_env - local LD_A=( $(tc-getBUILD_CC) ${BUILD_LDFLAGS} ) - local MY_BUILD_RUSTFLAGS="-C strip=none -C linker=${LD_A[0]}" - [[ ${#LD_A[@]} -gt 1 ]] && MY_BUILD_RUSTFLAGS+="$(printf -- ' -C link-arg=%s' "${LD_A[@]:1}")" - MY_BUILD_RUSTFLAGS+=" ${RUSTFLAGS} ${BUILD_RUSTFLAGS}" - tc-is-cross-compiler || MY_BUILD_RUSTFLAGS+=" ${TARGET_RUSTFLAGS}" - mkdir -p "${ECARGO_HOME}" || die cat > "${ECARGO_HOME}/config.toml" <<- _EOF_ || die "Failed to create cargo config" @@ -286,7 +273,6 @@ cargo_gen_config() { offline = true [build] - rustflags = "${MY_BUILD_RUSTFLAGS}" jobs = $(makeopts_jobs) incremental = false @@ -541,10 +527,11 @@ cargo_src_configure() { # @USAGE: Command with its arguments # @DESCRIPTION: # Run the given command under an environment needed for performing tasks with -# Cargo such as building. RUSTFLAGS is used for both the build and target host. -# BUILD_RUSTFLAGS and TARGET_RUSTFLAGS are used for just the build host and -# target host respectively. Ensure these are set consistently between Cargo -# invocations, otherwise rebuilds will occur. +# 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}" @@ -569,14 +556,40 @@ cargo_env() { HOST_CFLAGS=${BUILD_CFLAGS} HOST_CXXFLAGS=${BUILD_CXXFLAGS} - if tc-is-cross-compiler; then - 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} ${TARGET_RUSTFLAGS}" - fi + # 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