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!

No comments:

Post a Comment