dslm4515 / Musl-LFS

Linux From Scratch using Musl as Libc
GNU General Public License v3.0
167 stars 21 forks source link

Unable to cross-compile GCC for /tools with /cross-tools when Host Libc does not match Target Libc #5

Closed dslm4515 closed 4 years ago

dslm4515 commented 5 years ago

Building Binutils for /tools creates a linker in /tools/bin/ld that expects to find a musl libc in the host's /lib . This is okay if host uses musl libc. If host uses Glibc or another libc, ld in /tools/bin cannot execute.

Binutils will build and install for /tools, but GCC pass 1 for /tools will fail to build.

dslm4515 commented 5 years ago

TESTING: For building /tools, will change the order, starting with Musl Libc first...

Building and installing binutils in /tools still builds a bad linker:

$ ldd /tools/bin/ld
/tools/bin/ld: error while loading shared libraries: /usr/lib/libc.so
$ file /tools/bin/ld
/tools/bin/ld: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-musl-x86-64.so.1, with debug info, not stripped

Looks like the built binutils in /tools is not using /tools as sysroot

dslm4515 commented 5 years ago

Seems GCC pass 1 for /tools now builds. Current deviation from posted build instructions:

  1. Built Musl Libc for /tools first before Binutils
  2. Linked the Musl libc in /cross-tools/lib to host's /lib: ln -sv /cross-tools/libc.so /lib/ld-linux-x86_64.so.1

Will test later to see if linking libc from /cross-tools is necessary

gottaeat commented 5 years ago

Binutils will build and install for /tools, but GCC pass 1 for /tools will fail to build.

can confirm that i've experienced the same. everything went buttery smooth until the the pass 1 of the gcc in step 8. i've accidentally closed the terminal so the error output got lost but can attempt to reproduce on my gcc 9.2.0 + glibc 2.29 distribution if needed.

dslm4515 commented 5 years ago

I took a screenshot as my build machine does not have X11 installed atm.

When building GCC pass1 for /tools, build fails:

checking build system compiler gcc... no
configure: error: Specified CC_FOR_BUILD doesn't seem to work
make[1]: *** [Makefile:4718: configure-gmp] Error 1
make[1]: Leaving directory '/mnt/mlfs/sources/gcc-9.1.0/build`
make: *** [Makefile:941: all] Error 2

This was actually the original problem that I had when I first tried to compile musl-lfs on a Glibc host. So I created the cross toolchain (/cross-tools) to fix this issue. Not sure if it is re-surfacing due to newer binutils and GCC?

dslm4515 commented 5 years ago

I rebuilt the /cross-tools again, making sure I didn't have typos.

I tested the cross-compiler (x86_64-mlfs-linux-musl-gcc):

$ echo "int main(){}" > dummy.c
$ /cross-tools/bin/x86_64-mlfs-linux-musl-gcc dummy.c
$ /x86_64-mlfs-linux-musl-readelf -l a.out | grep Requesting
          [Requesting program interpreter: /lib/ld-musl-x86_64.so.1]

I assume this is bad because when I build /tools, those binaries will require /lib/ld-musl-x86_64.so.1 which will not be on the host nor present when in the chroot environment with /mnt/mlfs as [sys]root.

I created a specs file to override this:

$ /cross-tools/bin/x86_64-mlfs-linux-musl-gcc -dumpspecs > specs
$ vim specs

I replaced all instances of /lib/ld-musl-x86_64.so.1 with '/tools/lib/ld-musl-x86_64.so.1'

$ cp  specs /cross-tools/lib/gcc/x86_64-mlfs-linux-musl/9.1.0/
$ rm a.out && /cross-tools/bin/x86_64-mlfs-linux-musl-gcc dummy.c
$ /x86_64-mlfs-linux-musl-readelf -l a.out | grep Requesting
          [Requesting program interpreter: /tools/lib/ld-musl-x86_64.so.1]

Now the cross-toolchain produces binaries with the correct "program interpreter" that will be present while building /tools and in the chroot environment.

I will now see if GCC pass 1 will build...

[ UPDATE ] Looks like GCC Pass1 [for /tools] is now building. Previously, build failed when building GMP for GCC. Now GMP builds! I still built Musl libc before Binutils Pass 1 and GCC Pass1

