So it seems no one wanted to provide a good clear overview of the current situation and several people are already trying to offer solutions before everyone has a good understanding of the “problems” here. Let’s fix that.
First, the current situation.
Haiku currently uses the latest version of gcc (currently 11.2) in most cases. All the code can be compiled with it, and if you run anything but the 32-bit x86 version of Haiku, you won’t find any traces of gcc2 anywhere.
The current versions of gcc use a standardized ABI called the Itanium ABI (it was originally standardized for Itanium CPUs, but it is used also on other architectures). It has been broken exactly twice:
- In gcc3, gcc switched from a previous ABI that predates C++98 to the standardized Itanium ABI
- When implementing C++11, the std::string class was modified in GCC5
The first of these two was a major break with everything changing, and the compiler provides no way around it. Either you use gcc2, or you use later versions. It is not possible to mix both.
The second one is a minor change to one class in the standard library. The compiler can be toggled between the two versions as needed with a compile time flag. However, when running a program, all libraries and executables must agree on which style is being used. Indeed this required recompiling everything.
Now on the special case of the x86 32bit version of Haiku. This is the only version that provides compatibility with BeOS applications. Initially we aimed for full compatibility: not only applications, but also drivers, add-ons, etc. The drivers part has already been removed (because it was not needed by anyone anymore). As a result, even in this version, the kernel is compiled with a modern gcc and is not restricted to C++98. We can and will consider migrating more parts of the code to a modern gcc in the future. For example, there is no reason to compile app_server with gcc2 anymore.
Next question: where must the ABI match, and how can we mismatch things anyway?
The ABI must match between all things in a given process (or “team”, in BeOS wording). That means one executable, and all the libraries and add-ons it loads. There is no need for the kernel and userspace to use the same ABI, because the communication between the two is not traditional function calls, but system calls, which are much simpler and easier to provide compatibility for.
That also means there is no need for compatibility between the ABIs used by different apps. Here the communication will typically be done using BMessage, which does not change depending on the ABI.
So already we have reduced the surface of the problem a lot: it’s just that an application and its libraries must be compiled with the same compiler.
And even that isn’t completely true, it applies only if the interface between a library and an application uses something that has changed between the two ABIs. In the switch from gcc2 to gcc3 this was “everything C++”, but in gcc4 to gcc5 it was only std::string.
So, if your library exposes only C APIs, it is in fact possible to mix and match different compiler versions. For example, we have a version of ffmpeg that is built with a modern compiler, in a way that gcc2 applications can still use it without problems. It is not easy, but it is possible.
How do we handle this currently?
Our solution at the moment is to provide two versions of all system libraries: one compiled with gcc2, one compiled with gcc11. They are located in different directories and runtime_loader (the code tasked with starting new applications) knows how to load the correct ones for each application.
Some parts of the API are already not available for gcc2 apps. The goal is not to keep gcc2 working forever, but be able to run BeOS apps until they all have been updated or replaced. There is an ongoing effort by the HaikuArchives project to reach authors of BeOS apps and get them to update their work, or, if they don’t want to do that, publish the source under a license that allows us to update things.
Eventually, the interest for the gcc2 ABI will be sufficiently low, and we can remove it from Haiku. We have not reached that point yet.
With this setup, we have sufficient degrees of freedom to introduce modern C++ in the code for newer versions of the API and ABI, simply disabling these parts for the gcc2 build. So, only the parts of Haiku that replicate BeOS functionality really need to build with gcc2.
What will happen in the future?
We will have to break ABI every now and then for various reasons. Not only because of compiler changes, but also because of design problems in the existing API. In some cases we can make this work transparently by providing multiple versions of a function (this method is called symbol versioning).
At some point this may not be enough anymore, and we may decide to make an entirely new set of libraries. That is what we call “R2” (short for “Release 2”). There are not much written down plans for this, but I expect the R2 version will provide the R1 libraries to run old apps, and in addition also provide the new R2 libraries to run new apps, just like the current R1 version contains a build of the libraries for BeOS apps, and another set of libraries for the newer gcc11 apps.
We can easily commit to each version running the apps built on the previous one in this way. If we only do a major release every 20 to 25 years, that is more than enough. If we do releases more often, maybe we want to keep these alternate sets of libraries around for a bit longer. This is what Windows also does, you may know of the “Visual C++ redistributable” packages that some apps will install, there is one with every version of Visual Studio and it contains a copy of all the libraries to run apps compiled with that version of Visual Studio.
The “apocalypse” is when we remove support for one of these sets of libraries. It will have to happen eventually, but we will make it so people have a lot of time to adjust, by porting or replacing applications that have never been updated to a newer version. Or, if that’s not acceptable, somehow keep running these old apps by keeping their libraries around forever. Since they will be a separate set of libraries, they do not really force us to use C++98 for everything else.
I hope this answers most of your questions. Now people can discuss their ideas on how to make this work even better, or other problems that oculd happen and that I didn’t mention