DIY Linux Reference Build

Greg Schafer

Note: A version of this document entirely on one web page is available here.

Permission is granted to copy, distribute, and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is available at http://www.gnu.org/licenses/fdl.html.

This document may be copied and distributed in any medium, either commercially or noncommercially, provided that the GNU Free Documentation License (FDL), the copyright notices, and the license notice saying the GNU FDL applies to the document are reproduced in all copies, and that you add no other conditions whatsoever to those of the GNU FDL.

Jakub "Jimmac" Steiner created the admonition graphics (caution, important, note, tip, and warning) and the navigation graphics (home, next, prev, and up).

Linux is a registered trademark of Linus Torvalds.

All other trademarks and copyrights referred to are the property of their respective owners.

Revision History
Revision CVS24th April 2009
Please refer to the CVS ChangeLog for full revision history. Note: Due to the dynamic nature of the subject matter this document is forever evolving. As such, there will never be an official "release" with a version number.

Abstract

This is an attempt to document a robust method of natively bootstrapping a modern GNU/Linux system from source, with a strong focus on technical correctness, testing, automation and package management.


Table of Contents

1. Introduction
1.1. Preamble
1.2. Goals
1.3. Build Methods
1.4. Architectures
1.5. Automation
1.6. Build Notes
1.7. Prerequisites
1.8. Security
1.9. Kernel
1.10. Package Management
2. Getting Started
2.1. Environment
2.2. Tarballs
2.3. Patches
3. Temptools Phase - Next Generation Build Method
3.1. Bash-3.2 Pass 1
3.2. Make-3.81 Pass 1
3.3. Sed-4.1.5 Pass 1
3.4. Binutils Pass 1 a.k.a. Cross Binutils (2.16.1 through 2.18)
3.5. GCC Pass 1 a.k.a. Cross GCC (3.4.6 through 4.3.3)
3.6. Linux-Kernel-Headers-2.6.27
3.7. Linux-Libc-Headers-2.6.12.0 (Older toolchains only)
3.8. Glibc 32-bit - *ONLY* for Bi-arch x86_64 (2.3.6 through 2.8)
3.9. Glibc (2.3.6 through 2.8)
3.10. Adjust Toolchain
3.11. Binutils Pass 2 (2.16.1 through 2.18)
3.12. GCC Pass 2 (3.4.6 through 4.3.3)
3.13. Gawk-3.1.6
3.14. Coreutils-6.12
3.15. Bzip2-1.0.5
3.16. Gzip-1.3.12
3.17. Diffutils-2.8.1
3.18. Findutils-4.4.0
3.19. Make-3.81 Pass 2
3.20. Grep-2.5.4
3.21. Sed-4.1.5 Pass 2
3.22. Gettext-0.17
3.23. Ncurses-5.7
3.24. Patch-2.5.4
3.25. Tar-1.22
3.26. Texinfo-4.13a
3.27. Bash-3.2 Pass 2
3.28. M4-1.4.13
3.29. Bison-2.4.1
3.30. Flex-2.5.35
3.31. E2fsprogs-1.41.4
3.32. Util-Linux-ng-2.14.2
3.33. Perl-5.10.0
3.34. Tcl-8.4.19
3.35. Expect-5.43.0
3.36. DejaGnu-1.4.4
3.37. Fakeroot-1.11 (Optional)
3.38. Zlib-1.2.3 (Optional)
3.39. Libtar-1.2.11 (Optional)
3.40. Pacman-2.9.8 (Optional)
3.41. Ogdlutils-20041124 (Optional)
3.42. Cpio-2.9 (Optional)
3.43. BPM-1.7 (Optional)
3.44. Remove Cruft
4. Chroot Phase - Next Generation Build Method
4.1. About $PM_DEST
4.2. Enter Chroot Environment
4.3. Create Directories
4.4. Perform Mounts
4.5. Create Symlinks
4.6. Create Misc. Files
4.7. Create Users
4.8. Makedev-1.7
4.9. Man-Pages-3.20
4.10. Man-Pages-Posix-2003-a
4.11. Linux-Kernel-Headers-2.6.27
4.12. Linux-Libc-Headers-2.6.12.0 (Older toolchains only)
4.13. Glibc 32-bit - *ONLY* for Bi-arch x86_64 (2.3.6 through 2.8)
4.14. Glibc (2.3.6 through 2.8)
4.15. Readjust Toolchain
4.16. Zlib-1.2.3
4.17. Binutils (2.16.1 through 2.18)
4.18. GCC (3.4.6 through 4.3.3)
4.19. Sed-4.1.5
4.20. E2fsprogs-1.41.4
4.21. Coreutils-6.12
4.22. Iana-Etc-2.30
4.23. Gawk-3.1.6
4.24. Findutils-4.4.0
4.25. Ncurses-5.7
4.26. Readline-5.2
4.27. Vim-7.2
4.28. M4-1.4.13
4.29. Bison-2.4.1
4.30. Less-429
4.31. Groff-1.19.2
4.32. Flex-2.5.35
4.33. Gettext-0.17
4.34. Net-Tools-1.60
4.35. Inetutils-1.6
4.36. Procps-3.2.7
4.37. Perl-5.10.0
4.38. Gzip-1.3.12
4.39. Texinfo-4.13a
4.40. Grep-2.5.4
4.41. File-5.00
4.42. Libtool-2.2.6a
4.43. Autoconf-2.63
4.44. Automake-1.10.1
4.45. Bash-3.2
4.46. Bzip2-1.0.5
4.47. Diffutils-2.8.1
4.48. Ed-1.2
4.49. Kbd-1.14.1
4.50. Man-1.6f
4.51. Make-3.81
4.52. Module-Init-Tools-3.4.1
4.53. Patch-2.5.4
4.54. Psmisc-22.6
4.55. Shadow-4.1.2.2
4.56. Sysklogd-1.5
4.57. Sysvinit-2.86
4.58. Tar-1.22
4.59. Util-Linux-ng-2.14.2
4.60. Grub-0.97 (x86 and Bi-arch x86_64 Only)
4.61. Yaboot-1.3.14 (PPC Only)
4.62. Mac-Fdisk-0.1 (PPC Only)
4.63. Hfsutils-3.2.6 (PPC Only)
4.64. Fakeroot-1.11 (Optional)
4.65. Libtar-1.2.11 (Optional)
4.66. Pacman-2.9.8 (Optional)
4.67. Ogdlutils-20041124 (Optional)
4.68. Cpio-2.9 (Optional)
4.69. BPM-1.7 (Optional)
5. Finishing Up
5.1. Making it Functional
5.2. Conclusion
5.3. Acknowledgments
6. Temptools Phase - Original Build Method (Deprecated)
6.1. Bash-3.2 Pass 1
6.2. Make-3.81 Pass 1
6.3. Sed-4.1.5 Pass 1
6.4. Binutils Pass 1 (2.16.1 through 2.18)
6.5. GCC Pass 1 (3.4.6 through 4.2.4)
6.6. Linux-Kernel-Headers-2.6.27
6.7. Linux-Libc-Headers-2.6.12.0 (Older toolchains only)
6.8. Glibc (2.3.6 through 2.7)
6.9. Adjust Toolchain
6.10. GCC Pass 2 (3.4.6 through 4.2.4)
6.11. Binutils Pass 2 (2.16.1 through 2.18)
6.12. Gawk-3.1.6
6.13. Coreutils-6.12
6.14. Bzip2-1.0.5
6.15. Gzip-1.3.12
6.16. Diffutils-2.8.1
6.17. Findutils-4.4.0
6.18. Make-3.81 Pass 2
6.19. Grep-2.5.4
6.20. Sed-4.1.5 Pass 2
6.21. Gettext-0.17
6.22. Ncurses-5.7
6.23. Patch-2.5.4
6.24. Tar-1.22
6.25. Texinfo-4.13a
6.26. Bash-3.2 Pass 2
6.27. M4-1.4.13
6.28. Bison-2.4.1
6.29. Flex-2.5.35
6.30. E2fsprogs-1.41.4
6.31. Util-Linux-ng-2.14.2
6.32. Perl-5.10.0
6.33. Tcl-8.4.19
6.34. Expect-5.43.0
6.35. DejaGnu-1.4.4
6.36. Fakeroot-1.11 (Optional)
6.37. Zlib-1.2.3 (Optional)
6.38. Libtar-1.2.11 (Optional)
6.39. Pacman-2.9.8 (Optional)
6.40. Ogdlutils-20041124 (Optional)
6.41. Cpio-2.9 (Optional)
6.42. BPM-1.7 (Optional)
6.43. Remove Cruft
7. Chroot Phase - Original Build Method (Deprecated)
7.1. About $PM_DEST
7.2. Enter Chroot Environment
7.3. Create Directories
7.4. Perform Mounts
7.5. Create Symlinks
7.6. Create Misc. Files
7.7. Create Users
7.8. Makedev-1.7
7.9. Man-Pages-3.20
7.10. Man-Pages-Posix-2003-a
7.11. Linux-Kernel-Headers-2.6.27
7.12. Linux-Libc-Headers-2.6.12.0 (Older toolchains only)
7.13. Glibc (2.3.6 through 2.7)
7.14. Readjust Toolchain
7.15. GCC (3.4.6 through 4.2.4)
7.16. Binutils (2.16.1 through 2.18)
7.17. Sed-4.1.5
7.18. E2fsprogs-1.41.4
7.19. Coreutils-6.12
7.20. Zlib-1.2.3
7.21. Iana-Etc-2.30
7.22. Gawk-3.1.6
7.23. Findutils-4.4.0
7.24. Ncurses-5.7
7.25. Readline-5.2
7.26. Vim-7.2
7.27. M4-1.4.13
7.28. Bison-2.4.1
7.29. Less-429
7.30. Groff-1.19.2
7.31. Flex-2.5.35
7.32. Gettext-0.17
7.33. Net-Tools-1.60
7.34. Inetutils-1.6
7.35. Procps-3.2.7
7.36. Perl-5.10.0
7.37. Gzip-1.3.12
7.38. Texinfo-4.13a
7.39. Grep-2.5.4
7.40. File-5.00
7.41. Libtool-2.2.6a
7.42. Autoconf-2.63
7.43. Automake-1.10.1
7.44. Bash-3.2
7.45. Bzip2-1.0.5
7.46. Diffutils-2.8.1
7.47. Ed-1.2
7.48. Kbd-1.14.1
7.49. Man-1.6f
7.50. Make-3.81
7.51. Module-Init-Tools-3.4.1
7.52. Patch-2.5.4
7.53. Psmisc-22.6
7.54. Shadow-4.1.2.2
7.55. Sysklogd-1.5
7.56. Sysvinit-2.86
7.57. Tar-1.22
7.58. Util-Linux-ng-2.14.2
7.59. Grub-0.97 (X86 Only)
7.60. Yaboot-1.3.14 (PPC Only)
7.61. Mac-Fdisk-0.1 (PPC Only)
7.62. Hfsutils-3.2.6 (PPC Only)
7.63. Fakeroot-1.11 (Optional)
7.64. Libtar-1.2.11 (Optional)
7.65. Pacman-2.9.8 (Optional)
7.66. Ogdlutils-20041124 (Optional)
7.67. Cpio-2.9 (Optional)
7.68. BPM-1.7 (Optional)
A. Bootstrap Status
B. Toolchain Special Section

1. Introduction

1.1. Preamble

This document is dedicated to those crazy "Do It Yourself" Linux enthusiasts who would rather build their own GNU/Linux system from source code than run a precompiled binary distro.

DIY Linux is not for the faint of heart. There are many drawbacks and not everyone will have the ability or desire to do it. You don't need to be an experienced programmer but you must have above average knowledge of software building principles. If all you want is a GNU/Linux system that simply "just works" then you would be far better off with a precompiled binary distro prepared by professionals. Nevertheless, if you have a legitimate reason to build your own GNU/Linux system completely from source, have sufficient technical skill, are a bit of a control freak, or you're the kind of person who simply must be in the driver's seat when it comes to your Linux system, you'll find a high quality build recipe here.

The intended audience is the more technically adept Linux user. Folks new to the world of DIY Linux should first head over to the Linux From Scratch (LFS) project to learn the basics.

1.2. Goals

This "reference" build is intended to be a solid foundation for building custom GNU/Linux systems. It's only a Reference Build so feel free to add or remove packages and customize it in any way you see fit. However, please keep in mind that the build recipe and package versions presented here have been tested and are known to work, so if you deviate you'll be on your own. Of course you're on your own anyway as this is, after all, a "DIY" project.

The goals can be summarized as follows:

  • Build a reasonably up-to-date and usable base GNU/Linux system from source.

  • The term "usable" implies use of Package Management (PM), because a system without PM can be frustratingly difficult to maintain. Additionally, if PM is used to create binary packages, it's possible to take advantage of the "build once, deploy anywhere" philosophy thus simplifying maintenance and administration of multiple systems. Therefore this build recipe strives to accommodate general Package Management principles. You'll find the overall build method and individual build commands aiming to be "PM friendly" towards a number of existing Package Managers (see below).

  • The build method used to bootstrap the system must be robust and work from a virgin default development install of every major Linux distro released within the last 5 years. Upgrading tools on the host defeats the purpose and therefore does not qualify. The method must also work when coming the other way ie: from a host running a latest cutting edge distro.

  • The base system must be able to build a wide range of commonly used open source software.

  • The base system must be self-hosting i.e. be able to rebuild itself reproducibly with verification provided by a binary comparison technique known as Iterative Comparison Analysis (ICA).

  • Will use latest, stable, released, pristine upstream sources with as few patches as possible and as minimal build commands as efficiently possible (within reason). So called "beta" or "unstable" releases will be used in exceptional circumstances (see below).

  • New technologies will not be adopted into the Reference Build before they are ready.

1.3. Build Methods

The basic theory of operation involves building the target system natively inside a chroot environment. To this end, two separate build phases are utilized. The goal of the first phase is to build a self-hosted temporary toolchain which is installed into a non-standard prefix. The second phase is then conducted inside a chroot environment whereby the result of the first phase is used as a platform for building the final system.

There are currently two variations of the build method presented here. The first is the so-called "Next Generation" method which leverages cross compilation for the initial "Pass 1" toolchain. The second is the original method which is now deprecated and no longer recommended. The new method has 2 main advantages, 1) there is much less reliance on the host system and 2) it is much better equipped to handle modern "multi-arch" platforms like x86_64. For example, when targeting x86_64 it doesn't matter whether the host system is 32-bit or 64-bit or a combination of both (userland and/or kernel), or whether you want a pure 64-bit system or a bi-arch (multilib) system. The Next Generation build method caters for all these possibilities.

1.4. Architectures

The following architectures are supported by the Reference Build: i386 (x86), ppc (PowerPC) and x86_64 (AMD64). We don't have access to hardware for other architectures therefore we are unable to test or support them (this includes 64-bit PowerPC). Please note the PowerPC and AMD64 builds appear to function perfectly but they are not as well tested as the x86 build.

[Important]Important

The Reference Build assumes a mostly native build environment. However, it should be noted that the Next Generation build method employs cross compilation for the initial pass 1 toolchain only. This has many advantages. For example, if you are running a 32-bit x86 system on AMD64 hardware and want to build a 64-bit environment (single or multi-arch), the cross toolchain can be used to cross compile a 64-bit kernel at the appropriate point in the procedure. The original build method does not support bi-arch and in the case of pure x86_64, it required the host machine to already be running a 64-bit kernel and have a 64-bit userland available.

1.5. Automation

It is assumed the reader will be scripting his/her own builds. In order to make the script writer's life easier we have structured this document in such a way as to allow direct extraction of (a) each package's build commands ("scriptlets") and (b) overall package information ("packagedata"). You can find a tarball containing these files right here. These scriptlets (and packagedata) are extremely handy for integration into your own build scripts.

A sample implementation of this "Document Centric Automation" is the author's own build scripts which you can find here. It's worth noting that the author runs a full test build using these scripts before any changes are made to the published version of this document. This goes a long way towards ensuring that the build commands as printed here are of high quality and free of typographical errors.

1.6. Build Notes

In addition to the goals listed above, the aim is to produce an NPTL-enabled system based on:

  • Latest 2.6.X kernel.

  • Latest GCC releases. (Note: Multiple versions of all major Toolchain components are supported. Please see the important notes below for details.)

  • Latest Glibc releases.

  • Latest Binutils releases. (FSF or HJL contingent on prevailing toolchain climate - Please see Section B, “Which Binutils?” for some rationale discussion.)

[Important]Important - Latest not necessarily the greatest!

Glibc development moves quite rapidly these days. While this is very much welcomed, there is a downside in that the release schedules of other toolchain components can sometimes get out of sync. This is a problem because history has shown that you cannot easily mix and match versions of toolchain components. In particular, Glibc compilation is very sensitive to the GCC version. For example, you cannot expect to compile a recent Glibc with a GCC from the 2.95.X era. It simply doesn't work. In our experience the most stable and trouble-free combinations of toolchain components are those of same or similar vintage. Another point to consider, every new major GCC release is stricter than the last. This means that once you get beyond the base Reference Build you will almost certainly come across packages that fail to compile with the latest GCC. For these reasons we have decided to support multiple major versions of toolchain components. The DIY build recipe has been carefully crafted to remain "out of the box" compatible with multiple GCC, Glibc and Binutils versions as per the table below. Simply set the corresponding environment variable for each toolchain component (detailed in Section 2.1, “Environment”) to build with your chosen versions.

Another important factor in building toolchains is which set of kernel headers to use. The Linux-Libc-Headers package (LLH) worked well for a number of years. But it has now been superceded by a new method known as "make headers_install" (HDRS_INST) which was introduced in linux-2.6.18. HDRS_INST is now recommended because it provides a consistent and up-to-date set of headers that have the backing of kernel developers, system library developers and distributors alike.

The table below shows some recommended toolchain combinations. Other combinations might work but do not receive any testing, and in some cases require patches (not provided here). If you decide to mix and match versions, you need to be aware of the risks associated with doing so. For example, occasionally you'll see warnings from upstream developers like this and this.

GlibcGCCBinutilsHeadersComments
2.3.63.4.62.16.1 FSFLLHA classic. Rock solid, but starting to show its age.
2.6.14.2.42.18 FSFHDRS_INSTVery stable. Was the previous default.
2.74.2.42.18 FSFHDRS_INSTAn excellent match. Current Reference Build default.
2.74.3.32.18 FSFHDRS_INSTSeems to be stable. No known major problems.
2.84.3.32.18 FSFHDRS_INSTAppears OK. But still quite new so tread carefully.

This table shows toolchain combinations that were once recommended but are no longer tested. But in all likelihood they should still work fine in the current Reference Build context.

GlibcGCCBinutilsHeaders
2.3.64.0.42.16.1 FSFLLH
2.44.1.22.17 FSFLLH
2.5.14.1.22.17 FSFHDRS_INST

Udev is not yet included in the Reference Build. It'll go in once (a) there is unanimous Udev buy-in from all the major distros shipping 2.6 kernels which apparently hasn't happened yet and (b) Udev development settles down to a point where upgrading to the latest version doesn't break the system.

Bootscripts are not included in the Reference Build. Bootscripts tend to be a matter of personal taste so folks are encouraged to write their own or plug in an existing 3rd party package.

In the beginning we started out with something resembling the then current LFS. We then developed modifications with a view towards achieving the goals as listed above. Some other points worth noting:

  • The equivalent of LFS Chapters 5 & 6 are named the "Temptools phase" and the "Chroot phase". Better names might possibly be "Bootstrap phase" and "Sysroot phase" but confusion could arise as those terms are already used in GCC parlance.

  • The Temptools phase is essentially all about bootstrapping a new toolchain. Therefore it doesn't have to be perfect and it doesn't demand that test suites be run. As long as it can build a verifiably clean system (from a reproducibility point of view) inside the Chroot phase it has done its job.

  • The pass1's of Binutils and GCC are no longer statically linked. Static linking is a diversion from the real goal of the Temptools phase and is a potential source of failure when what is needed is robustness.

  • We have implemented use of `config.site' to increase efficiency with the build commands. Every package that uses an Autoconf produced configure script can take advantage of this. eg: specify `--prefix=/usr' only once in config.site instead of multiple times for every package.

  • We have dropped `make install' for many of the Temptools phase packages to reduce cruft. A simple `cp -v <prog> ${TT_PFX}/bin' will often do the trick.

  • We have added the optional capability for parallel building on SMP.

  • We have added the optional capability to build without debugging information via some careful use of CFLAGS and LDFLAGS. Stripping the binaries will achieve a similar result but generating all that debugging info in the first place is likely to slow down the build (think disk I/O).

  • We have added `-v' to our invocations of the core file utilities to enhance the level of system feedback while building.

  • We are compiling Glibc against sanitized kernel headers ie: the `linux-libc-headers' package. Compiling Glibc against raw kernel headers is always an option, but it goes against the Glibc developer's general advice of recent times to use distro-supplied sanitized headers. As of kernel-2.6, sanitized kernel headers are the only realistic option for installation into /usr/include because the raw headers are pretty much unusable when installed there.

  • The host MUST be running a 2.6.x kernel for the build of an NPTL-enabled Glibc to succeed. If you're bootstrapping the build on an old distro, you can usually get away with a procedure that involves building a temporary non-modular 2.6.x kernel then booting it with a grub boot floppy. See here for details. FIXME - must document this procedure properly.

1.7. Prerequisites

FIXME mention stuff like gawk for recent glibc, bison for bash, texinfo for HJL binutils etc. Also point out how one can easily build "pass 0" versions of these tools if getting them installed on the host is impossible FIXME

1.8. Security

FIXME shoot down the hysteria surrounding security patches. It's horses for courses. You want security? Then FFS run a distro which provides security updates. Mention how utterly idiotic it is to build a system yourself then place it in a security vulnerable situation (ie: on the internet) without having the faintest clue about security then expecting someone else to be responsible for patches. FIXME

1.9. Kernel

FIXME explain the issues touched upon here. FIXME

1.10. Package Management

There are many and varied techniques for implementing Package Management (PM) strategies. This LFS page has a reasonable writeup of the various PM styles that exist today. We've geared this Reference Build towards those Package Managers that operate on the basis of diverting `make install' to a temporary location for the purpose of creating an archive of the installed files. These Package Managers typically use the commonly available Makefile variable `DESTDIR' to achieve the diversion. Some examples of Package Managers in this category are RPM (Red Hat/Fedora etc), Dpkg (Debian etc), Portage (Gentoo), Pkgtool (Slackware), BPM (Bent Linux), Pacman (Arch Linux) and Pkgutils (Crux). Please note, we don't insist that you employ PM when using this Reference Build. All the build commands will still work correctly if you choose to perform a "build in place" style installation à la LFS. If you do decide to employ PM, feel free to choose any Package Manager from the supported category that meets your needs, because the Chroot phase installation commands are generic and should work with all of them. In our experience Package Managers with simple spec file formats are the easiest to integrate into a PM based Reference Build. You could even write your own simple Package Manager if you felt that way inclined.

In typical "build in place" style installations the entire Chroot phase is performed as root. However, in most source building scenarios it's generally considered best practice to build packages as a non-privileged user, and only when it's time for `make install' should you need to become root. Therefore in an ideal world involving PM, you would build and create archives as a non-privileged user, then install the archives with a Package Manager as root. We've set up this Reference Build in such a way as to try and achieve that ideal world. Be aware that creating package archives as a non-privileged user can sometimes result in wrong file ownerships and permissions on files inside the built archives. A potential solution to this problem is to make use of the "Fakeroot" package which we've included as an optional extra. Please note, we don't insist that you build packages in the Chroot phase as a non-privileged user when using this Reference Build. Building as root still works correctly.

2. Getting Started

2.1. Environment

The very first task is to set up a sane environment in which to perform the build. These environmental settings apply to the initial Temptools phase, though most will also be carried through into the Chroot phase. But first, a lesson that many folks have learned the hard way:

[Caution]Caution - Never build the Temptools phase as root!

There is a government advertising campaign here in Australia that goes something like "If you drink and drive... you're a bloody idiot". Well, the same thing applies to building the Temptools phase as root. Never do it. The risk of trashing your host system is too great.

Create a specific user and group in which to perform the build of the Temptools phase. Let's call them something creative like `build'. As root:

groupadd build
useradd -s /bin/bash -g build -m -k /dev/null build
passwd build

Decide where you want to build and install the system to. This doesn't have to be a partition, it can be anywhere, under $HOME, /mnt, /tmp or wherever you like, as long as there is plenty of space there (FIXME how much?). The location you've chosen to build the system will be assigned to the $SYSROOT variable below. Once the build has finished, the entire root file system image may be transferred to its intended final destination.

