There has been a substantive discussion unfolding at
https://github.com/gentoo/gentoo/pull/43693#pullrequestreview-3194144355 that
has evolved into a more general discussion that Eli suggested should be moved
to this mailing list. Allow me to summarize the issues and findings thus far...
The current state of affairs is as follows:
* multilib_toolchain_setup() in multilib.eclass, when switching to a
non-default ABI, sets the CHOST toolchain variables to the values returned by
the corresponding tc-get_*() functions in toolchain-funcs.eclass, except that
it appends $(get_abi_*FLAGS) where appropriate to switch various tools to the
non-default ABI. Then it overrides CHOST to the value of CHOST_${ABI}. For
example, on an amd64 system, when switching to the x86_32 ABI, CHOST becomes
"i686-pc-linux-gnu". Additionally, in the non-cross-compiling case,
multilib_toolchain_setup() overrides CBUILD to that same value (so that
${CHOST} == ${CBUILD} is still true).
* setup_meson_src_configure() in meson.eclass generates a Meson "native file"
that specifies toolchain tools and flags for the CBUILD machine. In the case of
cross-compiling (i.e., ${CHOST} != ${CBUILD}), it also generates a Meson "cross
file" that specifies toolchain tools and flags for the CHOST machine.
Although the above may seem reasonable at first glance, there are some issues:
* In the case that a build-time helper executable links with a library that is
listed in BDEPEND, the link will fail in a non-default ABI phase if the library
has not been installed for the non-default ABI. There is no way to require
libraries in BDEPEND to be installed for non-default ABIs, as using
${MULTILIB_USEDEP} in BDEPEND would break cross-compiles since the ABI flags
listed in MULTILIB_USEDEP are for the CHOST machine, not the CBUILD machine.
The reasonable answer is that build-time helper executables should only ever be
built for the default ABI.
--- a/eclass/multilib.eclass
+++ b/eclass/multilib.eclass
@@ -526,8 +526,12 @@ multilib_toolchain_setup() {
export _DEFAULT_ABI_SAVED="true"
# Set CBUILD only if not cross-compiling.
+ #
+ # It must use the default ABI since build-time helper
+ # executables might link with libraries that are installed
+ # only for the default ABI.
if [[ ${CBUILD} == "${CHOST}" ]]; then
- export CBUILD=$(get_abi_CHOST $1)
+ export CBUILD=$(get_abi_CHOST ${DEFAULT_ABI})
fi
* The above won't work out of the box, as now tc-is-cross-compiler() will
return true in non-default ABI phases (since ${CHOST} will no longer match
${CBUILD}), and thus the tc-getBUILD_*() functions will no longer fall back on
the CHOST toolchain variables in the case that the CBUILD toolchain variables
are unset. We wouldn't want that anyway, as the CHOST toolchain is being
altered with a non-default ABI flag, but we need the CBUILD toolchain to use
the default ABI. So, let's have multilib_toolchain_setup() set up the CBUILD
toolchain variables as well:
--- a/eclass/multilib.eclass
+++ b/eclass/multilib.eclass
@@ -487,6 +487,17 @@ multilib_toolchain_setup() {
local save_restore_variables=(
CBUILD
CHOST
+ BUILD_AR
+ BUILD_CC
+ BUILD_CXX
+ BUILD_LD
+ BUILD_NM
+ BUILD_OBJCOPY
+ BUILD_PKG_CONFIG
+ BUILD_RANLIB
+ BUILD_READELF
+ BUILD_STRINGS
+ BUILD_STRIP
AR
CC
CXX
@@ -536,6 +551,20 @@ multilib_toolchain_setup() {
# Make sure ${save_restore_variables[@]} list matches below.
export CHOST=$(get_abi_CHOST ${DEFAULT_ABI})
+ # Derive the build-machine toolchain variables before we
+ # override the host-machine toolchain variables.
+ export BUILD_AR="$(tc-getBUILD_AR)" # Avoid 'ar', use
"${CBUILD}-ar"
+ export BUILD_CC="$(tc-getBUILD_CC)" # Default ABI
+ export BUILD_CXX="$(tc-getBUILD_CXX)" # Default ABI
+ export BUILD_LD="$(tc-getBUILD_LD)" # Default ABI
+ export BUILD_NM="$(tc-getBUILD_NM)" # Avoid 'nm', use
"${CBUILD}-nm"
+ export BUILD_OBJCOPY="$(tc-getBUILD_OBJCOPY)" # Avoid
'objcopy', use "${CBUILD}-objcopy"
+ export BUILD_PKG_CONFIG="$(tc-getBUILD_PKG_CONFIG)"
+ export BUILD_RANLIB="$(tc-getBUILD_RANLIB)" # Avoid 'ranlib',
use "${CBUILD}-ranlib"
+ export BUILD_READELF="$(tc-getBUILD_READELF)" # Avoid
'readelf', use "${CBUILD}-readelf"
+ export BUILD_STRINGS="$(tc-getBUILD_STRINGS)" # Avoid
'strings', use "${CBUILD}-strings"
+ export BUILD_STRIP="$(tc-getBUILD_STRIP)" # Avoid 'strip', use
"${CBUILD}-strip"
+
export AR="$(tc-getAR)" # Avoid 'ar', use '${CHOST}-ar'
export CC="$(tc-getCC) $(get_abi_CFLAGS)"
export CXX="$(tc-getCXX) $(get_abi_CFLAGS)"
* This works great for Autotools and CMake build systems, but it may subtly
break packages using meson.eclass because now all non-default-ABI builds are
configured in Meson's cross mode with "needs_exe_wrapper = true" specified in
the cross file. Normally this is reasonable, as in the true cross-compiling
case we cannot expect host-machine executables to run on the build machine
without some help, but it is overly pessimistic in the non-cross,
non-default-ABI case. We would prefer not to disable build-time feature tests
that rely on being able to execute just-built binaries on the build machine.
One solution would be to set "needs_exe_wrapper = false" in the case that
${CBUILD} == ${CHOST_${DEFAULT_ABI}}.
--- a/eclass/meson.eclass
+++ b/eclass/meson.eclass
@@ -147,6 +147,7 @@
_meson_create_cross_file() {
local system cpu_family cpu
_meson_get_machine_info "${CHOST}"
+ local -n CHOST_default="CHOST_${DEFAULT_ABI}"
local fn=${T}/meson.${CHOST}.${ABI}.ini
@@ -181,7 +182,7 @@ _meson_create_cross_file() {
objcpp_link_args = $(_meson_env_array "${OBJCXXFLAGS} ${LDFLAGS}")
[properties]
- needs_exe_wrapper = true
+ needs_exe_wrapper = $([[ "${CBUILD:-${CHOST}}" != "${CHOST_default}" ]]
&& echo true || echo false)
sys_root = '${SYSROOT}'
pkg_config_libdir =
'${PKG_CONFIG_LIBDIR:-${EPREFIX}/usr/$(get_libdir)/pkgconfig}'
* There is one other loose end to tie up in meson.eclass: the native file is
named "meson.${CBUILD}.${ABI}.ini", but this actually makes no sense, as ${ABI}
belongs to the CHOST machine, not the CBUILD machine. It would make the most
sense simply to omit the ABI from the native file name since there will only
ever be one native ABI.
@@ -205,7 +206,7 @@ _meson_create_native_file() {
local system cpu_family cpu
_meson_get_machine_info "${CBUILD}"
- local fn=${T}/meson.${CBUILD}.${ABI}.ini
+ local fn=${T}/meson.${CBUILD}.ini
cat > "${fn}" <<-EOF
[binaries]
A Pull Request containing all of these proposed changes is at:
https://github.com/gentoo/gentoo/pull/43693