Project:Toolchain/use native symlinks

From Gentoo Wiki
Jump to: navigation, search

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:

FILE /etc/portage/profile/package.use.force
sys-devel/gcc-config -native-symlinks
sys-devel/binutils-config -native-symlinks

And then disable USE:

FILE /etc/portage/package.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