The following steps are taken to ensure a sane shell environment in which to work in. Your build script should, in practice, inherit these settings but it would be wise to at least sanity check the variables yourself when writing your script. Now login as user `build' and create the needed bash startup files and config.site. Then source the files:

[Important]Important

Be sure to substitute the location you've chosen for the build in the $SYSROOT variable assignment below. You'll likely also want to amend the value of $TZ to match your local time zone. $DIY_TARGET is used to select the target architecture you are building for. It is vitally important to ensure that the vendor field of the target triplet is something other than "pc" or "unknown". This is because we want to force the pass 1 toolchain into cross compilation mode. For example, if your real target is i686-pc-linux-gnu, set $DIY_TARGET to i686-diy-linux-gnu or even i686-FAKE-linux-gnu. If your real target is x86_64-unknown-linux-gnu, set $DIY_TARGET to x86_64-diy-linux-gnu, and so forth. Feel free to tweak $TT_PFX if you don't care for the name "temptools". If you are building on SMP, uncomment the MAKEFLAGS line to take advantage of make's parallel execution feature. This is becoming more important as multi-core CPUs increase in popularity. Even on UP you can achieve quicker builds with export MAKEFLAGS="-j2" (at the expense of system responsiveness). If you are targeting x86_64 and also want the ability to compile and run 32-bit code (recommended) set $BIARCH to YES. This will provide a basic bi-arch (multilib) setup with 2 separate Glibc installations and the ability to compile the Grub bootloader which depends on 32-bit compilation. From this basic multilib setup, you then have the capability to build up a full-blown multilib development environment (not covered here), but be aware that going down this path can be a lot of trouble for your average DIY'er. Everything else should remain as is.

If using the original (deprecated) build method, $DIY_ARCH is used to determine the target architecture ($DIY_TARGET and $BIARCH are ignored). Legal values for $DIY_ARCH are "i386", "ppc" and "x86_64" depending on which architecture you are building on.

su - build

cat > ~/.bash_profile << "EOF"
exec env -i HOME=$HOME TERM=$TERM PS1='\u:\w\$ ' /bin/bash
EOF

cat > ~/.bashrc << "EOF"
TT_PFX=/temptools
CONFIG_SHELL=${TT_PFX}/bin/bash
CONFIG_SITE=${HOME}/config.site
DIY_TARGET=i686-diy-linux-gnu
BIARCH=NO
if [ "$BIARCH" = YES ]; then
  if ! echo $DIY_TARGET | grep ^x86_64 >/dev/null; then
    echo Warning: no BIARCH support for target $DIY_TARGET !
  else
    export DIR_64=64
  fi
fi
LC_ALL=C
LDFLAGS="-s"
PATH=${TT_PFX}/bin:/bin:/usr/bin
SYSROOT=/mnt/sysroot
TZ='Australia/Sydney'
export TT_PFX CONFIG_SHELL CONFIG_SITE DIY_TARGET BIARCH LC_ALL LDFLAGS PATH SYSROOT TZ
#export MAKEFLAGS="-j3"
set +o hashall 2>/dev/null || set -o nohash
umask 022
BINUTILS_VER=2.18
GCC_VER=4.2.4
GLIBC_VER=2.7
export BINUTILS_VER GCC_VER GLIBC_VER
EOF

cat > ~/config.site << "EOF"
test "$prefix" = NONE && prefix=${TT_PFX}
test -z "$CFLAGS" && CFLAGS="-O2 -pipe"
test -z "$CXXFLAGS" && CXXFLAGS=${CFLAGS}
enable_nls=no
EOF

source ~/.bash_profile
# Add this section ONLY when using the original (deprecated) build method!
cat >> ~/.bashrc << "EOF"
export DIY_ARCH=i386
EOF

source ~/.bash_profile

FIXME explain rationale for each item above

Now become root and set up the sysroot area:

[Important]Important

Ensure you are currently logged in as user `build' then become root using plain `su'. DO NOT use `su -' (ie: with the hyphen) because you'll lose the environment variables that are critical for these commands to work as intended.

install -dv ${SYSROOT}${TT_PFX}/src/{tarballs,patches}
ln -sv ${SYSROOT}${TT_PFX} /
chown -Rv build ${SYSROOT}${TT_PFX}

Now exit the su (root) login and from this point onwards the environment should be sane enough to build the temptools phase whenever you login as user `build'. Dump all the needed tarballs and patches into their respective dirs. Now you're ready to rock.

2.2. Tarballs

Here is a list of source packages used in the build. This information is extracted into the aforementioned packagedata file for easy parsing and/or conversion into a wget script:

PackageDownload URLmd5sum
Autoconf http://ftp.gnu.org/gnu/autoconf/autoconf-2.63.tar.bz2 7565809ed801bb5726da0631ceab3699
Automake http://ftp.gnu.org/gnu/automake/automake-1.10.1.tar.bz2 4510391e6b3edaa4cffb3ced87c9560c
Bash http://ftp.gnu.org/gnu/bash/bash-3.2.tar.gz 00bfa16d58e034e3c2aa27f390390d30
Binutils (2.18.X) http://ftp.gnu.org/gnu/binutils/binutils-2.18.tar.bz2 9d22ee4dafa3a194457caf4706f9cf01
Binutils (2.17.X) http://ftp.gnu.org/gnu/binutils/binutils-2.17.tar.bz2 e26e2e06b6e4bf3acf1dc8688a94c0d1
Binutils (2.16.X) http://ftp.gnu.org/gnu/binutils/binutils-2.16.1.tar.bz2 6a9d529efb285071dad10e1f3d2b2967
Bison http://ftp.gnu.org/gnu/bison/bison-2.4.1.tar.bz2 84e80a2a192c1a4c02d43fbf2bcc4ca4
Bzip2 http://www.bzip.org/1.0.5/bzip2-1.0.5.tar.gz 3c15a0c8d1d3ee1c46a1634d00617b1a
Coreutils http://ftp.gnu.org/gnu/coreutils/coreutils-6.12.tar.gz 2ca9ac69823dbd567b905a9e9f53c4f6
DejaGnu http://ftp.gnu.org/gnu/dejagnu/dejagnu-1.4.4.tar.gz 053f18fd5d00873de365413cab17a666
Diffutils http://ftp.gnu.org/gnu/diffutils/diffutils-2.8.1.tar.gz 71f9c5ae19b60608f6c7f162da86a428
E2fsprogs http://osdn.dl.sf.net/sourceforge/e2fsprogs/e2fsprogs-1.41.4.tar.gz 59033388df36987d2b9c9bbf7e19bd57
Ed http://ftp.gnu.org/gnu/ed/ed-1.2.tar.gz 3d42ac815b2dfd9c82a89dbd03151519
Expect http://expect.nist.gov/src/expect-5.43.0.tar.bz2 e6aaab98967f6410099b40f2b3ddebb4
Fakeroot http://ftp.debian.org/debian/pool/main/f/fakeroot/fakeroot_1.11.tar.gz b95de26a01338eec7a9b372d0fb24507
File ftp://ftp.astron.com/pub/file/file-5.00.tar.gz fd0b4ce55a756151629e06eaa3411e0c
Findutils http://ftp.gnu.org/gnu/findutils/findutils-4.4.0.tar.gz 49e769ac4382fae6f104f99d54d0a112
Flex http://osdn.dl.sf.net/sourceforge/flex/flex-2.5.35.tar.bz2 10714e50cea54dc7a227e3eddcd44d57
Gawk http://ftp.gnu.org/gnu/gawk/gawk-3.1.6.tar.bz2 c9926c0bc8c177cb9579708ce67f0d75
GCC (4.3.X) http://ftp.gnu.org/gnu/gcc/gcc-4.3.3/gcc-4.3.3.tar.bz2 cc3c5565fdb9ab87a05ddb106ba0bd1f
GCC (4.2.X) http://ftp.gnu.org/gnu/gcc/gcc-4.2.4/gcc-4.2.4.tar.bz2 d79f553e7916ea21c556329eacfeaa16
GCC (4.1.X) http://ftp.gnu.org/gnu/gcc/gcc-4.1.2/gcc-4.1.2.tar.bz2 a4a3eb15c96030906d8494959eeda23c
GCC (4.0.X) http://ftp.gnu.org/gnu/gcc/gcc-4.0.4/gcc-4.0.4.tar.bz2 8970debbc55bea85ee80961d733080f0
GCC (3.4.X) http://ftp.gnu.org/gnu/gcc/gcc-3.4.6/gcc-3.4.6.tar.bz2 4a21ac777d4b5617283ce488b808da7b
Gettext http://ftp.gnu.org/gnu/gettext/gettext-0.17.tar.gz 58a2bc6d39c0ba57823034d55d65d606
Glibc (2.8.X) http://ftp.gnu.org/gnu/glibc/glibc-2.8.tar.bz2 39c75f96a712c56482018d5626306f5f
Glibc (2.7.X) http://ftp.gnu.org/gnu/glibc/glibc-2.7.tar.bz2 065c5952b439deba40083ccd67bcc8f7
Glibc (2.6.X) http://ftp.gnu.org/gnu/glibc/glibc-2.6.1.tar.bz2 11cf6d3fc86dbe0890b8d00372eb6286
Glibc (2.5.X) http://ftp.gnu.org/gnu/glibc/glibc-2.5.1.tar.bz2 10ea72e2c4d56c6aa13dabb7c4f9b195
Glibc (2.4.X) http://ftp.gnu.org/gnu/glibc/glibc-2.4.tar.bz2 7e9a88dcd41fbc53801dbe5bdacaf245
Glibc (2.3.X) http://ftp.gnu.org/gnu/glibc/glibc-2.3.6.tar.bz2 bfdce99f82d6dbcb64b7f11c05d6bc96
GMP [a] http://ftp.gnu.org/gnu/gmp/gmp-4.2.4.tar.bz2 fc1e3b3a2a5038d4d74138d0b9cf8dbe
Grep http://ftp.gnu.org/gnu/grep/grep-2.5.4.tar.bz2 5650ee2ae6ea4b39e9459d7d0585b315
Groff http://ftp.gnu.org/gnu/groff/groff-1.19.2.tar.gz f7c9cf2e4b9967d3af167d7c9fadaae4
Grub (X86 Only) ftp://alpha.gnu.org/gnu/grub/grub-0.97.tar.gz cd3f3eb54446be6003156158d51f4884
Gzip http://ftp.gnu.org/gnu/gzip/gzip-1.3.12.tar.gz b5bac2d21840ae077e0217bc5e4845b1
Hfsutils (PPC Only) ftp://ftp.mars.org/pub/hfs/hfsutils-3.2.6.tar.gz fa572afd6da969e25c1455f728750ec4
Iana-Etc http://www.sethwklein.net/iana-etc-2.30.tar.bz2 3ba3afb1d1b261383d247f46cb135ee8
Inetutils http://ftp.gnu.org/gnu/inetutils/inetutils-1.6.tar.gz 23cc24bc77751bf77d50a07a7395f9b3
Kbd http://ftp.altlinux.com/pub/people/legion/kbd/kbd-1.14.1.tar.gz 0f4e474032c992c05650924f29a06a92
Less http://www.greenwoodsoftware.com/less/less-429.tar.gz 206f2f13b9b0a35e45df660fcb6af31d
Libtool http://ftp.gnu.org/gnu/libtool/libtool-2.2.6a.tar.gz 8ca1ea241cd27ff9832e045fe9afe4fd
Linux Kernel http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.27.tar.bz2 b3e78977aa79d3754cb7f8143d7ddabd
Linux-Libc-Headers http://ep09.pld-linux.org/~mmazur/linux-libc-headers/linux-libc-headers-2.6.12.0.tar.bz2 eae2f562afe224ad50f65a6acfb4252c
M4 http://ftp.gnu.org/gnu/m4/m4-1.4.13.tar.bz2 28f9ccd3ac4da45409251008b911d677
Mac-Fdisk (PPC Only) http://ftp.debian.org/debian/pool/main/m/mac-fdisk/mac-fdisk_0.1.orig.tar.gz 24476329fe86ef6ccf222e233e2a99f1
Make http://ftp.gnu.org/gnu/make/make-3.81.tar.bz2 354853e0b2da90c527e35aabb8d6f1e6
Makedev http://downloads.linuxfromscratch.org/MAKEDEV-1.7.bz2 6ad9f744b586b2dad42958f1c0d334d9
Man http://primates.ximian.com/~flucifredi/man/man-1.6f.tar.gz 67aaaa6df35215e812fd7d89472c44b6
Man-Pages http://www.kernel.org/pub/linux/docs/manpages/man-pages-3.20.tar.bz2 e2e1063265231090b80e1503773f45a0
Man-Pages-Posix http://www.kernel.org/pub/linux/docs/manpages/man-pages-posix/man-pages-posix-2003-a.tar.bz2 7c78aff03c0a6767ba483d34f19e4b09
Module-Init-Tools http://www.kernel.org/pub/linux/utils/kernel/module-init-tools/module-init-tools-3.4.1.tar.bz2 e253b066a1bab1d727ca0d54f001b49c
MPFR [a] http://www.mpfr.org/mpfr-2.4.1/mpfr-2.4.1.tar.bz2 c5ee0a8ce82ad55fe29ac57edd35d09e
Ncurses http://ftp.gnu.org/gnu/ncurses/ncurses-5.7.tar.gz cce05daf61a64501ef6cd8da1f727ec6
Net-Tools http://www.tazenda.demon.co.uk/phil/net-tools/net-tools-1.60.tar.bz2 888774accab40217dde927e21979c165
Patch http://ftp.gnu.org/gnu/patch/patch-2.5.4.tar.gz ee5ae84d115f051d87fcaaef3b4ae782
Perl http://ftp.funet.fi/pub/CPAN/src/perl-5.10.0.tar.gz d2c39b002ebfd2c3c5dba589365c5a71
Procps http://procps.sourceforge.net/procps-3.2.7.tar.gz f490bca772b16472962c7b9f23b1e97d
Psmisc http://osdn.dl.sf.net/sourceforge/psmisc/psmisc-22.6.tar.gz 2e81938855cf5cc38856bd4a31d79a4c
Readline http://ftp.gnu.org/gnu/readline/readline-5.2.tar.gz e39331f32ad14009b9ff49cc10c5e751
Sed http://ftp.gnu.org/gnu/sed/sed-4.1.5.tar.gz 7a1cbbbb3341287308e140bd4834c3ba
Shadow ftp://pkg-shadow.alioth.debian.org/pub/pkg-shadow/shadow-4.1.2.2.tar.bz2 3d26d990d4c3add1b7f8387eec1d1fde
Sysklogd http://www.infodrom.org/projects/sysklogd/download/sysklogd-1.5.tar.gz e053094e8103165f98ddafe828f6ae4b
Sysvinit ftp://ftp.cistron.nl/pub/people/miquels/software/sysvinit-2.86.tar.gz 7d5d61c026122ab791ac04c8a84db967
Tar http://ftp.gnu.org/gnu/tar/tar-1.22.tar.bz2 07fa517027f426bb80f5f5ff91b63585
Tcl http://osdn.dl.sf.net/sourceforge/tcl/tcl8.4.19-src.tar.gz ade2c033a7b545ee108f3fdfeb629fcf
Texinfo http://ftp.gnu.org/gnu/texinfo/texinfo-4.13a.tar.gz 71ba711519209b5fb583fed2b3d86fcb
Util-Linux-ng http://www.kernel.org/pub/linux/utils/util-linux-ng/v2.14/util-linux-ng-2.14.2.tar.bz2 b9d0053a22cfcbf0b9c0aa6d6eccfbc8
Vim http://ftp.vim.org/vim/unix/vim-7.2.tar.bz2 f0901284b338e448bfd79ccca0041254
Yaboot (PPC Only) http://yaboot.ozlabs.org/releases/yaboot-1.3.14.tar.gz 9b1246c474eeb37f61081ad762563b35
Zlib http://www.zlib.net/zlib-1.2.3.tar.bz2 dee233bf288ee795ac96a98cc2e369b6
   
Libtar (Optional) ftp://ftp.feep.net/pub/software/libtar/libtar-1.2.11.tar.gz 604238e8734ce6e25347a58c4f1a1d7e
Pacman (Optional) ftp://ftp.archlinux.org/other/pacman/pacman-2.9.8.tar.gz 5d5e19c159d1fba7c7a6bb93b5bc14bd
   
Ogdlutils (Optional) http://osdn.dl.sf.net/sourceforge/ogdl/ogdlutils-20041124.tgz 45c7c81805480698c8c86881ab9be65c
Cpio (Optional) http://ftp.gnu.org/gnu/cpio/cpio-2.9.tar.bz2 e387abfdae3a0b9a8a5f762db653a96d
BPM (Optional) http://bent.latency.net/bent/darcs/bpm-1.7/src/bpm-1.7.tar.bz2 326eb2408e70414d10938fefa69a358a

[a] Only for GCC-4.3 and above.

2.3. Patches

Patches used in the Reference Build can be downloaded from http://downloads.diy-linux.org/patches/. Be sure to look in the "PM" subdirectory for Package Management related patches, "ppc" subdirectory for PowerPC related patches, etc.

3. Temptools Phase - Next Generation Build Method

[Warning]Warning -- Work In Progress!!

This is the Next Generation build method which is now the default and preferred option. The original method has been deprecated. The new method of bootstrapping a Linux system works well for all supported architectures, supports Package Management and has been ICA verified. For now, only use recent toolchain combinations with this method i.e. Glibc-2.6.x, GCC-4.2.x, Binutils-2.18 and newer. Please note - the Rationales are not yet accurate as all the text was just copied from the original method. This will be fixed progressively in due course.

3.1. Bash-3.2 Pass 1

[Important]Important

This first pass of Bash is the only package we install "by hand". Everything else after this point is expected to be automated via a build script. However, you can still drive the build manually by typing in all the commands on the interactive shell command line if you prefer. Note: Do not skip Bash Pass 1. It used to be optional but is now a requirement of the build method due to our use of CONFIG_SHELL (see below).

patch -p1 -i ${TT_PFX}/src/patches/bash-3.2-official-039-combined-1.patch &&
sh -c "unset CONFIG_SHELL; ./configure" &&
make &&
install -dv ${TT_PFX}/bin &&
cp -v bash ${TT_PFX}/bin/bash-pass1 &&
ln -sv bash-pass1 ${TT_PFX}/bin/bash &&
ln -sv bash ${TT_PFX}/bin/sh

Rationale Notes

  • Installing Bash as the very first package allows us to specify the "configure shell" to be used by all Autoconf-produced configure scripts during the Temptools phase. This is achieved via the CONFIG_SHELL environment variable mentioned earlier. It serves to enhance the robustness of the build method by reducing reliance on the host's /bin/sh thus avoiding potential breakage when bootstrapping from older distros.

  • Another reason for installing Bash first up is that we can write our build script using all the features of modern Bash without having to worry about which shell is installed as /bin/sh on the host. Simply launch your build script like this: `bash-pass1 myscript.sh'.

    [Tip]Tip

    There is additional benefit to using this technique in that it allows greater flexibility for handling the transition between the Temptools and Chroot phases. For example, you can set the interpreter path in your build script to `#!/temptools/bin/bash' which allows easy re-execution of the same script upon entering the chroot environment without having to fuss over having a `$SYSROOT/bin/sh' symlink already set up. Please refer to the author's own gsbuild scripts for a sample implementation. Naturally, this point is moot if you script in pure Bourne or handle the Temptools/Chroot phases transition using a different method.

  • For our purposes of bootstrapping a new Linux system within the Reference Build context, Bash should build fine on any sane distro made within the last 5 years.

  • The "unset CONFIG_SHELL" in the configure invocation is needed for configure to succeed because the shell pointed to by CONFIG_SHELL doesn't exist yet i.e. we are installing it here.

  • Note: some older hosts have `libtermcap' installed and Bash will prefer it over Ncurses if found by configure unless `--with-curses' is given. Bash also comes with its own Termcap. Rather than tinker with configure switches, it's actually more robust to just let configure work it out for itself. This Pass 1 of Bash is simply for running scripts during the Temptools phase so it shouldn't really matter which Termcap is used.

  • Double ampersands are used here because we're still operating in an interactive shell session at this point. We recommend that you employ a proper error trapping strategy in your build script (eg: set -e). Therefore, double ampersands are not provided in the build commands from this point onwards.

3.2. Make-3.81 Pass 1

./configure
make
cp -v make ${TT_PFX}/bin
ln -sv make ${TT_PFX}/bin/gmake

Rationale Notes

  • for bootstrapping purposes, Make should build fine on any sane distro made from 1999 onwards.

  • the Glibc build needs a version of `make' 3.79 or newer which older distros don't have. We remove all doubts by installing the current version. Why install it now rather than just prior to the Glibc build? Well, it makes sense to integrate it from the outset so that we can start using it immediately.

  • the `gmake' symlink is needed for robustness. `gmake' already exists on some hosts which will prevent Glibc's configure script from finding the `make' we install here.

3.3. Sed-4.1.5 Pass 1

./configure \
	ac_cv_header_stdbool_h=yes
make
cp -v sed/sed ${TT_PFX}/bin

Rationale Notes

  • for bootstrapping purposes, Sed should build fine on any sane distro made from 1999 onwards.

  • The ac_cv_header_stdbool_h=yes tweak is needed when building on older hosts. Please read this bug report for details. Note that on newer hosts the variable is set automatically by configure thus making the tweak unnecessary, but it's perfectly fine to leave it there in all circumstances.

  • Why do we install a Pass 1 of Sed here? There have been reported problems where the Glibc build chokes with older Sed versions. The author hasn't personally seen any such problem but feels it's safer to just install a current Sed from the outset. An added bonus is that we can rely on using `sed -i' during the entire Temptools phase thus simplifying scripting.

3.4. Binutils Pass 1 a.k.a. Cross Binutils (2.16.1 through 2.18)

# Red Hat 6.2 Hack
#[[ $DIY_TARGET == x86_64* ]] &&
#	sed -i.bak 's/bad_64bit_gcc=yes/bad_64bit_gcc=no/' bfd/configure

mkdir ../binutils-build
cd ../binutils-build

../binutils-$BINUTILS_VER/configure \
	--target=$DIY_TARGET \
	--with-lib-path=$TT_PFX/lib$DIR_64 \
	--disable-werror
echo "MAKEINFO = :" >> Makefile

make

[[ $DIY_TARGET == x86_64* && $BIARCH = NO ]] &&
	{ install -dv $TT_PFX/lib; ln -sv lib $TT_PFX/lib64; }

make install

Rationale Notes

  • The `echo "MAKEINFO = :" >> Makefile' tweak is used to remove dependence on `makeinfo' and therefore eliminate all associated problems. Please read the mailing list thread starting with this post for details.

  • We create a lib64 -> lib symlink in the x86_64 case because we are not building a multi-arch toolchain. Even in single-arch mode 64-bit architectures tend to hardwire references to "lib64" in many places throughout the toolchain. It's possible to force everything to "lib" but we'd rather keep all the build commands compatible with other architectures. The symlink keeps things sane and everything Just Works™.

  • After the first Binutils are installed, -B/usr/bin/ is temporarily added to the CC definition in order to force the host GCC to use the host Binutils. Without this override, the host GCC will find the newly installed Binutils in the PATH thus causing a toolchain mismatch and potential breakage. This breakage is likely to strike when using a bleeding edge distro as a host (eg: Fedora) and you're building a toolchain comprised of older versions of toolchain components than those on the host. The "if..echo..grep" statement is required on those hosts with GCC-2.95.x or earlier installed. More background on all of this can be found in the mailing list thread starting with this post (continued here).

  • Note: Unlike LFS, we don't statically link the Pass 1 of Binutils because it's simply unnecessary, and in actual fact is a potential source of failure. We therefore link dynamically for robustness reasons. If you still think static linking is a good idea then at least take note of the Glibc maintainer's views on the subject.

  • Because we're linking dynamically, there's no need to specify `make configure-host' after the initial configure. However, when building on SMP the top level Makefile will run the sub-configure scripts for Libiberty and Binutils simultaneously. This is great for speed and efficiency, but unfortunate for the build log which ends up all jumbled. If you'd like the build log to remain neat and tidy (eg: for diffing purposes), run the sub-configure scripts in serial by executing make configure-host -j1 after the initial configure.

3.5. GCC Pass 1 a.k.a. Cross GCC (3.4.6 through 4.3.3)

[[ $GCC_VER == 3.4* && $DIY_TARGET == i?86* ]] &&
	patch -p1 -i $TT_PFX/src/patches/gcc-3.4-branch-x86-inhibit_libc-1.patch

if [[ $GCC_VER > 4.2.9 ]]; then
	bunzip2 -dc $TT_PFX/src/tarballs/mpfr-2.4.1.tar.bz2 | tar xf -
	bunzip2 -dc $TT_PFX/src/tarballs/gmp-4.2.4.tar.bz2 | tar xf -
	mv -v mpfr* mpfr
	mv -v gmp* gmp
fi

mkdir ../gcc-build
cd ../gcc-build

[[ $DIY_TARGET == x86_64* && $BIARCH = NO ]] &&
	GCC_EXTRA_CONFIG="--disable-multilib"

../gcc-$GCC_VER/configure \
	--target=$DIY_TARGET \
	--enable-languages=c \
	--disable-shared \
	--disable-threads \
	--disable-libmudflap \
	--disable-libssp \
	--disable-libgomp \
	--disable-decimal-float \
	$GCC_EXTRA_CONFIG

make
make install -j1

ln -sv libgcc.a `$DIY_TARGET-gcc -print-libgcc-file-name | sed 's/libgcc/&_eh/'`
if [ "$BIARCH" = YES ]; then
	ln -sv libgcc.a `$DIY_TARGET-gcc -m32 -print-libgcc-file-name | sed 's/libgcc/&_eh/'`
fi

Rationale Notes

  • GCC-4.3 and above requires the MPFR and GMP libraries. Here we are taking advantage of the largely undocumented "combined tree" feature of the GNU toolchain. Integrating MPFR and GMP into the GCC build itself greatly simplifies matters and mostly removes all host issues and other complications of building these libs separately. More information in this mailing list post.

  • The switches `--disable-libmudflap', `--disable-libssp', `--disable-libgomp' and `--disable-decimal-float' first appeared in GCC-4.0, GCC-4.1, GCC-4.2 and GCC-4.3 respectively. They are used here to streamline our initial "bootstrap" GCC. The switches are all compatible within supported GCC versions ie: earlier versions simply ignore the later switches.

  • Note: Starting with GCC-4.2, the top-level bootstrap mechanism became the default. This means a plain "make" will now default to performing a 3 stage bootstrap unless `--disable-bootstrap' is given. The pre-GCC-4.2 method of "make bootstrap" behaves identically. Therefore, we can maintain compatibility with earlier versions by continuing to use "make bootstrap".

  • The libgcc_eh.a symlink is needed to satisfy the upcoming Glibc build. Please read this mailing list post for some rationale discussion.

3.6. Linux-Kernel-Headers-2.6.27

[Warning]Warning

The 2.6.18 kernel introduced the next generation method of obtaining sanitized kernel headers. For some background on the issue please see this mailing list post. When using the new technique you MUST SKIP the Linux-Libc-Headers step which follows next. In other words, choose one or the other, not both. Only use the old method when building a toolchain comprised of older components (see table of toolchain combinations listed earlier).

make mrproper
make headers_install INSTALL_HDR_PATH=temp
cp -rv temp/include $TT_PFX

Rationale Notes

  • Note: There is no need to specify `ARCH=xxx' above because as of kernel 2.6.24, the x86 headers produced for 32-bit and 64-bit arches are identical. More information in this mailing list post.

