TITLE: How to build a "pure" LFS LFS VERSION: CVS AUTHORS: Ryan Oliver , Greg Schafer SYNOPSIS: The current LFS build method is a lot better than it used to be but is still somewhat flawed in that not enough emphasis is placed on building a correct toolchain. This was recently highlighted by criticism levelled at LFS from senior Linux kernel hacker Alan Cox on the kernel mailing list. Here we present a new strategy aimed at building a correct toolchain and thus a "pure" LFS system. It is our belief that building a correct toolchain is the single most important lesson that people reading the LFS book need to know. Everything else is secondary. HINT: CHANGELOG ========= The latest version of this document should always be available at:- http://linuxfromscratch.org/~greg/ Failing that, a backup copy should also be available at:- http://www.zipworld.com.au/~gschafer/ * 1.0 2003-03-21 Initial revision DISCLAIMER ========== You use this hint at your own risk. Neither the authors, nor the Linux From Scratch project accept any reponsibility for anything that happens when using this document or associated files. This thing is very well tested but if in the unlikely event that it happens to break your system, you get to keep both pieces. INTRODUCTION ============ Broadly speaking, the toolchain comprises binutils, gcc and glibc. As of this writing, the current LFS version is 4.0. The problems with the build method as used in this version can be summarised as follows:- * too reliant on the host (build) system e.g. the autoconf tests for the static tools are performed whilst looking at the host system which may be vastly different from the final system. The most widely documented and glaring manifestation of this problem is gcc which ends up miscompiling a portion of glibc due to this flaw (the HAVE_GAS_HIDDEN hack works around this particular problem). * too much code is brought in from the host system e.g. all the static tools are statically linked against the host's glibc. The host's glibc is an unknown quantity and may contain bugs or anything. * too susceptible to incompatible glibc changes e.g. statically linked binaries compiled on a glibc-2.2.x based system that contain calls to getpwuid() crash when run on a glibc-2.3.x based system. * glibc is compiled whilst no existing glibc is present e.g. the glibc autoconf tests produce different results depending on whether an existing glibc is found or not. This leads to inconsistencies and encourages hacks and workarounds. (NOTE - some of the abovementioned issues have been partially addressed in the CVS version of the book but still do not go far enough and leave too much room for error.) To overcome all the issues, a new approach is required. The essence of what is presented below can be summarised as follows:- * build a fully "self contained" and "self hosting" toolchain that has no dependencies on the host system. The key differences between this approach and current LFS are:- * a glibc is built in Chapter 5 * this glibc is built using the Chapter 5 gcc and binutils (NOT the versions from the host) * the rest of Chapter 5 is built against the new glibc using the new binutils and gcc * Chapter 5 packages are installed into a prefix of "/stage1" rather than "$LFS/static" Some of the advantages to doing it this way are:- * we can build everything shared. It isn't necessary that we build all our binaries static in Chapter 5 (though you still can if you want to) as we will still have access to the shared libs we create when we chroot. * everything we use to build our shared binaries and libraries in Chapter 6 will ALREADY be built and linked against the glibc we are migrating to. This avoids glibc migration issues now and in the future. * the range of hosts suitable for building LFS from should increase due to less reliance on the host i.e. theoretically, the only requirement is that the host's compiler can bootstrap gcc. * a large portion of current LFS support related questions will disappear e.g. "failure to build Chapter 5 packages statically", "cannot build texinfo", "binutils detection related problems". Some key technical points of how the new approach works are:- * similar in principle to cross compiling whereby tools installed into the same prefix work in cooperation and thus utilise a little GNU "magic" * careful manipulation of ld's linker scripts (in particular, the SEARCH_DIR variables) * editing of gcc's "specs" file to tell gcc which dynamic linker to produce executables for At this point, it is worth mentioning there are other, less sophisticated ways of attaining a "pure" LFS. A "brute force" method is to build Chapter 6 twice. i.e. remove the /static directory (both physically and from the `PATH') then use Chapter 6 to rebuild itself. This is the basic idea behind the method employed by the Linux Standards Base folk with their LSB Sample Implementation[1]. Taking this approach is not practical for the LFS book. It is far too laborious and nowhere near as educational with regard to some of the toolchain internals we describe below. PROCEDURE ========= Toolchain cleanliness --------------------- It is important to realise there are varying degrees of "anal retentiveness" we can employ when building a new toolchain. The more anal we are, the "cleaner" the toolchain will be. For this reason it might seem we are building packages more times than we really need to, but you have to keep in mind, the goal here is to have a fully self hosted and very clean toolchain in which to perform the final clean build of our target system in Chapter 6. Steps that are not strictly necessary (i.e. less anal) will be pointed out as we move through the build. In other words, a few shortcuts can be taken at the expense of anal retentiveness. How we tested ------------- We started from a glibc-2.2.5/gcc-2.95.3 based host to ensure any glitches were caught early. The versions of the toolchain packages used in testing were binutils-2.13.2, gcc-3.2.1 and glibc-2.3.1. The main test platform was "i686-pc-linux-gnu". Where to get the patches and scripts ------------------------------------ The patches used in this document can be obtained from:- http://linuxfromscratch.org/~greg/patches/pure_lfs/ Additionally, we have made some scripts available:- http://linuxfromscratch.org/~greg/scripts/pure_lfs/ Please note, at this point in time the scripts are a bit further advanced than this document and do not match it exactly. Build considerations -------------------- Throughout this document we make a few assumptions that you may need to allow for depending on your circumstances. For example, in a few places you'll see hardcoded references to "i686-pc-linux-gnu" within the actual build commands. If your platform is anything other than i686-pc-linux-gnu (e.g. "i586-pc-linux-gnu" or "powerpc-unknown-linux-gnu") then you'll need to adjust accordingly. We also make use of the "*" wildcard operator so be mindful of this as it may cause you grief if for instance you have multiple versions of source packages lying around. It is also worth mentioning that the core toolchain packages all build in their own build directories (glibc is an exception in that it creates some files in the "manual" subdir but we take action to allow for this). It is therefore possible to reuse the same sources from previous build phases. If you do this, please be careful to undo any patches that may not be appropriate for the next phase. We'll warn you where necessary. Towards the end of this document you'll find a separate section that covers the perennial debate over which binutils release to use (FSF or HJL). For now, just be aware that a choice is available. Lastly, NLS is enabled throughout the build. The only 2 places where we use "--disable-nls" are the static "pass 1" builds of binutils and gcc. This is due to the fact that in certain circumstances, "--enable-nls" combined with a static link can cause build errors due to symbol conflicts. Please note that you are free to use "--disable-nls" throughout the remainder of the entire build if NLS is not desired and/or you wish to save space. Running the test suites - A quick overview ------------------------------------------ Most packages provide a test suite. Running the test suite is a good idea as it provides a nice "sanity check" and proves that a newly built package is functioning mostly as the developer intended. It does NOT guarantee that the package is bug free as this nigh on impossible. The test suites for gcc and binutils rely on the presence of 3 external packages i.e. tcl, expect and dejagnu. If you want to run the test suites from the very outset, you'll need to ensure those 3 packages are installed on the host system. This document assumes those 3 packages are not installed on the host and therefore does not run the test suites for the static "pass 1" builds of binutils and gcc. The "pass 1" builds are soon overwritten by the "pass 2" builds so skipping the "pass 1" test suites is not a major problem in our view. Be warned, the test suites for gcc and glibc can take a very long time to complete. If build time is a major problem for you then shortcuts are possible by skipping the Chapter 5 test suites but we do not recommend this. If you decide to take the shortcuts, then at the very least DO NOT skip the Chapter 6 test suites of glibc, binutils and gcc. But keep in mind, if you get to Chapter 6 then discover a problem that would have been picked up earlier by running the test suites in Chapter 5, you'll surely rue your earlier decision to take the shortcuts. Chapter 5 - Creating the /stage1 directory ------------------------------------------ We assume you have already reached Chapter 5 of the LFS book. i.e. partition created, filesystem made, partition mounted, $LFS/static created, lfs user added, environment set up. As mentioned in the introduction, we will use "/stage1" instead of "/static" due to the fact we will be building a dynamic (shared) Chapter 5. This naming is only a cosmetic thing. Leaving it as /static is likely to cause confusion. Please revisit the "Creating the $LFS/static directory" chapter of the book but instead run the following:- mkdir $LFS/stage1 Also, don't forget to perform the chown operation:- chown lfs $LFS/stage1 The next step is to create a "/stage1" symlink on the host system. It will point to the directory we just created on the LFS partition:- ln -s $LFS/stage1 / This ensures our toolchain will look in the same place (i.e. /stage1) in both Chapters 5 and 6 (when we are inside the chroot). This is an important concept to grasp. Don't worry if it's not clear right now. All will make sense once we get into Chapter 6. Chapter 5 - Setting up the environment -------------------------------------- Some adjustments to the environment set up are needed. Firstly, we do not use the:- export CC="gcc -s" thing. We are trying to do things correctly here and strictly speaking, the "-s" is a linker flag. Therefore we will put "-s" in the LDFLAGS where it belongs like so:- export LDFLAGS="-s" Secondly, we need to add "/stage1/bin" to the lfs user's `PATH' like so:- export PATH=/stage1/bin:$PATH As we progressively install Chapter 5 packages into "/stage1", the tools we just built will get picked up in the `PATH' and thus get integrated into the build process as we move along. Thirdly, if using the bash shell, it's not a bad idea to switch off the "hash" function of bash like so:- set +h Bash has a useful feature whereby it uses a hash table to remember the full pathnames of executable files to avoid multiple `PATH' searches. However, we'd like the new tools to become available as soon as they are installed. By switching off the hash function, our "interactive" commands (make, patch, sed, cp and so forth) will always use the newest available during the build process. Shells spawned by configure scripts are not influenced by the state of the hash facility in the current interactive shell so this step is considered optional. The performance impact of disabling the hash is negligible. To confirm the feature is switched off, simply type:- hash at the shell prompt and it should report something like "su: hash: hashing disabled". If you are using a shell other than bash, you might want to consult its documentation to see if a hash like feature exists. Please note, the intention here is to add the above commands to your "/home/lfs/.bash_profile" so that they are always available when "su'ing" to the lfs user. Therefore the "Setting up the environment" commands will be:- cat > ~/.bash_profile << "EOF" set +h umask 022 LFS=/mnt/lfs LC_ALL=POSIX LDFLAGS="-s" PATH=/stage1/bin:$PATH export LFS LC_ALL LDFLAGS PATH EOF source ~/.bash_profile One thing you'll notice throughout the build is some careful adjustment of the CFLAGS environment variable. This is NOT TO FIDDLE WITH OPTIMISATION! The sole purpose is to strip out the "-g" flag and thus save space during the builds. We also throw in "-pipe" for marginally quicker builds. We do not export the CFLAGS into the lfs user's environment globally because not all packages are cooperative with their treatment of CFLAGS. Another thing you'll notice is that in a few places we still specify LDFLAGS="-s" on the make command line even though we have already exported it into the environment. This is because those packages do not place the LDFLAGS from the environment into the top level Makefile and thus do not pass it down to the sub-make processes. Chapter 5 - Installing binutils - Pass 1 (static) ------------------------------------------------- This is basically the same as the current Chapter 5 binutils installation, but with an extra twist. mkdir ../binutils-build && cd ../binutils-build && CFLAGS="-O2 -pipe" ../binutils-2*/configure --prefix=/stage1 \ --disable-nls && make LDFLAGS="-all-static -s" && make install NOTE - if you happen to be using a HJL binutils release of 2.13.90.0.18 or greater and experience a build failure "C compiler cannot create executables" you will need to insert a "make configure-host" in between the configure and make lines. This is due to recent changes in the top level build system that do not cope with having "-all-static" in the LDFLAGS. IMPORTANT! - Do NOT remove the binutils-build dir as we are going to reuse it a bit further down the track. This will be explained further on, but for now, just run the following:- cd ld && make clean && make LIB_PATH=/stage1/lib DO NOT RUN "make install" AT THIS POINT! We are saving this for later. All will become clear in due course. One of the main differences is we use a prefix of /stage1 instead of the usual $LFS/static. Note the lack of $LFS. It is worth mentioning here that having the new binutils available from the outset is important because both glibc and gcc perform various feature tests on the linker and assembler to determine which software features to enable. Chapter 5 - Installing gcc - Pass 1 (static) -------------------------------------------- This is basically the same as the current Chapter 5 gcc installation, but with a few variations. Firstly, we need to apply the "no_fixincludes" patch to prevent the fixincludes script from running. We apply a patch instead of using the "install-no-fixedincludes" target because it is cleaner and results in a slightly quicker build and doesn't fail if you happen to use the "--enable-version-specific-runtime-libs" configure switch. We also apply the "mmap_test" patch which fixes a subtle gcc bug[2] that can (and will) undermine the integrity of the gcc build in certain circumstances. patch -Np1 -i ../gcc-3*.no_fixincludes.patch && patch -Np1 -i ../gcc-3*.mmap_test.patch && mkdir ../gcc-build && cd ../gcc-build && CFLAGS="-O2 -pipe" ../gcc-3*/configure --prefix=/stage1 \ --with-local-prefix=/stage1 --enable-languages=c \ --disable-nls --enable-shared && make BOOT_LDFLAGS="-static -s" BOOT_CFLAGS="-O2 -pipe" \ STAGE1_CFLAGS="-pipe" bootstrap && make install && ln -s gcc /stage1/bin/cc Here we start to experience some of the magic of the GNU toolchain. It is important to realise that gcc does not search the `PATH' during its configure run to search for which binutils to use. It actually searches $prefix/TARGET-TRIPLE/bin where TARGET-TRIPLE is for e.g. i686-pc-linux-gnu. This means everything "just works" and we don't have to specify --with-ld= and --with-as= to configure. Note the use of "make bootstrap". In subsequent gcc passes we can skip the bootstrap part and thus save lots of build time. But for this initial pass of gcc it is absolutely CRITICAL to use the bootstrap target. This ensures a 3 stage bootstrap of the compiler and is vital to ensuring the integrity of the overall build method. The extra BOOT_CFLAGS and STAGE1_CFLAGS on the make line are just extra steps to remove "-g" from the gcc build. A few occurrences still remain but the only clean way to remove them without resorting to use of "make -e" is to patch the source. You will find 2 patches at the URL mentioned above that do the job. The patches are of course optional and are named "gcc-3.2.2.libgcc_no_debug.patch" and "gcc-3.2.2.libstdc++_no_debug.patch". Another difference between normal LFS and here is that we use "--enable-shared" instead of "--disable-shared". This may seem counter-intuitive at first. But using this switch allows the building of "libgcc_s.so.1" and "libgcc_eh.a". Having "libgcc_eh.a" available ensures that the configure script for glibc (the next package) produces correct results for proper building of glibc itself. Please note, the gcc binaries will still be linked statically as this is controlled by the "-static" in the BOOT_LDFLAGS on the make command line. The other interesting configure switch is --with-local-prefix=/stage1. The purpose of this switch is to remove /usr/local/include from gcc's include search path. It is not absolutely essential but we want to try and minimise the influence from the host system so this is a logical thing to do. The gcc install page[3] says:- "The same value can be used for both --with-local-prefix and --prefix provided it is not /usr. This can be used to avoid the default search of /usr/local/include." which is exactly what we want. You can see the gcc search include order by compiling a test program with "-v" e.g. gcc -v foo.c. The following snippets of output demonstrate the issue. This is with the "--with-local-prefix" switch:- #include "..." search starts here: #include <...> search starts here: /stage1/include /stage1/lib/gcc-lib/i686-pc-linux-gnu/3.2.1/include /usr/include End of search list And this is without:- #include "..." search starts here: #include <...> search starts here: /usr/local/include /stage1/include /stage1/lib/gcc-lib/i686-pc-linux-gnu/3.2.1/include /usr/include End of search list Chapter 5 - Installing kernel headers ------------------------------------- In normal LFS we install the kernel headers in Chapter 6. But seeing as we are now installing a glibc in Chapter 5, we need to install the kernel headers in Chapter 5 also. The procedure is essentially the same as current LFS with the exception that the destination is /stage1 not /usr. In other words, follow the procedure from current LFS (minus the /bin/pwd hacks) and substitute "cp blah /usr/include" with "cp blah /stage1/include" and "touch /usr/blah" with "touch /stage1/blah":- make mrproper && make include/linux/version.h && make symlinks && cp -HR include/asm /stage1/include && cp -R include/asm-generic /stage1/include && cp -R include/linux /stage1/include && touch /stage1/include/linux/autoconf.h (NOTE - SHORTCUT ALERT! - seeing as we will be installing glibc again in Chapter 6, a potential shortcut here is to ALSO copy the kernel headers to the final destination of $LFS/usr/include. By doing this, the kernel headers will already be in place for the glibc compile in Chapter 6. But don't forget, we still need the headers in /stage1/include as per the above commands.) Chapter 5 - Installing glibc ---------------------------- By this stage we have a new binutils and a new gcc (both statically linked against the glibc on the host). We'll use both of these to build the Chapter 5 glibc. As per usual, don't forget to unpack the glibc-linuxthreads package. We are also going to run the glibc test suite by issuing "make check". mkdir -p /stage1/etc && touch /stage1/etc/ld.so.conf && mkdir ../glibc-build && cd ../glibc-build && CFLAGS="-O2 -pipe" ../glibc-2*/configure --prefix=/stage1 \ --enable-add-ons --disable-profile \ --with-binutils=/stage1/bin --with-headers=/stage1/include \ --without-gd && make && make check && make install && make localedata/install-locales "make check" is considered very important for glibc. It's the most important lib on the system and should not be installed unless it passes "make check". Any failures need to be investigated and resolved before continuing. Some possible causes of failure include:- * faulty or misconfigured gcc * faulty or misconfigured binutils * overoptimisation * environment not sane * bugs in glibc itself The math tests are known to be very CPU specific so any failures there are not surprising. If you happen to get some math failures, and after having looked at the specifics you are happy to continue on, you can issue "make -k check" to continue through the remainder of the test suite. Though if you do this, be sure to log the output so any further failures can be detected by perusing the log file. If you get a failure in "libio/tst-atime", the partition you're working on is probably mounted with the "noatime" option. Remount it with "atime" enabled then continue on. "make localedata/install-locales" is of course optional as per current LFS. However, not having some certain locales installed will cause failures in the gcc test suite (libstdc++ in particular). If you happen to skip "make localedata/install-locales", you can install the minimum locales necessary by issuing the following commands:- mkdir -p /stage1/lib/locale && localedef -i de_DE -f ISO-8859-1 de_DE && localedef -i de_DE@euro -f ISO-8859-15 de_DE@euro && localedef -i en_HK -f ISO-8859-1 en_HK && localedef -i en_PH -f ISO-8859-1 en_PH && localedef -i en_US -f ISO-8859-1 en_US && localedef -i es_MX -f ISO-8859-1 es_MX && localedef -i fr_FR -f ISO-8859-1 fr_FR && localedef -i fr_FR@euro -f ISO-8859-15 fr_FR@euro && localedef -i it_IT -f ISO-8859-1 it_IT && localedef -i ja_JP -f EUC-JP ja_JP The above commands can be issued even after you've deleted the glibc-build dir. Please note, the use of --with-binutils= and --with-headers= configure switches is not strictly required. But they do ensure nothing can go wrong with regard to the kernel headers and binutils that get used during the glibc build. If you perform a "diff" comparison between the two configured glibc-build dirs, both with, and without those switches, you'll surely believe it is a lot cleaner to use them. The --without-gd switch ensures that we don't build the "memusagestat" program which insists on linking against the host's libs (for libgd, libpng, libz and so forth). During a normal LFS install, memusagestat does not get built. As mentioned above, the CFLAGS saves space during the build. If you rely solely on the LDFLAGS from the environment then the *.a archives will still be chock full of debug symbols. It is important to understand the glibc build system is very sensible about how it treats the CFLAGS supplied by the user. In other words, the CFLAGS above do not change any vital aspect of the glibc build. They simply remove "-g" and add "-pipe". The other important thing to realise is that glibc is pretty well self contained in terms of its build mechanics. No fancy linker switches are required. It doesn't rely on compiler or linker defaults as all the required build switches are supplied "by hand". e.g. you will see stuff like:- -Wl,-dynamic-linker=/stage1/lib/ld-linux.so.2 during the glibc build. What is shown there is simply an example of how glibc's build system overrides gcc's default behaviour of passing:- -dynamic-linker=/lib/ld-linux.so.2 to the linker (ld) as it goes about its business of constructing the binaries and libraries. Linker scripts and library search order - A quick overview ---------------------------------------------------------- At this juncture, it is worth discussing how ld (the linker) performs its magic. On a normal LFS system you will find the linker scripts located in the /usr/lib/ldscripts dir. They have names like elf_i386.x, elf_i386.xc and so on. There are 13 of these scripts altogether but only the 8 that start with elf* concern us. The others are involved when creating a.out format binaries which basically means never. The a.out format was superceded years ago by the more modern ELF format. The linker scripts for our new toolchain in /stage1 are located in /stage1/TARGET-TRIPLE/lib/ldscripts. If you view the scripts, you'll notice the default linker search path (as indicated by the SEARCH_DIR variables) is:- $prefix/TARGET-TRIPLE/lib, $prefix/lib, /usr/local/lib, /lib, /usr/lib where $prefix is the value of the --prefix configure option and TARGET-TRIPLE is the cpu-arch-os triple for the host (e.g. i686-pc-linux-gnu). Anything linked by ld using these linker scripts will link against our new glibc installed into /stage1/lib because /stage1/lib comes before /usr/lib in the search path. So far so good. This is exactly what we want. However, what we really need is to remove /usr/local/lib, /lib, and /usr/lib from the search path altogther. In this way we can be 100% certain that nothing links against the libraries on the host system. There are a few ways we can achieve this:- 1. edit all the linker scripts by hand 2. perform some sort of sed substitution on each of the scripts 3. utilise the LIB_PATH variable in ld's Makefile to our advantage No 3 is the easiest solution. A small mention of LIB_PATH was made back in the "binutils - pass 1" section above. A bit further down, you'll see how its usage helps us out. Gcc's specs file - A quick overview ----------------------------------- >From the gcc info page:- "`gcc' is a driver program. It performs its job by invoking a sequence of other programs to do the work of compiling, assembling and linking. GCC interprets its command-line parameters and uses these to deduce which programs it should invoke, and which command-line options it ought to place on their command lines. This behavior is controlled by "spec strings". In most cases there is one spec string for each program that GCC can invoke, but a few programs have multiple spec strings to control their behavior. The spec strings built into GCC can be overridden by using the `-specs=' command-line switch to specify a spec file. "Spec files" are plaintext files that are used to construct spec strings." To find out where the specs file is located simply type in "gcc -v" like so:- gws@tigers-lfs:~$ gcc -v 2>&1 | head -n 1 Reading specs from /static/lib/gcc-lib/i686-pc-linux-gnu/3.2.1/specs If you examine a normal dynamic executable using the readelf utility, you can determine which dynamic linker (i.e. program interpreter) the executable was compiled for. Take a look at this example:- gws@tigers-lfs:~/src$ readelf -a foo | grep interpreter [Requesting program interpreter: /lib/ld-linux.so.2] If we want to change the program interpreter that gets embedded into our binaries we need to utilise the linker switch -dynamic-linker e.g. -Wl,-dynamic-linker=/stage1/lib/ld-linux.so.2. But forcing this onto every package we compile can be quite troublesome. It is much easier to simply force the issue by adjusting the specs string in the specs file to point where we want. There are a few ways we can achieve this:- 1. edit, sed or patch the specs file 2. patch the gcc source before we compile it Both methods are used below, depending on which stage of the build process we are at. Chapter 5 - "Locking in" our new glibc -------------------------------------- Now that we have the lectures out of the way, it is back to business. By now we have our Chapter 5 glibc installed and operational. This is the point in the proceedings where we need to ensure that we do not link against the libraries on the host system. i.e. we will "lock in" the new glibc. The first thing to do is adjust the linker scripts. Remember back in the "binutils - pass 1" section above we added a couple of extra commands at the end? Well here is where we utilise those commands. Simply cd back into your binutils-build dir and run the following:- cd ld && make install-data-local This installs the adjusted linker scripts. The linker scripts now contain no mention of /lib, /usr/lib or /usr/local/lib. From this point onwards, everything will link ONLY against the libs in /stage1/lib. It is now safe to remove the binutils-build dir. The next thing to do is amend our gcc specs file so that it points to the new dynamic linker. A sed can be used to accomplish this:- SPECFILE=/stage1/lib/gcc-lib/i686-pc-linux-gnu/*/specs && cp ${SPECFILE} ./XX && sed 's@/lib/ld-linux.so.2@/stage1/lib/ld-linux.so.2@g' ./XX > ${SPECFILE} && unset SPECFILE && rm -f ./XX We recommend you cut'n'paste the above rather than type it all in. You can always edit the specs file by hand if you really want to. Just replace "/lib/ld-linux.so.2" with "/stage1/lib/ld-linux.so.2". At this point, it is a good idea to check the linker scripts and the specs file to ensure the intended changes were actually made. Chapter 5 - Installing tcl, expect and dejagnu ---------------------------------------------- We now need to install the 3 external packages so that the gcc and binutils test suites can be run. If these 3 packages are already installed on the host system you can delay this step until the end of Chapter 5 if you wish. The versions we used in testing were tcl8.4.1, expect-5.38.0 and dejagnu-1.4.3. tcl: cd unix && ./configure --prefix=/stage1 && make && make install && ln -s tclsh8.4 /stage1/bin/tclsh NOTE - you must leave the tcl source dir in place until the expect package is installed as the expect package needs the tcl internal headers to build. expect: patch -Np1 -i ../expect-5*.patch && ./configure --prefix=/stage1 && make && make install The patch fixes a bug in expect that can result in bogus failures during the gcc test suite run[4]. dejagnu: ./configure --prefix=/stage1 && make && make install NOTE - you can run the test suites for these 3 packages if you wish but you'll more than likely see failures. Luckily, there is enough functionality to run the gcc and binutils test suites and that is only what we care about at this point. ADDITIONAL NOTE - you must have /dev/pts mounted (or be using devfs) for the dejagnu test suite to function properly. Chapter 5 - Installing gcc - Pass 2 (shared) -------------------------------------------- (NOTE - SHORTCUT ALERT! - this step could be considered optional as we already have a new gcc to begin compiling Chapter 6 with. However, this gcc is statically linked against the host's glibc. We recompile now so that we can add c++ to the mix and so that we end up with a shared gcc linked against the new glibc. c++ is not absolutely essential to bootstrap the Chapter 6 final build. However, the advantages to adding c++ are 1) if running "make check" for binutils (the next package) all tests will pass and 2) no need to disable building of the ncurses c++ binding when we get to the Chapter 5 ncurses. If you don't wish to build c++, just ensure that "--enable-languages" is equal to "c" only and drop the c++ specific switches i.e. --enable-threads=posix --enable-__cxa_atexit --enable-clocale=gnu.) Before we start this recompile of gcc, we need to change the default location of the traditional spec string for the dynamic linker. We therefore patch gcc (the file is gcc/config/i386/linux.h). It is just a simple substitution of "/lib/ld-linux.so.2" with "/stage1/lib/ld-linux.so.2". The reason why we patch now rather than adjust the specs file after installation is that it ensures our new dynamic linker gets used during the actual gcc build. i.e. all the final (and temporary) binaries created during the build will link against the new glibc. If you haven't already done so, don't forget to remove the previous gcc-build dir left over from pass 1 above. If using the same source from pass 1 there is no need to reapply the no_fixincludes or mmap_test patches (or the no_debug patches if you applied those as well). We are also going to run the gcc test suite by issuing "make -k check". patch -Np1 -i ../gcc-3*.no_fixincludes.patch && patch -Np1 -i ../gcc-3*.mmap_test.patch && patch -Np1 -i ../gcc-3*.specs.patch && mkdir ../gcc-build && cd ../gcc-build && CFLAGS="-O2 -pipe" CXXFLAGS="-O2 -pipe" ../gcc-3*/configure \ --prefix=/stage1 --with-local-prefix=/stage1 --enable-languages=c,c++ \ --enable-shared --enable-threads=posix --enable-__cxa_atexit \ --enable-clocale=gnu && make LDFLAGS="-s" && make -k check make install The main differences between here and pass 1 is the dropping of the "bootstrap" target, the addition of the c++ specific bits and no mention of "-static" in any of the FLAGS. Of course there is also the addition of "make -k check" to run the test suite. As mentioned earlier, the gcc "bootstrap" target is not needed at this stage. It is worth looking at the need for bootstrapping gcc from a historical viewpoint. It was first implemented to aid in building a GNU compiler on systems where there was only a non-GNU or proprietary compiler installed. Seeing as we already bootstrapped gcc in pass 1 and built it from the exact same source version as we are using now, there is no need to bootstrap again from this point onwards. We have thoroughly tested this aspect and can confirm that the installed files from a "bootstrapped" gcc build are "byte-for-byte" identical with the installed files from a "non-bootstrapped" build, AS LONG AS THE INITIAL PASS 1 WAS BOOTSTRAPPED! All bets are off if the initial pass 1 gcc was not bootstrapped. You can still "make bootstrap" pass 2 if you want to. Just substitute the "make" command from above with the one below. make BOOT_LDFLAGS="-s" BOOT_CFLAGS="-O2 -pipe" \ STAGE1_CFLAGS="-pipe" bootstrap The reason for the "-k" (and the lack of "&&") is we need the test suite to run through to completion and not stop at the first failure. The gcc test suite is very comprehensive and is almost always guaranteed to have a few failures. The gcc testing page[5] contains more information. The simplest way to get a summary of the test suite run is to use the "test_summary" script from within the gcc-build dir:- ../gcc-3*/contrib/test_summary | less Then you can compare your results to those that have been posted to the gcc-testresults mailing list for similar configurations to your own. Here is an example of how current gcc-3.2.x should look on i686-pc-linux-gnu:- http://gcc.gnu.org/ml/gcc-testresults/2003-02/msg00204.html Note that the results contain:- * 1 XPASS (unexpected pass) for g++ * 26 XPASS's for libstdc++ * 1 FAIL for libstdc++ The unexpected pass for g++ is due to the use of "--enable-__cxa_atexit". Apparently not all platforms supported by gcc have support for "__cxa_atexit" in their C libraries hence this test is not always expected to pass. The 26 unexpected passes for libstdc++ are due to the use of "--enable-clocale=gnu" which is the correct choice on glibc based systems of 2.2.5 and above. The underlying locale support in the GNU C library is superior to that of the otherwise selected "generic" model (which may be applicable if for instance you were using newlibc, sun-libc or whatever-libc). The libstdc++ test suite is apparently expecting the "generic" model hence those tests are not always expected to pass. The failure for libstdc++ is "26_numerics/c99_classification_macros_c.cc" and is a long standing known failure (since at least January 2002) that the developers are apparently unable to easily fix. Chapter 5 - Installing binutils - Pass 2 (shared) ------------------------------------------------- (NOTE - SHORTCUT ALERT! - this step could be considered optional as we already have a new binutils to begin compiling Chapter 6 with. However, this binutils is statically linked against the host's glibc and was compiled by the host's gcc. A recompile now and we'll have our binutils compiled by the new gcc and we'll end up with a completely shared toolchain linked against the new glibc.) Before recompiling binutils, we apply a patch (backported from the binutils CVS HEAD and currently appearing in the HJ Lu binutils releases) that allows us to specify --with-lib-path to configure. Specifying "--with-lib-path=/stage1/lib" allows us to keep /usr/local/lib, /lib and /usr/lib out of the linker scripts search paths. The reason why we couldn't use the --with-lib-path patch earlier in pass 1 is we needed the ability to link against the host's glibc for the static compile of binutils and gcc. If you haven't already done so, don't forget to remove the previous binutils-build dir left over from pass 1 above. We are also going to run the binutils test suite by issuing "make check". patch -Np1 -i ../binutils-2*.lib-path.patch && mkdir ../binutils-build && cd ../binutils-build && CFLAGS="-O2 -pipe" ../binutils-2*/configure --prefix=/stage1 \ --with-lib-path=/stage1/lib --enable-shared && make LDFLAGS="-s" && make check && make install NOTE - if you happen to be using a HJL binutils release of 2.13.90.0.10 or greater you will not need to apply the abovementioned patch. IMPORTANT! - Similar to our "binutils - pass 1" above, do NOT remove the binutils-build dir as we are going to reuse it in Chapter 6. For now, just run the following:- cd ld && make clean && make LIB_PATH=/usr/lib:/lib Again, DO NOT RUN "make install" just yet. We will wait for the appropriate time in Chapter 6 when we need to adjust the linker scripts. Note that the binutils test suite should always pass. Chapter 5 - Toolchain Summary ----------------------------- At this stage, we have compiled gcc twice, binutils twice and glibc once. A bit excessive you might think? Absolutely not. The toolchain is now very clean and that feeling of cleanliness is very powerful and worth every bit of effort in our opinion. Chapter 5 - Installing remaining packages - (shared) ---------------------------------------------------- The remaining Chapter 5 packages are built pretty much according to current LFS instructions with the obvious exceptions being:- * everything gets built with "--prefix=/stage1" * no mention of "LDFLAGS=-static" (we are building everything shared) * no mention of "CPPFLAGS=-Dre_max_failures=re_max_failures2" (this only applies to static builds) Here is a suggested list of packages and a suggested build order. Compared to current LFS there are 3 additional packages: ncurses, gettext and perl. The perl we install is a special trimmed down "miniperl". We don't need a full perl with all its associated bloat. Building a minimal perl as opposed to the full version also has the advantage of saving space and build time. Having perl available early in Chapter 6 is not absolutely essential. But it does ensure a more complete run of glibc's "make check" and also removes the need to patch glibc as per current LFS. It also takes away any doubts for various packages that may make assumptions about the presence of perl. Unlike current Chapter 5 LFS, order DOES matter (due to dependencies). NOTE - If you happen to be using the HJL binutils, you'll also need to add m4, bison and flex to the list below. This is due to packaging quirks in the HJL release. Feel free to add any other packages that you think may be useful once inside the chroot. For example the "less" package is a good candidate. gawk fileutils bzip2 gzip diffutils findutils make grep* (see below for suggested build commands) sed gettext* (see below for suggested build commands) textutils sh-utils ncurses* (see below for suggested build commands) patch tar texinfo bash util-linux perl* (see below for suggested build commands) grep: CFLAGS="-O2 -pipe" ./configure --prefix=/stage1 \ --disable-perl-regexp --with-included-regex && make && make install The "--with-included-regex" is needed so that all tests pass. Without this switch the regex code from glibc is used and as of glibc-2.3.1 that code is known to be a bit buggy. (NOTE - we are using the newer grep version of 2.5.1 which passes all tests.) gettext: CFLAGS="-O2 -pipe" ./configure --prefix=/stage1 && make && make install && rm -f /stage1/lib/gettext/gnu.gettext.* The "rm -f /stage1/lib/gettext/gnu.gettext.*" is optional. If gettext finds a java compiler on your system it builds some binaries that link against the host. Leaving the binaries there is harmless but we might as well remove them. ncurses: patch -Np1 -i ../ncurses-5*.etip.patch && ./configure --prefix=/stage1 --with-shared \ --without-debug && make && make install NOTE - you may need to add "--without-cxx-binding" if you opted not to enable c++ in the gcc pass 2 build. The patch is needed to fix a subtle bug[6] in ncurses that results in an incorrect header file. perl: patch -Np1 -i ../perl-5*.libc.patch && ./configure.gnu --prefix=/stage1 -Doptimize='-O2 -pipe' && make utilities && cp miniperl /stage1/bin/perl && cp pod/pod2man /stage1/bin && mkdir -p /stage1/lib/perl5/5.8.0 && cp -R lib/* /stage1/lib/perl5/5.8.0 NOTE - Be sure to issue "make utilities" instead of the usual "make" due to our desire to not build a full perl. But it should still be possible to build a full perl if you really want to. Just issue the usual "make" and "make install". The patch sets up perl to correctly build against our glibc in /stage1. The "-Doptimize='-O2 -pipe'" is there simply to use O2 instead of perl's default of 03. We install pod2man because it is used during the binutils build. If you previously skipped the installation of the tcl, expect and dejagnu packages because they were already installed on the host system, now is the time to install them into prefix /stage1 so that they are available for running the binutils and gcc test suites in Chapter 6. Chapter 6 - Initial steps ------------------------- The start of Chapter 6 is pretty much according to current LFS instructions with the obvious exception being:- * replace all occurrences of /static with /stage1 Enter the chroot, change ownership, create directories, mount the proc filesystem, create the mtab file, create the bash and sh symlinks, create the passwd and group files, create devices, install kernel headers. NOTE - we propose renaming the section of the LFS book entitled "Create the bash and sh symlinks" to "Create the essential symlinks". In this section we need to create a bunch of symlinks like so:- ln -s /stage1/bin/bash /bin/bash && ln -s bash /bin/sh && ln -s /stage1/bin/cat /bin/cat && ln -s /stage1/bin/perl /usr/bin/perl && ln -s /stage1/bin/pwd /bin/pwd && ln -s /stage1/bin/stty /bin/stty /bin/bash and /bin/sh are self explanatory. /bin/cat is needed by the glibc test suite. /usr/bin/perl is needed to ensure glibc's mtrace script is installed correctly. /bin/pwd is needed by the kernel headers install and glibc's configure script (as of glibc-2.3.2). /bin/stty is needed by the dejagnu test suite runs of binutils and gcc. The symlinks will stay in place until each one is overwritten by the corresponding real file during Chapter 6 package installation (except of course for /bin/sh). IMPORTANT! - make sure everything above is done prior to proceeding, especially the kernel headers installed into /usr/include! Be sure to NOT do the /bin/pwd symlink creation and deletion as per current LFS kernel headers install as we already created the symlink above and need to keep it around for later. As per current LFS, the chroot command will set the `PATH' for the environment inside the chroot. It's important to realise that /stage1/bin must be at the end of the `PATH' so as to ensure the newest tools always get used during the remainder of the build. It's worth mentioning here that user name and group name resolution will start working immediately after the passwd and group files are created because we have a glibc already installed. You can therefore execute:- exec /stage1/bin/bash --login to get rid of the "I have no name!" message in the command prompt. If preferred, it is worth doing the 'export LDFLAGS="-s"' and 'set +h' things like we did at the start of Chapter 5. Chapter 6 - Installing glibc ---------------------------- As mentioned earlier, the glibc build system is very well self contained and will install perfectly, even though our gcc specs file and ldscripts are still pointing at /stage1. We cannot adjust the specs and ldscripts before the glibc install because the glibc autoconf tests will give bogus results and thus defeat our goal of achieving a clean build. We are again going to run the glibc test suite by issuing "make check". As per usual, don't forget to unpack the glibc-linuxthreads package. NOTE - if reusing the same source from Chapter 5 then you'll need to issue:- rm -f manual/{texis,summary.texi,stamp-summary,chapters.texi,top-menu.texi} before configuring and whilst still inside the source dir to ensure the info pages are rebuilt using the new makeinfo. touch /etc/ld.so.conf && mkdir ../glibc-build && cd ../glibc-build && CFLAGS="-O2 -pipe" ../glibc-2*/configure --prefix=/usr \ --enable-add-ons --disable-profile --libexecdir=/usr/bin \ --with-headers=/usr/include && make && make check && make install && make localedata/install-locales "make localedata/install-locales" is of course optional as per current LFS. However, you'll need to install the minimum locales necessary for proper running of the gcc test suite as per the Chapter 5 glibc instructions above. We pass "--with-headers=/usr/include" to configure to ensure the kernel headers in /usr/include are used for this build. If we don't pass this switch then the headers from /stage1/include are used which of course is not ideal (although they should be identical). An advantage to using the switch is that the user will be informed immediately should they have forgotten to install the kernel headers into /usr/include. Once glibc is installed, don't forget to create the glibc configuration files (/etc/nsswitch.conf, /etc/localtime symlink and /etc/ld.so.conf). Chapter 6 - Adjusting our toolchain ----------------------------------- Now that we have our Chapter 6 glibc successfully installed into /usr, it is time to adjust our toolchain to use the new glibc. From this point onwards we need to ensure that we do not link against the glibc in /stage1. This is basically "undoing" what we did in the Chapter 5 "lock in" stage. The first thing to do is adjust the linker scripts. We retained the binutils-build dir from "Chapter 5 binutils - pass 2" for this reason. Simply cd back into your binutils-build dir and run the following:- cd ld && make INSTALL=/stage1/bin/install install-data-local This installs the adjusted linker scripts. The linker scripts now contain no mention of /stage1/lib. From now on everything will link ONLY against the libs in /usr/lib and /lib. The extra "INSTALL=/stage1/bin/install" is needed because the Makefile was created in Chapter 5 and still contains the reference to /usr/bin/install which we obviously haven't yet installed in Chapter 6. It is now safe to remove the binutils-build dir. The next thing to do is amend our gcc specs file so that it points to the new dynamic linker. Just like in Chapter 5, we use a sed to accomplish this:- SPECFILE=/stage1/lib/gcc-lib/i686-pc-linux-gnu/*/specs && cp ${SPECFILE} ./XX && sed 's@/stage1/lib/ld-linux.so.2@/lib/ld-linux.so.2@g' ./XX > ${SPECFILE} && unset SPECFILE && rm -f ./XX Again, cut'n'pasting the above is recommended. And just like before, it is a good idea to check the linker scripts and the specs file to ensure the intended changes were actually made. NOTE - the linker scripts will still contain a reference to "/stage1/i686-pc-linux-gnu/lib". This is unavoidable but luckily does not present a problem. There are no libs in that location as all the stage1 libs are located in "/stage1/lib". Chapter 6 - Installing binutils ------------------------------- Basically the same as current LFS:- mkdir ../binutils-build && cd ../binutils-build && CFLAGS="-O2 -pipe" ../binutils-2*/configure --prefix=/usr --enable-shared && make tooldir=/usr LDFLAGS="-s" && make check && make tooldir=/usr install && rm /usr/lib/libiberty.a We remove libiberty.a because it is generally not meant to be installed on its own. For this reason we also elect not to install libiberty.h. Note also that with recent binutils there is no need for an additional "make tooldir=/usr install-info" as the info pages are now installed by the normal "make tooldir=/usr install". Chapter 6 - Installing gcc -------------------------- Basically the same as current LFS. If using the same source from Chapter 5 there is no need to reapply the no_fixincludes or test_mmap patches (or the no_debug patches if you applied those as well). patch -Np1 -i ../gcc-3*.no_fixincludes.patch && patch -Np1 -i ../gcc-3*.mmap_test.patch && mkdir ../gcc-build && cd ../gcc-build && CFLAGS="-O2 -pipe" CXXFLAGS="-O2 -pipe" ../gcc-3*/configure --prefix=/usr \ --enable-shared --enable-languages=c,c++ --enable-threads=posix \ --enable-__cxa_atexit --enable-clocale=gnu && make LDFLAGS="-s" && make -k check make install && ln -s ../usr/bin/cpp /lib && ln -s gcc /usr/bin/cc && rm /usr/lib/libiberty.a WARNING! - if reusing the same source from Chapter 5 pass 2 be sure to reverse the "specs" patch we applied in that step. Again, no need for "make bootstrap" here. You can still "make bootstrap" if you want to. Just substitute the "make" command from above with the one below. make BOOT_LDFLAGS="-s" BOOT_CFLAGS="-O2 -pipe" \ STAGE1_CFLAGS="-pipe" bootstrap The notable difference between here and current LFS is the omission of "--with-slibdir=/lib" due to the fact that standard C executables no longer link against the shared libgcc_s.so.1 as used to happen when gcc-3.x was first released. We also do not symlink /usr/lib/cpp as we have never yet seen a package that needs this. And again we remove /usr/lib/libiberty.a for the reason mentioned earlier. Chapter 6 - Installing remaining packages ----------------------------------------- The remaining packages in Chapter 6 are installed as per current LFS and in the same order. Except of course for binutils, gcc and glibc which are already installed. There should be no need to reinstall glibc at the end of Chapter 6. Something to think about here, theoretically, one should be able to take a newly built LFS and use it to rebuild itself (essentially perform Chapter 6 again without the assistance of the /stage1 stuff) and have it reproduce identical bytes. We have performed an "Iterative Analysis" of this and hope to present an automated way of verifying it in the future. But for now, from our findings we are able to make the following recommendations so as to ensure code repeatability:- * ncurses - be sure to use the "etip" patch that was used in Chapter 5 * shadow - be sure to issue "touch /usr/bin/passwd" before configuring - be sure to perform the "Creating the /var/run/utmp, /var/log/wtmp and /var/log/btmp files" commands (from the end of Chapter 6) before the shadow package installation * groff - be sure to to configure like so:- PAGE=XX ./configure --prefix=/usr where "XX" is either "A4" or "letter" depending on your requiremnt. * perl - be sure to perform the "Creating the /etc/hosts file" commands before the perl installation Chapter 8 - Kernel compilation ------------------------------ The following paragraph from the CHANGES file in linux-2.4.20 explains things nicely:- "The recommended compiler for the kernel is gcc 2.95.x (x >= 3), and it should be used when you need absolute stability. You may use gcc 3.0.x instead if you wish, although it may cause problems. Later versions of gcc have not received much testing for Linux kernel compilation, and there are almost certainly bugs (mainly, but not exclusively, in the kernel) that will need to be fixed in order to use these compilers. In any case, using pgcc instead of egcs or plain gcc is just asking for trouble." The current wisdom on the Linux Kernel Mailing List still seems to suggest that gcc-2.95.3 is the optimal compiler for compiling the kernel. Please note we are talking about current linux-2.4.x. As gcc-3.x continues to mature and linux-2.6 nears release, the kernel developers may end up preferring gcc-3.x, but for now, the best bet is to use gcc-2.95.3 for your kernel compiles. The simplest way to achieve this is to install gcc-2.95.3 into a non-standard prefix, i.e. somewhere NOT in the standard system `PATH':- patch -Np1 -i ../gcc-2.95.3-2.patch && echo timestamp > gcc/cstamp-h.in && mkdir ../gcc-2-build && cd ../gcc-2-build && ../gcc-2.95*/configure --prefix=/opt/gcc-2.95.3 --enable-shared \ --enable-languages=c && make bootstrap && make install *** WARNING *** BE EXTRA CAREFUL NOT TO INSTALL INTO /USR OR YOU WILL DESTROY YOUR CURRENT GCC! The patch used is the one from LFS 3.3. The line starting with "echo" is just a safeguard to prevent a "Makefile induced" rerun of autoconf in certain unknown circumstances. Then when it comes time to compile the kernel:- make mrproper && make menuconfig && make CC=/opt/gcc-2.95.3/bin/gcc dep && make CC=/opt/gcc-2.95.3/bin/gcc bzImage && make CC=/opt/gcc-2.95.3/bin/gcc modules && make CC=/opt/gcc-2.95.3/bin/gcc modules_install && cp arch/i386/boot/bzImage /boot/lfskernel && cp System.map /boot The important thing is obviously the "CC=/opt/gcc-2.95.3/bin/gcc" on the make command lines. It is worth mentioning here that the BLFS project uses gcc-2.95.3 to create the c++ libs required by various closed source and precompiled binaries. With this in mind, you may want to combine the above gcc-2.95.3 instructions with the BLFS instructions to save yourself some time. Just be careful NOT to use --prefix=/usr. The perennial debate over which binutils release to use ------------------------------------------------------- The binutils release that you typically find on ftp.gnu.org is commonly known as the "FSF" binutils. Noted hacker H.J. Lu also makes releases out of the main CVS repository and these are commonly known as the "HJL" binutils and can usually be found on ftp.kernel.org. Debate often arises over which version to use due to the fact that most mainstream distros tend to use the HJL releases even though they are typically marked as "beta". Here is our interpretation of the differences between the two:- HJL: - for Linux OS only - marked as "beta" - closely follows the CVS HEAD - usually contains the latest subtle bug fixes - usually has latest bug fixes for non-x86 arch's - usually a new release every time a significant bug that affects Linux gets fixed - theoretically less stable due to newness of code FSF: - supports more OS's (not only Linux) - latest code from the stable branch of CVS - sometimes not up-to-date WRT to the latest bleeding edge kernel, gcc and glibc subtleties - often includes features backported from the CVS HEAD after a period of testing - theoretically more stable You'll notice in the above points words like "usually" and "sometimes". This demonstrates how the situation can be different depending on which particular point in time you happen to be referring to. For example, from time to time there will be a new bleeding edge feature in gcc or glibc that requires support from binutils. During these times you will often hear the developers say "you must be using the latest HJL binutils version x.y.z.a.b". The only way to correctly choose the most appropriate release to use is to:- * stay abreast of the issues on the project mailing lists of the core toolchain packages * have a large dose of technical prowess and/or programming talent to understand all the issues * test like crazy by running the test suites * test like crazy by building full systems The facts of the matter are that the core toolchain packages are all very tightly bound and must be tested to ensure they work together. You basically have to build a full working distro and test every aspect of it to be fully satisfied. If you follow the project mailing lists of the core toolchain packages for long enough, you'll soon realise that the developers do not care much whether a particular release of "Package A" works with a particular release of "Package B". In other words, release coordination between the projects is not a priority. In reality, this means that Alan Cox is right when he says that you cannot just go to ftp.gnu.org and grab the latest of everything and always expect it to just work. Conclusion ---------- We hope you have as much fun with this as we had making it. It was a lot of hard work but well worth it. Enjoy. Comments, feedback, flames, corrections, whatever, are all welcome. P.S. - Do not believe anyone who says that what is presented in this document is overkill. Those folk do not have enough knowledge to understand all the subtle issues. TODO ==== - look at integrating test suites for the remaining packages - look at ways to remove /usr/include from gcc's include search path - look at ways to remove unwanted dirs from "gcc -print-search-dirs" - look at using gcc's -enable-version-specific-runtime-libs for installing multiple versions of gcc into the one prefix CREDITS ======= Ryan - Devised the whole scheme. Bucket loads of testing and research. Helped with documentation. Greg - Wrote the bulk of the documentation. Helped refine the process, Helped with testing and research. Initially ranted on lfs-dev about potential build flaws and thus spurred Ryan into action :-) All the good folk on lfs-dev have been very helpful with ideas, feedback, corrections and testing. Thanks guys. FOOTNOTES ========= 1. http://www.linuxbase.org/impl/ 2. http://archive.linuxfromscratch.org/mail-archives/lfs-dev/2003/03/0193.html 3. http://gcc.gnu.org/install/configure.html 4. http://gcc.gnu.org/ml/gcc/2002-08/msg01071.html 5. http://gcc.gnu.org/install/test.html 6. http://mail.gnu.org/archive/html/bug-ncurses/2003-03/msg00019.html Copyright (c) 2003 Ryan Oliver and Greg Schafer