Note: A version of this document entirely on one web page is available here.
Copyright © 2004-2007, 2008 Greg Schafer
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 CVS | 28th April 2008 |
| 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
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.
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.
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.
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 |
|---|---|
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. | |
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.
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 - 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.
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.
| |||||||||||||||||||||||||||||||||||||
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.
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
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
FIXME explain the issues touched upon here. FIXME
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.
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 - 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 |
|---|---|
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.3
GLIBC_VER=2.6.1
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 |
|---|---|
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.
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:
Patches used in the Reference Build can be downloaded from http://www.diy-linux.org/downloads/patches/. Be sure to look in the "PM" subdirectory for Package Management related patches, "ppc" subdirectory for PowerPC related patches, etc.
![]() | 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. | |
![]() | 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-033-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 |
|---|---|
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.
./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.
./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.
# 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.
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 \ $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
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.
![]() | 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). | |
case $DIY_TARGET in i?86* | x86_64*) KARCH=x86 ;; powerpc-*) KARCH=powerpc ;; esac make mrproper make headers_install INSTALL_HDR_PATH=temp ARCH=$KARCH cp -rv temp/include $TT_PFX
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
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
![]() | 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. | |
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.
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.
[[ $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
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
[[ $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
[ "$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" >> gcc/config/$DL_HEADER
[[ $DIY_TARGET == x86_64* ]] &&
echo '
#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
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.
./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 |
|---|---|
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. | |
[[ $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
./configure \
--disable-perl-regexp \
MISSING=true
make
cp -v src/{,e,f}grep ${TT_PFX}/bin
Rationale Notes
cd gettext-tools
./configure \
--disable-shared
make -C gnulib-lib
make -C src msgfmt
cp -v src/msgfmt ${TT_PFX}/bin
./configure \ --without-debug \ --without-ada \ --enable-overwrite make make install
patch -p1 -i ${TT_PFX}/src/patches/bash-3.2-official-033-combined-1.patch
./configure \
--without-bash-malloc
make
install -v bash ${TT_PFX}/bin
Rationale Notes
Please skip ahead to Section 4.43, “Bash-3.2” for some rationale discussion about the `--without-bash-malloc' switch.
![]() | 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
cp -v src/m4 ${TT_PFX}/bin
mkdir build cd build ../configure make libs 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.
./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.
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.
cd unix
./configure
make
make install
make install-private-headers
ln -sv tclsh8.4 ${TT_PFX}/bin/tclsh
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”.
./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.
![]() | 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
patch -p1 -i ${TT_PFX}/src/patches/libtar-1.2.11-2.patch
./configure
make
make install
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
![]() | 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
![]() | 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. | |
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.
![]() | 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
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.
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
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."
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.
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.
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 dev