3.7. Linux-Libc-Headers-2.6.12.0 (Older toolchains only)

patch -p1 -i ${TT_PFX}/src/patches/linux-libc-headers-2.6.12.0-syscalls-3.patch
cp -Rv include/asm-${DIY_ARCH} ${TT_PFX}/include/asm
cp -Rv include/linux ${TT_PFX}/include

3.8. Glibc 32-bit - *ONLY* for Bi-arch x86_64 (2.3.6 through 2.8)

[[ $GCC_VER > 4.2.9 && $GLIBC_VER == 2.7* ]] &&
	patch -p1 -i $TT_PFX/src/patches/glibc-2.7-gcc43-1.patch

mkdir ../glibc-build
cd ../glibc-build

CC="$DIY_TARGET-gcc -m32" \
CFLAGS="-O2 -march=i486 -pipe" \
../glibc-$GLIBC_VER/configure \
	--host=i686-diy-linux-gnu \
	--build=$(../glibc-$GLIBC_VER/scripts/config.guess) \
	--disable-profile \
	--enable-add-ons \
	--with-headers=$TT_PFX/include \
	libc_cv_initfini_array=yes \
	libc_cv_forced_unwind=yes \
	libc_cv_c_cleanup=yes

echo "AUTOCONF=no
MAKEINFO=:" > configparms

make
make install -j1

3.9. Glibc (2.3.6 through 2.8)

[Caution]Proceed with Caution!

Glibc is possibly the most critical piece of software you will compile in a base Reference Build. There is a high probability of something going wrong. Be sure to heed the advice contained in Section B, “Glibc General Advice” before taking on this monster. Note: the Glibc compiled here in the Temptools phase is merely a "throw away bootstrap" Glibc, but please do read the aforementioned advice anyway.

[[ $GCC_VER > 4.2.9 && $GLIBC_VER == 2.7* ]] &&
	patch -p1 -i $TT_PFX/src/patches/glibc-2.7-gcc43-1.patch

mkdir ../glibc-build
cd ../glibc-build

[[ $DIY_TARGET == i?86* ]] && MARCH=-march=i486

CFLAGS="-O2 $MARCH -pipe" \
../glibc-$GLIBC_VER/configure \
	--host=$DIY_TARGET \
	--build=$(../glibc-$GLIBC_VER/scripts/config.guess) \
	--disable-profile \
	--enable-add-ons \
	--with-headers=$TT_PFX/include \
	libc_cv_initfini_array=yes \
	libc_cv_forced_unwind=yes \
	libc_cv_c_cleanup=yes

echo "AUTOCONF=no
MAKEINFO=:" > configparms

[ "$BIARCH" = YES ] &&
echo "slibdir=$TT_PFX/lib64
libdir=$TT_PFX/lib64" >> configparms

make
make install -j1

Rationale Notes

  • We need to fiddle with `-march=' in CFLAGS because as of Glibc-2.6, i486 is the minimum supported configuration on x86. More information here.

  • `--without-selinux' is a workaround needed on Fedora Core 3 hosts (those with the "libselinux-devel" package installed) to prevent build failure caused by a subtle Makefile bug. Upstream have been notified of the issue.

  • `AUTOCONF=no' is used here for robustness. It simply prevents unnecessary Autoconf invocations when the Makefiles detect a `configure' file older than its respective `configure.in'. This is usually the case when working with CVS snapshots, but it also applies to release tarballs prior to glibc-2.3.5 when the issue was finally addressed. These unnecessary Autoconf invocations have been known to cause build failures on Debian hosts. An alternative approach is to run `find . -name configure | xargs touch' in the src dir before running `configure'. Note: `--without-cvs' does not address the issue.

  • `MAKEINFO=:' is used to prevent installation failures when the host has an older `makeinfo'. Problems were first noticed with Glibc-2.7.

3.10. Adjust Toolchain

case $DIY_TARGET in
  i?86*)	DL=/lib/ld-linux.so.2 ;;
  powerpc-*)	DL=/lib/ld.so.1 ;;
  x86_64*)	DL=/lib64/ld-linux-x86-64.so.2 ;;
esac

$DIY_TARGET-gcc -dumpspecs | sed \
	-e "s,$DL,$TT_PFX&," \
	-e "/^\*cpp:$/{n;s,$, -isystem $TT_PFX/include,}" \
	> `dirname $($DIY_TARGET-gcc -print-libgcc-file-name)`/specs

echo 'main(){}' | $DIY_TARGET-gcc -B $TT_PFX/lib$DIR_64/ -x c - -lrt
readelf -l a.out | grep ": $TT_PFX"
rm -fv a.out

Rationale Notes

  • For x86_64 we need to empty the "multilib" spec to prevent GCC from searching for libs on the host. The sed simply modifies the spec to mirror how it would appear in a single-arch scenario. More information in this mailing list post.

3.11. Binutils Pass 2 (2.16.1 through 2.18)

[[ $DIY_TARGET == x86_64* && $(uname -m) == i?86 ]] &&
	{ echo 'build a 64-bit kernel and reboot into it!'; exit 1; }

mkdir ../binutils-build
cd ../binutils-build

CC="$DIY_TARGET-gcc -B $TT_PFX/lib$DIR_64/" \
AR=$DIY_TARGET-ar RANLIB=$DIY_TARGET-ranlib \
../binutils-$BINUTILS_VER/configure \
	--with-lib-path=$TT_PFX/lib$DIR_64
echo "MAKEINFO = :" >> Makefile

make
make install

make -C ld clean
make -C ld LIB_PATH=/lib$DIR_64:/usr/lib$DIR_64
cp -v ld/ld-new $TT_PFX/bin

3.12. GCC Pass 2 (3.4.6 through 4.3.3)

case $DIY_TARGET in
  i?86*)	DL=/lib/ld-linux.so.2;		DL_HEADER=i386/linux.h ;;
  powerpc-*)	DL=/lib/ld.so.1;		DL_HEADER=rs6000/sysv4.h ;;
  x86_64*)	DL=/lib64/ld-linux-x86-64.so.2; DL_HEADER=i386/linux64.h
		if [ "$BIARCH" = NO ]; then
			GCC_EXTRA_CONFIG=--disable-multilib
		else
			DL32=/lib/ld-linux.so.2
		fi ;;
esac

if [[ $GCC_VER > 4.2.9 ]]; then
	bunzip2 -dc $TT_PFX/src/tarballs/mpfr-2.4.1.tar.bz2 | tar xf -
	bunzip2 -dc $TT_PFX/src/tarballs/gmp-4.2.4.tar.bz2 | tar xf -
	mv -v mpfr* mpfr
	mv -v gmp* gmp
	patch -p1 -i $TT_PFX/src/patches/gcc-4.3-branch-startfiles-1.patch
fi

if [[ $BINUTILS_VER > 2.17.9 && $GCC_VER > 4.1.9 && $GLIBC_VER > 2.5.9 ]]; then
	patch -p1 -i $TT_PFX/src/patches/gcc-4.2-branch-hash-style-gnu-2.patch
	sed -i.bak '/^#define LINK_SPEC/s/i386} \\/i386} --hash-style=gnu \\/' \
		gcc/config/i386/linux64.h
fi

sed -i.bak "s@$DL@$TT_PFX&@" gcc/config/$DL_HEADER
[ "$BIARCH" = YES ] &&
	sed -i.bak2 "s@$DL32@$TT_PFX&@" gcc/config/$DL_HEADER

echo '
/* Remove /usr/include from include search path.  */
#undef STANDARD_INCLUDE_DIR
#define STANDARD_INCLUDE_DIR 0

/* Remove /lib and /usr/lib from startfiles search path.  */
#define STANDARD_STARTFILE_PREFIX_1 ""
#define STANDARD_STARTFILE_PREFIX_2 ""' >> gcc/config/$DL_HEADER

sed -i.bak \
	's,\./fixinc\.sh,-c true,' gcc/Makefile.in

[[ $GCC_VER == 4.* && $DIY_TARGET == i?86* ]] &&
	sed -i.bak2 's/^XCFLAGS =$/& -fomit-frame-pointer/' gcc/Makefile.in

mkdir ../gcc-build
cd ../gcc-build

CC="$DIY_TARGET-gcc -B $TT_PFX/lib$DIR_64/" \
AR=$DIY_TARGET-ar RANLIB=$DIY_TARGET-ranlib \
../gcc-$GCC_VER/configure \
	--with-local-prefix=$TT_PFX \
	--enable-shared \
	--disable-bootstrap \
	--enable-languages=c,c++ \
	--enable-clocale=gnu \
	--enable-threads=posix \
	--enable-__cxa_atexit \
	--disable-libstdcxx-pch \
	$GCC_EXTRA_CONFIG

make
make install -j1
ln -sv gcc $TT_PFX/bin/cc

# Sanity check - ensure host not being searched for libs
echo 'main(){}' | cc -x c -lbogus -v -Wl,--verbose - &> foo || :
if grep "^attempt to open /usr" foo; then
	echo Oops; exit 1
fi

Rationale Notes

  • The tweak to STANDARD_STARTFILE_PREFIX_{1,2} ensures there is zero chance of any libs and startfiles being found on the host. More information in this mailing list post. Some older information related to the same issue can be found here.

  • As mentioned earlier, we need to pass `--disable-bootstrap' here to prevent GCC-4.2 and above from performing a 3 stage bootstrap. The switch is ignored by earlier versions and is therefore compatible.

  • The notes about `make configure-host' from Binutils Pass 1 and GCC Pass 1 also apply here. However, it gets a little more complicated because we're also building Libstdc++. To achieve the same outcome (ie: run sub-configures in serial for neat build logs under SMP), the sequence needs to be like this:

    make configure-host -j1
    make all-host
    make configure-target -j1
    make all-target
  • When building with GCC-4.x we use a sed to add `-fomit-frame-pointer' to the GCC Makefile to address a correctness issue. Please read this mailing list post for some rationale discussion.

3.13. Gawk-3.1.6

./configure \
	ac_cv_func_working_mktime=yes
make
cp -v gawk ${TT_PFX}/bin
ln -sv gawk ${TT_PFX}/bin/awk

Rationale Notes

3.14. Coreutils-6.12

patch -p1 -i $TT_PFX/src/patches/coreutils-6.12-utimensat-1.patch
./configure \
	--enable-install-program=hostname,su
make
make install
cp -v src/su ${TT_PFX}/bin

Rationale Notes

  • For some background on the `--enable-install-program=hostname,su' configure switch, please read this mailing list post.

  • Because we are operating as a non-privileged user, Coreutils will suppress installation of the `su' program. This is signified by a message shown during `make install': "WARNING: insufficient access; not installing su NOTE: to install su, run 'make install-root' as root". The reason for this is `su' needs to be installed setuid root in order to be fully functional. We manually install it here because even without the setuid bit, we can still use it when inside the Chroot environment to (a) run various testsuites as a non-privileged user and (b) employ Package Management techniques that require building sources as a non-privileged user.

[Important]Important

From this point onwards if you need to become root you must call the host's `su' explicitly by running /bin/su. Just running su will call the first `su' in the $PATH which is the one we just installed (it will fail because of the missing setuid bit). This is especially important when we go to enter the Chroot environment at the beginning of the next phase.

3.15. Bzip2-1.0.5

make PREFIX=${TT_PFX} LDFLAGS=${LDFLAGS} install

3.16. Gzip-1.3.12

[[ $GLIBC_VER > 2.5.9 ]] &&
	sed -i.bak 's/futimens/gl_&/' gzip.c lib/utimens.{c,h}

./configure
make
cp -v gunzip gzip ${TT_PFX}/bin

3.17. Diffutils-2.8.1

./configure
make
cp -v src/{cmp,diff} ${TT_PFX}/bin

3.18. Findutils-4.4.0

./configure
make
cp -v find/find xargs/xargs ${TT_PFX}/bin

3.19. Make-3.81 Pass 2

./configure
make
cp -v make ${TT_PFX}/bin

3.20. Grep-2.5.4

./configure \
	--without-included-regex \
	--disable-perl-regexp
make
cp -v src/{,e,f}grep ${TT_PFX}/bin

Rationale Notes

  • The `MISSING=true' tweak is needed to work around a bug in the current release whereby the build will fail if `makeinfo' is unavailable. See here and here for examples.

3.21. Sed-4.1.5 Pass 2

./configure
make
cp -v sed/sed ${TT_PFX}/bin

3.22. Gettext-0.17

cd gettext-tools
./configure \
	--disable-shared
make -C gnulib-lib
make -C src msgfmt
cp -v src/msgfmt ${TT_PFX}/bin

3.23. Ncurses-5.7

./configure \
	--without-debug \
	--without-ada \
	--enable-overwrite
make
make install

3.24. Patch-2.5.4

./configure
make
cp -v patch ${TT_PFX}/bin

3.25. Tar-1.22

./configure
make
cp -v src/tar ${TT_PFX}/bin

3.26. Texinfo-4.13a

./configure
make
make install

3.27. Bash-3.2 Pass 2

patch -p1 -i ${TT_PFX}/src/patches/bash-3.2-official-039-combined-1.patch
./configure \
	--without-bash-malloc \
	ac_cv_func_working_mktime=yes
make
install -v bash ${TT_PFX}/bin

Rationale Notes

3.28. M4-1.4.13

[Tip]Tip

It's worth noting the next 3 packages (M4, Bison and Flex) are not strictly necessary in the Temptools phase when using an official FSF Binutils release. However, they are mandatory if using a release from HJL. The reason is that FSF releases are made with a "make dist" style procedure whereby the generated files (from Bison and Flex) are already included in the tarball thus removing the requirement for Bison and Flex at Binutils build time (in the Chroot phase). Our recommendation is to always build M4, Bison and Flex here to ensure the build recipe remains compatible with both FSF and HJL Binutils releases. There is another issue: if you skip M4, Bison and Flex here it's likely you'll run into ICA trouble which will require an additional hack when building Bison in the Chroot phase.

./configure
make V=1
cp -v src/m4 ${TT_PFX}/bin

3.29. Bison-2.4.1

./configure
make
make install

3.30. Flex-2.5.35

./configure
make
cp -v flex ${TT_PFX}/bin

3.31. E2fsprogs-1.41.4

mkdir build
cd build
../configure
make libs -j1
make install-libs

Rationale Notes

  • We install the E2fsprogs libraries here to satisfy the build of `mount' from Util-Linux-ng in the next step. If you choose not to build `mount' then these libraries are naturally not required.

3.32. Util-Linux-ng-2.14.2

./configure
make -C mount
make -C getopt
cp -v mount/{,u}mount getopt/getopt ${TT_PFX}/bin

Rationale Notes

  • We install `mount' here so we can mount the virtual file systems from within the chroot environment. Please read this mailing list post for some rationale discussion.

  • We install `getopt' here because it's needed by the optional Fakeroot package (see below). If you're not installing Fakeroot then you don't need to install `getopt' here.

3.33. Perl-5.10.0

chmod -v u+w hints/linux.sh

cat >> hints/linux.sh << "EOF"
libc=${prefix}/lib/`ls -l ${prefix}/lib/libc.so.6 | awk '{print $NF}'`
locincpth=""
loclibpth=""
usrinc="${prefix}/include"
glibpth="${prefix}/lib"
EOF

./configure.gnu \
	--prefix=${TT_PFX} \
	-Dstatic_ext='IO Fcntl Data/Dumper POSIX'

make perl utilities ext/Errno/pm_to_blib
cp -v perl pod/pod2man ${TT_PFX}/bin
mkdir -pv ${TT_PFX}/lib/perl5/5.10.0
cp -Rv lib/* ${TT_PFX}/lib/perl5/5.10.0

Rationale Notes

  • For some background on the commands containing "static_ext" and "ext/Errno/pm_to_blib" please read the mailing list thread starting with this post.

3.34. Tcl-8.4.19

cd unix
./configure
make
make install
make install-private-headers
ln -sv tclsh8.4 ${TT_PFX}/bin/tclsh

3.35. Expect-5.43.0

patch -p1 -i ${TT_PFX}/src/patches/expect-5.43-spawn-1.patch
sed -i.bak '/echo.*STTY_BIN/i STTY_BIN=stty' configure
./configure \
	--with-tcl=${TT_PFX}/lib \
	--with-tclinclude=${TT_PFX}/include \
	--with-x=no
make
make SCRIPTS="" install -j1

Rationale Notes

  • The sed to `configure' forces Expect to call a plain `stty' instead of `/bin/stty' or even worse, `/usr/local/bin/stty'. In this way the first `stty' in the PATH will always be used. It also avoids the need to create a `/bin/stty' symlink in Section 4.5, “Create Symlinks”.

3.36. DejaGnu-1.4.4

./configure
make install -j1

3.37. Fakeroot-1.11 (Optional)

./configure
make
sed -i.bak \
	's,^PATHS=,&/lib$DIR_64:/usr/lib$DIR_64:,' \
	scripts/fakeroot
make install

Rationale Notes

  • As mentioned in the Introduction, if you're employing Package Management by building and creating archives as a non-privileged user, files in the resultant archives can sometimes end up with wrong file ownerships and permissions. Fakeroot can provide a solution to this problem. It acts as a wrapper around various library functions and a typical invocation is like this: fakeroot commands-you-want-run-under-a-fake-root-environment. Generally, you only want to be performing the commands associated with installation under Fakeroot. Running commands associated with configuring and building usually work, but the Fakeroot documentation recommends against it. Never run the testsuites for Glibc, Coreutils and Perl under Fakeroot because you will experience failures. The Bash testsuite can also be problematic. Consider this package optional if you're a) not employing Package Management b) building as root or c) using a Package Manager that doesn't require assistance from Fakeroot.

  • The sed is needed to force Fakeroot to load the correct Glibc when inside the Chroot environment. Without it, Fakeroot will load the Temptools Glibc.

  • Another package with similar functionality but having a slightly different feature set is Pretendroot. Details on this package can be found here. Note: we haven't tested Pretendroot in the context of a Reference Build so your mileage may vary.

3.38. Zlib-1.2.3 (Optional)

[Note]Note -- Optional Package Management with Pacman

Only install the next 3 packages (Zlib, Libtar and Pacman) if you intend implementing Pacman based package management. Pacman is a simple tar.gz-based package manager for Linux originally written for the Arch Linux distro. Please refer to the gsbuild scripts for a sample Pacman implementation. It's worth noting the author personally uses Pacman which means it receives regular testing within the Reference Build context.

./configure --prefix=${TT_PFX}
make
make install

3.39. Libtar-1.2.11 (Optional)

patch -p1 -i ${TT_PFX}/src/patches/libtar-1.2.11-2.patch
./configure
make
make install

3.40. Pacman-2.9.8 (Optional)

patch -p1 -i ${TT_PFX}/src/patches/pacman-2.9.8-custom-mods-2.patch
patch -p1 -i ${TT_PFX}/src/patches/pacman-2.9.6-temptools-1.patch
patch -p1 -i ${TT_PFX}/src/patches/pacman-2.9.8-sep_install-1.patch
./configure
make
cp -v pacman scripts/makepkg ${TT_PFX}/bin
cp -v etc/{makepkg,pacman}.conf ${TT_PFX}/etc

3.41. Ogdlutils-20041124 (Optional)

[Note]Note -- Optional Package Management with BPM

Only install the next 3 packages (Ogdlutils, Cpio and BPM) if you intend implementing BPM based package management. BPM is an extremely compact package manager with the simplest spec file format imaginable. It comes from the Bent Linux distro. Please refer to the gsbuild scripts for a sample BPM implementation. BPM only receives occasional testing within the Reference Build context and is included here mainly as a proof of concept. (Note: the gsbuild BPM implementation currently gets some file permissions wrong - FIXME).

make -C c libogdl gpath -j1
cp -v c/gpath ${TT_PFX}/bin

3.42. Cpio-2.9 (Optional)

./configure
make
cp -v src/cpio ${TT_PFX}/bin

3.43. BPM-1.7 (Optional)

cp -v bpm{build,install,pkgfix} ${TT_PFX}/bin

3.44. Remove Cruft

rm -rfv ${TT_PFX}/{,share/}{info,man}

4. Chroot Phase - Next Generation Build Method

[Warning]Warning -- Work In Progress!!

This is the Next Generation build method which is now the default and preferred option. The original method has been deprecated. The new method of bootstrapping a Linux system works well for all supported architectures, supports Package Management and has been ICA verified. For now, only use recent toolchain combinations with this method i.e. Glibc-2.6.x, GCC-4.2.x, Binutils-2.18 and newer. Please note - the Rationales are not yet accurate as all the text was just copied from the original method. This will be fixed progressively in due course.

4.1. About $PM_DEST

As mentioned in the Introduction, Package Management (PM) is a goal of the Reference Build. Accordingly, all build commands in this Chroot phase strive to be "PM friendly". This is reflected in those individual commands associated with file installation. Commands associated with configuring and building remain exactly the same as when performing a "build in place" style installation.

You'll notice that a typical invocation of make install has now become make DESTDIR=$PM_DEST install. The expectation is this: if you're employing PM then you'll assign a value to the PM_DEST variable in your scripting environment that is equivalent to wherever your chosen Package Manager expects to find the installed files. Doing it this way ensures the installation commands remain generic. If you're not employing PM, that is you're performing a usual "build in place" style installation, you just have to ensure that the PM_DEST variable is nonexistent (or empty or unset), then the installation commands will work exactly as if `DESTDIR=$PM_DEST' weren't specified.

4.2. Enter Chroot Environment

[Important]Important

Earlier in the Temptools phase we installed a somewhat crippled `su' program from Coreutils (with a missing setuid bit). Therefore, in order to become root and enter the Chroot environment, you must call the host's `su' explicitly by running /bin/su or else you'll fail to gain root privilege.

Before entering the chroot environment, be sure to become root using plain `/bin/su'. DO NOT use `/bin/su -' (ie: with the hyphen) because you'll lose the environment variables that are critical for the following chroot command to work as intended. When including this chroot command in your script you'll need to make 2 adjustments: (a) you should omit the $PS1 variable because it is normally unset in non-interactive shells and (b) you'll want to execute a script instead of ${TT_PFX}/bin/bash --login +h (make sure your script does a set +h to switch off hashing).

$TT_PFX/bin/chroot $SYSROOT \
	$TT_PFX/bin/env -i \
	HOME=/root \
	PATH=/bin:/usr/bin:/sbin:/usr/sbin:$TT_PFX/bin \
	PS1='\u-in-chroot:\w\$ ' \
	TERM=$TERM \
	CONFIG_SITE=/etc/config.site \
	LC_ALL=C \
	LDFLAGS=$LDFLAGS \
	${MAKEFLAGS+"MAKEFLAGS=$MAKEFLAGS"} \
	TT_PFX=$TT_PFX \
	TZ=$TZ \
	BINUTILS_VER=$BINUTILS_VER \
	GCC_VER=$GCC_VER \
	GLIBC_VER=$GLIBC_VER \
	DIY_TARGET=$DIY_TARGET \
	BIARCH=$BIARCH \
	${DIR_64+DIR_64=$DIR_64} \
	$TT_PFX/bin/bash --login +h

