Tuesday, 13 July 2010

LAP - Toolchain, Part 4 - Rebuild

It is now time to go back to binutils.  Last time we built this we used the compilers and other software from Ubuntu.  In particular the software that we installed in the build-essential package.  It is now time to build binutils again, but this time with the new software that we just made.

tar -jxvf $LFS/sources/binutils-2.20.tar.bz2
mkdir -v binutils-build
cd binutils-build
CC="$LFS_TGT-gcc -B/tools/lib/" AR=$LFS_TGT-ar RANLIB=$LFS_TGT-ranlib ../binutils-2.20/configure --prefix=/tools --disable-nls --with-lib-path=/tools/lib

The [CC="$LFS_TGT-gcc -B/tools/lib/" AR=$LFS_TGT-ar RANLIB=$LFS_TGT-ranlib] bit is specifically telling the program to compile using our new tools and not the ones on the host system.  We have already seen the [prefix] and [disable-nls] options.  The last option again forces the compiler to use the new stuff and now the host programs.

make install

We also now need to do a bit of work to prepare for the next phase.  Essentially we are preparing to reverse the step where we pointed to the /tools directory for all compiling operations.  To do so we will need a new version of some of the binutils software.  We could uncompress the archive and make the software at that stage, but it is easier to just do it just now.

make -C ld clean

This cleans out the directory ld so we can:

make -C ld LIB_PATH=/usr/lib:/lib

This rebuilds the ld program, pointing at the normal /usr and /lib locations that will finally be used rather than the temporary /tools.

cp -v ld/ld-new /tools/bin

This just [c]o[p]ys the file we just made to its destination.  Do not worry that it is in /tools, we will sort that all out in due course.

Lets clean up again.

cd ..
rm -rfv binutils-2.20 binutils-build

Now, lets do the same to GCC.

tar -jxvf $LFS/sources/gcc-4.4.3.tar.bz2
cd gcc-4.4.3

For the first time we need to patch the software before we can use it.  The reason for this is that this software does not expect to be used in the way the the Linux From Scratch install uses it.  So we need to literally reprogram it.  Helpfully someone has put together a list of the changes that need to be made, and we apply them by running this command:

patch -Np1 -i $LFS/sources/gcc-4.4.3-startfiles_fix-1.patch

This runs the [patch] command using the [i]nput file [cdrom/sources/gcc-4.4.3-startfiles_fix-1.patch].  The option [N] means that it will skip over patches that appear to have already been applied.  The [p1] bit affects how filenames in the files to be patched are treated.  Effectively it lops off part of the path of each filename.  Why this is necessary is beyond me.  The output of that command looked like this to me:

patching file gcc/gcc.c 
Hunk #1 succeeded at 6467 (offset 97 lines).

Part of the compilation of GCC calls a script to fix broken parts of GCC or Glibc.  The authors of Linux From Scratch are confident that this is not needed, and indeed worried that if it is run it may bring in some material from the host system.  The script is disabled as follows:

cp -v gcc/Makefile.in{,.orig}
sed 's@\./fixinc\.sh@-c true@' gcc/Makefile.in.orig > gcc/Makefile.in

I am beginning to see a theme developing here.  If the 'sed' command is used it is usually followed by some bizarre string of characters that seem to magically achieve the desired effect.  The first command here just makes a backup of the file [Makefile.in] before the 'sed' weirdness is let loose on it.  Only sensible if you ask me.

In a similar vein to the last one, we need to force some behaviour that would ordinarily not happen.  This is something to do with bootstrapping, which sounds like a punishment in a nineteenth century boys school.

cp -v gcc/Makefile.in{,.tmp}
sed 's/^T_CFLAGS =$/& -fomit-frame-pointer/' gcc/Makefile.in.tmp > gcc/Makefile.in

There's that fucking sed again.  Next we need to, again, ensure that we are building using the new tools and not anything on the host system.  This involves editing lots of text files, which would be boring, so lets do it automatically.

for file in $(find gcc/config -name linux64.h -o -name linux.h -o -name sysv4.h)
  cp -uv $file{,.orig}
  sed -e 's@/lib\(64\)\?\(32\)\?/ld@/tools&@g' -e 's@/usr@/tools@g' $file.orig > $file
  echo '
#define STANDARD_STARTFILE_PREFIX_2 ""' >> $file
  touch $file.orig

Roughly speaking this sets up a loop (the bit between the do and done) for every file found by the bit in brackets in the first line.  Because this involves more sed insanity I refuse to try and work out what else is going on.  When I run it, it seems to edit about 20 or so files.  This is again a command that you paste into the terminal in one go.

We need the maths libraries again, so unpack them once more:

tar -jxf $LFS/sources/mpfr-2.4.2.tar.bz2
mv -v mpfr-2.4.2 mpfr
tar -jxf $LFS/sources/gmp-5.0.0.tar.bz2
mv -v gmp-5.0.0 gmp

After we have moved to the temp build directory, it is time to configure the build:

mkdir -v ../gcc-build
cd ../gcc-build
CC="$LFS_TGT-gcc -B/tools/lib/" AR=$LFS_TGT-ar RANLIB=$LFS_TGT-ranlib ../gcc-4.4.3/configure --prefix=/tools  --with-local-prefix=/tools --enable-clocale=gnu  --enable-shared --enable-threads=posix --enable-__cxa_atexit --enable-languages=c,c++ --disable-libstdcxx-pch --disable-multilib --disable-bootstrap

We have now seen most of these before.  The [with-local-prefix] option is not documented in either the book or the configure --help information.  It obviously seems to be connected to the new software.  [enable-clocale=gnu] sets some locale to make sure that it does not speak german.  This time we are enabling the [shared] option, which makes about as much sense to me as disabling it – but hey ho.  The [enable-threads=posix] configures gcc for multi-threading so you can take advantage of multicore cpus.  The [ enable-__cxa_atexit] option is explained as follows in the book:

“This option allows use of __cxa_atexit, rather than atexit, to register C++ destructors for local statics and global objects.”

Make sense to you?  Makes no sense to me, but Destructors sound cool.  Do they fight Autobots?  The [enable-languages=c,c++] makes sense – we now need more language support because we are building more than Glibc with this compiler.  [disable-libstdcxx-pch] stops the compilation of something called a pre-compiled header for libstdc++, because according to the book, we have no use for it.  Lastly, the [disable-bootstrap] option stops it assaulting schoolboys.  Wait, what?  Oh, right apparently it prevents the build doing time consuming checks.

make install

The program we have just made is called gcc, but some software looks for a program called cc, so lets make a quick symbolic link:

ln -vs gcc /tools/bin/cc

To test the compiler run the test commands again:

echo 'main(){}' > dummy.c
cc dummy.c
readelf -l a.out | grep ': /tools'

The output should be the same:

[Requesting program interpreter: /tools/lib/ld-linux.so.2]

Assuming that works fine, just delete the temporary files:

rm -v dummy.c a.out

Clean up the source code files:

cd ..
rm -rvf gcc-4.4.3 gcc-build

Now, onto some new packages.

No comments:

Post a Comment