Add two small tooldir prefix patches to aid cross-compiling #8
+165
−0
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
These are small but a tad controversial.
There has long been a desire for crossdev to initialise environments with a given profile rather than the embedded profile that few people actually want. I picked up a PR for this, tried it with a merged-usr profile, and found that things break very badly once you point the sysroot somewhere else.
For some bizarre reason, GCC adds
/usr/${CHOST}/lib
to the library search path before the sysroot's own/lib
and/usr/lib
. Gentoo has previously got away with this as there were generally no conflicting libraries in the toolchain's/lib
, but with merged-usr, this is now the same directory as the toolchain's/usr/lib
.Aside from ABI compatibility issues, the toolchain's
/usr/lib/libc.so
ld script is now found before the sysroot's. This includes a reference to/lib/libc.so.6
. The sysroot is only prepended to this when the ld script itself is within that sysroot, so/lib/libc.so.6
is taken literally, causing the build machine's libc to be used instead, which immediately breaks any linking.I couldn't see any good reason to use the toolchain's
/lib
when the sysroot has been changed, so the "lib" patch simply omits it in that case.The "bin" patch involves the code immediately before. The issue here is similar in that
/usr/${CHOST}/bin
is searched for toolchain programs, but at least on Gentoo, only non-native binaries live here. It would be better to fail to find a given tool than inadvertently try to execute a non-native build of it via QEMU. While this change is not strictly necessary, I felt it made sense alongside the first change.Note that I have deliberately not adjusted the whitespace of the existing code to keep the patches minimal. This way, they only add a single line each.
I didn't want to submit the "lib" patch without considering whether Clang would need similar treatment. It sadly does suffer from the same issue. You can kind of work around it by pointing
--gcc-install-dir
inside the sysroot, but this gets messy when bootstrapping a new system. When I found the code responsible though, it turned out to reveal much more about GCC than it did about Clang.With merged-usr, we are totally violating that second rule. The original commit from 2013 (llvm/llvm-project@7f8042c) says a little more about how this behaviour is "frustrating" but apparently necessary for Android and MIPS platforms. I take that to mean their SDKs.
I can confirm that gating the above line with
if (SysRoot.empty())
fixes the issue, although another line just below is needed to avoid the corresponding/lib
(as opposed to/lib64
) entry.Since upstream clearly thought this behaviour is terrible, I don't feel so bad about nullifying it. I don't think we need to worry about what is needed by these SDKs (if they even do still need this) because they probably have their own toolchains. I can't really see any other way around it. merged-usr is now the default, so cross environments really should support it.
As for the "bin" patch, Clang also mirrors GCC's behaviour here, but I think it is less likely to fall back to the problematic directory, as everything it needs should be in
/usr/lib/llvm/${V}/bin
, which is where it looks first.