4.3. Create Directories

mkdir -pv /{bin,etc,home,lib,proc,sys} \
	/dev/{pts,shm} \
	/usr/{bin,include,lib/locale,share/{man,doc,info}} \
	/var/{lock,log,mail,run}
#ln -sv share/{man,doc,info} /usr
install -dvm 0750 /root
install -dvm 1777 {,/var}/tmp

if [[ $DIY_TARGET == x86_64* ]]; then
	if [ "$BIARCH" = NO ]; then
		ln -sv lib /lib64
		ln -sv lib /usr/lib64
	else
		mkdir -pv /{,usr/}lib64
	fi
fi

Rationale Notes

  • There really shouldn't be any need to create a whole directory layout from the outset. Just create the bare minimum to get the build going then let the packages themselves create the rest. If you want a full FHS/LSB compliant layout then just add the missing bits after the build. Consider this experimental. FIXME

  • Current LFS inefficiently uses a raft of `install -d' commands for directory creation here. There is no need for this when `mkdir' is perfectly suited to the task. Only when custom permissions are required do we use `install -d'.

  • The command to create compatibility symlinks in /usr is commented out above. We force packages to install man and info files into proper FHS compliant locations by globally setting defaults in config.site (see below). Those few packages that don't pick up the defaults are taken care of individually in the build commands. Feel free to uncomment the above line if you still prefer to keep the compatibility symlinks.

4.4. Perform Mounts

test -r /etc/mtab || > /etc/mtab
mount proc /proc -t proc
mount devpts /dev/pts -t devpts
mount shm /dev/shm -t tmpfs
mount sysfs /sys -t sysfs

4.5. Create Symlinks

ln -sv $TT_PFX/bin/{bash,cat,echo,pwd} /bin
ln -sv $TT_PFX/bin/perl /usr/bin
ln -sv $TT_PFX/lib/lib{gcc_s.so.1,stdc++.so.6} /usr/lib
[ "$BIARCH" = YES ] &&
	ln -sv $TT_PFX/lib64/lib{gcc_s.so.1,stdc++.so.6} /usr/lib64
ln -sv $TT_PFX/lib/libfakeroot.so /usr/lib$DIR_64
ln -sv bash /bin/sh

Rationale Notes

  • The `/bin/echo' symlink is required for the Glibc-2.6 (and above) testsuite to pass. More information here.

  • The `libstdc++.so.6' symlink is needed to satisfy the Glibc-2.4 (and above) testsuite. More information here.

  • The `libfakeroot.so.0' symlink is only needed if you installed the optional Fakeroot package. If you build Glibc under Fakeroot (not recommended) the build will fail in the absence of this symlink. Additionally, when Fakeroot is used to wrap file installation commands only (its preferred mode of operation), the symlink prevents some ugly non-fatal errors during Glibc and GCC installation eg: "ERROR: ld.so: object 'libfakeroot.so.0' from LD_PRELOAD cannot be preloaded: ignored."

4.6. Create Misc. Files

cat > /etc/passwd << "EOF"
root:x:0:0:root:/root:/bin/bash
EOF

cat > /etc/group << "EOF"
root:x:0:
bin:x:1:
sys:x:2:
kmem:x:3:
tty:x:4:
tape:x:5:
daemon:x:6:
floppy:x:7:
disk:x:8:
lp:x:9:
dialout:x:10:
audio:x:11:
utmp:x:12:
EOF

echo "127.0.0.1 localhost $(hostname)" > /etc/hosts

touch /var/run/utmp /var/log/{btmp,lastlog,wtmp}
chmod -v 644 /var/run/utmp /var/log/{btmp,lastlog,wtmp}
chgrp -v utmp /var/run/utmp

cat > $CONFIG_SITE << "EOF"
test "$prefix" = NONE && prefix=/usr
test "$mandir" = '${prefix}/man' && mandir='${prefix}/share/man'
test "$infodir" = '${prefix}/info' && infodir='${prefix}/share/info'
test -z "$CFLAGS" && CFLAGS="-O2 -pipe"
test -z "$CXXFLAGS" && CXXFLAGS=${CFLAGS}
EOF

Rationale Notes

  • A dummy `/etc/hosts' file is created here to satisfy the Perl testsuite later on.

4.7. Create Users

echo "pkgmgr:x:999:" >> /etc/group
echo "pkgmgr2:x:998:pkgmgr" >> /etc/group
echo "pkgmgr:x:999:999::/home/pkgmgr:/bin/bash" >> /etc/passwd
install -dv -o pkgmgr -g pkgmgr /home/pkgmgr

echo "dummy1:x:1000:" >> /etc/group
echo "dummy2:x:1001:dummy" >> /etc/group
echo "dummy:x:1000:1000::/home:/bin/bash" >> /etc/passwd

Rationale Notes

  • If you're employing Package Management, the chances are you'll probably want to build packages as a non-privileged user. Here we setup a user called "pkgmgr" for exactly this purpose. You can use the `su' program (installed earlier) to build packages as the Package Management User (PMU). To build a package as the PMU, something like: su pkgmgr -c "command-to-build-package" should achieve the desired effect. Creating the PMU is of course optional if you'd prefer to build the Chroot phase as root.

  • We also create a dummy user and some dummy groups for the benefit of those testsuites that need to be run as a non-privileged user. These entries should be removed upon completion of the build.

4.8. Makedev-1.7

bzcat ${TT_PFX}/src/tarballs/MAKEDEV-1.7.bz2 > $PM_DEST/dev/MAKEDEV
chmod -v 754 $PM_DEST/dev/MAKEDEV
cd $PM_DEST/dev
./MAKEDEV -v generic-nopty

Rationale Notes

  • We install MAKEDEV here primarily for the purpose of bootstrapping the Reference Build. That is, you don't have to deploy the MAKEDEV script and the "on disk" device special files it created in your final file system image. Some folks prefer to use the (now deprecated) kernel based Devfs facility to manage /dev. However, lately the general trend has moved towards the Udev system which runs entirely in userspace. Other options for populating /dev during the chroot phase of the Reference Build include: (a) performing a `mount --bind' of the host's /dev onto $SYSROOT/dev (b) manually mknod'ing the bare minimum device special files needed to satisfy the build or (c) running the `udevstart' program from Udev. All of these solutions are suboptimal in the author's opinion which is why using MAKEDEV here is recommended. What you do to manage /dev in the final deployed system is entirely your choice, but if you're after the latest and greatest, Udev would be your best bet.

4.9. Man-Pages-3.20

rm -fv man3/getspnam.3 man5/passwd.5
make DESTDIR=$PM_DEST install

Rationale Notes

  • In general terms, GNU prefers the Info documentation system over man pages. However, many GNU packages install both info pages and (in some cases, less than adequate) man pages. The man pages listed above will be installed later on by Coreutils, Diffutils and Shadow and are therefore superfluous. We suppress their installation here because some Package Managers will refuse to install an archive if a file conflict is detected. If you'd prefer to keep the copies here, omit the rm statements and somehow suppress the installation of said man pages when installing the 3 aforementioned packages later on.

4.10. Man-Pages-Posix-2003-a

make DESTDIR=$PM_DEST install

4.11. Linux-Kernel-Headers-2.6.27

[Warning]Warning

As mentioned earlier, the 2.6.18 kernel introduced the next generation method of obtaining sanitized kernel headers. When using the new technique you MUST SKIP the Linux-Libc-Headers step which follows next.

make mrproper
make headers_check || :
make headers_install INSTALL_HDR_PATH=temp
mkdir -pv $PM_DEST/usr
cp -rv temp/include $PM_DEST/usr

4.12. Linux-Libc-Headers-2.6.12.0 (Older toolchains only)

patch -p1 -i ${TT_PFX}/src/patches/linux-libc-headers-2.6.12.0-syscalls-3.patch
mkdir -pv $PM_DEST/usr/include
cp -Rv include/asm-${DIY_ARCH} $PM_DEST/usr/include/asm
cp -Rv include/linux $PM_DEST/usr/include

4.13. Glibc 32-bit - *ONLY* for Bi-arch x86_64 (2.3.6 through 2.8)

sed -i.bak \
	's|libs -o|libs -L/usr/lib -Wl,-dynamic-linker=/lib/ld-linux.so.2 -o|' \
	scripts/test-installation.pl

[[ $GCC_VER > 4.2.9 && $GLIBC_VER == 2.7* ]] &&
	patch -p1 -i $TT_PFX/src/patches/glibc-2.7-gcc43-1.patch

[[ $GCC_VER == 4.2* ]] &&
	patch -p1 -i $TT_PFX/src/patches/glibc-2.6-x86-math-tests-1.patch

[[ $GLIBC_VER == 2.8* ]] &&
	patch -p1 -i $TT_PFX/src/patches/glibc-2.8-iconv-tests-1.patch

mkdir ../glibc-build
cd ../glibc-build

MARCH=-march=i686
[[ $GCC_VER > 4.1.9 ]] && MARCH="$MARCH -mtune=generic"

CC="gcc -m32" CXX="g++ -m32" \
CFLAGS="-O3 $MARCH -pipe" \
../glibc-$GLIBC_VER/configure \
	--host=i686-pc-linux-gnu \
	--build=$(../glibc-$GLIBC_VER/scripts/config.guess) \
	--disable-profile \
	--enable-add-ons \
	--libexecdir=/usr/lib \
	--with-headers=/usr/include \
	--enable-kernel=2.6.18 \
	--enable-bind-now

echo "cross-compiling=no" > configparms

make

[[ $GLIBC_VER > 2.7.9 ]] &&
	cp -v ../glibc-$GLIBC_VER/iconvdata/gconv-modules iconvdata

make -k check || :
make install_root=$PM_DEST install -j1

if [ "$PM_DEST" ]; then
	cp -v $PM_DEST/usr/include/{gnu/stubs-32,sys/{elf,vm86}}.h /tmp
	rm -rfv $PM_DEST/{etc,sbin,usr/{bin,include,sbin,share}}
	mkdir -pv $PM_DEST/usr/include/{gnu,sys}
	mv -v /tmp/{elf,vm86}.h $PM_DEST/usr/include/sys
	mv -v /tmp/stubs-32.h $PM_DEST/usr/include/gnu
fi

4.14. Glibc (2.3.6 through 2.8)

[Caution]Proceed with Caution!

Glibc is possibly the most critical piece of software you will compile in a base Reference Build. There is a high probability of something going wrong. Be sure to heed the advice contained in Section B, “Glibc General Advice” before taking on this monster.

case $DIY_TARGET in
  i?86*)	DL=/lib/ld-linux.so.2; MARCH=-march=i686
		[[ $GCC_VER > 4.1.9 ]] && MARCH="$MARCH -mtune=generic" ;;
  powerpc-*)	DL=/lib/ld.so.1 ;;
  x86_64*)	DL=/lib64/ld-linux-x86-64.so.2 ;;
esac

sed -i.bak \
	"s|libs -o|libs -L/usr/lib$DIR_64 -Wl,-dynamic-linker=${DL} -o|" \
	scripts/test-installation.pl

[[ $GCC_VER > 4.2.9 && $GLIBC_VER == 2.7* ]] &&
	patch -p1 -i $TT_PFX/src/patches/glibc-2.7-gcc43-1.patch

[[ $GCC_VER == 4.2* && $DIY_TARGET == i?86* ]] &&
	patch -p1 -i $TT_PFX/src/patches/glibc-2.6-x86-math-tests-1.patch

[[ $GLIBC_VER == 2.8* ]] &&
	patch -p1 -i $TT_PFX/src/patches/glibc-2.8-iconv-tests-1.patch

mkdir ../glibc-build
cd ../glibc-build

CFLAGS="-O3 $MARCH -pipe" \
../glibc-$GLIBC_VER/configure \
	--disable-profile \
	--enable-add-ons \
	--libexecdir=/usr/lib$DIR_64 \
	--with-headers=/usr/include \
	--enable-kernel=2.6.18 \
	--enable-bind-now

[ "$BIARCH" = YES ] &&
echo "slibdir=/lib64
libdir=/usr/lib64" > configparms

make

[[ $GLIBC_VER > 2.7.9 ]] &&
	cp -v ../glibc-$GLIBC_VER/iconvdata/gconv-modules iconvdata

make -k check || :
make install_root=$PM_DEST install -j1
#make install_root=$PM_DEST localedata/install-locales
cp -v --remove-destination $PM_DEST/usr/share/zoneinfo/$TZ $PM_DEST/etc/localtime

cat > $PM_DEST/etc/nsswitch.conf << "EOF"
# Begin /etc/nsswitch.conf

passwd: files
group: files
shadow: files

hosts: files dns
networks: files

protocols: files
services: files
ethers: files
rpc: files

# End /etc/nsswitch.conf
EOF

cat > $PM_DEST/etc/ld.so.conf << "EOF"
# Begin /etc/ld.so.conf

/usr/local/lib

# End /etc/ld.so.conf
EOF

Rationale Notes

  • For an explanation of why we add `-mtune=generic' to CFLAGS in the x86 GCC-4.2 and above case, please read this mailing list post.

  • Whenever Glibc is installed directly into a prefix of /usr via `make install' (ie: the Makefile variable `install_root' is unset), a script called `test-installation.pl' is run to perform some basic sanity checks (compiling, linking, executing, etc) against the newly installed Glibc. If all goes well, a message "Your new glibc installation seems to be ok." will be shown. However, at the time the script is run our toolchain defaults are still pointing to $TT_PFX. In particular, ld's library search path is pointing to $TT_PFX/lib and gcc's dynamic linker spec is pointing to $TT_PFX${DL}. In actual fact, this means the checks are made against the wrong Glibc. The problem will usually go unnoticed because the Glibc's in $TT_PFX/lib and /usr/lib are functionally equivalent and the checks always pass. You can expose the problem by building different Glibc addons in each phase eg: configure the Temptools phase Glibc with `--enable-add-ons=nptl' and configure the Chroot phase Glibc with `--enable-add-ons=nptl,libidn' (assuming you have downloaded and unpacked the separate addon for Libidn). We work around the issue by using a sed to insert `-L/usr/lib -Wl,-dynamic-linker=${DL}' at an appropriate place. Note that ld's library search path and the gcc dynamic linker spec will be readjusted to point to the new Glibc in the next step.

  • The `gconv-modules' modules tweak is a workaround for the testsuite. Backgroud information can be found here.

  • The command to install the localedata has been commented out above. If you need all the locales, unlikely as that may be, feel free to uncomment the relevant line. It used to be the case that some of these locales were required for the Libstdc++ testsuite to pass. But that is no longer true with the advent of GCC-3.4. More information about this issue is here. However, the Libstdc++ docs do recommend a minimum list of locales, so having them installed should result in wider Libstdc++ testsuite coverage. Note that you can install individual locales at any time using the `localedef' command ie: locale installation doesn't have to occur as part of the Glibc install. At the very least, you'll probably want to install a locale for your own country.

  • The warning in current LFS about unsetting CFLAGS and not overriding the default optimization for Glibc is a crock. Glibc is EXACTLY the kind of package that should be optimized - Refer Golden Rule No. 2 in Section B, “Glibc General Advice”. The warning in LFS dates back to times when clues were scarce and tools weren't as good.

[Tip]Tip -- Set up Dual Threading Libraries

Ever since the advent of NPTL most mainstream distros are set up with both NPTL and Linuxthreads enabled Glibc's installed side by side. This is for backwards compatibility reasons. NPTL is still relatively new and a lot of commercial software simply won't run under it. Be sure to check out Section B, “Dual Threading Libraries” if you need this backwards compatibility and want to set up your system to match the distros.

4.15. Readjust Toolchain

ln -sv ${TT_PFX}/bin/ld-new /usr/bin/ld

case $DIY_TARGET in
  i?86*)	DL=/lib/ld-linux.so.2 ;;
  powerpc-*)	DL=/lib/ld.so.1 ;;
  x86_64*)	DL=/lib64/ld-linux-x86-64.so.2 ;;
esac

gcc -dumpspecs | sed \
	-e "/^\*link:$/{n;s,$, -L/usr/lib$DIR_64,}" \
	-e "s,${TT_PFX}${DL},${DL}," \
	-e '/^\*cpp:$/{n;s,$, -isystem /usr/include,}' \
	> /tmp/myspecs

# Sanity checks.
echo 'main(){}' | cc \
	-x c \
	-specs=/tmp/myspecs \
	-B/usr/lib$DIR_64/ \
	-B/usr/bin/ \
	-Wl,--verbose \
	- -lrt &> foo

# 1. dynamic linker
readelf -l a.out | grep ": /lib"

# 2. start files
grep " /usr/lib$DIR_64/crt1.o succ" foo

# 3. libc
grep " /lib.*libc.so.6 succ" foo

# 4. deps found from DT_NEEDED
grep "^found.*at /lib.*/libpth" foo

rm -fv a.out foo

4.16. Zlib-1.2.3

sed -i.bak \
	'/SFL.*fPIC/s/${CFLAGS-"-fPIC -O3"}/"${CFLAGS-"-O3"} -fPIC"/' \
	configure

CC="gcc -specs=/tmp/myspecs -B/usr/lib$DIR_64/ -B/usr/bin/" \
./configure \
	--prefix=/usr
make
mv -v {,x}libz.a
make clean

CC="gcc -specs=/tmp/myspecs -B/usr/lib$DIR_64/ -B/usr/bin/" \
./configure \
	--prefix=/usr \
	--shared

[ "$BIARCH" = YES ] &&
	sed -i.bak '/^libdir/s/lib$/&64/' Makefile

make
make check
make prefix=$PM_DEST/usr install
cp -v xlibz.a $PM_DEST/usr/lib$DIR_64/libz.a
mkdir -pv $PM_DEST/lib$DIR_64
mv -v $PM_DEST/usr/lib$DIR_64/libz.so.* $PM_DEST/lib$DIR_64
ln -sfv ../../lib$DIR_64/libz.so.1 $PM_DEST/usr/lib$DIR_64/libz.so

Rationale Notes

  • We build Zlib here in the build order to satisfy Binutils starting with version 2.19. More rationale in this mailing list post.

  • The sed to `configure' replicates a fix from upstream which ensures the shared lib is always built with -fPIC. Currently, -fPIC is lost if CFLAGS happen to be set in the environment. More information in this mailing list post. Note: Zlib beta versions can be found here.

  • The reason for the mv -v {,x}libz.a etc. is to allow better locality of the "installation" commands. More rationale in this mailing list post.

4.17. Binutils (2.16.1 through 2.18)

rm -fv etc/standards.info
sed -i.bak '/^INFO/s/standards.info //' etc/Makefile.in

[[ $GCC_VER > 4.2.9 && $BINUTILS_VER == 2.18 ]] &&
	patch -p1 -i $TT_PFX/src/patches/binutils-2.18-gcc43-ld-shared-tests-1.patch

mkdir ../binutils-build
cd ../binutils-build

CC="gcc -specs=/tmp/myspecs -B/usr/lib$DIR_64/ -B/usr/bin/" \
../binutils-$BINUTILS_VER/configure \
	--enable-shared \
	${DIR_64+--libdir=/usr/lib64}
echo "MAKEINFO = makeinfo" >> Makefile
make tooldir=/usr
make -k check || :
make tooldir=/usr DESTDIR=$PM_DEST install
cp -v ../binutils-$BINUTILS_VER/include/libiberty.h $PM_DEST/usr/include

Rationale Notes

  • A newer `standards.info' is installed later by the Autoconf package. Here we use `rm' and a Makefile sed to suppress installation of the unwanted file. The `rm' is needed when using FSF releases but is otherwise harmless when using HJL releases.

4.18. GCC (3.4.6 through 4.3.3)

[Caution]Caution -- Check your GCC Testsuite Results!

Upon completion of the GCC Testsuite run, sanity check your results by comparing against a set of known good results as per the links in the following table:

i686-pc-linux-gnupowerpc-unknown-linux-gnux86_64-unknown-linux-gnu
4.3.2 4.3.0 4.3.0
4.2.4 4.2.1 FIXME
4.1.2 4.1.2 4.1.1
4.0.4 4.0.4 4.0.3
3.4.6 3.4.6 3.4.6

Note: if you're using GCC-3.4.4 or earlier and running under a 2.6.12 kernel or above, a new kernel feature known as "address space randomization" will likely cause some PCH tests to fail as per these unsatisfactory results. The problem is now resolved in GCC-3.4.5 and above. However, if for some reason you need to use an old GCC version, the problem can be worked around by following the advice contained in this mailing list post.

if [[ $GCC_VER > 4.2.9 ]]; then
	tar -xf $TT_PFX/src/tarballs/mpfr-2.4.1.tar.bz2 --transform='s/-2.4.1//'
	tar -xf $TT_PFX/src/tarballs/gmp-4.2.4.tar.bz2 --transform='s/-4.2.4//'
fi

sed -i.bak \
	's/install_to_$(INSTALL_DEST) //' libiberty/Makefile.in

if [[ $BINUTILS_VER > 2.17.9 && $GCC_VER > 4.1.9 && $GLIBC_VER > 2.5.9 ]]; then
	patch -p1 -i $TT_PFX/src/patches/gcc-4.2-branch-hash-style-gnu-2.patch
	sed -i.bak '/^#define LINK_SPEC/s/i386} \\/i386} --hash-style=gnu \\/' \
		gcc/config/i386/linux64.h
fi

sed -i.bak \
	's,\./fixinc\.sh,-c true,' gcc/Makefile.in

[[ $GCC_VER == 4.* && $DIY_TARGET == i?86* ]] &&
	sed -i.bak2 's/^XCFLAGS =$/& -fomit-frame-pointer/' gcc/Makefile.in

