Modified DIY Linux Reference Build

[Note] Note

This is an unofficial and "unauthorized" version of the Reference Build taken from here, as modified by myself, Jon Grosshart. I've removed, added and adusted pieces of the document for an up-to-date build. My ultimate goal is to document my slightly modified DIY build using pkgtools in the same easy to read format that Greg uses, eg - this web page and CSS. If this is a problem, please send me an e-mail and I will remove it at once.

As always, the original project and reference build can be found at http://www.diy-linux.org/

The original Copyright and terms of the document are listed below....

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.

Table of Contents

 
1. Getting Started

1.1. Environment
 
2. Temptools Phase

2.1. Bash-4.1 Pass 1
2.2. Make-3.81 Pass 1
2.3. Sed-4.2.1 Pass 1
2.4. Binutils-2.20 Pass 1 a.k.a. Cross Binutils
2.5. GCC-4.4.3 Pass 1 a.k.a. Cross GCC
2.6. Linux-Kernel-Headers-2.6.31.12
2.7. Glibc-2.11.1 32-bit - *ONLY* for Bi-arch x86_64
2.8. Glibc-2.11.1
2.9. Adjust Toolchain
2.10. Binutils-2.20 Pass 2
2.11. GCC-4.4.3 Pass 2
2.12. Gawk-3.1.7
2.13. Coreutils-8.4
2.14. Bzip2-1.0.5
2.15. Gzip-1.3.13
2.16. Diffutils-2.8.1
2.17. Findutils-4.4.2
2.18. Make-3.81 Pass 2
2.19. Grep-2.5.4
2.20. Sed-4.2.1 Pass 2
2.21. Gettext-0.17
2.22. Ncurses-5.7
2.23. Patch-2.6
2.24. Tar-1.22
2.25. Texinfo-4.13a
2.26. Bash-4.1 Pass 2
2.27. M4-1.4.13
2.28. Bison-2.4.1
2.29. Flex-2.5.35
2.30. E2fsprogs-1.41.9
2.31. Util-Linux-ng-2.16.2
2.32. Perl-5.10.1
2.33. Tcl-8.4.19
2.34. Expect-5.43.0
2.35. DejaGnu-1.4.4
2.36. File-5.03
2.37. Which-2.20
2.38. Xz-4.999.9
2.39. Remove Cruft
 
3. Chroot Phase

3.1. Enter Chroot Environment
3.2. Base-8.0 Pass 1
3.3. Perform Mounts
3.4. Create Symlinks
3.5. Create /etc/config.site
3.6. Etc-8.0 Pass 1
3.7. Pkgtools-13.0 Pass 1
3.8. Makedev-1.7
3.9. Base-8.0 Pass 2
3.10. Etc-8.0 Pass 2
3.11. Finish off with 'base-order.txt'
3.12. Readjust Toolchain
 

1. Getting Started

1.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.

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.

