Building a #Linuxulator userland from source on #FreeBSD -- I'm not giving up yet. But, starting over 😞

This time, I try building some "complete" #GNU cross-toolchain targeting #Linux first in some dedicated prefix. Maybe this will finally work out. 😜

I really don't get it. I *had* a working port building "some" (with lots of missing features, e.g. threads) cross-#gcc (build: #FreeBSD, host: #Linux). Now I try to build this same port in some separate PREFIX and, it fails 😞

Progress again. 

GCC builds fine when I previously install binutils in the exactly *same* prefix!

Ok, this means I'll need an extra "bootstrapping" port for binutils as well...

Time for bed!

Been a week now I'm working on this idea ...

So far, whenever something looked like good progress, I ran into some dead end one or two ports later.

Should probably decide for some #timebox I will set myself for this. If I can't at least come up with a *working* cross (#FreeBSD -> #Linux) #GNU toolchain within that timebox, the idea should be abandoned as unfeasible 😞

I'm carefully optimistic now again 😎

After first building very basic/limited "-bootstrap" versions of binutils and gcc into a separate prefix, it seems I could finally build a complete #GNU cross (#FreeBSD -> #Linux) toolchain, including #binutils, #glibc and #gcc (with libstdc++). This final cross gcc at least passed the most basic sanity check -- it successfully compiles an empty program πŸ™ˆ

Now doing a bit of cleanup and then trying whether this beast is able to build the *real* (native) glibc for a new #Linuxulator userland 😎

And we're getting closer ... this new cross-toolchain successfully builds a "native" glibc as the first package for the new #Linuxulator userland πŸ₯³

So now, just a few more ports until I reach one that will require C++11 threading functionality ... that's where it finally broke beyond repair with my first more naive approach (without any "bootstrapping" ports/packages).

Ok. #zstd was the first #Linux port that needs C++11 threads. And, it builds!

My #GNU cross toolchain on #FreeBSD finally seems to work! πŸ₯³

Time to party, hehe. Or, time for bed in fact.

Next step will be a *native* Linux toolchain to build the rest of the #Linuxulator userland.

https://github.com/Zirias/zfbsd-ports/blob/linux/archivers/linux-zstd/Makefile

zfbsd-ports/archivers/linux-zstd/Makefile at linux Β· Zirias/zfbsd-ports

Zirias' FreeBSD ports tree. Contribute to Zirias/zfbsd-ports development by creating an account on GitHub.

GitHub

This feature-branch finally starts to look somewhat promising, just added native #Linux #GNU #binutils for #FreeBSD's #Linuxulator 😎

linux_base-dirs is a tiny metaport just owning ${LINUXBASE} and a few essential subdirs.

Everything prefixed "lxcross-" is part of the cross-toolchain and installed to ${LXCROSSBASE}, defaulting to ${LOCALBASE}/linux-cross.

Everything suffixed "-bootstrap" is some minimal/temporary port needed to build the full cross-toolchain and installed to ${LXBOOTSTRAP}, defaulting to ${LXCROSSBASE}/bootstrap.

Everything prefixed "linux-" is Linux-native and installed to ${LINUXBASE}.

linuxheaders44 just contains the headers from Linux-4.4.x, installed to ${LINUXBASE} but coming with a slave-port installing to ${LXCROSSBASE} for the cross toolchain.

Next step: GNU gmp! Let's see 😎

We have #glibc, #zlib, #binutils, #gmp, #mpfr and #mpc ... in theory everything needed to build a full-featured native #gcc for C and C++. Oh wow. Now, trying to create *this* port 😎

Edit: My hope is that with the --sysroot option (set to ${LINUXBASE}), this new toolchain will only ever look for libraries inside ${LINUXBASE}, avoiding weird build issues you might get when using the existing linux-c7-devtools port. Well, I'm not sure I fully understand this --sysroot magic πŸ™ˆ

Another little update on this endeavor .. native #Linux #GCC for #FreeBSD's #Linuxulator finally builds! πŸ₯³

Still needs some "love" in detail (like, correct path for man files).

And also, I have to find a way to package #libgcc separately, cause most software built for Linux using GCC will need it, and it doesn't make sense that everything pulls in the whole GCC as a dependency ...

Well, maybe tomorrow then πŸ™ˆ

Indeed, sanity-checking the new #Linux-native #GCC for #FreeBSD's #Linuxulator shows it works perfectly fine at least for C, and using static #libgcc (because I removed the libgcc_s.so file, should really be packaged separately) πŸ₯³