[[ $GCC_VER == 4.* ]] &&
	sed -i.bak '/dg-timeout/s/3\|10/20/' libmudflap/testsuite/libmudflap.cth/*.c

mkdir ../gcc-build
cd ../gcc-build

[[ $DIY_TARGET == x86_64* && $BIARCH = NO ]] &&
	GCC_EXTRA_CONFIG=--disable-multilib

CC="gcc -specs=/tmp/myspecs -B/usr/lib$DIR_64/ -B/usr/bin/" \
../gcc-${GCC_VER}/configure \
	--libexecdir=/usr/lib$DIR_64 \
	--enable-shared \
	--disable-bootstrap \
	--enable-languages=c,c++ \
	--enable-clocale=gnu \
	--enable-threads=posix \
	--enable-__cxa_atexit \
	$GCC_EXTRA_CONFIG

make \
	LDFLAGS=$LDFLAGS \
	MAKEINFO=makeinfo \
	gcc_cv_prog_makeinfo_modern=yes

make -k check || :
../gcc-${GCC_VER}/contrib/test_summary
make DESTDIR=$PM_DEST install -j1

mkdir -pv $PM_DEST/lib
ln -sfv ../usr/bin/cpp $PM_DEST/lib
ln -sfv gcc $PM_DEST/usr/bin/cc

Rationale Notes

  • When building with GCC-4.x we use a sed to add `-fomit-frame-pointer' to the GCC Makefile to address a correctness issue. Please read this mailing list post for some rationale discussion.

  • When building with GCC-4.x we use a sed to increase the timeouts on 2 libmudflap tests to avoid spurious failures. The problem is most noticeable when running the GCC testsuite in parallel on SMP. Upstream have been notified of the issue. Note the timeouts were increased from 3 to 10 seconds as of GCC-4.1 but this is still not enough. The sed is compatible across all supported GCC versions.

  • We add "MAKEINFO=makeinfo" and "gcc_cv_prog_makeinfo_modern=yes" to the `make' invocation to ensure installation of the GCC info pages. Please read this mailing list post for background details.

4.19. Sed-4.1.5

./configure \
	--bindir=/bin \
	--enable-html
make
make check
make DESTDIR=$PM_DEST install

4.20. E2fsprogs-1.41.4

sed -i.bak 's,/bin/rm,rm,' lib/blkid/test_probe.in

mkdir build
cd build

../configure \
	--with-root-prefix="" \
	--enable-elf-shlibs \
	${DIR_64+--libdir=/usr/lib64}
make
make check
make DESTDIR=$PM_DEST install install-libs ${DIR_64+root_libdir=/lib64}

Rationale Notes

  • The sed to `lib/blkid/test_probe.in' removes a hard-wired reference to /bin/rm in the testsuite. Without this sed (or a /bin/rm symlink) the testsuite will produce some non-fatal errors.

4.21. Coreutils-6.12

patch -p1 -i $TT_PFX/src/patches/coreutils-6.12-utimensat-1.patch
sed -i.bak 's,HOME",HOME /dev/shm",' tests/other-fs-tmpdir
sed -i.bak 's/test-getaddrinfo\$(EXEEXT) //' gnulib-tests/Makefile.in

./configure \
	--enable-no-install-program=kill,uptime \
	--enable-install-program=hostname,su
make

if [ `id -u` -eq 0 ]; then
	make NON_ROOT_USERNAME=dummy check-root
	chown -v dummy gnulib-tests/.deps
	su dummy -c "make RUN_EXPENSIVE_TESTS=yes check"
else
	make RUN_EXPENSIVE_TESTS=yes check
fi
make DESTDIR=$PM_DEST install
mkdir -pv $PM_DEST/{bin,usr/sbin}
mv -v $PM_DEST/usr/bin/{cat,chgrp,chmod,chown,cp,date} $PM_DEST/bin
mv -v $PM_DEST/usr/bin/{dd,df,echo,false,hostname,ln,ls} $PM_DEST/bin
mv -v $PM_DEST/usr/bin/{mkdir,mknod,mv,pwd,rm,rmdir,sleep} $PM_DEST/bin
mv -v $PM_DEST/usr/bin/{stty,su,sync,touch,true,uname} $PM_DEST/bin
mv -v $PM_DEST/usr/bin/chroot $PM_DEST/usr/sbin

Rationale Notes

  • For an explanation of the Makefile.in sed, configure switches and chown command, please read this mailing list post.

  • The sed to `tests/other-fs-tmpdir' adds /dev/shm as a location to search when the testsuite goes looking for a writable directory on a different disk partition. This allows some tests to run that would otherwise be skipped. Passing `CANDIDATE_TMP_DIRS=/dev/shm' would achieve the same effect but the sed saves us passing it twice.

  • A bunch of commands are moved to /bin as mandated by the FHS. In the case of `[' and `test', the FHS says they must be together in either /bin or /usr/bin. We leave them in /usr/bin to match the big distros. Even though `sleep' and `touch' are not mentioned by the FHS, we move them to /bin because: (a) they are commonly used in bootscripts, (b) they have always traditionally been there and (c) this matches the big distros. Please read this mailing list post for some rationale discussion.

  • We have opted to use the `su' from Coreutils rather than the one from Shadow. Please read this mailing list post for some rationale discussion. If you would rather use the `su' from Shadow, simply omit `su' from the --enable-install-program configure switch and the 4th mv command.

  • If you would like `uname' to print something useful for the `-p' and `-i' options instead of "unknown", 3rd party patches are known to exist (or at least have existed in the past) at the LFS and Gentoo projects. But before applying any such hacks, ask yourself this question: Why haven't these types of patches been integrated by the upstream Coreutils developers? Some insight into this issue can be found in this mailing list thread.

4.22. Iana-Etc-2.30

make STRIP=yes
make test
make DESTDIR=$PM_DEST install

Rationale Notes

  • Note: You should be aware there are performance implications when using this package because it results in an enormous /etc/services file. Please read this mailing list post for some background discussion.

4.23. Gawk-3.1.6

./configure \
	--libexecdir=/usr/lib$DIR_64 \
	ac_cv_func_working_mktime=yes
make
make check
make DESTDIR=$PM_DEST install

Rationale Notes

  • The `ac_cv_func_working_mktime=yes' tweak is needed to work around a buggy Autoconf macro tickled by GCC-4.3. More information here.

4.24. Findutils-4.4.0

./configure \
	--libexecdir=/usr/lib$DIR_64/locate \
	--localstatedir=/var/lib/locate
make
make check
make DESTDIR=$PM_DEST install

4.25. Ncurses-5.7

./configure \
	--with-shared \
	--without-debug \
	${DIR_64+--libdir=/usr/lib64}
make
make DESTDIR=$PM_DEST install
mkdir -pv $PM_DEST/lib$DIR_64
mv -v $PM_DEST/usr/lib$DIR_64/libncurses.so.5* $PM_DEST/lib$DIR_64
ln -sfv ../../lib$DIR_64/libncurses.so.5 $PM_DEST/usr/lib$DIR_64/libncurses.so
ln -sfv libncurses.so $PM_DEST/usr/lib$DIR_64/libcurses.so

4.26. Readline-5.2

patch -p1 -i ${TT_PFX}/src/patches/readline-5.2-official-012-combined-1.patch
./configure \
	${DIR_64+--libdir=/usr/lib64} \
	bash_cv_func_ctype_nonascii=yes
make SHLIB_LIBS=-lcurses
sed -i.bak '/MV.*old/d' Makefile
make DESTDIR=$PM_DEST install
mkdir -pv $PM_DEST/lib$DIR_64
mv -v $PM_DEST/usr/lib$DIR_64/lib{readline,history}.so.5* $PM_DEST/lib$DIR_64
ln -sfv ../../lib$DIR_64/libhistory.so.5 $PM_DEST/usr/lib$DIR_64/libhistory.so
ln -sfv ../../lib$DIR_64/libreadline.so.5 $PM_DEST/usr/lib$DIR_64/libreadline.so

Rationale Notes

  • We add "bash_cv_func_ctype_nonascii=yes" to the `configure' invocation to force the correct result in scenarios where the en_US.ISO8859-1 locale is not present. More information here.

4.27. Vim-7.2

echo '#define SYS_VIMRC_FILE "/etc/vimrc"' >> src/feature.h

./configure
make
make test -j1
mkdir -pv $PM_DEST/etc
make DESTDIR=$PM_DEST install -j1
ln -sfv vim $PM_DEST/usr/bin/vi

cat > $PM_DEST/etc/vimrc << "EOF"
" Begin /etc/vimrc

set nocompatible
set backspace=2
syntax on

" End /etc/vimrc
EOF

Rationale Notes

  • Note: The Vim author makes available a number of patches to fix bugs discovered after the latest release which you may want to consider applying. The patches can be found here.

4.28. M4-1.4.13

./configure
make V=1
make check V=1
make DESTDIR=$PM_DEST install

4.29. Bison-2.4.1

./configure \
	${DIR_64+--libdir=/usr/lib64}
make
make check
make DESTDIR=$PM_DEST install

4.30. Less-429

./configure \
	--sysconfdir=/etc
make
make DESTDIR=$PM_DEST install

4.31. Groff-1.19.2

PAGE=A4 ./configure
make -j1
mkdir -pv $PM_DEST/usr
make prefix=$PM_DEST/usr install
ln -sfv soelim $PM_DEST/usr/bin/zsoelim
ln -sfv eqn $PM_DEST/usr/bin/geqn
ln -sfv tbl $PM_DEST/usr/bin/gtbl

4.32. Flex-2.5.35

./configure \
	${DIR_64+--libdir=/usr/lib64}
make
make check -j1
make DESTDIR=$PM_DEST install
ln -sfv flex $PM_DEST/usr/bin/lex
ln -sfv libfl.a $PM_DEST/usr/lib$DIR_64/libl.a

4.33. Gettext-0.17

./configure \
	${DIR_64+--libdir=/usr/lib64}
make
make -k check || :
make DESTDIR=$PM_DEST install

Rationale Notes

  • The Gettext testsuite takes a painfully long time to run, and seeing as Gettext is not a critical component in the overall scheme of things, running this testsuite is considered optional. You can reduce the pain somewhat by only running the less time consuming parts of the testsuite like so: make -C gettext-tools check.

  • Note that the Gettext testsuite will gain wider coverage if you have a bunch of various locales installed (the testsuite will inform you of which ones are missing).

  • Note also that 2 tests will fail if Gettext is configured with `--disable-nls' and the fr_FR locale is installed. More information about this issue is here.

4.34. Net-Tools-1.60

sed -i.bak \
	-e '/PROGS/s/hostname //' \
	-e '/hostname.*bin/d' \
	Makefile
sed -i.bak 's/in 1 5/in 5/' man/Makefile
sed -i.bak '/default:/d' lib/inet_sr.c
sed -i.bak 's/of(x25/of(struct x25/' lib/x25_sr.c

yes "" | make config
make LOPTS=${LDFLAGS} -j1
make BASEDIR=$PM_DEST update

4.35. Inetutils-1.6

sed -i.bak '/man_MANS =/d' \
	{ftpd,inetd,logger,rexecd,rlogind,rshd,syslogd,talkd,telnetd,tftpd}/Makefile.in

./configure \
	--disable-servers \
	--disable-hostname \
	--disable-logger \
	--disable-whois \
	--disable-ifconfig \
	--libexecdir=/usr/sbin
make
make DESTDIR=$PM_DEST install
mkdir -pv $PM_DEST/bin
mv -v $PM_DEST/usr/bin/ping $PM_DEST/bin

4.36. Procps-3.2.7

make
make DESTDIR=$PM_DEST ldconfig=: install

4.37. Perl-5.10.0

sed -i.bak \
	"/if grep/a skip \"not testing setlogsock('stream'): _PATH_LOG unavailable\", 10 \
	unless -e Sys::Syslog::_PATH_LOG();" \
	ext/Sys/Syslog/t/syslog.t

./configure.gnu \
	-Dpager="/usr/bin/less -isR"

make BUILD_ZLIB=False
make test
make DESTDIR=$PM_DEST install

Rationale Notes

  • The sed replicates a testsuite fix from upstream. More background in this mailing list post.

  • BUILD_ZLIB=False is passed on the `make' command line in order to use the system installed Zlib. More background in this mailing list post.

4.38. Gzip-1.3.12

[[ $GLIBC_VER > 2.5.9 ]] &&
	sed -i.bak 's/futimens/gl_&/' gzip.c lib/utimens.{c,h}

./configure
make bindir=/bin
make check
make DESTDIR=$PM_DEST install
mkdir -pv $PM_DEST/bin
mv -v $PM_DEST/usr/bin/{gunzip,gzip,zcat} $PM_DEST/bin

Rationale Notes

  • Adding `bindir=/bin' to the make invocation is not strictly necessary. But it at least ensures the installed scripts have an optimal setting for PATH.

  • Some LFS versions add a `/bin/compress' symlink here. We believe this is technically incorrect. Please read this mailing list post for some rationale discussion.

4.39. Texinfo-4.13a

./configure
make
make check
make DESTDIR=$PM_DEST install

4.40. Grep-2.5.4

./configure \
	--bindir=/bin \
	--without-included-regex
make
make check
make DESTDIR=$PM_DEST install

4.41. File-5.00

./configure \
	${DIR_64+--libdir=/usr/lib64}
make
make check
make DESTDIR=$PM_DEST install

4.42. Libtool-2.2.6a

./configure \
	${DIR_64+--libdir=/usr/lib64}
make
make check
make DESTDIR=$PM_DEST install

4.43. Autoconf-2.63

./configure
make
make check
make DESTDIR=$PM_DEST install

4.44. Automake-1.10.1

./configure
make
make -k check || :
make DESTDIR=$PM_DEST install
  • This release of Automake contains an expected testsuite failure when run as root. More information here.

4.45. Bash-3.2

[Important]Important

The Bash testsuite is unlike most others in that it doesn't stop if errors are encountered. This means you have to physically examine the output and cannot rely on the exit status of the `make tests' command. It even tells you as much at the beginning of the run: "Any output from any test, unless otherwise noted, indicates a possible anomaly".

patch -p1 -i ${TT_PFX}/src/patches/bash-3.2-official-039-combined-1.patch
echo '#define NON_INTERACTIVE_LOGIN_SHELLS' >> config-top.h
./configure \
	--without-bash-malloc \
	--with-installed-readline \
	ac_cv_func_working_mktime=yes
make

sed -i '/THIS/s,1$,1 </dev/tty,' tests/run-test

if [ `id -u` -eq 0 ]; then
	chown -R dummy .
	su dummy -c "make tests"
else
	make tests
fi
make DESTDIR=$PM_DEST install
mkdir -pv $PM_DEST/bin
mv -v $PM_DEST/usr/bin/bash $PM_DEST/bin

Rationale Notes

  • The sed to `tests/run-test' implements redirection of the input device to ensure this test passes when running su'd to non-root. More information in this mailing list post.

  • The Bash testsuite will issue warnings if you run it as root. We therefore take steps to run it as the dummy user.

  • The configure switch `--without-bash-malloc' causes Bash to use the system supplied malloc from Glibc rather than Bash's own malloc. Please read this mailing list post for some rationale discussion.

  • Please skip back to Section 4.23, “Gawk-3.1.6” for some rationale discussion about the `ac_cv_func_working_mktime=yes' tweak.

4.46. Bzip2-1.0.5

sed -i.bak \
	-e 's,X)/man,X)/share/man,g' \
	-e '/ln .*PREFIX/s,$(PREFIX)/bin/,,' \
	Makefile

[ "$BIARCH" = YES ] &&
	sed -i.bak 's,/lib\( \|$\|/\),/lib64\1,g' Makefile

make -f Makefile-libbz2_so
make clean
make
make PREFIX=$PM_DEST/usr install
mkdir -pv $PM_DEST/{bin,lib$DIR_64}
cp -v bzip2-shared $PM_DEST/bin/bzip2
cp -av libbz2.so* $PM_DEST/lib$DIR_64
ln -sfv ../../lib$DIR_64/libbz2.so.1.0 $PM_DEST/usr/lib$DIR_64/libbz2.so
rm -fv $PM_DEST/usr/bin/{bunzip2,bzcat,bzip2}
ln -sfv bzip2 $PM_DEST/bin/bunzip2
ln -sfv bzip2 $PM_DEST/bin/bzcat

Rationale Notes

  • The sed serves to (a) ensure man pages are installed into proper FHS compliant location and (b) fix a minor Makefile bug affecting "staged" installations. More information here.

4.47. Diffutils-2.8.1

./configure
make
make DESTDIR=$PM_DEST install

4.48. Ed-1.2

./configure \
	--prefix=/usr \
	--bindir=/bin
make
make check
make DESTDIR=$PM_DEST install

4.49. Kbd-1.14.1

sed -i.bak \
	's/ifdef OPTIONAL_PROGS/ifeq ($(OPTIONAL_PROGS),yes)/' \
	man/Makefile.in

sed -i.bak \
	's,@datadir@,&/kbd,' \
	{src,data}/Makefile.in

./configure \
	--enable-nls
make KEYCODES_PROGS=yes RESIZECONS_PROGS=yes
make KEYCODES_PROGS=yes RESIZECONS_PROGS=yes DESTDIR=$PM_DEST install

Rationale Notes

4.50. Man-1.6f

sed -i.bak 's/-is/&R/' configure
sed -i.bak 's%MANPATH./usr/man%#&%' src/man.conf.in
./configure \
	-default \
	-confdir=/etc
make
make DESTDIR=$PM_DEST install

4.51. Make-3.81

./configure
make
make check
make DESTDIR=$PM_DEST install

4.52. Module-Init-Tools-3.4.1

./configure
make check DOCBOOKTOMAN=:
make maintainer-clean
patch -p1 -i $TT_PFX/src/patches/module-init-tools-3.4-manpages-1.patch

./configure --exec-prefix=/ --enable-zlib
make
make INSTALL=install DESTDIR=$PM_DEST install

Rationale Notes

  • Testing kernel module handling in a live kernel cannot be done easily for obvious reasons. Therefore the Module-Init-Tools developers have devised a custom testsuite procedure that involves separately compiling the package with a set of stubs (see testing.h). The net result of this means we must first run the testsuite, perform a `make distclean' then compile the package for real.

  • Please read the mailing list thread starting with this post for some rationale behind the above build commands.

4.53. Patch-2.5.4

./configure
make
make prefix=$PM_DEST/usr install

4.54. Psmisc-22.6

./configure
make
make DESTDIR=$PM_DEST install
mkdir -pv $PM_DEST/bin
mv -v $PM_DEST/usr/bin/{fuser,killall} $PM_DEST/bin

4.55. Shadow-4.1.2.2

[[ $GLIBC_VER == 2.3* ]] &&
	sed -i.bak '1i #include <sys/types.h>' lib/{pw,group}io.h

./configure \
	--sysconfdir=/etc
make

find man -name Makefile | \
	xargs sed -i.bak \
		-e 's/groups\.1 //' \
		-e 's/su\.1\( \|$\)//' \
		-e 's/suauth\.5 //'
make DESTDIR=$PM_DEST bin_PROGRAMS=login suidbins= install
sed -i \
	-e 's%/var/spool/mail%/var/mail%' \
	-e 's%#MD5_CRYPT_ENAB.no%MD5_CRYPT_ENAB yes%' \
	$PM_DEST/etc/login.defs
sed -i \
	-e '/MAIL/s,yes,no,' \
	$PM_DEST/etc/default/useradd
mv -v $PM_DEST/usr/bin/passwd $PM_DEST/bin

Rationale Notes

  • The `bin_PROGRAMS=login suidbins=' addition to the `make install' invocation is used to suppress installation of `groups' and `su'. This is because we have opted to use the versions from Coreutils instead. In the case of `su', please read this mailing list post for some rationale discussion. If you would rather use the `su' from Shadow, replace the installation line above with make DESTDIR=$PM_DEST bin_PROGRAMS="login su" install. You would also want to adjust the sed to `man/Makefile' to ensure installation of the su related man pages.

4.56. Sysklogd-1.5

make
mkdir -pv $PM_DEST/{etc,usr/{share/man/man{5,8},sbin}}
make prefix=$PM_DEST install

cat > $PM_DEST/etc/syslog.conf << "EOF"
# Begin /etc/syslog.conf

auth,authpriv.* -/var/log/auth.log
*.*;auth,authpriv.none -/var/log/sys.log
daemon.* -/var/log/daemon.log
kern.* -/var/log/kern.log
mail.* -/var/log/mail.log
user.* -/var/log/user.log
*.emerg *

# End /etc/syslog.conf
EOF

4.57. Sysvinit-2.86

make -C src
mkdir -pv $PM_DEST/{{,s}bin,etc,usr/{{bin,include},share/man/man{1,5,8}}}
make -C src ROOT=$PM_DEST install

cat > $PM_DEST/etc/inittab << "EOF"
# Begin /etc/inittab
id:3:initdefault:

si::sysinit:/etc/rc.d/init.d/rc sysinit

l0:0:wait:/etc/rc.d/init.d/rc 0
l1:S1:wait:/etc/rc.d/init.d/rc 1
l2:2:wait:/etc/rc.d/init.d/rc 2
l3:3:wait:/etc/rc.d/init.d/rc 3
l4:4:wait:/etc/rc.d/init.d/rc 4
l5:5:wait:/etc/rc.d/init.d/rc 5
l6:6:wait:/etc/rc.d/init.d/rc 6

ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -r now

su:S016:once:/sbin/sulogin

1:2345:respawn:/sbin/agetty tty1 9600
2:2345:respawn:/sbin/agetty tty2 9600
3:2345:respawn:/sbin/agetty tty3 9600
4:2345:respawn:/sbin/agetty tty4 9600
5:2345:respawn:/sbin/agetty tty5 9600
6:2345:respawn:/sbin/agetty tty6 9600
# End /etc/inittab
EOF

4.58. Tar-1.22

./configure \
	--bindir=/bin \
	--libexecdir=/usr/sbin
make
make check
make DESTDIR=$PM_DEST install

4.59. Util-Linux-ng-2.14.2

sed -i.bak \
	's@etc/adjtime@var/lib/hwclock/adjtime@' \
	hwclock/hwclock.c

./configure \
	--enable-arch \
	--enable-write \
	--disable-wall
make
make DESTDIR=$PM_DEST install
mkdir -pv $PM_DEST/var/lib/hwclock

Rationale Notes

4.60. Grub-0.97 (x86 and Bi-arch x86_64 Only)

sed -i.bak '/ufs2/d' stage2/size_test
patch -p1 -i $TT_PFX/src/patches/grub-0.97-ext-256byte-inode-1.patch

./configure default_CFLAGS=yes
make
make check
make DESTDIR=$PM_DEST install
mkdir -pv $PM_DEST/boot/grub
cp -v $PM_DEST/usr/lib/grub/*/stage{1,2} $PM_DEST/boot/grub

Rationale Notes

  • The sed to `stage2/size_test' is used to work around an issue with a failing ufs2 test. Just ignoring the failure is unsatisfactory because the `size_test' script bails out on the first failure and therefore doesn't test the remaining file systems (fat, e2fs, minix) 2 of which are clearly important.

  • The "256 byte inode" patch could be considered optional in some circumstances. But it's probably best to apply it. More detailed rationale discussion can be found in this mailing list thread.

  • The Grub build is sensitive to non-standard CFLAGS in the environment. Seeing as we have already set our CFLAGS globally in `config.site', we force Grub to use its own defaults by configuring with `default_CFLAGS=yes'.

4.61. Yaboot-1.3.14 (PPC Only)

