As I promised yesterday, here is the post summarizing what needs to be done in order to have GCC running in HelenOS as a native compiler.
I tried to divide the missing things into some bigger topics that are outlined below. Their order does not imply their significance neither their difficulty.
Supported architectures
So far, I was reporting results for ia32
architecture only.
I also tried to build for other architectures but with less success.
The first problem is that GMP requires longjmp
.
But this function is implemented for ia32
only.
Although the implementation for ia32
looks trivial, I would rather
leave implementation for other architectures to someone stronger in assembler.
I encountered next problem during linking on amd64
.
Our linker script drops .data.rel.ro
section, preventing linking with GMP.
On amd64
, another function for counting bits was missing as well.
Adding the function is easy but I am not so sure about the linker
script.
Maybe, there is some reason why this section is being omitted.
Aside from this, I believe there is not a principial problem in building GCC for all architectures supported by HelenOS.
Proper *-helenos-* target
As I already wrote
there is a problem persuading the configure
script that it is actually
cross-compiling when both --build
and --target
refer to the
same architecture.
The proper solution is to have a HelenOS specific target.
That is, to have a *-helenos-*
triplet instead of a *-linux-*
one.
With such target, we would be building for e.g. i686-pc-helenos
instead of i686-pc-linux-gnu
.
Adding such target to GCC is possible: see for example this tutorial on OSDev.
As a matter of fact, such patches already exists and they are present
in current mainline.
With them, the toolchain.sh
can create a toolchain for HelenOS
with *-helenos-*
triplet.
If you have spare time, build this toolchain as well and try to compile
HelenOS with it.
There shall not be any difference compared to the current toolchain
(they can coexist without problems) and eventually we may want to
use the HelenOS-specific toolchain only.
But these patches are for GCC 4.8.1 while I was playing with 4.6.3. The reason is rather simple: new GCC requires a full fledged C++ support while 4.6 and older were written in plain C. So, the patches for HelenOS target needs to be modified to fit 4.6.3. Or, we need to port some C++ library (STL) to HelenOS or write our own.
Patching libiberty
The iberty
library is a GNU wrapper providing various utility functions
(such as command-line argument parsing) hiding details of the underlying
C libraries.
The idea behind libiberty
(link with -liberty
) is to simplify
writing portable software.
HelenOS behaves a lot like a standard Unix system and thus there is not
much need to patch this library.
The only exception is launching of new processes.
HelenOS does not support fork
/exec
pair and thus implementation
of the process-execution function had to be provided.
Currently, the file contains a lot of dead code and definitely needs
to be cleaned-up.
Other problem is that it directly calls functions from HelenOS libc
.
Namely, it calls task_create()
and task_wait()
.
But this breaks a bit the namespaces.
When the program is linked with libposix
, symbols from libc
are
mostly hidden and are not expected to be used
(except, of course, from functions in libposix
).
It is not a critical problem but a cleaner separation of libposix
and libc
shall be eventually done.
As a matter of fact, I think we should eventually introduce something
like libstdc
containing functions from a C standard.
Including those we do not want to have in our libc
, such as strcpy()
,
and those that are there now, such as fopen()
.
The ultimate goal is to reach a situation when porting application
that has event.h
header or event_subscribe()
function
would not cause any clashes requiring wild hacks to overcome the collision.
I believe it is possible with some linker magic and some clean-up
in our current headers.
Reducing command-line options
The really ugly thing about current situation is that user needs to specify about 7 options on the command-line to compile a single file. These options needs to be repeated for any compilation.
What needs to be done in this manner is very simple.
GCC can be configured (at build time) where to look for libraries or include
files.
The natural prerequisite is that we would have a *-helenos-*
target to
avoid overriding Linux settings (which is of course possible but it is
extremely ugly).
The actual configuration is then rather simple: you just override a macro
definition and add an inclusion of a specific header file.
For completeness, below is a list of things that should be specified inside GCC at build-time instead of run-time.
- Default include directories
- HelenOS-specific defines (such as
__LE__
or__32_BITS__
) - Path to default linker script
- Path to libraries
- Default libraries to link with
Distribution and packaging
Building of GCC or binutils is quite time-consuming operation.
I think it is not wise to try to include GCC building inside HelenOS source
tree as it is done with binutils.
In fact, I think we should move binutils outside of the source tree as well.
However, once they are build, they can be used even if HelenOS was rebuild
in the mean time (minus situation when something in libposix
was changed).
Maybe we should start thinking about providing a repository with prebuilt software for HelenOS. Since we have a downloader in HelenOS, a simple batch script would be enough to download these automatically into a running HelenOS.
Definitely, following software can be distributed like that
- GCC
- binutils (linker, assembler etc.)
- PCC
- MSIM
- minigzip (example application from zlib)
As a matter of fact, we may start seriously thinking about a proper package manager for HelenOS.
Miscellaneous
Last thing that occured to me is that it would be nice to provide
our own switches to GCC.
These would be used to determine what kind of application is being built.
Native HelenOS applications would be build by default.
But if user would like to build a ported POSIX application, she would pass
-posix
switch to GCC that would ensure that libposix
is used and
POSIX headers are on the include path.
Just an idea :-).
Battle-plan
This is all I know about that is missing from completing GCC port. The question is what is next.
I would probably start with patching GCC with *-helenos-*
triplet
followed by adding correct default paths.
In the process I want to clean-up the HelenOS PEX module in libiberty
as well.
That is something I know how to do.
With others tasks, I would certainly welcome some help.
I guess adding the longjmp
is a piece of cake for someone familiar with
the assembler of individual architectures.
Writing our own STL seems to me as a waste of time so maybe we should look around for some BSD-licensed library that would be easy to port. libc++ looks promising: active development, it offers C++11 functionality and is dual-licensed under MIT and UIUC (BSD-like).
Regarding the linker script.
In my opinion we shall not drop the .data.rel.ro
section but I would
like to have a confirmation on this.
The question on packaging and distribution certainly deserves a dicussion on the mailing-list. Maybe I will provide a prebuilt packages with GCC and binutils somewhere here. Maybe.
And that is all. Thanks for reading.
Comments
Watch comments through RSS