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 33508159C96 for ; Wed, 24 Jul 2024 22:08:41 +0000 (UTC) Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id A8816E2AB9; Wed, 24 Jul 2024 22:08:14 +0000 (UTC) Received: from smtp.gentoo.org (dev.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 4A84CE2AB6 for ; Wed, 24 Jul 2024 22:08:14 +0000 (UTC) From: James Le Cuirot To: gentoo-dev Cc: James Le Cuirot Subject: [gentoo-dev] [PATCH 2/3] cargo.eclass: Handle LDFLAGS and RUSTFLAGS better Date: Wed, 24 Jul 2024 23:07:56 +0100 Message-ID: <20240724220800.16994-2-chewi@gentoo.org> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240724220800.16994-1-chewi@gentoo.org> References: <20240724220800.16994-1-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: c71aacb1-e880-42cf-848e-1972d2317362 X-Archives-Hash: 73a31393de608ea3a7a37b0fdef8663e 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 | 47 ++++++++++++++++++++++++++++++++------------- 1 file changed, 34 insertions(+), 13 deletions(-) diff --git a/eclass/cargo.eclass b/eclass/cargo.eclass index b6d5fe21f0a7b..65eaee6f84e4b 100644 --- a/eclass/cargo.eclass +++ b/eclass/cargo.eclass @@ -527,27 +527,48 @@ 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="-C linker=${LD_A[0]}" + [[ ${#LD_A[@]} -gt 1 ]] && declare CARGO_BUILD_RUSTFLAGS+="$(printf -- ' -C link-arg=%s' "${LD_A[@]:1}")" + declare CARGO_BUILD_RUSTFLAGS+=" ${RUSTFLAGS} ${CARGO_BUILD_RUSTFLAGS}" + 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="-C linker=${LD_A[0]}" + [[ ${#LD_A[@]} -gt 1 ]] && declare CARGO_TARGET_"${TRIPLE^^}"_RUSTFLAGS+="$(printf -- ' -C link-arg=%s' "${LD_A[@]:1}")" + declare CARGO_TARGET_"${TRIPLE^^}"_RUSTFLAGS+=" ${RUSTFLAGS} ${CARGO_TARGET_RUSTFLAGS}" + 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