Packages which use GNU Autoconf scripts will assume your system type
is something like “i686-pc-linux-gnu” when it should be named
“i686-pc-linux-uclibc”. With
most packages it is not vital to correct this, but with the toolchain
it is important. We can make a config.site file to set the --host/build/target=i686-pc-linux-uclibc
parameters, and set the CONFIG_SITE
environment variable to match, which will tell packages our uClibc
system type. Most packages will use it without issue, some will not.
The Expect package, for instance, will complain that the uClibc
system type is unknown, however with the Expect package this is
harmless. Other packages, in the next chapter or BLFS, may need their
config.sub replaced with a newer
version which is installed to /usr/share/automake by the Automake package. The
next command creates the config.site
file and sets it in the shell environment. If you log out of the
shell for any reason during this chapter then be sure to reset it:
install -vd /tools/share cat > /tools/share/config.site << "EOF" host=$(uname -m)-pc-linux-uclibc build=$host target=$host ac_cv_host=$host ac_cv_build=$build ac_cv_target=$target EOF export CONFIG_SITE=/tools/share/config.site
Now that the temporary C libraries have been installed, all tools compiled in the rest of this chapter should be linked against these libraries. In order to accomplish this, the linker and the compiler's specs file need to be adjusted.
The linker, adjusted at the end of the Embryo toolchain, needs to be
renamed so that it can be properly found and used. First, backup the
original linker, then replace it with the adjusted linker. We'll also
create a link to its counterpart in /tools/$(gcc -dumpmachine)/bin
mv -v /tools/bin/{ld,ld-old}
mv -v /tools/$(gcc -dumpmachine)/bin/{ld,ld-old}
mv -v /tools/bin/{ld-new,ld}
ln -sv /tools/bin/ld /tools/$(gcc -dumpmachine)/bin/ld
From this point onwards, everything will link only against the
libraries in /tools/lib.
The next task is to point GCC to the new dynamic linker. This is done by dumping GCC's “specs” file to a location where GCC will look for it by default. A simple sed substitution then alters the dynamic linker that GCC will use:
gcc -dumpspecs | sed -e 's@/lib/@/tools/lib/@g' \
-e 's@ld-linux.so.2@ld-uClibc.so.0@g' \
> `dirname $(gcc -print-libgcc-file-name)`/specs
It is recommended that the above command be copy-and-pasted in order to ensure accuracy. Alternatively, the specs file can be edited by hand. This is done by replacing every occurrence of “/lib/ld-linux.so.2” with “/tools/lib/ld-uClibc.so.0”
Be sure to visually inspect the specs file in order to verify the intended changes have been made.
During the build process, GCC runs a script (fixincludes) that scans the system for header files that may need to be fixed (they might contain syntax errors, for example), and installs the fixed versions in a private include directory. There is a possibility that, as a result of this process, some header files from the host system have found their way into GCC's private include directory. As the rest of this chapter only requires the headers from GCC and libc, which have both been installed at this point, any “fixed” headers can safely be removed. This helps to avoid any host headers polluting the build environment. Run the following commands to remove the header files in GCC's private include directory (you may find it easier to copy and paste these commands, rather than typing them by hand, due to their length):
GCC_INCLUDEDIR=`dirname $(gcc -print-libgcc-file-name)`/include &&
find ${GCC_INCLUDEDIR}/* -maxdepth 0 -xtype d -exec rm -rvf '{}' \; &&
rm -vf `grep -l "DO NOT EDIT THIS FILE" ${GCC_INCLUDEDIR}/*` &&
unset GCC_INCLUDEDIR
At this point, it is imperative to stop and ensure that the basic functions (compiling and linking) of the new toolchain are working as expected. To perform a sanity check, run the following commands:
echo 'int main(){return 0;}' > dummy.c
cc dummy.c
./a.out &&
readelf -l a.out | grep ': /tools'
If everything is working correctly, there should be no errors, and the output of the last command will be of the form:
[Requesting program interpreter:
/tools/lib/ld-uClibc.so.0]
Note that /tools/lib appears as the
prefix of the dynamic linker.
If the output is not shown as above or there was no output at all,
then something is wrong. Investigate and retrace the steps to find
out where the problem is and correct it. This issue must be
resolved before continuing on. First, perform the sanity check
again, using gcc
instead of cc. If
this works, then the /tools/bin/cc
symlink is missing. Revisit Section 5.2, “Embryo
Toolchain,” and install the symlink. Next, ensure that
the PATH is correct. This can be checked
by running echo $PATH
and verifying that /tools/bin is at
the head of the list. If the PATH is
wrong it could mean that you are not logged in as user hlfs or that something went wrong back in
Section 3.7,
“Setting Up the Environment.” Another option is
that something may have gone wrong with the specs file amendment
above. In this case, redo the specs file amendment, being careful
to copy-and-paste the commands.
Once all is well, clean up the test files:
rm -v dummy.c a.out
Building TCL in the next section will serve as an additional check that the toolchain has been built properly. If TCL fails to build, it is an indication that something has gone wrong with the Binutils, GCC, or libc installation, but not with TCL itself.