Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
Bug 555810 - [PATCH] bootstrap-prefix.sh stage2: Emerge binutils after gcc
Summary: [PATCH] bootstrap-prefix.sh stage2: Emerge binutils after gcc
Status: RESOLVED FIXED
Alias: None
Product: Gentoo/Alt
Classification: Unclassified
Component: Prefix Support (show other bugs)
Hardware: All Linux
: Normal normal (vote)
Assignee: Gentoo Prefix
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2015-07-24 18:23 UTC by gilad.arnold
Modified: 2019-12-27 13:39 UTC (History)
0 users

See Also:
Package list:
Runtime testing required: ---


Attachments
bootstrap-prefix.sh.patch (bootstrap-prefix.sh.patch,666 bytes, patch)
2015-07-24 18:23 UTC, gilad.arnold
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description gilad.arnold 2015-07-24 18:23:26 UTC
Created attachment 407548 [details, diff]
bootstrap-prefix.sh.patch

This appears to be a known problem with recent Ubuntu/Debian due to multiarch (I'm running Ubuntu 14). Essentially, once binutils is emerged in stage2, gcc seems to pick up the newly installed linker ($EPREFIX/tmp/usr/bin/ld) and further emerges fail with ld complaining that it wasn't built with sysroot support.

The attached patch simply reverses the order of emerge: gcc and deps are emerged first, binutils second. It seems to have fixed the problem: I got all the way through stage3 and my Prefix looks like it's working.
Comment 1 gilad.arnold 2015-07-24 18:46:53 UTC
Neglected to mention: problem occurs when trying to emerge dev-libs/gmp-6.0.0a, which is the first of the listed gcc deps. It fails in the configure step when checking for a working gcc.
Comment 2 Fabian Groffen gentoo-dev 2015-07-25 07:16:46 UTC
Hmm, so you say that gcc will not complain if there is no linker in $EPREFIX/usr/bin/ld?  That's tricky, but might be necessary for these platforms.
Comment 3 gilad.arnold 2015-07-26 06:23:41 UTC
It solved the problem on my particular setup. Is there a particular reason to emerge binutils prior to gcc and deps? If not, then swapping the order might be useful at least for some users...
Comment 4 Fabian Groffen gentoo-dev 2015-07-26 06:57:48 UTC
The problem is that the linker may not be gnu, or a version that's weirdish.  By first emerging binutils, then gcc, gcc will configure itself to use the linker we intend to use.  If we don't, it configures itself to use the linker that the host uses.  This will break in certain scenarios.

How did you start it by the way?  Shouldn't the script abort if it finds a multi-arch platform?
Comment 5 gilad.arnold 2015-07-27 04:32:28 UTC
That makes sense. I wonder if there's other ways to prevent the host's gcc from picking up the prefix's installed linker?

I ran the script in non-interactive mode with explicit stage arguments ;-)
Comment 6 gilad.arnold 2015-07-27 22:43:41 UTC
Reading a bit more about how gcc finds the linker and other binaries I'm wondering why this is not a more widespread problem: from what I gather, if gcc is not given an explicit binary search path (-B), for binaries that do not live in /usr/lib/gcc it will end up scanning PATH. However, when bootstrapping Prefix we prepend $EPREFIX/tmp/usr/bin to PATH early on. Having emerged binutils into $EPREFIX/tmp means it is bound to be picked up by the host gcc thereafter.