[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.

[Note] Note

I, Jon Grosshart, build as the root user on the host the entire way through. For both temptools and chroot. I've removed all refrences to the user 'build'. If it wasn't clear from the very top of this document, I'm taking the refrence build docs and modifying them the way I build. I've also ditched pacman, fakeroot and everything else towards the end along with the optional PPC packages.

I only build for x86 and x86_64 so that's all I'm leaving in. Make sure the below environment commands are correct for your setup.

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=x86_64-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=/jaguar
TZ='America/New_York'
export TT_PFX CONFIG_SHELL CONFIG_SITE DIY_TARGET BIARCH LC_ALL LDFLAGS PATH SYSROOT TZ
#export MAKEFLAGS="-j5"
set +o hashall 2>/dev/null || set -o nohash
umask 022
BINUTILS_VER=2.20
GCC_VER=4.4.3
GLIBC_VER=2.11.1
export BINUTILS_VER GCC_VER GLIBC_VER
EOF

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

source ~/.bash_profile

Now set up the sysroot area:

install -dv ${SYSROOT}${TT_PFX}
ln -sv ${SYSROOT}${TT_PFX} /

2. Temptools Phase

2.1. Bash-4.1 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 ../bash-4.1-official-002-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.

2.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.

2.3. Sed-4.2.1 Pass 1

./configure
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.

  • 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.

2.4. Binutils-2.20 Pass 1 a.k.a. Cross Binutils

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.

2.5. GCC-4.4.3 Pass 1 a.k.a. Cross GCC

bunzip2 -dc ../mpfr-2.4.2.tar.bz2 | tar xf -
bunzip2 -dc ../gmp-4.3.1.tar.bz2 | tar xf -
mv -v mpfr* mpfr
mv -v gmp* gmp

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.

2.6. Linux-Kernel-Headers-2.6.31.12

make mrproper
make headers_install INSTALL_HDR_PATH=temp
find temp/include -type f -name ".*install*" | xargs rm -v
cp -rv temp/include $TT_PFX

2.7. Glibc-2.11.1 32-bit - *ONLY* for Bi-arch x86_64

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

CC="$DIY_TARGET-gcc -m32" \
CFLAGS="-O2 -march=i686 -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

2.8. Glibc-2.11.1

[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.

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

[[ $DIY_TARGET == i?86* ]] && MARCH=-march=i686
[[ $DIY_TARGET == x86_64* ]] && MARCH=-march=core2

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.

  • `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.

2.9. 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

2.10. Binutils-2.20 Pass 2

[[ $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

2.11. GCC-4.4.3 Pass 2

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

bunzip2 -dc ../mpfr-2.4.2.tar.bz2 | tar xf -
bunzip2 -dc ../gmp-4.3.1.tar.bz2 | tar xf -
mv -v mpfr* mpfr
mv -v gmp* gmp
patch -p1 -i ../gcc-4.3-branch-startfiles-1.patch

patch -p1 -i ../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

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.

2.12. Gawk-3.1.7

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

2.13. Coreutils-8.4

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

Rationale Notes

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

2.14. Bzip2-1.0.5

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

2.15. Gzip-1.3.13

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

2.16. Diffutils-2.8.1

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

2.17. Findutils-4.4.2

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

2.18. Make-3.81 Pass 2

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

2.19. Grep-2.5.4

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

2.20. Sed-4.2.1 Pass 2

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

2.21. Gettext-0.17

patch -p1 -i ../gettext-0.17-upstream_fixes-2.patch
cd gettext-tools
./configure \
	--disable-shared
make -C gnulib-lib
make -C src msgfmt
cp -v src/msgfmt ${TT_PFX}/bin

2.22. Ncurses-5.7

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

2.23. Patch-2.6

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

2.24. Tar-1.22

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

2.25. Texinfo-4.13a

./configure
make
make install

2.26. Bash-4.1 Pass 2

patch -p1 -i ../bash-4.1-official-002-combined-1.patch
./configure \
	--without-bash-malloc
make
install -v bash ${TT_PFX}/bin

Rationale Notes

  • 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.

2.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

2.28. Bison-2.4.1

./configure
make
make install

2.29. Flex-2.5.35

patch -p1 -i ../flex-2.5.35-gcc44-1.patch
./configure
make
cp -v flex ${TT_PFX}/bin

2.30. E2fsprogs-1.41.9 (SKIP)

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

Rationale Notes

  • With versions of util-linux-ng ≤ 2.14.x, we would install the E2fsprogs libraries here to satisfy the build of `mount' in the next step. The trend has always been to install the shlibs from e2fsprogs but now that util-linux-ng is shipping them, I'm not entirely sure what to do (with regards to the chroot build). As far as the temptools are concerned, I see no reason to install e2fsprogs anymore.

2.31. Util-Linux-ng-2.16.2

./configure --disable-static
make
make -C shlibs install
make -C mount install
cp -v text-utils/rev ${TT_PFX}/bin

Rationale Notes

  • As mentioned above, offhand, I see no reason not to use the shlibs from util-linux-ng instead of e2fsprogs.

  • 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.

  • `rev' is installed to satisfy a new pkgtools-13.0 dependency.

2.32. Perl-5.10.1

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.1
cp -Rv lib/* ${TT_PFX}/lib/perl5/5.10.1

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.

2.33. Tcl-8.4.19

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

2.34. Expect-5.43.0

patch -p1 -i ../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”.

2.35. DejaGnu-1.4.4

./configure
make install -j1

2.36. File-5.03

./configure --disable-static
make
make install

2.37. Which-2.20

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

2.38. Xz-4.999.9

./configure --disable-static
make
make install

2.39. Remove Cruft

find ${SYSROOT}${TT_PFX} -type d -name "$DIY_TARGET" -exec rm -rfv {} \;
find ${SYSROOT}${TT_PFX} -type f -name "${DIY_TARGET}*" -exec rm -rfv {} \;
rm -rfv ${TT_PFX}/{,share/}{info,man,doc} 

Rationale Notes

  • We can remove the 'cross compile' toolchain directories along with the unnecessary info, man and doc pages. It would be wise at this point to tar up your temptools/ directory for safe keeping.

3. Chroot Phase

3.1. Enter Chroot Environment

[Important]Important

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

3.2. Base-8.0 Pass 1

sh base.build
cd /
tar xf /tmp/base-8.0-noarch-1.tgz
sh install/doinst.sh
rm -rf install

Rationale Notes

  • pkgtools is not installed yet so we do a manual run of the base-8.0 build script to create our directories.

  • If you look closely, you'll see a failed chgrp command because the etc-8.0 package has not been installed yet. Thus, the reason for a second pass run of base-8.0 after etc-8.0 is on the system.

3.3. 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

3.4. 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 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.

3.5. Create /etc/config.site

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

Rationale Notes

  • Make sure you adjust your $CFLAGS

3.6. Etc-8.0 Pass 1

sh etc.build
cd /
tar xf /tmp/etc-8.0-noarch-1.tgz
sh install/doinst.sh
rm -rf install

Rationale Notes

  • Again, pkgtools is not on the system yet so we manually build and extract this package to the root of our filesystem.

3.7. Pkgtools-13.0 Pass 1

sh pkgtools.build
cd /
tar xf /tmp/pkgtools-13.0-*-1.tgz
rm -rf install

Rationale Notes

  • Again, we have to manually create this package and extract it to the root of our system before we can start making packages with pkgtools. We won't bother installing our final pkgtools until we build the ncurses package later on. Right now, this pkgtools has linked against the ncurses in /temptools and is only temporary.

3.8. Makedev-1.7

cd /dev && ./MAKEDEV -v generic-nopty

Rationale Notes

  • Even tho we will be using udev to boot our system, we'll need a compliment of device nodes during chroot. If not, test suite failures will be common and things will just start to break in general.

3.9. Base-8.0 Pass 2

sh base.build
installpkg /tmp/base-8.0-noarch-1.t*

Rationale Notes

  • Since we have extracted the etc-8.0 package which contains the file /etc/group, the proper permissions will be set for /var/run/utmp and /var/log/lastlog in the base-8.0 package... Also, now that we have a preliminary pkgtools on the system, this will be our first 'official' package made and installed with pkgtools. Go ahead... Type 'pkgtool' and bask in the glory of your one whole package installed.

3.10. Etc-8.0 Pass 2

sh etc.build
installpkg /tmp/etc-8.0-noarch-1.t*

3.11. Finish off with 'base-order.txt'

http://jaguarlinux.com/pub/DIY/source/base-order.txt

3.12. 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