2013-01-24

Towards GCC for HelenOS

Compiling GCC to run inside HelenOS is for quite some time on the ToDo list of HelenOS. I decided to give it a try and if you want to follow what I did so far, carry on reading.

GCC itself has several dependencies that have to be compiled first. This was already described during GSoC but unfortunately the project didn't make it through.

Currently, the only option for compiling all these libraries is to cross compile them outside of HelenOS. This looks like a simple job because most of GNU software has special flags (--host) for configure scripts that shall simplify cross-compiling. But studying the intrusive.sh from the binutils port reveals that it is not always that simple. However, for simple libraries this approach shall work.

Theoretically, it shall be sufficient to just call ./configure with proper --host argument and specify a few CFLAGS and we are done. Practically, there has to be done more than that.

I decided to first play with porting zlib compression library that has virtually no dependencies and its configure is pretty simple. After few attempts to correctly set the CFLAGS that always resulted in awful screams from the configuration script, I realized that I have to automate this work at least a bit.

Thus the script configure-for-helenos.sh was born. You can find it in my HelenOS scripts repository on GitHub. The script gets directory with HelenOS sources as a parameter and extracts from it all the necessary settings, such as path to the cross-compiler or flags for it and then calls the configure script. Thus, instead of manually specifying all the flags and paths into HelenOS source tree, you only specify path to HelenOS source root and the script does the rest.

So, let's try it on zlib sources. Let's unpack them and configure the library using the helper script. Assuming you placed the script into ~/bin/, the following command will do the trick - used options are described later.

~/bin/configure-for-helenos.sh \
    -d ~/helenos/mainline \
    --run-with-env \
    --link-with-cc \
    --ldflags-ignored \
    --verbose \
    -- \
        ./configure \
            --static

The meaning of individual arguments is following. The normal parameters specify the script to run and any arguments to it. Here we call the standard configuration script and we specify that we want only static library. The individual options are:

-d
Path to HelenOS sources. HelenOS has to be already configured and built.
--run-with-env
Execute the script (configure) through env, passing settings as environmental variables instead of parameters to configure. The difference is shown below.
--link-with-cc
The build process links the binary by calling compiler, not linker directly.
--ldflags-ignored
Moreover, (pretty standard) variable LDFLAGS is completely ignored and shall be merged into CFLAGS.
--verbose
Just be more verbose.

The difference between running with --run-with-env is following. Without this option, the configure is run as

./configure --static \
    CC=gcc CFLAGS="-whatever -flags -you -want"

while with this option, env is invoked first.

env CC=gcc CFLAGS="-whatever -flags -you -want" \
    ./configure --static

The configuration is pretty short and below is a sample output for mips32/msim:

Building static library libz.a version 1.2.7 with \
    /usr/local/cross/mips32/bin/mipsel-linux-gnu-gcc.
Checking for off64_t... Yes.
Checking for fseeko... Yes.
Checking for strerror... Yes.
Checking for unistd.h... Yes.
Checking for stdarg.h... Yes.
Checking whether to use vs[n]printf() \
    or s[n]printf()... using vs[n]printf().
Checking for vsnprintf() in stdio.h... Yes.
Checking for return value of vsnprintf()... Yes.
Checking for attribute(visibility) support... Yes.
./configure: line 719: ./ztest5950: \
    cannot execute binary file
Looking for a four-byte integer type... Not found.

The mentioned error only means that configure was trying to determine 4B integer type by launching a simple application and it did not succeed. Unsurprisingly, since the binary was compiled for MIPS-32 while the build was running on AMD-64. But it still works.

Then, just run make. It shall execute okay and produce libz.a static library and minigzip executable.

To try a live demo, copy the minigzip to uspace/dist/app and rebuild HelenOS. Then in terminal (in HelenOS) run

ls /
minigzip /textdemo
ls /

The second listing shall display textdemo.gz instead of textdemo. Cool, isn't it?

And that is all for now. Next time, I will describe building some of the real GCC dependencies. If you are impatient, you may try it by yourself - there is a short explanation in the README of the HelenOS scripts repository. Please, note that so far I do not have a working GCC for HelenOS and it is possible that this serie will end with a pessimistic scream such as it doesn't work and it won't work because abc until we xyz. Stay tuned ;-).

5 komentářů:

  1. Looking forward for more news from this area...

    OdpovědětSmazat
  2. Hi,
    We are trying to cross compile Nano then Emacs text editor as our project. Can you give us some details on how to cross compile an application like Nano text editor for HelenOS. Please provide as much details an you can for Nano, it will be very helpful to kick start out project for Emacs.
    -Pratik Mankawde
    pratik.mankawde@iiitb.org

    OdpovědětSmazat
  3. Hello, Pratik,
    I never tried compiling Nano for HelenOS and really I can't give you much guidance for this particular application.

    By looking at this PKGBUILD (that captures how to build Nano for Arch Linux) it seems that Nano uses the standard ./configure && make && make install triplet and cross-compiling it for HelenOS would be similar to the one described in this post or other posts of this serie.

    The problem is that Nano requires ncurses and I guess that porting that library would not be that easy. This library expects a Unix-like terminal to run in and the vterm we have in HelenOS is something completely different. Thus, porting of ncurses would be rather reimplementing the library from scratch, and keeping the API only.

    As a matter of fact, Emacs needs ncurses too. So, you need to port that library first anyway.

    If you encounter any concrete problem, do not hesitate to ask on the HelenOS development mailing list.

    OdpovědětSmazat
  4. Hello Vojta,
    Thanks for the answer. I tried to port ncurses to helenos and reached same conclusion. Anyway I will try to do it. Can we use the same version of libgmp, libmpc and libmpfr as compiled on gcc or will have to cross compile it first, the way you explained here and then include its path to ncurses compilation for cross compiling ncurses?
    Sorry for bothering you too much, I am a grad. student, and a beginner on linux, porting and related stuff.

    OdpovědětSmazat
  5. Hello, Pratik,

    Can we use the same version of libgmp, libmpc and libmpfr as compiled on gcc or will have to cross compile it first, the way you explained here and then include its path to ncurses compilation for cross compiling ncurses

    First of all, I do not think that you need libgmp & co. at all for ncurses. But assuming you need them, you would have to cross-compile them first. AFAIK ncurses expects glibc which is something we do not have in HelenOS.

    Sorry for bothering you too much, I am a grad. student, and a beginner on linux, porting and related stuff.

    No problem :-). However, Linux does not enter into it as HelenOS is not Linux.

    OdpovědětSmazat