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.
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.
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.
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...
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?
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 ;-)
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?
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.
(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}')
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?
(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.
> > 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<----
Sorry, that should be -print-prog-name with single dash.
Fixed in by passing --sysroot=/ to binutils. https://gitweb.gentoo.org/repo/proj/prefix.git/commit/?id=0af56bfa67625683611aee6b65262c0a9743df98