Moving to GCC 4.4
From ReactOS
| | This page is a candidate for speedy deletion If you disagree with its speedy deletion, please explain why on its talk page.
Watch also the Criteria for speedy deletion! |
Contents |
Motivation
The current RosBE official compiler is GCC 4.1.3. This version of the compiler is coming up on its two year anniversary, and is riddled with severe bugs which require:
- Manual patching to even make it work on Vista or generate proper code
- Hacks in the tree to support exception handling, such as disabling pre-compiled headers or optimizations to make the code faster
Additionally, up until GCC 4.3, the early GCC 4.x series was struggling to fix regressions from the stable 3.x series, which resulted in a compiler that had several missing features, especially when compared to compilers such as Microsoft's. This results in the ReactOS codebase using GCC as the "lowest common denominator" to avoid compiler issues, significantly reducing the techniques and code that can be used.
Finally, GCC 4.1.3 is much more forgiving with bad code sequences, resulting in code of poor quality compiling when it shouldn't.
GCC 4.4 provides an efficient, stable, base for our future compiler, and offers additional compatibility with other compilers. The optimizer is much more improved over older versions of GCC, and it should make for a smooth transition to GCC 4.5 when the time comes. GCC 4.4 is also the basis of the ARM port, and is also nearer to the version used by the AMD64 port. Finally, LLVM 2.6 is built on GCC 4.4, making the exploration and eventual use of llvm-gcc/clang a more realistic goal.
Moving to a new compiler, especially after two years, is not an easy task. The following attempts to document some of the work required.
Building
On Windows platforms, the MinGW project already offers binaries for GCC 4.4 that can be natively used. Efforts are currently under way to compile trunk with this version of GCC, so on the Windows side, building is not an issue.
On Linux/BSD platforms, GCC 4.4 must be built for the MinGW target by hand. While your distro may already offer a binary version, it does not make sense to try supporting every Linux user with his or her own version of the compiler. We already have a mechanism for supplying a "supported" compiler through RosBE/Unix, so this needs to be updated to come with GCC 4.4 and updated binutils instead. RosBE 1.5 for Unix will hopefully support this.
Compiling
Every new version of the compiler typically introduces stronger standards compliance, better checks for poor quality code, and additional warnings and optimizations which can reveal code defects. As the ReactOS has gotten crusty with the years, some of the code may not compile anymore. A log, generated on August 23rd 2009, is available to showcase the current compilation issues: GCC 4.4 Build Log.
There are two classes of warnings:
- Serious Warnings such as non-initialized variables, dangerous code sequences, undefined functions, redefinitions, dangerous conversions from one type to another
- Trivial warnings such as printf-formatting, non-dangerous type conversion
As you can see, most warnings are serious.
Looking through the build log, you will note the following types of modules which generate warnings.
- Priority 1: ReactOS-maintained code, such as kernel32, ntdll, the drivers, the kernel, our internal build tools, etc. These warnings should be fixed first. Even trivial warnings here should be fixed.
- Priority 2: Wine-maintained code, such as tools and user-mode DLLs and libraries. These warnings should either be fixed by sending upstream patches to Wine, or by making them part of the winesync-ros-diff process. If the warning is trivial and will likely not be fixed (unlikely), consider adding a -Wno-XXX compiler warning override to silence the warning.
- Priority 3: Third-party maintained code, such as 3rd party static libraries. First of all, check if a newer version of the library is available and import it. If the problem persists, submit a patch to the original project. If the warning is serious, patch it locally and make some note in whichever file documents the merge changes required to get the 3rd party project building for ReactOS. If the warning is trivial, consider adding a -Wno-XXX compiler warning override to silence the warning.
- Priority 4: Code outside the standard ReactOS module in the repository, such as winetests and rosapps. For rosapps, fix the warnings directly in-tree. If they are trivial, consider adding a -Wno-XXX compiler warning override to silence the warning. For code such as winetests, follow priority 2's guidelines, and consider adding a -Wno-XXX compiler warning override to silence the warnings, especially if they are trivial.
In general, for a successful move to a new compiler target, all possible warnings should be fixed in the tree, and trivial warnings silenced if they serve no purpose and would cause too much divergence from the original 3rd-party import (this mostly applies to signedness, pointer and printf formatter warnings).
Platform Support (Linking)
As GCC has evolved over the years, it offers newer functionality that requires support from various standard libraries and modules. Examples include C++ support, DWARF2 exceptions, and support for non-executable memory sections. These features are either incompatible with the aging ReactOS code base, or were not built to function in some of the environments that ReactOS code needs to execute in, such as NT kernel mode.
At a minimum, the following changes are required:
- C++ support, more probably for C++ exceptions. This might need to go in our C++ CRT, or we can try linking with libstdc++ instead.
- libgcc support, notably for executable stack support. The MinGW project offers a compatible version for Win32 development, but not for a native and/or kernel-mode environment. We need our in-tree version of this library with support for these additional environments (it would be nice to feed this back to MinGW).
- DWARF2 symbol support in rsym, since the STABS format is dying and deprecated.
Testing
Once the entire tree builds without warnings, it is time to begin testing the new operating system, rigorously. If things go well, a boot and test CD should be generated and tested, and will hopefully work without major problems. Major testing should be done to ensure everything works well.
If issues arise, they should be documented, and bugs opened for them. The exact modules responsible for causing a runtime failure should be isolated, by keeping a version of the GCC 4.1.3 tree and mix-and-matching binaries until the problem is found.
Once a GCC 4.4 binary is found to cause problems, the issue should be investigated. The first step is to try building without optimizations. Other steps include binary diffing to see which functions could cause problems. Because GCC 4.4 allows disabling optimization at a per-file and per-function level, this can also be used for investigation.
If a binary truly does not work when compiled with GCC 4.4, this is a show-stopper issue and serious developer time should be dedicated to fixing the issue.
New Features
Once ReactOS is proven to work reliably and at least as well with GCC 4.4 as it did with GCC 4.1.3, analysis of new features offered by GCC 4.4 should be investigated. Namely, these include:
- New compiler intrinsics
- Support for stack-aligned variables (removing the EX_PUSH_LOCK_WAIT_BLOCK hack)
- Per-function optimization control (allowing more assembly functions to be moved to C files if certain optimizations being disabled and/or enabled can guarantee successful code)
- Per-file and per-function pragmas for warnings
- The creation of a header to create compatible pragmas between Microsoft and GNU compilers, since GCC now supports these
- New optimization settings which can result in more aggressively compiled and efficient code
- Looking into using a non-optimized build for the build server's static compilation tests. This was previously infeasible since disabling optimizations would disable certain warnings, but this has now been fixed in GCC.

