Saturday 14 July 2012

Fixing eglibc/manual Makefile rules

In my last blog, I cheated a bit, as I said that "I had to edit manual/Makefile, splitting the implicit and explicit make rules".

At the time, I hadn't actually done this, but the process was reasonably straightforward. Line 235 of manual/Makefile contained the line:


$(objpfx)stubs ../po/manual.pot $(objpfx)stamp%:

The % on the end of the third target makes it an implicit rule, whereas the other two targets are explicit (or normal). The fix was simply to duplicate the steps against separate targets; one explicit and one implicit. This is in fact how the Makefile looks in later versions of eglibc.


When I came to make install eglibc, I still encountered problems with it failing to build the manual (which I didn't want anyway). I tried downloading the source for the manual, but that didn't fix it. Instead I made another edit to the Makefile, changing the subdir_install target (line 181) to be empty (removing the "install" dependency).

Following this all built smoothly and I now have a working stage3 compiler!

Monday 9 July 2012

A First CC

Before I start, I'd like to note that I have entirely followed the instructions from the eglibc source code, which I downloaded on my Raspberry Pi using "apt-get source eglibc".

[edit] I have since discovered that patches should then be applied by entering the eglibc-2.11.3 directory and running debian/rules patchThis required quilt to be installed (apt-get install quilt) [/edit]

From there, I used scp to copy the sources folder to my netbook, into a src folder under my home directory.

The first instruction was to set up some environment variables, which proved very useful later.  I put these in a file that I could source later.  Firstly, setting our aims:

export build=i686-pc-linux-gnu
export host=$build
export target=arm-unknown-linux-gnueabi
export linux_arch=arm


Next, some version information. I didn't use all of these, but it's good for reference:

export binutilsv=binutils-2.20.1
export gccv=gcc-4.7.1
export linuxv=linux-3.1.9


Finally, our environment:

export top=~/src/cross-compile/arm
export src=~/src/cross-compile/src
export obj=$top/obj


export tools=$top/tools
export sysroot=$top/sysroot


With the environment set up, I was ready to build.  First up was binutils, the package of useful utilities for making C programs actually runnable (as far as I understand!). This was straightforward; I simply copied the steps from the Readme:

    $ mkdir -p $obj/binutils
    $ cd $obj/binutils
    $ $src/$binutilsv/configure \
    >     --target=$target \
    >     --prefix=$tools \
    >     --with-sysroot=$sysroot
    $ make
    $ make install


Next up was the first gcc; the Readme says that 3 are needed. This blog post will just cover the building of the first one, as there were quite a few steps and pitfalls to cover.

I had a bit of a false start with gcc, as I started, as before, by running apt-get source gcc.  To cut a long story short, this downloaded the wrong package, then I located the right package, but unpacking it failed, so I headed over to gcc.gnu.org to get the latest GCC code (4.7.1), figuring that I didn't need to match the compiler version that compiled the original libraries.

While configuring, gcc told me it needed GMP, MPFR and MPC libraries, so I had to head back to the gcc mirrors for these. Fortunately, configuring and compiling them was a doddle, just needing to specify the location of the previously built libraries while going through the list. I wasn't sure where to put the installed binaries, so I opted for a prefix of $top/i686.

     $ cd $obj
     $ mkdir gmp mpfr mpc
     $ cd gmp
     $ $src/gmp-4.3.2/configure --prefix=$top/i686
     $ make
     $ make install

     $ cd ../mpfr
     $ $src/mpfr-2.4.2/configure \
     >     --prefix=$top/i686 \
     >     --with-gmp=$top/i686
     $ make
     $ make install

     $ cd ../mpc
     $ $src/mpc-0.8.1/configure \
     >     --prefix=$top/i686 --with-gmp=$top/i686 \
     >     --with-mpfr=$top/i686
     $ make
     $ make install


When compiling gcc I had to enter an extra --disable-libquadmath flag to the configure script, as this was attempting to load the library (for tests) but was unable to. I guessed I could live without it.  The full command was:

    $ $src/$gccv/configure --target=$target \
    > --prefix=$tools --with-newlib --disable-shared \
    > --disable-threads --disable-libssp \
    > --disable-libgomp --disable-libmudflap \
    > --enable-languages=c --with-gmp=$top/i686 \
    > --with-mpc=$top/i686 --with-mpfr=$top/i686 \
    > --disable-libquadmath
    $ PATH=$tools/bin:$PATH make
    $ PATH=$tools/bin:$PATH make install


I downloaded the sources for the linux 3.1.9 sources twice, firstly from kernel.org, then from the raspberrypi project on github. To install the headers, a copy must first be made in the source directory, then the "headers_install" make target run:


    $ cp -r $src/raspberrypi-linux-c47ee9d $obj/linux
    $ cd $obj/linux
    $ PATH=$tools/bin:$PATH \
    > make headers_install \
    > ARCH=$linux_arch CROSS_COMPILE=$target- \
    > INSTALL_HDR_PATH=$sysroot/usr


Finally, we get to build eglibc itself. I found that I had problems building initially, with make complaining about a missing "manual" directory. This was because I hadn't applied the debian patches to the source (see the top of the post), but there was a bug with the patch against my version of make, so I had to edit manual/Makefile, splitting the implicit and explicit make rules. Once this was sorted out, it was just a case of following the instructions to build the libraries. The most interesting of these instructions was compiling /dev/null into libc.so, since, although this file is required by the build, it is never read!

... some instructions omitted, find in the eglibc source code ...

    $ $tools/bin/$target-gcc -nostdlib -nostartfiles \
    >                        -shared -x c /dev/null \
    >                        -o $sysroot/usr/lib/libc.so

And there you have your first GCC. I'm still not entirely sure what it can do, however! The document says that the second CC will be able to build eglibc and I think the third is a full cross-compiler. The instructions look pretty straightforward, so I'll give it a go and let you know how I get on!