Linux from Scratch: A Cautionary Tale, Part 1
And I’m started with Linux from Scratch! Here are some helpful pointers for anyone considering running LFS on their own. Caution: this is highly nerdy and keyworded to hell to hopefully allow your favourite search engine to grab solutions from this post.
Getting Started, AKA: Use a Distribution You Know
LFS needs an existing Linux environment. Don’t try and use unetbootin on the LFS liveCD (I used lfslivecd-x86_64-6.3-r2145-min.iso to get started, but there is a newer revision 2160 available on one of the mirrors.) unetbootin in this configuration is just a bag of hurt and you’ll spend an inordinate amount of time trying to get your root volume to work, so just burn a CD.
If I was building LFS again I’d have started from a stable Debian base or other Linux distribution where I’m comfortable and have network access – there are a number of reasons below I suggest this, but you really want your host system kernel to be 2.6.25 or higher.
Make sure to have all the patches from linuxfromscratch.org/lfs/view/stable/chapter03/patches.html are downloaded and in a location you can access from your host distribution. USB sticks are OK for this if you don’t have network access (mount the stick, and then copy the patches and packages to the sources directory). Use DownThemAll or a similar mass downloading application/extension on the patches page to save time and grief.
Watch What You Mount
Augh, out of space! It’s quite possible to mount /mnt/lfs on two partitions at the same time by missing a directory, like this:
$ mount /dev/sdb3 /mnt/lfs $ mount /dev/sdb1 /mnt/lfs
Oops – I missed /boot at the end of the second mount command. To confirm this before copying any files, “mount” should show only one partition active at /mnt/lfs. Since my /dev/sdb1 partition was only 200MB I got to the GCC extraction step and was promptly disappointed. I ended up unmounting everything, recreating the filesystem (mke2fs -v /dev/sdb1) and then remounting (mkdir -pv /mnt/lfs/boot; mount -t ext2 /dev/sdb1 /mnt/lfs/boot).
For more tales of installation havoc, keep reading…
Where The Files Are At
Package directories in the manual are not exactly clear/accurate. All compilation instructions assume that you’ve already extracted the package and are currently in the directory it creates. GCC is a gigantic pain if you aren’t in the exact location required. (GCC depends on mpfr which depends on gmp, which it’s having a hard time dealing with. I lose the Saint badge here.)
To be a bit more clear, when extracting GCC (http://www.linuxfromscratch.org/lfs/view/stable/chapter05/gcc-pass1.html) and moving components around, everything needs to be inside the gcc-4.6.1 directory. So the filesystem initially looks like:
mnt/ -> lfs/ -> sources/ -> 7.0/ -> (all .patch and .gz/.bz2 files)
You might have better luck with following commands when I provide the absolute path. First, get rid of the 7.0 in the sources directory and make sure that all .patch and .gz/.bz2 files are directly in /mnt/lfs/sources:
/mnt/lfs $ mv /mnt/lfs/sources/7.0/* /mnt/lfs/sources/ /mnt/lfs $ rm -rf /mnt/lfs/sources/7.0 /mnt/lfs $ cd /mnt/lfs/sources /mnt/lfs/sources $ tar -jxf gcc-4.6.1.tar.bz2 /mnt/lfs/sources $ cd gcc-4.6.1 /mnt/lfs/sources/gcc-4.6.1 $
Continuing instructions from the book, with their correct directories listed:
/mnt/lfs/sources/gcc-4.6.1 $ tar -jxf ../mpfr-3.1.0.tar.bz2 /mnt/lfs/sources/gcc-4.6.1 $ mv -v mpfr-3.1.0 mpfr /mnt/lfs/sources/gcc-4.6.1 $ tar -jxf ../gmp-5.0.2.tar.bz2 /mnt/lfs/sources/gcc-4.6.1 $ mv -v gmp-5.0.2 gmp /mnt/lfs/sources/gcc-4.6.1 $ tar -zxf ../mpc-0.9.tar.gz /mnt/lfs/sources/gcc-4.6.1 $ mv -v mpc-0.9 mpc /mnt/lfs/sources/gcc-4.6.1 $ patch -Np1 -i ../gcc-4.6.1-cross_compile-1.patch /mnt/lfs/sources/gcc-4.6.1 $
In summary, the mpfr, gmp and mpc directories should be under /mnt/lfs/sources/gcc-4.6.1/. This also means that the “gcc-build” directory is located at /mnt/lfs/sources/gcc-build:
/mnt/lfs/sources/gcc-4.6.1 $ mkdir -v ../gcc-build /mnt/lfs/sources/gcc-4.6.1 $ cd ../gcc-build /mnt/lfs/sources/gcc-build $ ../gcc-4.6.1/configure \ ... rest of the switches from the book here. /mnt/lfs/sources/gcc-build $ make /mnt/lfs/sources/gcc-build $ make install /mnt/lfs/sources/gcc-build $
Moving On: Recent Software Helps
In section 5.8, you’ll want to have the SPECS content as a text file – typing it out is way too prone to errors. Again, it would have been nice to have an Internet-enabled host system, but you can throw the contents on a USB stick, mount it and then run it with sh.
When compiling binutils pass 2, another blocking error came up as “configure: error: cannot run C compiled programs.” I read config.log as directed, and the problem ended up being an instruction in section 5.7 (glibc), where there is a directive “–enable-kernel=2.6.25.” The kernel shipped in the LFS LiveCD rev2145 is 2.6.22. You can also detect this condition when asked to compile a sample C program; attempting to run a.out will give a fatal kernel error. To resolve, reconfigure and recompile glibc without that flag, or use a host distribution with 2.6.25 or newer. This was incredibly frustrating!
I also had to re-extract binutils-2.21.1a.tar.bz2 and clear the binutils-build directories from my previous attempts. “make distclean” did not work worth a damn. I should probably have followed the important instructions regarding cleaning up work directories, to be honest.
For coreutils-8.14, the LFS LiveCD r2145 version of tar does not support the “-J” option to decompress .tar.xz files. Again, another reason to use a recent distribution you know and trust for this work! Since the GNU project is no longer providing .tar.gz files, you’ll have to either start over, or use a newer version of tar to extract and recreate the archive. The Unarchiver on OS X gave me a real problem; extracting on my Mac and then copying the coreutils-8.14 directory to a USB stick was unsuccessful. This extraction/copy subsequently caused the “po” directory to not have a Makefile created, which blocked compilation of coreutils completely.
To fix, you can obtain my packaged version of coreutils as a .tar.gz (coreutils-8.14.tar.gz) or create your own from the .xz with a newer tar version; the default tar found in Debian Squeeze at version 1.23 worked for me.
Also keep in mind that this is the only asinine .tar.xz file like this found in the entire LFS 7.0 package list.
In my next post, I’ll go over some of the issues I had in the chroot environment with chapter 6 onwards. But at least we’re started!