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 7DC7D159C96 for ; Wed, 24 Jul 2024 22:19:46 +0000 (UTC) Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id 1D649E2AC7; Wed, 24 Jul 2024 22:19:36 +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)) (No client certificate requested) by pigeon.gentoo.org (Postfix) with ESMTPS id B96C4E2AC4 for ; Wed, 24 Jul 2024 22:19:35 +0000 (UTC) From: James Le Cuirot To: gentoo-dev Cc: James Le Cuirot Subject: [gentoo-dev] [PATCH 2/3 v2] cargo.eclass: Handle LDFLAGS and RUSTFLAGS better Date: Wed, 24 Jul 2024 23:18:25 +0100 Message-ID: <20240724221830.31469-5-chewi@gentoo.org> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240724221830.31469-3-chewi@gentoo.org> References: <20240724221830.31469-3-chewi@gentoo.org> Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-dev@lists.gentoo.org Reply-to: gentoo-dev@lists.gentoo.org X-Auto-Response-Suppress: DR, RN, NRN, OOF, AutoReply MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Archives-Salt: ac8f5ce2-9d48-4eb6-83a3-37aeb6007ebe X-Archives-Hash: 244597e1f7d4daaed80d940dd4788965 LDFLAGS are not currently honoured by Cargo builds at all. It would be particularly advantageous to honour -fuse-ld because alternative linkers like mold are known to be significantly faster at handling Rust. As things stand, the eclass sets the linker to CC when cross-compiling, but it does so erroneously due to a shell quoting issue. If CC includes arguments, an error occurs when setting the CARGO_TARGET_*_LINKER variable. Even with the right quoting, Cargo still fails because this variable is not allowed to include arguments. They have to be specified via RUSTFLAGS instead. We would also like to configure the build host linker properly when cross-compiling, but strangely there is no equivalent linker variable for the build host. It can only be set via RUSTFLAGS. For consistency, we now use RUSTFLAGS for the target host linker as well. Some ebuilds already set RUSTFLAGS, so some consideration was given to how to handle these. When set, Cargo prioritises RUSTFLAGS over CARGO_BUILD_RUSTFLAGS and CARGO_TARGET_*_RUSTFLAGS, so we need it unset to allow different flags for the build and target hosts. We can still include its contents in the latter variables for convenience though. It should not be necessary for ebuilds to figure out which Rust ABI is applicable in order to set flags only for the target host, so the helper reads from a simple CARGO_TARGET_RUSTFLAGS variable without the triple for convenience. Unfortunately, I have not yet encountered a package that makes use of CARGO_BUILD_RUSTFLAGS while cross-compiling, but as far as I can tell, it should work. Signed-off-by: James Le Cuirot --- eclass/cargo.eclass | 45 ++++++++++++++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 13 deletions(-) diff --git a/eclass/cargo.eclass b/eclass/cargo.eclass index b6d5fe21f0a7b..9ccd482e6b2d1 100644 --- a/eclass/cargo.eclass +++ b/eclass/cargo.eclass @@ -527,27 +527,46 @@ 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. +# Cargo such as building. RUSTFLAGS is used for both the build and target host. +# CARGO_BUILD_RUSTFLAGS and CARGO_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_env() { filter-lto tc-export AR CC CXX PKG_CONFIG + # Set vars for cc-rs crate. + tc-export_build_env + declare -x \ + HOST_AR=$(tc-getBUILD_AR) + HOST_CC=$(tc-getBUILD_CC) + HOST_CXX=$(tc-getBUILD_CXX) + HOST_CFLAGS=${BUILD_CFLAGS} + HOST_CXXFLAGS=${BUILD_CXXFLAGS} + + # 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. + local LD_A=( ${HOST_CC} ${BUILD_LDFLAGS} ) + declare -x CARGO_BUILD_RUSTFLAGS="${RUSTFLAGS} ${CARGO_BUILD_RUSTFLAGS} -C linker=${LD_A[0]}" + [[ ${#LD_A[@]} -gt 1 ]] && declare CARGO_BUILD_RUSTFLAGS+="$(printf -- ' -C link-arg=%s' "${LD_A[@]:1}")" + if tc-is-cross-compiler; then declare -x CARGO_BUILD_TARGET=$(rust_abi) - local TRIPLE=${CARGO_BUILD_TARGET//-/_} - declare -x CARGO_TARGET_"${TRIPLE^^}"_LINKER=$(tc-getCC) - - # Set vars for cc-rs crate. - tc-export_build_env - declare -x \ - HOST_AR=$(tc-getBUILD_AR) - HOST_CC=$(tc-getBUILD_CC) - HOST_CXX=$(tc-getBUILD_CXX) - HOST_CFLAGS=${BUILD_CFLAGS} - HOST_CXXFLAGS=${BUILD_CXXFLAGS} + local TRIPLE=${CARGO_BUILD_TARGET//-/_} LD_A=( $(tc-getCC) ${LDFLAGS} ) + declare -x CARGO_TARGET_"${TRIPLE^^}"_RUSTFLAGS="${RUSTFLAGS} ${CARGO_TARGET_RUSTFLAGS} -C linker=${LD_A[0]}" + [[ ${#LD_A[@]} -gt 1 ]] && declare CARGO_TARGET_"${TRIPLE^^}"_RUSTFLAGS+="$(printf -- ' -C link-arg=%s' "${LD_A[@]:1}")" + else + CARGO_BUILD_RUSTFLAGS+=" ${CARGO_TARGET_RUSTFLAGS}" fi - "${@}" + ( + # Bare RUSTFLAGS will override the above, even if empty, so unset it + # locally. Do this in a subshell so that it remains set afterwards. + unset RUSTFLAGS + + "${@}" + ) } # @FUNCTION: cargo_src_compile -- 2.45.2