Is this a correct assessment? If so, how can can it be solved in the context of bootstrapping, where we want the binaries in EPREFIX/tmp to be able to find one another, but don't want the host toolchain to do the same?
Comment 7 Fabian Groffen gentoo-dev 2015-07-28 06:30:39 UTC
only binutils-config makes the usr/bin/ld executable available (via symlink), so gcc shouldn't be able to find ld, unless binutils-config was installed and run.
Comment 8 Michael Haubenwallner (RETIRED) gentoo-dev 2015-07-28 06:32:36 UTC
(In reply to gilad.arnold from comment #5)
> I wonder if there's other ways to prevent the host's gcc
> from picking up the prefix's installed linker?

This is a bug in the host's gcc package, seen on some enterprise linux as well.

To work around that, this symlink should help:
$ sudo ln -s . /usr/$(LC_ALL=C /usr/bin/gcc -v 2>&1 | awk '/Target:/{print $2}')
Comment 9 gilad.arnold 2015-07-28 16:15:20 UTC
I can confirm that the temporary symlink fixes the error I was seeing and stage2 completed successfully with it.

Is there a deterministic way to know whether this hack is needed for the host and/or gcc in question? If so, the script could wait for the user to add the symlink and remind them to remove it when done.

Alternatively, is there another way to solve this that does not involve sudo? For example, can it be done by setting GCC_EXEC_PREFIX to some value?
Comment 10 Michael Haubenwallner (RETIRED) gentoo-dev 2015-07-28 16:35:23 UTC
(In reply to gilad.arnold from comment #9)
> I can confirm that the temporary symlink fixes the error I was seeing and
> stage2 completed successfully with it.

I'm not sure whether to call this symlink "temporary" or "permanent workaround", though.

> Is there a deterministic way to know whether this hack is needed for the
> host and/or gcc in question? If so, the script could wait for the user to
> add the symlink and remind them to remove it when done.

Probably yes: "gcc -print-prog-name=ld" tells how ld is called. If that does not contain some "/", then $PATH is used.

> Alternatively, is there another way to solve this that does not involve
> sudo? For example, can it be done by setting GCC_EXEC_PREFIX to some value?

Unsure about this one.
Comment 11 gilad.arnold 2015-07-28 23:12:12 UTC
> > Alternatively, is there another way to solve this that does not
> > involve sudo? For example, can it be done by setting GCC_EXEC_PREFIX
> > to some value?
>
> Unsure about this one.

Tried prepending GCC_EXEC_PREFIX="$(dirname "$(type -P gcc)")" to the
emerge call. Problem is this now prevents gcc from finding cc1, although
the documentation suggests that gcc should still use the default paths
(/usr/lib/gcc, etc) specified one fails. Sigh.

> > Is there a deterministic way to know whether this hack is needed for the
> > host and/or gcc in question? If so, the script could wait for the user to
> > add the symlink and remind them to remove it when done.
>
> Probably yes: "gcc -print-prog-name=ld" tells how ld is called. If
> that does not contain some "/", then $PATH is used.

Makes sense. So it looks like we can at least detect when things are
likely going to break with high confidence, and advise the user about
a temporary fix (instead of cowardly bailing out). I tested this piece
of code and it seems to do what's described above. I can submit a patch if there's interest.

--8<------8<------8<------8<------8<------8<------8<------8<------8<----
if [[ $(gcc --print-prog-name=ld) != /* ]]; then
  host_gcc_prefix="$(dirname "$(dirname "$(type -P gcc)")")"
  host_gcc_target="$(LC_ALL=C gcc -v 2>&1 | grep '^Target:' | cut -d\  -f2)"
  host_gcc_binpath="${host_gcc_prefix}/${host_gcc_target}"
  if [[ ! -e ${host_gcc_binpath} ]]; then
    cat <<EOF
I think we have a problem.  The way your compiler was built might cause it to
pick up binary tools from the Prefix we're about to install while we are still
bootstrapping.  This is a bug and there isn't much I can do about it, but you
may be able to work around it by running this command:

 sudo ln -s . ${host_gcc_binpath}

This will basically let your compiler find the binary tools it was
actually meant to use while we're using it to build new ones.  Although
it's generally harmless, you can remove it when we're done, like so:

 sudo rm -f ${host_gcc_binpath}

Please get this fixed and run me again when you're ready.
EOF
    exit 1
  fi
fi
--8<------8<------8<------8<------8<------8<------8<------8<------8<----
Comment 12 gilad.arnold 2015-07-28 23:13:22 UTC
Sorry, that should be -print-prog-name with single dash.
Comment 13 Benda Xu gentoo-dev 2019-12-27 13:39:43 UTC
Fixed in by passing --sysroot=/ to binutils.

https://gitweb.gentoo.org/repo/proj/prefix.git/commit/?id=0af56bfa67625683611aee6b65262c0a9743df98