Project:Toolchain/use native symlinks
Overview
Packages should not normally use or rely on gcc, ld and similar commands at build time. They should use user's preferred tools specified in CC=..., CXX=... and similar variables.
If CC is unset then build systems normally discover CHOST-prefixed tools like x86_64-pc-linux-gnu-gcc via --host=${CHOST}. Or ebuilds/eclass implement equivalent mechanism via CC=$(tc-getCC) and friends.
To ease catching of ebuilds that hardcode gcc, ld and similar a few toolchain packages provide -native-symlinks mode. Disabling native-symlinks removes unprefixed tools from PATH.
Currently sys-devel/binutils-config-5.3.1 and sys-devel/gcc-config-2.3 provide the mechanism.
Why would you use it?
- multilib environments and cross-compiler environments can use tools like gcc or cpp by accident and target wrong ABI as a result. cpp is especially tricky as preprocessor rarely fails. It just generates data for wrong target.
- environments with non-standard tools like AR=${CHOST}-gcc-ar or even CC=gcc-9999 have a better chance being applied consistently.
TODO: links to more details on discoverable tools and expand on cross-compilation use case.
The good news is that autoconf build systems already use only prefixed variant of tools as Gentoo always passes --build=/--host=/--target= options to ./configure.
Removing native symlinks
Currently the flags are use.force masked as many packages including base system fail to build if native symlinks are not present. Ideally they all should be fixed.
You need to unforce flags first:
sys-devel/gcc-config -native-symlinks
sys-devel/binutils-config -native-symlinks
And then disable USE:
sys-devel/gcc-config -native-symlinks
sys-devel/binutils-config -native-symlinks
List of removed files
For sys-devel/gcc the list of disappeared files is:
user $
ls -1 $(gcc-config -B) | fgrep -v $(portageq envvar CHOST)- | sort -u
c++ cpp g++ gcc gcc-ar gcc-nm gcc-ranlib gccgo gcov gcov-dump gcov-tool gfortran go-11 gofmt-11 lto-dump
For sys-devel/binutils the list of disappeared files is:
user $
ls -1 $(binutils-config -B) | fgrep -v $(portageq envvar CHOST)- | sort -u
addr2line ar as c++filt coffdump dlltool dllwrap dwp elfedit gprof ld ld.bfd ld.gold nm objcopy objdump ranlib readelf size srconv strings strip sysdump windmc windres
Example fixes
TODO: autotools examples, make-based examples, leaking/embedding '/lib/cpp' into other toolchains examples.
automake AR example
This one is simplest. Autoconf frequently generates $(AR) calls to build static libraries. If the project uses automake build system (the hint is presence of Makefile.am file), then fix is a one-liner:
--- a/configure.ac
+++ b/configure.ac
@@ -22,6 +22,7 @@ AC_CHECK_TOOL(GHC, ghc)
AM_CONDITIONAL([HAVE_GHC], ["$GHC" --version])
AC_CHECK_PROG(PANDOC, pandoc, yes)
AM_CONDITIONAL([HAVE_PANDOC], [test x"$PANDOC" = x"yes"])
+AM_PROG_AR
# Checks for header files.
AC_CHECK_HEADERS([dlfcn.h fcntl.h float.h limits.h \
Example fix in abyss project: https://github.com/bcgsc/abyss/pull/335
hardcoded tool example
Sometimes ./configure hardcodes binutils' or gcc's tool like strings or as as-is. The fix is usually 2 lines:
Here is the cairo's example fix:
--- a/build/aclocal.float.m4
+++ b/build/aclocal.float.m4
@@ -31,10 +31,13 @@ int main() { return 0; }
]])], [
-if strings -a conftest$ac_exeext | grep noonsees >/dev/null ; then
+# allow users to override default 'strings' with 'llvm-strings'
+# or ${CHOST}-strings.
+AC_CHECK_TOOL(STRINGS, strings)
+if $STRINGS -a conftest$ac_exeext | grep noonsees >/dev/null ; then
ax_cv_c_float_words_bigendian=yes
fi
-if strings -a conftest$ac_exeext | grep seesnoon >/dev/null ; then
+if $STRINGS -a conftest$ac_exeext | grep seesnoon >/dev/null ; then
if test "$ax_cv_c_float_words_bigendian" = unknown; then
ax_cv_c_float_words_bigendian=no
else
Taken from bug #726200.
Ideally such AC_CHECK_TOOL tool discovery should be applied to all binutils-provided binaries. That way switching from binutils to llvm tool suite can be done with a few envvironment tweaks.
CC_FOR_BUILD (AX_PROG_CC_FOR_BUILD) example
The symptom is early ./configure failure:
user $
./configure --build... --host... --target...
... checking dependency style of x86_64-pc-linux-gnu-gcc -m32... none checking how to run the C preprocessor... x86_64-pc-linux-gnu-gcc -m32 -E checking for gcc... no checking for cc... no checking for cl.exe... no configure: error: in `/tmp/portage/x11-libs/gtk+-3.24.20/work/gtk+-3.24.20-abi_x86_32.x86': configure: error: no acceptable C compiler found in $PATH See `config.log' for more details ...
This is usually caused by AX_PROG_CC_FOR_BUILD macro. Ideally it should check for ${build}-gcc presence (like AC_PROG_CC does for --host=... case). But it does not and requires user to supply CC_FOR_BUILD environment.
The simplest fix is to set CC_FOR_BUILD in eclass/ebuild if it's not explicitly defined by user as:
--- a/x11-libs/gtk+/gtk+-3.24.20.ebuild
+++ b/x11-libs/gtk+/gtk+-3.24.20.ebuild
@@ -5,7 +5,7 @@ EAPI=6
GNOME2_LA_PUNT="yes"
GNOME2_EAUTORECONF="yes"
-inherit flag-o-matic gnome2 multilib virtualx multilib-minimal
+inherit flag-o-matic gnome2 multilib virtualx multilib-minimal toolchain-funcs
DESCRIPTION="Gimp ToolKit +"
HOMEPAGE="https://www.gtk.org/"
@@ -131,6 +131,8 @@ src_prepare() {
eapply "${FILESDIR}"/${PN}-3.22.20-libcloudproviders-automagic.patch
gnome2_src_prepare
+
+ export CC_FOR_BUILD="$(tc-getBUILD_CC)"
}
multilib_src_configure() {
Taken from bug #726186.
Discussion/report on autoconf-archives: https://lists.gnu.org/archive/html/autoconf-archive-maintainers/2020-06/msg00000.html
Links and references
- bug #243502: tc-directly tracker with known to fail ebuilds
- bug #724980: bug to user helpers to add gcc to users' path