sed -i 's@usr/local@usr@' Makefile etc/yaboot.conf man/*
make
make ROOT=$PM_DEST MANDIR=share/man install

4.62. Mac-Fdisk-0.1 (PPC Only)

patch -p1 -i ${TT_PFX}/src/patches/mac-fdisk-0.1.orig-debian-2.patch
make
mkdir -pv $PM_DEST/sbin
make DESTDIR=$PM_DEST install

4.63. Hfsutils-3.2.6 (PPC Only)

./configure
make
mkdir -pv $PM_DEST/usr/{bin,share/man/man1}
make prefix=$PM_DEST/usr install

4.64. Fakeroot-1.11 (Optional)

sed -i.bak 's,${srcdir}/tartest,true,' test/t.tar
./configure \
	${DIR_64+--libdir=/usr/lib64}
make
make check
make DESTDIR=$PM_DEST install

4.65. Libtar-1.2.11 (Optional)

[Note]Note -- Optional Package Management with Pacman

As mentioned earlier in the Temptools phase, you only need the next 2 packages (Libtar and Pacman) if you've implemented Pacman based package management.

patch -p1 -i ${TT_PFX}/src/patches/libtar-1.2.11-2.patch
./configure \
	${DIR_64+--libdir=/usr/lib64}
make
make DESTDIR=$PM_DEST install

4.66. Pacman-2.9.8 (Optional)

patch -p1 -i ${TT_PFX}/src/patches/pacman-2.9.8-custom-mods-2.patch
patch -p1 -i ${TT_PFX}/src/patches/pacman-2.9.8-sep_install-1.patch
./configure
make
make DESTDIR=$PM_DEST install

4.67. Ogdlutils-20041124 (Optional)

[Note]Note -- Optional Package Management with BPM

As mentioned earlier in the Temptools phase, you only need the next 3 packages (Ogdlutils, Cpio and BPM) if you've implemented BPM based package management.

make -C c libogdl gpath -j1
mkdir -pv $PM_DEST/usr/bin
cp -v c/gpath $PM_DEST/usr/bin

4.68. Cpio-2.9 (Optional)

./configure \
	--enable-mt \
	--with-rmt=/usr/sbin/rmt
make
make check
make DESTDIR=$PM_DEST rmtdir= install

4.69. BPM-1.7 (Optional)

make DESTDIR=$PM_DEST install

5. Finishing Up

5.1. Making it Functional

FIXME

Mention some brief stuff here about kernel compilation and installation, bootscripts, network setup, system config files, fstab, bootloader, etc, etc, etc. In other words, anything needed to make the built system functional.

Remove the dummy user and groups that were created earlier.

sed -i '/dummy/d' /etc/{group,passwd}

For enhanced security, you probably want to enable shadow passwords and shadow group passwords:

/usr/sbin/pwconv
/usr/sbin/grpconv

5.2. Conclusion

If you found this document useful, I'd appreciate you dropping me a line at . It will help me gauge levels of interest in the project and determine future development direction.

5.3. Acknowledgments

Many folks have helped out with fixes, suggestions, bug reports and testing (too numerous to list here). But some have made outstanding contributions for which I'd like to especially say thanks:

  • Jon Grosshart generously donated a PowerPC based Mac Mini to allow ppc to be added as a supported architecture.

6. Temptools Phase - Original Build Method (Deprecated)

[Warning]Warning -- Original Build Method Now Deprecated

What follows is the original build method which is now deprecated. It no longer receives any testing from the author and it only receives mechanical updates which renders it essentially unmaintained. In particular, the original method will not be updated for GCC 4.3. Please note that it will be removed entirely in due course. The Next Generation build method is now the preferred option.

6.1. Bash-3.2 Pass 1

[Important]Important

This first pass of Bash is the only package we install "by hand". Everything else after this point is expected to be automated via a build script. However, you can still drive the build manually by typing in all the commands on the interactive shell command line if you prefer. Note: Do not skip Bash Pass 1. It used to be optional but is now a requirement of the build method due to our use of CONFIG_SHELL (see below).

patch -p1 -i ${TT_PFX}/src/patches/bash-3.2-official-039-combined-1.patch &&
sh -c "unset CONFIG_SHELL; ./configure" &&
make &&
install -dv ${TT_PFX}/bin &&
cp -v bash ${TT_PFX}/bin/bash-pass1 &&
ln -sv bash-pass1 ${TT_PFX}/bin/bash &&
ln -sv bash ${TT_PFX}/bin/sh

Rationale Notes

  • Installing Bash as the very first package allows us to specify the "configure shell" to be used by all Autoconf-produced configure scripts during the Temptools phase. This is achieved via the CONFIG_SHELL environment variable mentioned earlier. It serves to enhance the robustness of the build method by reducing reliance on the host's /bin/sh thus avoiding potential breakage when bootstrapping from older distros.

  • Another reason for installing Bash first up is that we can write our build script using all the features of modern Bash without having to worry about which shell is installed as /bin/sh on the host. Simply launch your build script like this: `bash-pass1 myscript.sh'.

    [Tip]Tip

    There is additional benefit to using this technique in that it allows greater flexibility for handling the transition between the Temptools and Chroot phases. For example, you can set the interpreter path in your build script to `#!/temptools/bin/bash' which allows easy re-execution of the same script upon entering the chroot environment without having to fuss over having a `$SYSROOT/bin/sh' symlink already set up. Please refer to the author's own gsbuild scripts for a sample implementation. Naturally, this point is moot if you script in pure Bourne or handle the Temptools/Chroot phases transition using a different method.

  • For our purposes of bootstrapping a new Linux system within the Reference Build context, Bash should build fine on any sane distro made within the last 5 years.

  • The "unset CONFIG_SHELL" in the configure invocation is needed for configure to succeed because the shell pointed to by CONFIG_SHELL doesn't exist yet i.e. we are installing it here.

  • Note: some older hosts have `libtermcap' installed and Bash will prefer it over Ncurses if found by configure unless `--with-curses' is given. Bash also comes with its own Termcap. Rather than tinker with configure switches, it's actually more robust to just let configure work it out for itself. This Pass 1 of Bash is simply for running scripts during the Temptools phase so it shouldn't really matter which Termcap is used.

  • Double ampersands are used here because we're still operating in an interactive shell session at this point. We recommend that you employ a proper error trapping strategy in your build script (eg: set -e). Therefore, double ampersands are not provided in the build commands from this point onwards.

6.2. Make-3.81 Pass 1

./configure
make
cp -v make ${TT_PFX}/bin
ln -sv make ${TT_PFX}/bin/gmake

Rationale Notes

  • for bootstrapping purposes, Make should build fine on any sane distro made from 1999 onwards.

  • the Glibc build needs a version of `make' 3.79 or newer which older distros don't have. We remove all doubts by installing the current version. Why install it now rather than just prior to the Glibc build? Well, it makes sense to integrate it from the outset so that we can start using it immediately.

  • the `gmake' symlink is needed for robustness. `gmake' already exists on some hosts which will prevent Glibc's configure script from finding the `make' we install here.

6.3. Sed-4.1.5 Pass 1

./configure \
	ac_cv_header_stdbool_h=yes
make
cp -v sed/sed ${TT_PFX}/bin

Rationale Notes

  • for bootstrapping purposes, Sed should build fine on any sane distro made from 1999 onwards.

  • The ac_cv_header_stdbool_h=yes tweak is needed when building on older hosts. Please read this bug report for details. Note that on newer hosts the variable is set automatically by configure thus making the tweak unnecessary, but it's perfectly fine to leave it there in all circumstances.

  • Why do we install a Pass 1 of Sed here? There have been reported problems where the Glibc build chokes with older Sed versions. The author hasn't personally seen any such problem but feels it's safer to just install a current Sed from the outset. An added bonus is that we can rely on using `sed -i' during the entire Temptools phase thus simplifying scripting.

6.4. Binutils Pass 1 (2.16.1 through 2.18)

mkdir ../binutils-build
cd ../binutils-build

../binutils-${BINUTILS_VER}/configure \
	--disable-werror
echo "MAKEINFO = :" >> Makefile
make LDFLAGS=${LDFLAGS}

[ "$DIY_ARCH" = x86_64 ] && {
	mkdir -pv $TT_PFX/lib; ln -sv lib $TT_PFX/lib64; }

make install

export CC="gcc -B/usr/bin/"
if echo | $CC -E -o /dev/null - 2>&1 | grep never > /dev/null; then
	CC=gcc
fi

make -C ld clean
make -C ld \
	CC="${CC}" \
	LDFLAGS=${LDFLAGS} \
	LIB_PATH=${TT_PFX}/lib
unset CC
cp -v ld/ld-new ${TT_PFX}/bin

Rationale Notes

  • The `echo "MAKEINFO = :" >> Makefile' tweak is used to remove dependence on `makeinfo' and therefore eliminate all associated problems. Please read the mailing list thread starting with this post for details.

  • We create a lib64 -> lib symlink in the x86_64 case because we are not building a multi-arch toolchain. Even in single-arch mode 64-bit architectures tend to hardwire references to "lib64" in many places throughout the toolchain. It's possible to force everything to "lib" but we'd rather keep all the build commands compatible with other architectures. The symlink keeps things sane and everything Just Works™.

  • After the first Binutils are installed, -B/usr/bin/ is temporarily added to the CC definition in order to force the host GCC to use the host Binutils. Without this override, the host GCC will find the newly installed Binutils in the PATH thus causing a toolchain mismatch and potential breakage. This breakage is likely to strike when using a bleeding edge distro as a host (eg: Fedora) and you're building a toolchain comprised of older versions of toolchain components than those on the host. The "if..echo..grep" statement is required on those hosts with GCC-2.95.x or earlier installed. More background on all of this can be found in the mailing list thread starting with this post (continued here).

  • Note: Unlike LFS, we don't statically link the Pass 1 of Binutils because it's simply unnecessary, and in actual fact is a potential source of failure. We therefore link dynamically for robustness reasons. If you still think static linking is a good idea then at least take note of the Glibc maintainer's views on the subject.

  • Because we're linking dynamically, there's no need to specify `make configure-host' after the initial configure. However, when building on SMP the top level Makefile will run the sub-configure scripts for Libiberty and Binutils simultaneously. This is great for speed and efficiency, but unfortunate for the build log which ends up all jumbled. If you'd like the build log to remain neat and tidy (eg: for diffing purposes), run the sub-configure scripts in serial by executing make configure-host -j1 after the initial configure.

6.5. GCC Pass 1 (3.4.6 through 4.2.4)

sed -i.bak \
	-e '/^LIBGCC2_DEBUG/d' \
	-e '/^STAGE1_CHECK/d' \
	gcc/Makefile.in

BOOT_CFLAGS="-O2 -pipe"
[[ $GCC_VER == 4.* && $DIY_ARCH == i386 ]] &&
	BOOT_CFLAGS="$BOOT_CFLAGS -fomit-frame-pointer"

mkdir ../gcc-build
cd ../gcc-build

export CC="gcc -B/usr/bin/"
if echo | $CC -E -o /dev/null - 2>&1 | grep never > /dev/null; then
	CC=gcc
fi

../gcc-${GCC_VER}/configure \
	--with-local-prefix=${TT_PFX} \
	--disable-shared \
	--disable-libmudflap \
	--disable-libssp \
	--disable-libgomp \
	--disable-multilib \
	--disable-checking \
	--disable-stage1-checking \
	--enable-languages=c \
	--with-ld=${TT_PFX}/bin/ld \
	--with-as=${TT_PFX}/bin/as
unset CC

make \
	BOOT_LDFLAGS=${LDFLAGS} \
	BOOT_CFLAGS="${BOOT_CFLAGS}" \
	STAGE1_CFLAGS="-pipe" \
	LDFLAGS=${LDFLAGS} \
	bootstrap

make install -j1

ln -sv libgcc.a `gcc -print-libgcc-file-name | \
	sed 's/libgcc/&_eh/'`
ln -sv gcc ${TT_PFX}/bin/cc

Rationale Notes

  • We apply a sed to remove STAGE1_CHECKING from the GCC Makefile and also pass `--disable-checking' to configure in order to considerably reduce bootstrap time. Please read this mailing list post for some rationale discussion. Note: 4.2.X introduced `--disable-stage1-checking' which achieves the same effect as the sed. The switch is compatible within supported GCC versions ie: earlier versions simply ignore this switch. The sed doesn't work on 4.2.X but is harmless nevertheless. More info in this mailing list post.

  • Just as in Binutils Pass 1, we again need the CC="gcc -B/usr/bin/" tweak for the same reasons mentioned there. Our new GCC will start combining with our new Binutils in stage 2 of the 3 stage GCC bootstrap procedure.

  • No static linking here for the same reasons as mentioned above in Binutils Pass 1. Additionally, the note about `make configure-host' from there also applies here (Binutils and GCC share the same top level build machinery).

  • When building with GCC-4.x the Makefile variable BOOT_CFLAGS contains `-O2 -g -fomit-frame-pointer' by default. Because we are passing BOOT_CFLAGS to `make' by hand (basically to avoid building with debugging information) we must add `-fomit-frame-pointer' to BOOT_CFLAGS to ensure the compiler is built as intended by the GCC developers. Please read this mailing list post for some background discussion.

  • The switches `--disable-libmudflap', `--disable-libssp' and `--disable-libgomp' first appeared in GCC-4.0, GCC-4.1 and GCC-4.2 respectively. They are used here to streamline our initial "bootstrap" GCC. The switches are all compatible within supported GCC versions ie: earlier versions simply ignore the later switches.

  • We pass `--disable-multilib' here (and in subsequent GCC builds) because it's required to achieve a pure 64-bit build on x86_64. It also speeds up the PowerPC build by omitting the "nof" directory (ie: applicable to -msoft-float). The switch has no effect on x86 and is therefore compatible.

  • Note: Starting with GCC-4.2, the top-level bootstrap mechanism became the default. This means a plain "make" will now default to performing a 3 stage bootstrap unless `--disable-bootstrap' is given. The pre-GCC-4.2 method of "make bootstrap" behaves identically. Therefore, we can maintain compatibility with earlier versions by continuing to use "make bootstrap".

  • The libgcc_eh.a symlink is needed to satisfy the upcoming Glibc build. Please read this mailing list post for some rationale discussion.

6.6. Linux-Kernel-Headers-2.6.27

[Warning]Warning

The 2.6.18 kernel introduced the next generation method of obtaining sanitized kernel headers. For some background on the issue please see this mailing list post. When using the new technique you MUST SKIP the Linux-Libc-Headers step which follows next. In other words, choose one or the other, not both. Only use the old method when building a toolchain comprised of older components (see table of toolchain combinations listed earlier).

make mrproper
make headers_install INSTALL_HDR_PATH=temp
cp -rv temp/include $TT_PFX

6.7. Linux-Libc-Headers-2.6.12.0 (Older toolchains only)

patch -p1 -i ${TT_PFX}/src/patches/linux-libc-headers-2.6.12.0-syscalls-3.patch
cp -Rv include/asm-${DIY_ARCH} ${TT_PFX}/include/asm
cp -Rv include/linux ${TT_PFX}/include

6.8. Glibc (2.3.6 through 2.7)

[Caution]Proceed with Caution!

Glibc is possibly the most critical piece of software you will compile in a base Reference Build. There is a high probability of something going wrong. Be sure to heed the advice contained in Section B, “Glibc General Advice” before taking on this monster. Note: the Glibc compiled here in the Temptools phase is merely a "throw away bootstrap" Glibc, but please do read the aforementioned advice anyway.

[[ $GLIBC_VER > 2.5.9 && $DIY_ARCH == i386 ]] &&
	MARCH="-march=i486"

mkdir ../glibc-build
cd ../glibc-build

CFLAGS="-O2 $MARCH -pipe" \
../glibc-${GLIBC_VER}/configure \
	--disable-profile \
	--enable-add-ons \
	--with-binutils=${TT_PFX}/bin \
	--with-headers=${TT_PFX}/include \
	--without-selinux

echo "AUTOCONF=no
MAKEINFO=:" > configparms

make
make install -j1

Rationale Notes

  • We need to fiddle with `-march=' in CFLAGS because as of Glibc-2.6, i486 is the minimum supported configuration on x86. More information here.

  • `--without-selinux' is a workaround needed on Fedora Core 3 hosts (those with the "libselinux-devel" package installed) to prevent build failure caused by a subtle Makefile bug. Upstream have been notified of the issue.

  • `AUTOCONF=no' is used here for robustness. It simply prevents unnecessary Autoconf invocations when the Makefiles detect a `configure' file older than its respective `configure.in'. This is usually the case when working with CVS snapshots, but it also applies to release tarballs prior to glibc-2.3.5 when the issue was finally addressed. These unnecessary Autoconf invocations have been known to cause build failures on Debian hosts. An alternative approach is to run `find . -name configure | xargs touch' in the src dir before running `configure'. Note: `--without-cvs' does not address the issue.

  • `MAKEINFO=:' is used to prevent installation failures when the host has an older `makeinfo'. Problems were first noticed with Glibc-2.7.

6.9. Adjust Toolchain

cp -pv ${TT_PFX}/bin/ld-new ${TT_PFX}/bin/ld
cp -pv ${TT_PFX}/bin/ld-new ${TT_PFX}/`gcc -dumpmachine`/bin/ld

case "$DIY_ARCH" in
  i386)   DL=/lib/ld-linux.so.2 ;;
  ppc)	  DL=/lib/ld.so.1 ;;
  x86_64) DL=/lib64/ld-linux-x86-64.so.2 ;;
esac

gcc -dumpspecs | sed \
	"s,${DL},${TT_PFX}&," > \
	`gcc -print-search-dirs | head -n 1 | awk '{ print $2 }'`specs

[ "$DIY_ARCH" = x86_64 ] &&
	sed -i.bak '/^\*multilib:$/{n;s/.*/. ;/}' `gcc -print-file-name=specs`

I=`gcc -print-file-name=include`
rm -rfv ${I}/*
J=`gcc -print-file-name=install-tools`
cp -pv ${J}/include/* ${I}
cp -pv ${J}/gsyslimits.h ${I}/syslimits.h

echo 'main(){}' | cc -x c -
readelf -l a.out | grep ": ${TT_PFX}"
rm -fv a.out

Rationale Notes

  • For x86_64 we need to empty the "multilib" spec to prevent GCC from searching for libs on the host. The sed simply modifies the spec to mirror how it would appear in a single-arch scenario. More information in this mailing list post.

6.10. GCC Pass 2 (3.4.6 through 4.2.4)

case "$DIY_ARCH" in
  i386)   DL=/lib/ld-linux.so.2;	  DL_HEADER=i386/linux.h ;;
  ppc)	  DL=/lib/ld.so.1;		  DL_HEADER=rs6000/sysv4.h ;;
  x86_64) DL=/lib64/ld-linux-x86-64.so.2; DL_HEADER=i386/linux64.h
	  sed -i.bak '/MULTILIB_OSDIRNAMES/d' gcc/config/i386/t-linux64 ;;
esac

[[ $BINUTILS_VER == 2.18* && $GCC_VER > 4.1.9 && $GLIBC_VER > 2.5.9 ]] &&
	patch -p1 -i ${TT_PFX}/src/patches/gcc-4.2-branch-hash-style-gnu-1.patch

sed -i.bak \
	"s@${DL}@${TT_PFX}&@" gcc/config/${DL_HEADER}

echo "
/* Remove /usr/include from end of include search path.  */
#undef STANDARD_INCLUDE_DIR
#define STANDARD_INCLUDE_DIR 0" >> gcc/config/${DL_HEADER}

sed -i.bak \
	-e 's,\./fixinc\.sh,-c true,' \
	-e '/^LIBGCC2_DEBUG/d' gcc/Makefile.in

[[ $GCC_VER == 4.* && $DIY_ARCH == i386 ]] &&
	sed -i.bak2 's/^XCFLAGS =$/& -fomit-frame-pointer/' gcc/Makefile.in

mkdir ../gcc-build
cd ../gcc-build

../gcc-${GCC_VER}/configure \
	--with-local-prefix=${TT_PFX} \
	--enable-shared \
	--disable-multilib \
	--disable-bootstrap \
	--enable-languages=c,c++ \
	--enable-clocale=gnu \
	--enable-threads=posix \
	--enable-__cxa_atexit \
	--disable-libstdcxx-pch

make LDFLAGS=${LDFLAGS}

make install -j1

Rationale Notes

  • On x86_64 we sed out the MULTILIB_OSDIRNAMES reference which has the same effect as emptying the "multilib" spec. This is done for the same reason mentioned earlier i.e. prevent GCC from searching for libs on the host. More information in this mailing list post.

  • As mentioned earlier, we need to pass `--disable-bootstrap' here to prevent GCC-4.2 and above from performing a 3 stage bootstrap. The switch is ignored by earlier versions and is therefore compatible.

  • The notes about `make configure-host' from Binutils Pass 1 and GCC Pass 1 also apply here. However, it gets a little more complicated because we're also building Libstdc++. To achieve the same outcome (ie: run sub-configures in serial for neat build logs under SMP), the sequence needs to be like this:

    make configure-host -j1
    make all-host
    make configure-target -j1
    make all-target
  • When building with GCC-4.x we use a sed to add `-fomit-frame-pointer' to the GCC Makefile to address a correctness issue. Please read this mailing list post for some rationale discussion.

6.11. Binutils Pass 2 (2.16.1 through 2.18)

mkdir ../binutils-build
cd ../binutils-build

../binutils-${BINUTILS_VER}/configure \
	--with-lib-path=${TT_PFX}/lib
echo "MAKEINFO = :" >> Makefile
make LDFLAGS=${LDFLAGS}
make install

make -C ld clean
make -C ld \
	LDFLAGS=${LDFLAGS} \
	LIB_PATH=/lib:/usr/lib
cp -v ld/ld-new ${TT_PFX}/bin

6.12. Gawk-3.1.6

./configure
make
cp -v gawk ${TT_PFX}/bin
ln -sv gawk ${TT_PFX}/bin/awk

6.13. Coreutils-6.12

patch -p1 -i $TT_PFX/src/patches/coreutils-6.12-utimensat-1.patch
./configure \
	--enable-install-program=hostname,su
make
make install
cp -v src/su ${TT_PFX}/bin

Rationale Notes

  • For some background on the `--enable-install-program=hostname,su' configure switch, please read this mailing list post.

  • Because we are operating as a non-privileged user, Coreutils will suppress installation of the `su' program. This is signified by a message shown during `make install': "WARNING: insufficient access; not installing su NOTE: to install su, run 'make install-root' as root". The reason for this is `su' needs to be installed setuid root in order to be fully functional. We manually install it here because even without the setuid bit, we can still use it when inside the Chroot environment to (a) run various testsuites as a non-privileged user and (b) employ Package Management techniques that require building sources as a non-privileged user.

[Important]Important

From this point onwards if you need to become root you must call the host's `su' explicitly by running /bin/su. Just running su will call the first `su' in the $PATH which is the one we just installed (it will fail because of the missing setuid bit). This is especially important when we go to enter the Chroot environment at the beginning of the next phase.

6.14. Bzip2-1.0.5

make PREFIX=${TT_PFX} LDFLAGS=${LDFLAGS} install

6.15. Gzip-1.3.12

[[ $GLIBC_VER > 2.5.9 ]] &&
	sed -i.bak 's/futimens/gl_&/' gzip.c lib/utimens.{c,h}

./configure
make
cp -v gunzip gzip ${TT_PFX}/bin

6.16. Diffutils-2.8.1

./configure
make
cp -v src/{cmp,diff} ${TT_PFX}/bin

6.17. Findutils-4.4.0

./configure
make
cp -v find/find xargs/xargs ${TT_PFX}/bin

6.18. Make-3.81 Pass 2

./configure
make
cp -v make ${TT_PFX}/bin

6.19. Grep-2.5.4

./configure \
	--without-included-regex \
	--disable-perl-regexp
make
cp -v src/{,e,f}grep ${TT_PFX}/bin

Rationale Notes

  • The `MISSING=true' tweak is needed to work around a bug in the current release whereby the build will fail if `makeinfo' is unavailable. See here and here for examples.

6.20. Sed-4.1.5 Pass 2

./configure
make
cp -v sed/sed ${TT_PFX}/bin

6.21. Gettext-0.17

cd gettext-tools
./configure \
	--disable-shared
make -C gnulib-lib
make -C src msgfmt
cp -v src/msgfmt ${TT_PFX}/bin

6.22. Ncurses-5.7

./configure \
	--without-debug \
	--without-ada \
	--enable-overwrite
make
make install

6.23. Patch-2.5.4

./configure
make
cp -v patch ${TT_PFX}/bin

6.24. Tar-1.22

./configure
make
cp -v src/tar ${TT_PFX}/bin

6.25. Texinfo-4.13a

./configure
make
make install

6.26. Bash-3.2 Pass 2

patch -p1 -i ${TT_PFX}/src/patches/bash-3.2-official-039-combined-1.patch
./configure \
	--without-bash-malloc
make
install -v bash ${TT_PFX}/bin

Rationale Notes

6.27. M4-1.4.13

[Tip]Tip

It's worth noting the next 3 packages (M4, Bison and Flex) are not strictly necessary in the Temptools phase when using an official FSF Binutils release. However, they are mandatory if using a release from HJL. The reason is that FSF releases are made with a "make dist" style procedure whereby the generated files (from Bison and Flex) are already included in the tarball thus removing the requirement for Bison and Flex at Binutils build time (in the Chroot phase). Our recommendation is to always build M4, Bison and Flex here to ensure the build recipe remains compatible with both FSF and HJL Binutils releases. There is another issue: if you skip M4, Bison and Flex here it's likely you'll run into ICA trouble which will require an additional hack when building Bison in the Chroot phase.

./configure
make V=1
cp -v src/m4 ${TT_PFX}/bin

6.28. Bison-2.4.1

./configure
make
make install

6.29. Flex-2.5.35

./configure
make
cp -v flex ${TT_PFX}/bin

6.30. E2fsprogs-1.41.4

mkdir build
cd build
../configure
make libs -j1
make install-libs

Rationale Notes

  • We install the E2fsprogs libraries here to satisfy the build of `mount' from Util-Linux-ng in the next step. If you choose not to build `mount' then these libraries are naturally not required.

6.31. Util-Linux-ng-2.14.2

./configure
make -C mount
make -C getopt
cp -v mount/{,u}mount getopt/getopt ${TT_PFX}/bin