So, to complete the toolchain, next steps will be separate ports for libgcc and libstdc++, should be possible to build these with this native gcc, we will see!

Currently adding more symlinks for the very same dynamic linker (aka #ELF "program interpreter") to my linux-glibc port, making sure it's present in /lib, /lib64, /usr/lib and /usr/lib64 -- yes, different #Linux (and #GNU) tools expect it in different places 🀯

Mood ... dafuq is this crap...

He, finally. The #Linux-native #GNU toolchain for #FreeBSD's #Linuxulator just passed a first sanity check using C++ πŸ₯³

I guess this means I could start creating ports for a basic userland now... πŸ˜‰

Trying to get this to the other archs supported by #FreeBSD's #Linuxulator (amd64 and i386), I'm hitting yet another wall: #Linux headers fail to build there. Oh freakin hell, I expected to do quite some adaptions to support all 3 archs, but I didn't expect it to fail at *this* stage 🀯

Already tried to understand what happens in Linux' build system. Well, it's not exactly easy to understand πŸ™„

Shot in the dark, trying it with #gcc (instead of the base #clang) now... (which will take a while cause my test machine has to *build* this gcc first, bah ....)

Well ... no, building with #gcc didn't help.

Turns out the issue were #ELF relocation types. I have no idea why #Linux needs them *just* to build the headers (which is all I need for #Linuxulator, cause the actual #kernel will *still* be #FreeBSD), but yep, one type is named slightly differently: R_X86_64_JUMP_SLOT on Linux, R_X86_64_JMP_SLOT on FreeBSD. It has the same value, 7, so for now I just hardcoded it in the port Makefile for the Linux headers. πŸ™ˆ (hey, it works πŸ€·β€β™‚οΈ)

@zirias have you tried it on #FreeBSD 14? As far I remember it has support for the newer version of Linux plus some fixes for existing ones. 13 has only support for older API. Maybe that's the problem? Maybe you use too recent Linux source. πŸ˜‰

@thindil No, that's not the issue, it was really just about this slightly different spelled constant for some ELF relocation type ... it works now.

I'm btw only testing on 14 so far. But I use #Linux 4.4.x for the headers (to be compatible with FreeBSD 13). I will add a metaport later that will pick Linux 5.10(?) on 14 instead.

For the #GNU toolchain, I'm using the newest versions in any case. They're still compatible with Linux 4.4 πŸ˜‰

@zirias Nice, keep up the good work. πŸ₯³ We will see the final effect. 😊

@thindil Thanks!

I'm almost done with at least the cross (#FreeBSD -> #Linux) #GNU toolchain for all supported archs (aarch64. amd64 and i386), currently working on #glibc for it. It's a bit tedious work because all parts of the toolchain seem to have a pkg-plist dependent on the target architecture πŸ™„

@zirias As far I remember, that's the beauty of low level thingies. πŸ˜‰ Later should be better. I hope for that. πŸ™‚

@thindil That's what I assume as well, once I'm done with the toolchain, architecture-specific differences should be rare (if encountered at all). πŸ™

Just finished the cross-version of #glibc for all archs. Two more (#binutils and #gcc) to go for the FULL cross-toolchain. That will be the goal for today, the native toolchain maybe tomorrow 😎

@thindil Little weird issue (of so many I'm hunting down and fixing right now): #FreeBSD's strip can perfectly strip any #Linux lib or binary for amd64 and aarch64 ... but obviously NOT for i386. Damn weird.

Sure, the cross toolchain has some "cross strip". Let's use that one instead πŸ™ˆ

@zirias Let's hope it helps. πŸ˜€

@thindil it sure does. Another one of these things that *should* be solved once the *native* toolchain is completed.

Just redefine ${STRIP_CMD} (for direct usage), and when used from "install -s", it should then automatically use the "native" strip, because the toolchain is compiled with --with-sysroot=${LINUXBASE} ... we will see!

@zirias does this mean a new go on debian #kfreebsd distro?

@bdiederik No. #Debian's #kfreebsd is a #GNU userland configured to use the (native) #FreeBSD kernel. What I'm building here is a #GNU userland using a #Linux kernel (although "faked" by #FreeBSD's #Linuxulator -- the kernel can provide a Linux-compatible userspace-ABI, syscalls etc...)

The goal is to replace the ancient "linux-c7" userland currently offered in FreeBSD ports. I'm testing here whether building a userland from source would be a feasible way πŸ˜‰

@zirias
I'm very interested in the results of your work. I would really love more functional linuxulator. I mean, easier to use, more documented, ... you name it @bdiederik

@meka @bdiederik Right now, all I have is a working native toolchain. On aarch64. Next step, test on i386 and amd64 (to cover all archs supported by #FreeBSD's #Linuxulator at all) and do the necessary adaptions.

Once *this* is done, I can try to start building an *actual* Linuxulator userland from source.

I'm certainly not talking about documentation at this stage πŸ™ˆ

But thanks, nice to see people are interested in this project. If it works out at all (still not sure), I *am* sure I won't be able to maintain it all alone πŸ˜‚

@zirias A more functional and easy to use #Linuxulator would be awesome!

@meka @bdiederik

@hnygd @meka @bdiederik The "normal" approach would be to find another (newer) Linux distribution and re-package *that* instead of Centos-7.

And maybe, this is the better approach, I'm not sure yet. But I really want to try the "build it all from source" approach as well πŸ˜‰

@zirias @meka o yeah popularity counts. I made the best "awnsering machine" in the world with asterisk tasker and home assistant and no one cares.
@zirias
Might be a good idea
Setting a limit.
In the end: If it is only frustrating it might not be the best thing to spend time on

@jhx It would be a lot less frustrating if I wouldn't have to sit and wait all the time (e.g. rebuilding my minimal cross-gcc takes around 11 minutes).

I wonder whether #ccache with #poudriere would also work for some custom-built cross-compiler? πŸ€”

@zirias
True, the waiting is what makes it annoying!

Mhh, not sure about that... in general: sure, you could leverage ccache... question is how good it would work.
I know that ccache can sometimes bork builds

@zirias Just a stupid question here. πŸ˜‰ What exactly is the purpose of the project? Because if it is just cross-compiler from #FreeBSD to #Linux, you can use:

1. Linuxator and GCC there. That could be literally native compilation.

2. Get the proper libraries and use clang cross-compilation abilities. That solution is more native for FreeBSD and require less disk space.

@thindil Background is that #FreeBSD's #Linuxulator userland is in desperate need of an upgrade. The "linux-c7" userland is both too antiquated and incomplete for a lot of #Linux software you might want to run on FreeBSD.

Purpose of my project is to evaluate an approach of building a new userland from source instead of repackaging another Linux #distribution. The rough plan is to create a feature-complete native #GNU toolchain for Linux and then use that to build the Linuxulator userland packages.

The benefit I would *hope* for is that this could allow to relatively quickly create new packages for the Linux userland from existing FreeBSD ports (maybe using "slave ports"), but this has to be proven in practice.

@zirias I agree with upgrade. CentOS is going down in the next year and all that infrastructure will go down with it too.
The idea is interesting, just I'm not sure if not too complicated. πŸ˜‰ Each Linux distro is almost that same different each other, like BSD systems. I would prefer to stick with one distro and just use its internal packaging manager to keep everything up to date. I have bad memories with creating Linuxator packages. 😁 Eventually, you could look at Linux From Scratch.

@thindil I'm actually using #LFS as a reference to get around the weirdest issues "bootstrapping" some #GNU toolchain at all. But of course it can't be used as is, LFS expects to be built on some Linux system and even uses #chroot to build some packages, definitely impossible using #FreeBSD #ports.

I certainly don't want two package managers on my system. Plus, a #Linuxulator userland should only install what's *different* from the normal FreeBSD userland, because /compat/linux works as an "overlay".

Trying to create new ports/packages for the Linuxulator userland is cumbersome, first you have to rely on what the repackaged distro offers, second you have to understand the special repackaging magic used.... that's exactly what I *hope* to improve by just building from source. No, I'm not convinced myself yet this is a good idea, I have to try!

@zirias True, the only way to know do it's a good idea is to test it. πŸ˜‰ And before I forgot again, there is also Chimera Linux: https://chimera-linux.org/ Maybe it will be helpful.

Linuxator isn't exactly an "overlay". #FreeBSD has implemented two APIs in the kernel and can detect, on a binary execution, via magic bits, which API to use. Thus you can't mix, for example FreeBSD library and Linux binary. We need to deliver the whole dependencies chain for that binary.

Chimera Linux

Chimera Linux

Chimera Linux
@thindil I said /compat/linux is an overlay, not #Linuxulator itself. Linuxulator basically consists of the kernel's "Linux personality" (Linux syscalls exposed when the running #ELF binary is a Linux binary) *and* this overlay for the userland. When running a Linux binary, any attempt to access some file is first tried with /compat/linux prepended to the path, only when nothing is found there, it's tried in /.
@zirias Ah, my bad then. 😊 Thank you for the correction. But still, we need to build the whole chain, unless there's a way to mix the different ABIs.

@thindil I can certainly use #FreeBSD "tools" (gmake, bison, gettext, whatever) for building this cross-toolchain. But indeed, for libraries, they need to be built targeting #Linux. And because #GCC with the full feature set needs e.g.#glibc when targeting Linux, but then you need GCC to *build* glibc, I need at least some "bootstrapping" ports. It's really a mess.

Once I have a full-featured cross GCC targeting Linux ready, I'll stop for a while to party πŸ˜‚

@zirias A very long party I suggest. 🀣 The problem is that there's no binary compatibility between distributions, even between older versions of the same distro. That's why even Microsoft supports only selected distros, and not Linux at all. That's why I prefer to use existing distro in Linuxator. After all, you are going to recreate the whole Ubuntu. That's a huge task. πŸ˜€

@thindil Oh there *is* binary compatibility for sure. The #Linux kernel typically doesn't break its userspace-facing #ABI. #Glibc and #GCC's libstdc++ use symbol versioning to provide backwards compatibility.

The issue starts with all the other libs, there's no standard for some "base" GNU/Linux system. That's where all these (IMHO damn broken) ideas like #AppImage, #Flatpak etc come from. Of course, you could just link statically instead, seems people don't get that any more πŸ™ˆ

Anyways, quite some binary #Linux software will work "anywhere" as long as the required libs are not too old (looking e.g. at browsers...). And having a #Linuxulator userland built from source *should* enable you to just add ports for missing libraries. Well, in theory πŸ™ˆ

@zirias I wish that was true. 🀣One of things which I learned as a someone who was creating software for Linux is that binary compiled on Fedora will usually not work on Ubuntu.
1. Contrary to popular believes, Linux pretty often breaks compatibility, mostly by putting some API calls hidden by switches.
2. There's no binary compatibility between GNU lib C releases. Theoretically you have right, but practically it not always works.
3. There's no more standard for Linux base system. LSB is dead.
@thindil
1. The "#Linux" ABI is the syscalls (and a few other things) offered by the kernel ... yes, this thing actually *called* "Linux". It doesn't break, as far as I know.
2. There is. But only in one direction of course. Something built against some newer #glibc won't work on a system with an older version.
3. Yes, definitely yes πŸ™„

@zirias 1. From my experience, breaks. Reason: distros use different build flags. And whole piles of patches. 😁
2. Unless there's some security problems, then they break backward compatibility too. 🀣

Btw, I'm sure that I forgot to mention that there's no standard C library in Linux world? IIRC, there are 3 or 4 incompatible ones. The two major are GNU lib C and musl. 🀯 Ubuntu ships them both. πŸ˜‚

@thindil
1. This doesn't affect the public #ABI of the kernel. Do you have any example of breakage here? πŸ€” Don't get me wrong, I'm really not a fan of the chaos GNU/Linux actually is, but this is still hard to believe.
2. Possible. I don't know any example though ....

Regarding the "standard" #libc, if we're talking about "GNU/Linux", this will always be #glibc. AFAIK, any #Linuxulator userland ever shipped in #FreeBSD ports used it. I plan to do the same trying to build this mess from source πŸ˜‚

BTW, my "lxcross-glibc" package seems to work, and it seems I'm able to build some *almost* complete cross #GCC using it right now ... still need the --disable-libsanitizer configure flag πŸ€”

@zirias 1. Mostly from work. An old binary was depending on some old, insecure syscalls which were disabled by default in later versions of the kernel. Sure, rebuild kernel was fixed the problem. But it's hard to call that: "we don't break API". πŸ˜‰ Sometimes I have feeling, that FreeBSD has better compatibility with Linux than all these distros.

And nice result, congratulations. πŸ₯³ Let's hope the best with the rest. πŸ™‚

@zirias @thindil It's about time that "the Linux community" (userland, not kernel) define a proper platform. https://gitlab.com/probono/platformissues
probonopd / platformissues Β· GitLab

Desktop Linux Platform Issues

GitLab
@probono Nice initiative, I hope it will work. 😊 But I have feeling, that it will take some time. Let's hope not too long.
@zirias
Try debootstrap.
@thindil @alelab

@dexter @thindil @alelab
No thanks. I certainly want to avoid to have some area managed by a "foreign" package manager.

Of course, no existing #FreeBSD #port of #Linux software could ever work that way either (and I'm maintaining one of them: multimedia/makemkv)