dslm4515 commented 5 years ago

Binutils will build and install for /tools, but GCC pass 1 for /tools will fail to build.

can confirm that i've experienced the same. everything went buttery smooth until the the pass 1 of the gcc in step 8. i've accidentally closed the terminal so the error output got lost but can attempt to reproduce on my gcc 9.2.0 + glibc 2.29 distribution if needed.

Yes, if you can!

gottaeat commented 5 years ago

Yes, if you can!

as i stated in the previous closed issue, after the latest commits and the creation of the stable-5.00 branch, i was able to build a properly working toolchain in the /tools directory. i also created a pull request off of the small changes i made to fix/update/failproof certain stuff, i'd be happy if you can check it out.

dslm4515 commented 5 years ago

I finally got a working /tools toolchain on both a x86_64-glibc and x86_64-musl host. So maybe I might upload it as stable-5.01? I adjusted the /cross-tools with a modified GCC specs file before building musl libc for the /tools toolchain... not sure if that's in your pull-request.

Essentially, stable-5.00 was supposed to be stable-4.00 updated with GCC-9.1.0 (still waiting for patches from void Linux for GCC 9.2.0) AND fixed to build on non-musl-libc hosts. Ever since I build my first Musl-LFS system with branch stable-3.00 I've been using that system to work on Musl-LFS...so i didn't know Musl-LFS wouldnt build on glibc hosts.

I will review your pull request. I am very excited you got some sed commands for the GCC specs files!! That was on my to-do list as there is no text editor while in a chroot environment with the /tools toolchain.

dslm4515 commented 5 years ago

Also, i haven't check the other steps for building the final system... probably still works fine if following stable-4.00 ... but i would like to update the packages to last versions too.

gottaeat commented 5 years ago

finally got a working /tools toolchain on both a x86_64-glibc and x86_64-musl host. So maybe I might upload it as stable-5.01?

strange, it was building just fine as it was for me, except for minor typos and the header installation failing because ARCH was being set to x86_64 instead of x86 since there's no arch/x86_64 under the linux sauce. none the less, i can build if you push your changes and report back.

That was on my to-do list as there is no text editor while in a chroot environment with the /tools toolchain.

it is useful to have statically linked busybox binary ready for those situations but just running sed is indeed much more failproof.

Also, i haven't check the other steps for building the final system... probably still works fine if following stable-4.00

i actually tried continuing from the place where the stable-5.00 left with stable-4.00 and it gave me an error at the place where we move ld-old, ld-new and ld, can try again after you push 5.01 and give an exact error.

but i would like to update the packages to last versions too.

i meant to do that but then i didn't want to touch the patches and the general way you prefer doing things since it's your project. also, it'll be really nice to mention the linux from scratch version that the branches are based on if they are based on lfs when it comes to packages since the producing of a sources.list would be much easier.

dslm4515 commented 5 years ago

I've merged your changes to stable-5.00 and then applied my changes. Should be up to date now.

Yes, I agree, sed commands are better than using a busybox binary.

I've not gotten to building the Final System steps yet... i will upload them as I go

dslm4515 commented 4 years ago

Looks like issue is fixed. Closing.

firasuke commented 4 years ago

This weird error when GMP is being configured when building cross-native GCC can be solved by specifying --build equal to both --host and --target.

Conventionally, in a cross musl toolchain and on a Glibc host, both --build and --host are set equal to gnu and --target is equal to musl, and in the cross-native musl toolchain both --host and --target are equal to musl while --build is left equal to gnu.

This works perfectly fine with cross-native binutils as it gladly accepts CC=$TARGET-gcc (With target being something with musl), CC_FOR_TARGET=$TARGET-gcc and CC_FOR_BUILD=gcc (with gcc being the host's gnu gcc), as well as libstdc++-v3 (if built), but doesn't work all that well with cross-native GCC as GMP is the first to complain about CC_FOR_BUILD=gcc.

This can be solved by setting --build equal to both --host and --target equal to musl without specifying anything gnu related as it sets CC_FOR_BUILD=$TARGET-gcc (with target being something with musl).

This error is only shown on Glibc hosts, and doesn't happen on musl hosts.