Rationale Notes

  • We install `mount' here so we can mount the virtual file systems from within the chroot environment. Please read this mailing list post for some rationale discussion.

  • We install `getopt' here because it's needed by the optional Fakeroot package (see below). If you're not installing Fakeroot then you don't need to install `getopt' here.

6.32. Perl-5.10.0

chmod -v u+w hints/linux.sh

cat >> hints/linux.sh << "EOF"
libc=${prefix}/lib/`ls -l ${prefix}/lib/libc.so.6 | awk '{print $NF}'`
locincpth=""
loclibpth=""
usrinc="${prefix}/include"
glibpth="${prefix}/lib"
EOF

./configure.gnu \
	--prefix=${TT_PFX} \
	-Dstatic_ext='IO Fcntl Data/Dumper POSIX'

make perl utilities ext/Errno/pm_to_blib
cp -v perl pod/pod2man ${TT_PFX}/bin
mkdir -pv ${TT_PFX}/lib/perl5/5.10.0
cp -Rv lib/* ${TT_PFX}/lib/perl5/5.10.0

Rationale Notes

  • For some background on the commands containing "static_ext" and "ext/Errno/pm_to_blib" please read the mailing list thread starting with this post.

6.33. Tcl-8.4.19

cd unix
./configure
make
make install
make install-private-headers
ln -sv tclsh8.4 ${TT_PFX}/bin/tclsh

6.34. Expect-5.43.0

patch -p1 -i ${TT_PFX}/src/patches/expect-5.43-spawn-1.patch
sed -i.bak '/echo.*STTY_BIN/i STTY_BIN=stty' configure
./configure \
	--with-tcl=${TT_PFX}/lib \
	--with-tclinclude=${TT_PFX}/include \
	--with-x=no
make
make SCRIPTS="" install -j1

Rationale Notes

  • The sed to `configure' forces Expect to call a plain `stty' instead of `/bin/stty' or even worse, `/usr/local/bin/stty'. In this way the first `stty' in the PATH will always be used. It also avoids the need to create a `/bin/stty' symlink in Section 7.5, “Create Symlinks”.

6.35. DejaGnu-1.4.4

./configure
make install -j1

6.36. Fakeroot-1.11 (Optional)

./configure
make
sed -i.bak \
	's,^PATHS=,&/lib:/usr/lib:,' \
	scripts/fakeroot
make install

Rationale Notes

  • As mentioned in the Introduction, if you're employing Package Management by building and creating archives as a non-privileged user, files in the resultant archives can sometimes end up with wrong file ownerships and permissions. Fakeroot can provide a solution to this problem. It acts as a wrapper around various library functions and a typical invocation is like this: fakeroot commands-you-want-run-under-a-fake-root-environment. Generally, you only want to be performing the commands associated with installation under Fakeroot. Running commands associated with configuring and building usually work, but the Fakeroot documentation recommends against it. Never run the testsuites for Glibc, Coreutils and Perl under Fakeroot because you will experience failures. The Bash testsuite can also be problematic. Consider this package optional if you're a) not employing Package Management b) building as root or c) using a Package Manager that doesn't require assistance from Fakeroot.

  • The sed is needed to force Fakeroot to load the correct Glibc when inside the Chroot environment. Without it, Fakeroot will load the Temptools Glibc.

  • Another package with similar functionality but having a slightly different feature set is Pretendroot. Details on this package can be found here. Note: we haven't tested Pretendroot in the context of a Reference Build so your mileage may vary.

6.37. Zlib-1.2.3 (Optional)

[Note]Note -- Optional Package Management with Pacman

Only install the next 3 packages (Zlib, Libtar and Pacman) if you intend implementing Pacman based package management. Pacman is a simple tar.gz-based package manager for Linux originally written for the Arch Linux distro. Please refer to the gsbuild scripts for a sample Pacman implementation. It's worth noting the author personally uses Pacman which means it receives regular testing within the Reference Build context.

./configure --prefix=${TT_PFX}
make
make install

6.38. Libtar-1.2.11 (Optional)

patch -p1 -i ${TT_PFX}/src/patches/libtar-1.2.11-2.patch
./configure
make
make install

6.39. Pacman-2.9.8 (Optional)

patch -p1 -i ${TT_PFX}/src/patches/pacman-2.9.8-custom-mods-2.patch
patch -p1 -i ${TT_PFX}/src/patches/pacman-2.9.6-temptools-1.patch
patch -p1 -i ${TT_PFX}/src/patches/pacman-2.9.8-sep_install-1.patch
./configure
make
cp -v pacman scripts/makepkg ${TT_PFX}/bin
cp -v etc/{makepkg,pacman}.conf ${TT_PFX}/etc

6.40. Ogdlutils-20041124 (Optional)

[Note]Note -- Optional Package Management with BPM

Only install the next 3 packages (Ogdlutils, Cpio and BPM) if you intend implementing BPM based package management. BPM is an extremely compact package manager with the simplest spec file format imaginable. It comes from the Bent Linux distro. Please refer to the gsbuild scripts for a sample BPM implementation. BPM only receives occasional testing within the Reference Build context and is included here mainly as a proof of concept. (Note: the gsbuild BPM implementation currently gets some file permissions wrong - FIXME).

make -C c libogdl gpath -j1
cp -v c/gpath ${TT_PFX}/bin

6.41. Cpio-2.9 (Optional)

./configure
make
cp -v src/cpio ${TT_PFX}/bin

6.42. BPM-1.7 (Optional)

cp -v bpm{build,install,pkgfix} ${TT_PFX}/bin

6.43. Remove Cruft

rm -rfv ${TT_PFX}/{,share/}{info,man}

7. Chroot Phase - Original Build Method (Deprecated)

[Warning]Warning -- Original Build Method Now Deprecated

What follows is the original build method which is now deprecated. It no longer receives any testing from the author and it only receives mechanical updates which renders it essentially unmaintained. In particular, the original method will not be updated for GCC 4.3. Please note that it will be removed entirely in due course. The Next Generation build method is now the preferred option.

7.1. About $PM_DEST

As mentioned in the Introduction, Package Management (PM) is a goal of the Reference Build. Accordingly, all build commands in this Chroot phase strive to be "PM friendly". This is reflected in those individual commands associated with file installation. Commands associated with configuring and building remain exactly the same as when performing a "build in place" style installation.

You'll notice that a typical invocation of make install has now become make DESTDIR=$PM_DEST install. The expectation is this: if you're employing PM then you'll assign a value to the PM_DEST variable in your scripting environment that is equivalent to wherever your chosen Package Manager expects to find the installed files. Doing it this way ensures the installation commands remain generic. If you're not employing PM, that is you're performing a usual "build in place" style installation, you just have to ensure that the PM_DEST variable is nonexistent (or empty or unset), then the installation commands will work exactly as if `DESTDIR=$PM_DEST' weren't specified.

7.2. Enter Chroot Environment

[Important]Important

Earlier in the Temptools phase we installed a somewhat crippled `su' program from Coreutils (with a missing setuid bit). Therefore, in order to become root and enter the Chroot environment, you must call the host's `su' explicitly by running /bin/su or else you'll fail to gain root privilege.

Before entering the chroot environment, be sure to become root using plain `/bin/su'. DO NOT use `/bin/su -' (ie: with the hyphen) because you'll lose the environment variables that are critical for the following chroot command to work as intended. When including this chroot command in your script you'll need to make 2 adjustments: (a) you should omit the $PS1 variable because it is normally unset in non-interactive shells and (b) you'll want to execute a script instead of ${TT_PFX}/bin/bash --login +h (make sure your script does a set +h to switch off hashing).

${TT_PFX}/bin/chroot $SYSROOT \
	${TT_PFX}/bin/env -i \
	HOME=/root \
	PATH=/bin:/usr/bin:/sbin:/usr/sbin:${TT_PFX}/bin \
	PS1='\u-in-chroot:\w\$ ' \
	TERM=${TERM} \
	CONFIG_SITE=/etc/config.site \
	DIY_ARCH=${DIY_ARCH} \
	LC_ALL=C \
	LDFLAGS=${LDFLAGS} \
	${MAKEFLAGS+"MAKEFLAGS=$MAKEFLAGS"} \
	TT_PFX=${TT_PFX} \
	TZ=${TZ} \
	BINUTILS_VER=${BINUTILS_VER} \
	GCC_VER=${GCC_VER} \
	GLIBC_VER=${GLIBC_VER} \
	${TT_PFX}/bin/bash --login +h

7.3. Create Directories

mkdir -pv /{bin,etc,home,lib,proc,sys} \
	/dev/{pts,shm} \
	/usr/{bin,include,lib/locale,share/{man,doc,info}} \
	/var/{lock,log,mail,run}
#ln -sv share/{man,doc,info} /usr
install -dvm 0750 /root
install -dvm 1777 {,/var}/tmp

if [ "$DIY_ARCH" = x86_64 ]; then
	ln -sv lib /lib64
	ln -sv lib /usr/lib64
fi

Rationale Notes

  • There really shouldn't be any need to create a whole directory layout from the outset. Just create the bare minimum to get the build going then let the packages themselves create the rest. If you want a full FHS/LSB compliant layout then just add the missing bits after the build. Consider this experimental. FIXME

  • Current LFS inefficiently uses a raft of `install -d' commands for directory creation here. There is no need for this when `mkdir' is perfectly suited to the task. Only when custom permissions are required do we use `install -d'.

  • The command to create compatibility symlinks in /usr is commented out above. We force packages to install man and info files into proper FHS compliant locations by globally setting defaults in config.site (see below). Those few packages that don't pick up the defaults are taken care of individually in the build commands. Feel free to uncomment the above line if you still prefer to keep the compatibility symlinks.

7.4. Perform Mounts

test -r /etc/mtab || > /etc/mtab
mount proc /proc -t proc
mount devpts /dev/pts -t devpts
mount shm /dev/shm -t tmpfs
mount sysfs /sys -t sysfs

7.5. Create Symlinks

ln -sv ${TT_PFX}/bin/{bash,cat,echo,pwd} /bin
ln -sv ${TT_PFX}/bin/perl /usr/bin
ln -sv ${TT_PFX}/lib/lib{gcc_s.so.1,stdc++.so.6,fakeroot.so} /usr/lib
ln -sv bash /bin/sh

Rationale Notes

  • The `/bin/echo' symlink is required for the Glibc-2.6 (and above) testsuite to pass. More information here.

  • The `libstdc++.so.6' symlink is needed to satisfy the Glibc-2.4 (and above) testsuite. More information here.

  • The `libfakeroot.so.0' symlink is only needed if you installed the optional Fakeroot package. If you build Glibc under Fakeroot (not recommended) the build will fail in the absence of this symlink. Additionally, when Fakeroot is used to wrap file installation commands only (its preferred mode of operation), the symlink prevents some ugly non-fatal errors during Glibc and GCC installation eg: "ERROR: ld.so: object 'libfakeroot.so.0' from LD_PRELOAD cannot be preloaded: ignored."

7.6. Create Misc. Files

cat > /etc/passwd << "EOF"
root:x:0:0:root:/root:/bin/bash
EOF

cat > /etc/group << "EOF"
root:x:0:
bin:x:1:
sys:x:2:
kmem:x:3:
tty:x:4:
tape:x:5:
daemon:x:6:
floppy:x:7:
disk:x:8:
lp:x:9:
dialout:x:10:
audio:x:11:
utmp:x:12:
EOF

echo "127.0.0.1 localhost $(hostname)" > /etc/hosts

touch /var/run/utmp /var/log/{btmp,lastlog,wtmp}
chmod -v 644 /var/run/utmp /var/log/{btmp,lastlog,wtmp}
chgrp -v utmp /var/run/utmp

cat > $CONFIG_SITE << "EOF"
test "$prefix" = NONE && prefix=/usr
test "$mandir" = '${prefix}/man' && mandir='${prefix}/share/man'
test "$infodir" = '${prefix}/info' && infodir='${prefix}/share/info'
test -z "$CFLAGS" && CFLAGS="-O2 -pipe"
test -z "$CXXFLAGS" && CXXFLAGS=${CFLAGS}
EOF

Rationale Notes

  • A dummy `/etc/hosts' file is created here to satisfy the Perl testsuite later on.

7.7. Create Users

echo "pkgmgr:x:999:" >> /etc/group
echo "pkgmgr2:x:998:pkgmgr" >> /etc/group
echo "pkgmgr:x:999:999::/home/pkgmgr:/bin/bash" >> /etc/passwd
install -dv -o pkgmgr -g pkgmgr /home/pkgmgr

echo "dummy1:x:1000:" >> /etc/group
echo "dummy2:x:1001:dummy" >> /etc/group
echo "dummy:x:1000:1000::/home:/bin/bash" >> /etc/passwd

Rationale Notes

  • If you're employing Package Management, the chances are you'll probably want to build packages as a non-privileged user. Here we setup a user called "pkgmgr" for exactly this purpose. You can use the `su' program (installed earlier) to build packages as the Package Management User (PMU). To build a package as the PMU, something like: su pkgmgr -c "command-to-build-package" should achieve the desired effect. Creating the PMU is of course optional if you'd prefer to build the Chroot phase as root.

  • We also create a dummy user and some dummy groups for the benefit of those testsuites that need to be run as a non-privileged user. These entries should be removed upon completion of the build.

7.8. Makedev-1.7

bzcat ${TT_PFX}/src/tarballs/MAKEDEV-1.7.bz2 > $PM_DEST/dev/MAKEDEV
chmod -v 754 $PM_DEST/dev/MAKEDEV
cd $PM_DEST/dev
./MAKEDEV -v generic-nopty

Rationale Notes

  • We install MAKEDEV here primarily for the purpose of bootstrapping the Reference Build. That is, you don't have to deploy the MAKEDEV script and the "on disk" device special files it created in your final file system image. Some folks prefer to use the (now deprecated) kernel based Devfs facility to manage /dev. However, lately the general trend has moved towards the Udev system which runs entirely in userspace. Other options for populating /dev during the chroot phase of the Reference Build include: (a) performing a `mount --bind' of the host's /dev onto $SYSROOT/dev (b) manually mknod'ing the bare minimum device special files needed to satisfy the build or (c) running the `udevstart' program from Udev. All of these solutions are suboptimal in the author's opinion which is why using MAKEDEV here is recommended. What you do to manage /dev in the final deployed system is entirely your choice, but if you're after the latest and greatest, Udev would be your best bet.

7.9. Man-Pages-3.20

rm -fv man3/getspnam.3 man5/passwd.5
make DESTDIR=$PM_DEST install

Rationale Notes

  • In general terms, GNU prefers the Info documentation system over man pages. However, many GNU packages install both info pages and (in some cases, less than adequate) man pages. The man pages listed above will be installed later on by Coreutils, Diffutils and Shadow and are therefore superfluous. We suppress their installation here because some Package Managers will refuse to install an archive if a file conflict is detected. If you'd prefer to keep the copies here, omit the rm statements and somehow suppress the installation of said man pages when installing the 3 aforementioned packages later on.

7.10. Man-Pages-Posix-2003-a

make DESTDIR=$PM_DEST install

7.11. Linux-Kernel-Headers-2.6.27

[Warning]Warning

As mentioned earlier, the 2.6.18 kernel introduced the next generation method of obtaining sanitized kernel headers. When using the new technique you MUST SKIP the Linux-Libc-Headers step which follows next.

make mrproper
make headers_check || :
make headers_install INSTALL_HDR_PATH=temp
mkdir -pv $PM_DEST/usr
cp -rv temp/include $PM_DEST/usr

7.12. Linux-Libc-Headers-2.6.12.0 (Older toolchains only)

patch -p1 -i ${TT_PFX}/src/patches/linux-libc-headers-2.6.12.0-syscalls-3.patch
mkdir -pv $PM_DEST/usr/include
cp -Rv include/asm-${DIY_ARCH} $PM_DEST/usr/include/asm
cp -Rv include/linux $PM_DEST/usr/include

7.13. Glibc (2.3.6 through 2.7)

[Caution]Proceed with Caution!

Glibc is possibly the most critical piece of software you will compile in a base Reference Build. There is a high probability of something going wrong. Be sure to heed the advice contained in Section B, “Glibc General Advice” before taking on this monster.

case "$DIY_ARCH" in
  i386)   DL=/lib/ld-linux.so.2; MARCH="-march=i686"
	  [[ $GCC_VER > 4.1.9 ]] && MARCH="$MARCH -mtune=generic" ;;
  ppc)	  DL=/lib/ld.so.1 ;;
  x86_64) DL=/lib64/ld-linux-x86-64.so.2 ;;
esac

sed -i.bak \
	"s|libs -o|libs -L/usr/lib -Wl,-dynamic-linker=${DL} -o|" \
	scripts/test-installation.pl

[[ $GLIBC_VER == 2.4* ]] &&
sed -i.bak \
	'/shlib_handle = NULL/{n;n;n;s/else$/& if (step->__shlib_handle == NULL)/}' \
	iconv/gconv_db.c

[[ $GLIBC_VER > 2.5.9 ]] &&
	patch -p1 -i ${TT_PFX}/src/patches/glibc-2.6-x86-math-tests-1.patch

mkdir ../glibc-build
cd ../glibc-build

CFLAGS="-O3 $MARCH -pipe" ../glibc-${GLIBC_VER}/configure \
	--disable-profile \
	--enable-add-ons \
	--libexecdir=/usr/lib \
	--with-headers=/usr/include \
	--enable-kernel=2.6.0 \
	--enable-bind-now

[[ $GLIBC_VER == 2.3* && $DIY_ARCH == x86_64 ]] &&
	sed -i.bak '/combreloc/s/no/yes/' config.make

make
make -k check || :
make install_root=$PM_DEST install -j1
#make install_root=$PM_DEST localedata/install-locales
cp -v --remove-destination $PM_DEST/usr/share/zoneinfo/${TZ} $PM_DEST/etc/localtime

mkdir -pv $PM_DEST/usr/include/hacks/glibc/bits
cp -v `find ../glibc-${GLIBC_VER} -name stdio-lock.h | grep -v nptl` \
	$PM_DEST/usr/include/hacks/glibc/bits

cat > $PM_DEST/etc/nsswitch.conf << "EOF"
# Begin /etc/nsswitch.conf

passwd: files
group: files
shadow: files

hosts: files dns
networks: files

protocols: files
services: files
ethers: files
rpc: files

# End /etc/nsswitch.conf
EOF

cat > $PM_DEST/etc/ld.so.conf << "EOF"
# Begin /etc/ld.so.conf

/usr/local/lib

# End /etc/ld.so.conf
EOF

Rationale Notes

  • For an explanation of why we add `-mtune=generic' to CFLAGS in the x86 GCC-4.2 and above case, please read this mailing list post.

  • Whenever Glibc is installed directly into a prefix of /usr via `make install' (ie: the Makefile variable `install_root' is unset), a script called `test-installation.pl' is run to perform some basic sanity checks (compiling, linking, executing, etc) against the newly installed Glibc. If all goes well, a message "Your new glibc installation seems to be ok." will be shown. However, at the time the script is run our toolchain defaults are still pointing to $TT_PFX. In particular, ld's library search path is pointing to $TT_PFX/lib and gcc's dynamic linker spec is pointing to $TT_PFX${DL}. In actual fact, this means the checks are made against the wrong Glibc. The problem will usually go unnoticed because the Glibc's in $TT_PFX/lib and /usr/lib are functionally equivalent and the checks always pass. You can expose the problem by building different Glibc addons in each phase eg: configure the Temptools phase Glibc with `--enable-add-ons=nptl' and configure the Chroot phase Glibc with `--enable-add-ons=nptl,libidn' (assuming you have downloaded and unpacked the separate addon for Libidn). We work around the issue by using a sed to insert `-L/usr/lib -Wl,-dynamic-linker=${DL}' at an appropriate place. Note that ld's library search path and the gcc dynamic linker spec will be readjusted to point to the new Glibc in the next step.

  • The sed to iconv/gconv_db.c is required to fix a bug that is known to affect at least Samba (crash on startup). It essentially replicates this fix from upstream. More information here.

  • The sed to config.make on x86_64 fixes a subtle bug in the autoconfigury which arrives at a wrong result for the "-z combreloc" feature test. The issue is fixed in Glibc-2.4.x. More information here.

  • The command to install the localedata has been commented out above. If you need all the locales, unlikely as that may be, feel free to uncomment the relevant line. It used to be the case that some of these locales were required for the Libstdc++ testsuite to pass. But that is no longer true with the advent of GCC-3.4. More information about this issue is here. However, the Libstdc++ docs do recommend a minimum list of locales, so having them installed should result in wider Libstdc++ testsuite coverage. Note that you can install individual locales at any time using the `localedef' command ie: locale installation doesn't have to occur as part of the Glibc install. At the very least, you'll probably want to install a locale for your own country.

  • We install the generic version of `bits/stdio-lock.h' into a non-standard location because it gives us the capability of pursuading some legacy software to compile successfully, in particular, apps that define `_IO_MTSAFE_IO' eg: the libstdc+ library from GCC-2.95.x. Clearly, installing this header is a kludge and of course optional. More information about the issue is here. Note that we use `find' to locate the header because it changed location between Glibc-2.3.x and Glibc-2.4.x.

  • The warning in current LFS about unsetting CFLAGS and not overriding the default optimization for Glibc is a crock. Glibc is EXACTLY the kind of package that should be optimized - Refer Golden Rule No. 2 in Section B, “Glibc General Advice”. The warning in LFS dates back to times when clues were scarce and tools weren't as good.

[Tip]Tip -- Set up Dual Threading Libraries

Ever since the advent of NPTL most mainstream distros are set up with both NPTL and Linuxthreads enabled Glibc's installed side by side. This is for backwards compatibility reasons. NPTL is still relatively new and a lot of commercial software simply won't run under it. Be sure to check out Section B, “Dual Threading Libraries” if you need this backwards compatibility and want to set up your system to match the distros.

7.14. Readjust Toolchain

ln -sv ${TT_PFX}/bin/ld-new /usr/bin/ld

case "$DIY_ARCH" in
  i386)   DL=/lib/ld-linux.so.2 ;;
  ppc)	  DL=/lib/ld.so.1 ;;
  x86_64) DL=/lib64/ld-linux-x86-64.so.2 ;;
esac

gcc -dumpspecs | sed \
	-e '/^\*link:$/{n;s,$, -L/usr/lib,}' \
	-e "s,${TT_PFX}${DL},${DL}," \
	-e '/^\*cpp:$/{n;s,$, -isystem /usr/include,}' \
	> /tmp/myspecs

# Sanity checks.
echo 'main(){}' | cc \
	-x c \
	-specs=/tmp/myspecs \
	-B/usr/lib/ \
	-B/usr/bin/ \
	-Wl,--verbose \
	- &> foo

# 1. dynamic linker
readelf -l a.out | grep ": /lib"

# 2. start files
grep " /usr/lib/crt1.o succ" foo

# 3. libc
grep " /lib.*libc.so.6 succ" foo

# 4. deps found from DT_NEEDED
grep "^found.*at /lib.*/ld" foo

rm -fv a.out foo

7.15. GCC (3.4.6 through 4.2.4)

[Caution]Caution -- Check your GCC Testsuite Results!

Upon completion of the GCC Testsuite run, sanity check your results by comparing against a set of known good results as per the links in the following table:

i686-pc-linux-gnupowerpc-unknown-linux-gnux86_64-unknown-linux-gnu
4.2.4 4.2.1 FIXME
4.1.2 4.1.2 4.1.1
4.0.4 4.0.4 4.0.3
3.4.6 3.4.6 3.4.6

Note: if you're using GCC-3.4.4 or earlier and running under a 2.6.12 kernel or above, a new kernel feature known as "address space randomization" will likely cause some PCH tests to fail as per these unsatisfactory results. The problem is now resolved in GCC-3.4.5 and above. However, if for some reason you need to use an old GCC version, the problem can be worked around by following the advice contained in this mailing list post.

sed -i.bak \
	's/install_to_$(INSTALL_DEST) //' libiberty/Makefile.in

[[ $BINUTILS_VER == 2.18* && $GCC_VER > 4.1.9 && $GLIBC_VER > 2.5.9 ]] &&
	patch -p1 -i ${TT_PFX}/src/patches/gcc-4.2-branch-hash-style-gnu-1.patch

sed -i.bak \
	-e 's,\./fixinc\.sh,-c true,' \
	-e '/^LIBGCC2_DEBUG/d' gcc/Makefile.in

[[ $GCC_VER == 4.* && $DIY_ARCH == i386 ]] &&
	sed -i.bak2 's/^XCFLAGS =$/& -fomit-frame-pointer/' gcc/Makefile.in

[[ $GCC_VER == 4.* ]] &&
	sed -i.bak '/dg-timeout/s/3\|10/20/' libmudflap/testsuite/libmudflap.cth/*.c

mkdir ../gcc-build
cd ../gcc-build

CC="gcc -specs=/tmp/myspecs -B/usr/lib/ -B/usr/bin/" \
	../gcc-${GCC_VER}/configure \
	--libexecdir=/usr/lib \
	--enable-shared \
	--disable-multilib \
	--disable-bootstrap \
	--enable-languages=c,c++ \
	--enable-clocale=gnu \
	--enable-threads=posix \
	--enable-__cxa_atexit

make \
	LDFLAGS=${LDFLAGS} \
	MAKEINFO=makeinfo \
	gcc_cv_prog_makeinfo_modern=yes

make -k check || :
../gcc-${GCC_VER}/contrib/test_summary
make DESTDIR=$PM_DEST install -j1

mkdir -pv $PM_DEST/lib
ln -sfv ../usr/bin/cpp $PM_DEST/lib
ln -sfv gcc $PM_DEST/usr/bin/cc

Rationale Notes

  • When building with GCC-4.x we use a sed to add `-fomit-frame-pointer' to the GCC Makefile to address a correctness issue. Please read this mailing list post for some rationale discussion.

  • When building with GCC-4.x we use a sed to increase the timeouts on 2 libmudflap tests to avoid spurious failures. The problem is most noticeable when running the GCC testsuite in parallel on SMP. Upstream have been notified of the issue. Note the timeouts were increased from 3 to 10 seconds as of GCC-4.1 but this is still not enough. The sed is compatible across all supported GCC versions.

  • We add "MAKEINFO=makeinfo" and "gcc_cv_prog_makeinfo_modern=yes" to the `make' invocation to ensure installation of the GCC info pages. Please read this mailing list post for background details.

7.16. Binutils (2.16.1 through 2.18)

rm -fv etc/standards.info
sed -i.bak '/^INFO/s/standards.info //' etc/Makefile.in
mkdir ../binutils-build
cd ../binutils-build

../binutils-${BINUTILS_VER}/configure \
	--enable-shared
echo "MAKEINFO = makeinfo" >> Makefile
make LDFLAGS=${LDFLAGS} tooldir=/usr
make -k check || :
make tooldir=/usr DESTDIR=$PM_DEST install
cp -v ../binutils-${BINUTILS_VER}/include/libiberty.h $PM_DEST/usr/include

Rationale Notes

  • A newer `standards.info' is installed later by the Autoconf package. Here we use `rm' and a Makefile sed to suppress installation of the unwanted file. The `rm' is needed when using FSF releases but is otherwise harmless when using HJL releases.

7.17. Sed-4.1.5

./configure \
	--bindir=/bin \
	--enable-html
make
make check
make DESTDIR=$PM_DEST install

7.18. E2fsprogs-1.41.4

sed -i.bak 's,/bin/rm,rm,' lib/blkid/test_probe.in

mkdir build
cd build

../configure \
	--with-root-prefix="" \
	--enable-elf-shlibs
make
make check
make DESTDIR=$PM_DEST install install-libs

Rationale Notes

  • The sed to `lib/blkid/test_probe.in' removes a hard-wired reference to /bin/rm in the testsuite. Without this sed (or a /bin/rm symlink) the testsuite will produce some non-fatal errors.

7.19. Coreutils-6.12

patch -p1 -i $TT_PFX/src/patches/coreutils-6.12-utimensat-1.patch
sed -i.bak 's,HOME",HOME /dev/shm",' tests/other-fs-tmpdir
sed -i.bak 's/test-getaddrinfo\$(EXEEXT) //' gnulib-tests/Makefile.in

./configure \
	--enable-no-install-program=kill,uptime \
	--enable-install-program=hostname,su
make

if [ `id -u` -eq 0 ]; then
	make NON_ROOT_USERNAME=dummy check-root
	chown -v dummy gnulib-tests/.deps
	su dummy -c "make RUN_EXPENSIVE_TESTS=yes check"
else
	make RUN_EXPENSIVE_TESTS=yes check
fi
make DESTDIR=$PM_DEST install
mkdir -pv $PM_DEST/{bin,usr/sbin}
mv -v $PM_DEST/usr/bin/{cat,chgrp,chmod,chown,cp,date} $PM_DEST/bin
mv -v $PM_DEST/usr/bin/{dd,df,echo,false,hostname,ln,ls} $PM_DEST/bin
mv -v $PM_DEST/usr/bin/{mkdir,mknod,mv,pwd,rm,rmdir,sleep} $PM_DEST/bin
mv -v $PM_DEST/usr/bin/{stty,su,sync,touch,true,uname} $PM_DEST/bin
mv -v $PM_DEST/usr/bin/chroot $PM_DEST/usr/sbin

Rationale Notes

  • For an explanation of the Makefile.in sed, configure switches and chown command, please read this mailing list post.

  • The sed to `tests/other-fs-tmpdir' adds /dev/shm as a location to search when the testsuite goes looking for a writable directory on a different disk partition. This allows some tests to run that would otherwise be skipped. Passing `CANDIDATE_TMP_DIRS=/dev/shm' would achieve the same effect but the sed saves us passing it twice.

  • A bunch of commands are moved to /bin as mandated by the FHS. In the case of `[' and `test', the FHS says they must be together in either /bin or /usr/bin. We leave them in /usr/bin to match the big distros. Even though `sleep' and `touch' are not mentioned by the FHS, we move them to /bin because: (a) they are commonly used in bootscripts, (b) they have always traditionally been there and (c) this matches the big distros. Please read this mailing list post for some rationale discussion.

  • We have opted to use the `su' from Coreutils rather than the one from Shadow. Please read this mailing list post for some rationale discussion. If you would rather use the `su' from Shadow, simply omit `su' from the --enable-install-program configure switch and the 4th mv command.

  • If you would like `uname' to print something useful for the `-p' and `-i' options instead of "unknown", 3rd party patches are known to exist (or at least have existed in the past) at the LFS and Gentoo projects. But before applying any such hacks, ask yourself this question: Why haven't these types of patches been integrated by the upstream Coreutils developers? Some insight into this issue can be found in this mailing list thread.

7.20. Zlib-1.2.3

sed -i.bak \
	'/SFL.*fPIC/s/${CFLAGS-"-fPIC -O3"}/"${CFLAGS-"-O3"} -fPIC"/' \
	configure

./configure \
	--prefix=/usr
make
mv -v {,x}libz.a
make clean

./configure \
	--prefix=/usr \
	--shared
make
make check
make prefix=$PM_DEST/usr install
cp -v xlibz.a $PM_DEST/usr/lib/libz.a
mkdir -pv $PM_DEST/lib
mv -v $PM_DEST/usr/lib/libz.so.* $PM_DEST/lib
ln -sfv ../../lib/libz.so.1 $PM_DEST/usr/lib/libz.so

Rationale Notes

  • The sed to `configure' replicates a fix from upstream which ensures the shared lib is always built with -fPIC. Currently, -fPIC is lost if CFLAGS happen to be set in the environment. More information in this mailing list post. Note: Zlib beta versions can be found here.

  • The reason for the mv -v {,x}libz.a etc. is to allow better locality of the "installation" commands. More rationale in this mailing list post.

7.21. Iana-Etc-2.30

make STRIP=yes
make test
make DESTDIR=$PM_DEST install

Rationale Notes

  • Note: You should be aware there are performance implications when using this package because it results in an enormous /etc/services file. Please read this mailing list post for some background discussion.

7.22. Gawk-3.1.6

./configure \
	--libexecdir=/usr/lib
make
make check
make DESTDIR=$PM_DEST install

7.23. Findutils-4.4.0

./configure \
	--libexecdir=/usr/lib/locate \
	--localstatedir=/var/lib/locate
make
make check
make DESTDIR=$PM_DEST install

7.24. Ncurses-5.7

./configure \
	--with-shared \
	--without-debug
make
make DESTDIR=$PM_DEST install
mkdir -pv $PM_DEST/lib
mv -v $PM_DEST/usr/lib/libncurses.so.5* $PM_DEST/lib
ln -sfv ../../lib/libncurses.so.5 $PM_DEST/usr/lib/libncurses.so
ln -sfv libncurses.so $PM_DEST/usr/lib/libcurses.so

7.25. Readline-5.2

patch -p1 -i ${TT_PFX}/src/patches/readline-5.2-official-012-combined-1.patch
./configure \
	bash_cv_func_ctype_nonascii=yes
make SHLIB_LIBS=-lcurses
sed -i.bak '/MV.*old/d' Makefile
make DESTDIR=$PM_DEST install
mkdir -pv $PM_DEST/lib
mv -v $PM_DEST/usr/lib/lib{readline,history}.so.5* $PM_DEST/lib
ln -sfv ../../lib/libhistory.so.5 $PM_DEST/usr/lib/libhistory.so
ln -sfv ../../lib/libreadline.so.5 $PM_DEST/usr/lib/libreadline.so

Rationale Notes

  • We add "bash_cv_func_ctype_nonascii=yes" to the `configure' invocation to force the correct result in scenarios where the en_US.ISO8859-1 locale is not present. More information here.

7.26. Vim-7.2

echo '#define SYS_VIMRC_FILE "/etc/vimrc"' >> src/feature.h

./configure
make
make test -j1
mkdir -pv $PM_DEST/etc
make DESTDIR=$PM_DEST install -j1
ln -sfv vim $PM_DEST/usr/bin/vi

cat > $PM_DEST/etc/vimrc << "EOF"
" Begin /etc/vimrc

set nocompatible
set backspace=2
syntax on

" End /etc/vimrc
EOF

Rationale Notes

  • Note: The Vim author makes available a number of patches to fix bugs discovered after the latest release which you may want to consider applying. The patches can be found here.

7.27. M4-1.4.13

./configure
make V=1
make check V=1
make DESTDIR=$PM_DEST install

7.28. Bison-2.4.1

./configure
make
make check
make DESTDIR=$PM_DEST install

7.29. Less-429

./configure \
	--sysconfdir=/etc
make
make DESTDIR=$PM_DEST install

7.30. Groff-1.19.2

PAGE=A4 ./configure
make -j1
mkdir -pv $PM_DEST/usr
make prefix=$PM_DEST/usr install
ln -sfv soelim $PM_DEST/usr/bin/zsoelim
ln -sfv eqn $PM_DEST/usr/bin/geqn
ln -sfv tbl $PM_DEST/usr/bin/gtbl

7.31. Flex-2.5.35

./configure
make
make check -j1
make DESTDIR=$PM_DEST install
ln -sfv flex $PM_DEST/usr/bin/lex
ln -sfv libfl.a $PM_DEST/usr/lib/libl.a

7.32. Gettext-0.17

./configure
make
make -k check || :
make DESTDIR=$PM_DEST install

Rationale Notes

  • The Gettext testsuite takes a painfully long time to run, and seeing as Gettext is not a critical component in the overall scheme of things, running this testsuite is considered optional. You can reduce the pain somewhat by only running the less time consuming parts of the testsuite like so: make -C gettext-tools check.

  • Note that the Gettext testsuite will gain wider coverage if you have a bunch of various locales installed (the testsuite will inform you of which ones are missing).

  • Note also that 2 tests will fail if Gettext is configured with `--disable-nls' and the fr_FR locale is installed. More information about this issue is here.

7.33. Net-Tools-1.60

sed -i.bak \
	-e '/PROGS/s/hostname //' \
	-e '/hostname.*bin/d' \
	Makefile
sed -i.bak 's/in 1 5/in 5/' man/Makefile
sed -i.bak '/default:/d' lib/inet_sr.c
sed -i.bak 's/of(x25/of(struct x25/' lib/x25_sr.c

yes "" | make config
make LOPTS=${LDFLAGS} -j1
make BASEDIR=$PM_DEST update

7.34. Inetutils-1.6

sed -i.bak '/man_MANS =/d' \
	{ftpd,inetd,logger,rexecd,rlogind,rshd,syslogd,talkd,telnetd,tftpd}/Makefile.in

./configure \
	--disable-servers \
	--disable-hostname \
	--disable-logger \
	--disable-whois \
	--disable-ifconfig \
	--libexecdir=/usr/sbin
make
make DESTDIR=$PM_DEST install
mkdir -pv $PM_DEST/bin
mv -v $PM_DEST/usr/bin/ping $PM_DEST/bin

7.35. Procps-3.2.7

make
make DESTDIR=$PM_DEST ldconfig=: install

7.36. Perl-5.10.0

sed -i.bak \
	"/if grep/a skip \"not testing setlogsock('stream'): _PATH_LOG unavailable\", 10 \
	unless -e Sys::Syslog::_PATH_LOG();" \
	ext/Sys/Syslog/t/syslog.t

./configure.gnu \
	-Dpager="/usr/bin/less -isR"

make BUILD_ZLIB=False
make test
make DESTDIR=$PM_DEST install

Rationale Notes

  • The sed replicates a testsuite fix from upstream. More background in this mailing list post.

  • BUILD_ZLIB=False is passed on the `make' command line in order to use the system installed Zlib. More background in this mailing list post.

7.37. Gzip-1.3.12

[[ $GLIBC_VER > 2.5.9 ]] &&
	sed -i.bak 's/futimens/gl_&/' gzip.c lib/utimens.{c,h}

./configure
make bindir=/bin
make check
make DESTDIR=$PM_DEST install
mkdir -pv $PM_DEST/bin
mv -v $PM_DEST/usr/bin/{gunzip,gzip,zcat} $PM_DEST/bin

Rationale Notes

  • Adding `bindir=/bin' to the make invocation is not strictly necessary. But it at least ensures the installed scripts have an optimal setting for PATH.

  • Some LFS versions add a `/bin/compress' symlink here. We believe this is technically incorrect. Please read this mailing list post for some rationale discussion.

7.38. Texinfo-4.13a

./configure
make
make check
make DESTDIR=$PM_DEST install

7.39. Grep-2.5.4

./configure \
	--bindir=/bin \
	--without-included-regex
make
make check
make DESTDIR=$PM_DEST install

7.40. File-5.00

./configure
make
make check
make DESTDIR=$PM_DEST install

7.41. Libtool-2.2.6a

./configure
make
make check
make DESTDIR=$PM_DEST install

7.42. Autoconf-2.63

./configure
make
make check
make DESTDIR=$PM_DEST install

7.43. Automake-1.10.1

./configure
make
make -k check || :
make DESTDIR=$PM_DEST install
  • This release of Automake contains an expected testsuite failure when run as root. More information here.

7.44. Bash-3.2

[Important]Important

The Bash testsuite is unlike most others in that it doesn't stop if errors are encountered. This means you have to physically examine the output and cannot rely on the exit status of the `make tests' command. It even tells you as much at the beginning of the run: "Any output from any test, unless otherwise noted, indicates a possible anomaly".

patch -p1 -i ${TT_PFX}/src/patches/bash-3.2-official-039-combined-1.patch
echo '#define NON_INTERACTIVE_LOGIN_SHELLS' >> config-top.h
./configure \
	--without-bash-malloc \
	--with-installed-readline
make

sed -i '/THIS/s,1$,1 </dev/tty,' tests/run-test

if [ `id -u` -eq 0 ]; then
	chown -R dummy .
	su dummy -c "make tests"
else
	make tests
fi
make DESTDIR=$PM_DEST install
mkdir -pv $PM_DEST/bin
mv -v $PM_DEST/usr/bin/bash $PM_DEST/bin

Rationale Notes

  • The sed to `tests/run-test' implements redirection of the input device to ensure this test passes when running su'd to non-root. More information in this mailing list post.

  • The Bash testsuite will issue warnings if you run it as root. We therefore take steps to run it as the dummy user.

  • The configure switch `--without-bash-malloc' causes Bash to use the system supplied malloc from Glibc rather than Bash's own malloc. Please read this mailing list post for some rationale discussion.

7.45. Bzip2-1.0.5

sed -i.bak \
	-e 's,X)/man,X)/share/man,g' \
	-e '/ln .*PREFIX/s,$(PREFIX)/bin/,,' \
	Makefile

make -f Makefile-libbz2_so
make clean
make
make PREFIX=$PM_DEST/usr install
mkdir -pv $PM_DEST/{bin,lib}
cp -v bzip2-shared $PM_DEST/bin/bzip2
cp -av libbz2.so* $PM_DEST/lib
ln -sfv ../../lib/libbz2.so.1.0 $PM_DEST/usr/lib/libbz2.so
rm -fv $PM_DEST/usr/bin/{bunzip2,bzcat,bzip2}
ln -sfv bzip2 $PM_DEST/bin/bunzip2
ln -sfv bzip2 $PM_DEST/bin/bzcat

Rationale Notes

  • The sed serves to (a) ensure man pages are installed into proper FHS compliant location and (b) fix a minor Makefile bug affecting "staged" installations. More information here.

7.46. Diffutils-2.8.1

./configure
make
make DESTDIR=$PM_DEST install

7.47. Ed-1.2

./configure \
	--prefix=/usr \
	--bindir=/bin
make
make check
make DESTDIR=$PM_DEST install

7.48. Kbd-1.14.1

sed -i.bak \
	's/ifdef OPTIONAL_PROGS/ifeq ($(OPTIONAL_PROGS),yes)/' \
	man/Makefile.in

sed -i.bak \
	's,@datadir@,&/kbd,' \
	{src,data}/Makefile.in

./configure \
	--enable-nls
make KEYCODES_PROGS=yes RESIZECONS_PROGS=yes
make KEYCODES_PROGS=yes RESIZECONS_PROGS=yes DESTDIR=$PM_DEST install

Rationale Notes

7.49. Man-1.6f

sed -i.bak 's/-is/&R/' configure
sed -i.bak 's%MANPATH./usr/man%#&%' src/man.conf.in
./configure \
	-default \
	-confdir=/etc
make
make DESTDIR=$PM_DEST install

7.50. Make-3.81

./configure
make
make check
make DESTDIR=$PM_DEST install

7.51. Module-Init-Tools-3.4.1

./configure
make check DOCBOOKTOMAN=:
make maintainer-clean
patch -p1 -i $TT_PFX/src/patches/module-init-tools-3.4-manpages-1.patch

./configure --exec-prefix=/ --enable-zlib
make
make INSTALL=install DESTDIR=$PM_DEST install

Rationale Notes

  • Testing kernel module handling in a live kernel cannot be done easily for obvious reasons. Therefore the Module-Init-Tools developers have devised a custom testsuite procedure that involves separately compiling the package with a set of stubs (see testing.h). The net result of this means we must first run the testsuite, perform a `make distclean' then compile the package for real.

  • Please read the mailing list thread starting with this post for some rationale behind the above build commands.

7.52. Patch-2.5.4

./configure
make
make prefix=$PM_DEST/usr install

7.53. Psmisc-22.6

./configure
make
make DESTDIR=$PM_DEST install
mkdir -pv $PM_DEST/bin
mv -v $PM_DEST/usr/bin/{fuser,killall} $PM_DEST/bin

7.54. Shadow-4.1.2.2

[[ $GLIBC_VER == 2.3* ]] &&
	sed -i.bak '1i #include <sys/types.h>' lib/{pw,group}io.h

./configure \
	--sysconfdir=/etc
make

find man -name Makefile | \
	xargs sed -i.bak \
		-e 's/groups\.1 //' \
		-e 's/su\.1\( \|$\)//' \
		-e 's/suauth\.5 //'
make DESTDIR=$PM_DEST bin_PROGRAMS=login suidbins= install
sed -i \
	-e 's%/var/spool/mail%/var/mail%' \
	-e 's%#MD5_CRYPT_ENAB.no%MD5_CRYPT_ENAB yes%' \
	$PM_DEST/etc/login.defs
sed -i \
	-e '/MAIL/s,yes,no,' \
	$PM_DEST/etc/default/useradd
mv -v $PM_DEST/usr/bin/passwd $PM_DEST/bin

Rationale Notes

  • The `bin_PROGRAMS=login suidbins=' addition to the `make install' invocation is used to suppress installation of `groups' and `su'. This is because we have opted to use the versions from Coreutils instead. In the case of `su', please read this mailing list post for some rationale discussion. If you would rather use the `su' from Shadow, replace the installation line above with make DESTDIR=$PM_DEST bin_PROGRAMS="login su" install. You would also want to adjust the sed to `man/Makefile' to ensure installation of the su related man pages.

7.55. Sysklogd-1.5

make
mkdir -pv $PM_DEST/{etc,usr/{share/man/man{5,8},sbin}}
make prefix=$PM_DEST install

cat > $PM_DEST/etc/syslog.conf << "EOF"
# Begin /etc/syslog.conf

auth,authpriv.* -/var/log/auth.log
*.*;auth,authpriv.none -/var/log/sys.log
daemon.* -/var/log/daemon.log
kern.* -/var/log/kern.log
mail.* -/var/log/mail.log
user.* -/var/log/user.log
*.emerg *

# End /etc/syslog.conf
EOF

7.56. Sysvinit-2.86

make -C src
mkdir -pv $PM_DEST/{{,s}bin,etc,usr/{{bin,include},share/man/man{1,5,8}}}
make -C src ROOT=$PM_DEST install

cat > $PM_DEST/etc/inittab << "EOF"
# Begin /etc/inittab
id:3:initdefault:

si::sysinit:/etc/rc.d/init.d/rc sysinit

l0:0:wait:/etc/rc.d/init.d/rc 0
l1:S1:wait:/etc/rc.d/init.d/rc 1
l2:2:wait:/etc/rc.d/init.d/rc 2
l3:3:wait:/etc/rc.d/init.d/rc 3
l4:4:wait:/etc/rc.d/init.d/rc 4
l5:5:wait:/etc/rc.d/init.d/rc 5
l6:6:wait:/etc/rc.d/init.d/rc 6

ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -r now

su:S016:once:/sbin/sulogin

1:2345:respawn:/sbin/agetty tty1 9600
2:2345:respawn:/sbin/agetty tty2 9600
3:2345:respawn:/sbin/agetty tty3 9600
4:2345:respawn:/sbin/agetty tty4 9600
5:2345:respawn:/sbin/agetty tty5 9600
6:2345:respawn:/sbin/agetty tty6 9600
# End /etc/inittab
EOF

7.57. Tar-1.22

./configure \
	--bindir=/bin \
	--libexecdir=/usr/sbin
make
make check
make DESTDIR=$PM_DEST install

7.58. Util-Linux-ng-2.14.2

sed -i.bak \
	's@etc/adjtime@var/lib/hwclock/adjtime@' \
	hwclock/hwclock.c

./configure \
	--enable-arch \
	--enable-write \
	--disable-wall
make
make DESTDIR=$PM_DEST install
mkdir -pv $PM_DEST/var/lib/hwclock

Rationale Notes

7.59. Grub-0.97 (X86 Only)

sed -i.bak '/ufs2/d' stage2/size_test
patch -p1 -i $TT_PFX/src/patches/grub-0.97-ext-256byte-inode-1.patch

./configure default_CFLAGS=yes
make
make check
make DESTDIR=$PM_DEST install
mkdir -pv $PM_DEST/boot/grub
cp -v $PM_DEST/usr/lib/grub/i386-pc/stage{1,2} $PM_DEST/boot/grub

Rationale Notes

  • The sed to `stage2/size_test' is used to work around an issue with a failing ufs2 test. Just ignoring the failure is unsatisfactory because the `size_test' script bails out on the first failure and therefore doesn't test the remaining file systems (fat, e2fs, minix) 2 of which are clearly important.

  • The "256 byte inode" patch could be considered optional in some circumstances. But it's probably best to apply it. More detailed rationale discussion can be found in this mailing list thread.

  • The Grub build is sensitive to non-standard CFLAGS in the environment. Seeing as we have already set our CFLAGS globally in `config.site', we force Grub to use its own defaults by configuring with `default_CFLAGS=yes'.

7.60. Yaboot-1.3.14 (PPC Only)

sed -i 's@usr/local@usr@' Makefile etc/yaboot.conf man/*
make
make ROOT=$PM_DEST MANDIR=share/man install

7.61. Mac-Fdisk-0.1 (PPC Only)

patch -p1 -i ${TT_PFX}/src/patches/mac-fdisk-0.1.orig-debian-2.patch
make
mkdir -pv $PM_DEST/sbin
make DESTDIR=$PM_DEST install

7.62. Hfsutils-3.2.6 (PPC Only)

./configure
make
mkdir -pv $PM_DEST/usr/{bin,share/man/man1}
make prefix=$PM_DEST/usr install

7.63. Fakeroot-1.11 (Optional)

sed -i.bak 's,${srcdir}/tartest,true,' test/t.tar
./configure
make
make check
make DESTDIR=$PM_DEST install

7.64. Libtar-1.2.11 (Optional)

[Note]Note -- Optional Package Management with Pacman

As mentioned earlier in the Temptools phase, you only need the next 2 packages (Libtar and Pacman) if you've implemented Pacman based package management.

patch -p1 -i ${TT_PFX}/src/patches/libtar-1.2.11-2.patch
./configure
make
make DESTDIR=$PM_DEST install

7.65. Pacman-2.9.8 (Optional)

patch -p1 -i ${TT_PFX}/src/patches/pacman-2.9.8-custom-mods-2.patch
patch -p1 -i ${TT_PFX}/src/patches/pacman-2.9.8-sep_install-1.patch
./configure
make
make DESTDIR=$PM_DEST install

7.66. Ogdlutils-20041124 (Optional)

[Note]Note -- Optional Package Management with BPM

As mentioned earlier in the Temptools phase, you only need the next 3 packages (Ogdlutils, Cpio and BPM) if you've implemented BPM based package management.

make -C c libogdl gpath -j1
mkdir -pv $PM_DEST/usr/bin
cp -v c/gpath $PM_DEST/usr/bin

7.67. Cpio-2.9 (Optional)

./configure \
	--enable-mt \
	--with-rmt=/usr/sbin/rmt
make
make check
make DESTDIR=$PM_DEST rmtdir= install

7.68. BPM-1.7 (Optional)

make DESTDIR=$PM_DEST install

A. Bootstrap Status

The DIY Linux Reference Build prides itself on being able to be bootstrapped from many different build hosts (assuming, of course, a sane toolchain). In essence, if the Reference Build fails to bootstrap from any particular distro, we want to know about it so that the problem can be addressed. This table details the current status of bootstraps from various distributions that the author has tested personally. Expect the number of entries to increase over time.

Distro NameWhen ReleasedGlibc VersionGCC VersionBinutils VersionKernel VersionLast CheckedBootstrap Status
Debian 2.1March 19992.0.72.7.2.32.9.12.0.38FIXMEFAIL
Debian 2.2August 20002.1.32.95.22.9.52.2.1924 March 2005OK
Debian 3.0July 20022.2.52.95.42.12.90.0.12.2.2026 March 2005OK
Red Hat 6.2March 20002.1.32.91.662.9.52.2.1429 March 2005OK
Fedora Core 3November 20042.3.33.4.22.15.92.0.22.6.923 March 2005OK

B. Toolchain Special Section

Glibc General Advice

Glibc is an incredibly complex beast. This is no "configure; make; make install" type package. Extreme care is needed to get it right. If you're not careful a build of Glibc will expose flaws in your:

  1. Toolchain
  2. Environment
  3. Running Kernel
  4. Kernel Headers
  5. Technical Competence

Please read this enlightening post from the Glibc maintainer for the "final word" on the subject:

http://sources.redhat.com/ml/libc-alpha/2004-03/msg00114.html

Despite all of that, it is still possible to attain a DIY production Glibc that works very well. Here are some golden rules for building Glibc:

  1. Always compile and install in a chroot environment. At the very least, build as a non-privileged user. Never `make install' over a live system.
  2. See how the pro's do it. Study the RPM spec files closely, especially those from Red Hat/Fedora (Ulrich Drepper, Roland McGrath and Jakub Jelinek are the main forces behind Glibc development and these guys are all @redhat.com).
  3. Stay abreast of toolchain issues. Monitor the mailing lists for Binutils, GCC and of course Glibc. Also monitor the Kernel list if possible.
  4. Always run `make check'. Investigate and understand any failures.
  5. Recognize that grabbing all the latest and greatest source packages from ftp.gnu.org is never the best strategy for compiling Glibc.

Which Binutils?

FIXME - My text from the original Purelfs hint was integrated into the LFS FAQ here. Take that text, revamp it, make it current, add the missing bits, then put a new version here in the form of some rationale discussion.

Dual Threading Libraries

FIXME - Insert procedure here.