Toucan Linux Project - 8
A Roll Your Own Distribution
Goal 1 – Base System
Stage 2 – Building the Base System
We will continue to build the software of the base system. This will contain the tools and utilities we need to maintain the system and recover from crashes. Once complete, will move on to configuring the system and installing a kernel. This post is exactly like the previous We will use are custom build program, cci.pl, to continue the process. Start in the $LFS/cci directory (or where you placed it if you are modifying the process more to your methods.)Step 1 – Verify the System
Follow all the verification steps of the last post and then check that you still have the confs variable set withecho $confs
If it doesn’t print anything run
export confs=/sources/confs
The standard warning applies: Remember for this whole section you are working as root and even though your are restricted to the target’s filesystem (due to chroot) it is still very easy to undo a lot of your hard work. Work slowly and carefully as you should anytime you are using the root account and always double-check the command line before you press ENTER. Again you can copy and paste as much as possible.
Step 2 – xz 5.2.4
Make the configcat > $confs/config.xz << EOF
./configure --prefix=/usr \
--disable-static \
--docdir=/usr/share/doc/xz-5.2.4
EOF
Make the install which will move a few binaries
cat > $confs/install.xz << "EOF"
make install
mv -v /usr/bin/{lzma,unlzma,lzcat,xz,unxz,xzcat} /bin
mv -v /usr/lib/liblzma.so.* /lib
ln -svf ../../lib/$(readlink /usr/lib/liblzma.so) /usr/lib/liblzma.so
EOF
And build with
./cci.pl -n xz -p xz-5.2.4.tar.xz -c config.xz -i install.xz
Step 3- kmod 26
Create the configcat > $confs/config.kmod << EOF
./configure --prefix=/usr \
--bindir=/bin \
--sysconfdir=/etc \
--with-rootlibdir=/lib \
--with-xz \
--with-zlib
EOF
The kmod package handles module administration replacing the old module-init-tools which supplied the familiar lsmod, insmod, modprobe, and other module commands. The kmod program replaces all of those and performs the same functionality by using symbolic links which need to be made by the install component. The install creation is as follows
echo > $confs/install.kmod << "EOF"
make install
for target in depmod insmod lsmod modinfo modprobe rmmod; do
ln -sfv ../bin/kmod /sbin/$target
done
ln -sfv kmod /bin/lsmod
EOF
We can't run the test suite as it has a lot of requirements. Use the null package instead
./cci.pl -n kmod -p kmod-26.tar.xz -c config.kmod -t null -i install.kmod
Step 4 - gettext 0.20.1
Create the configcat > $confs/config.gettext << EOF
./configure --prefix=/usr \
--disable-static \
--docdir=/usr/share/doc/gettext-0.20.1
EOF
And the install which needs to change permissions
cat > $confs/install.gettext << EOF
make install
chmod -v 0755 /usr/lib/preloadable_libintl.so
EOF
The build with
./cci.pl -n gettext -p gettext-0.20.1.tar.xz -c config.gettext -i install.gettext
Step 5 - libelf 0.176
The only component LFS uses from the elfutils (Executable and Linking Format) package is libelf. It compiles all components by only installs libelf. The package will use all the defaults except the install. Even though we are installing only libelf, we will keep the name elfutils.Make the config
cat > $confs/install.elfutils << EOF
make -C libelf install
install -vm644 config/libelf.pc /usr/lib/pkgconfig
EOF
Build with
./cci.pl -n elfutils -p elfutils-0.176.tar.bz2 -i install.elfutils
Step 6 - libffi 3.2.1
We only need the config component as the others are defaultcat > $confs/config.libffi << "EOF"
sed -e '/^includesdir/ s/$(libdir).*$/$(includedir)/' \
-i include/Makefile.in
sed -e '/^includedir/ s/=.*$/=@includedir@/' \
-e 's/^Cflags: -I${includedir}/Cflags:/' \
-i libffi.pc.in
./configure --prefix=/usr \
--disable-static \
--with-gcc-arch=native
EOF
Build with
./cci.pl -n libffi -p libffi-3.2.1.tar.gz -c config.libffi
Step 7 - OpenSSL 1.1.1c
Build the configcat > $confs/config.openssl << "EOF"
sed -i '/\} data/s/ =.*$/;\n memset(\&data, 0, sizeof(data));/' \
crypto/rand/rand_lib.c
./config --prefix=/usr \
--openssldir=/etc/ssl \
--libdir=lib \
shared \
zlib-dynamic
EOF
Create the install which will install the additional documentation. If you would rather not, leave the last two lines before the EOF out of the file
cat > $confs/install.opensll << "EOF"
sed -i '/INSTALL_LIBS/s/libcrypto.a libssl.a//' Makefile
make MANSUFFIX=ssl install
mv -v /usr/share/doc/openssl /usr/share/doc/openssl-1.1.1c
cp -vfr doc/* /usr/share/doc/openssl-1.1.1c
EOF
Install with
./cci.pl -n openssl -p openssl-1.1.1c.tar.gz -c config.openssl -i install.openssl
Step 8 - Python 3.7.4
With this package there is a chance it might run out of space in the build ramdisk. If it does unmount the ramdisk withumount /sources/build
though I have found it to always work.
Create the config
cat > $confs/config.python << EOF
./configure --prefix=/usr \
--enable-shared \
--with-system-expat \
--with-system-ffi \
--with-ensurepip=yes
EOF
Create the install
cat > $confs/install.python << EOF
make install
chmod -v 755 /usr/lib/libpython3.7m.so
chmod -v 755 /usr/lib/libpython3.so
ln -sfv pip3.7 /usr/bin/pip3
EOF
There is additional HTML documentation you can install on the LFS page. Add those lines above the EOF in the install.
Build the package with
./cci.pl -n python -p Python-3.7.3.tar.xz -c config.python -i install.python
If it was necessary to umount the ramdisk remount it with:
mount -o size=250M -t tmpfs tmpfs /sources/build
Step 9 - ninja 1.9.0
Ninja uses python as the build language. Since it is non-standard we will create three scripts and use the null script for the config.Create the compile script
echo "python3 configure.py --bootstrap" >> $confs/compile.ninja
Create the test script
echo "./ninja ninja_test && ./ninja_test --gtest_filter=-SubprocessTest.SetWithLots" >> $confs/test.ninja
Make the install script
cat > $confs/install.ninja << EOF
install -vm755 ninja /usr/bin/
install -vDm644 misc/bash-completion /usr/share/bash-completion/completions/ninja
install -vDm644 misc/zsh-completion /usr/share/zsh/site-functions/_ninja
EOF
Finally, build with
./cci.pl -n ninja -p ninja-1.9.0.tar.gz -c compile.ninja -t test.ninja -i install.ninja
To avoid a user from exhausting system memory, LFS suggests a modification but it depends on the user creating an environment variable (or allowing the system to supply one) that is easily overridden. This isn't a security patch and I opted not to apply it.
Step 10 - Meson 0.51.1
Meson, like Ninja, is a build system that uses Python. It has only a compile and install.Make the compile
echo "python3 setup.py build" > $confs/compile.meson
And the install:
echo 'python3 setup.py install --root=dest && cp -rv dest/* /' > $confs/install.meson
The build using null for the config and test scripts
./cci.pl -n meson -p meson-0.50.1.tar.gz -c null -m compile.meson -t null -i install.meson
Step 11 - coreutils 8.31
Again we have a patch we will handle using an absolute path. Our package manager will handle this much better. Create the config with the patchcat > $confs/config.coreutils << "EOF"
patch -Np1 -i /sources/coreutils-8.31-i18n-1.patch
sed -i '/test.lock/s/^/#/' gnulib-tests/gnulib.mk
autoreconf -fiv
FORCE_UNSAFE_CONFIGURE=1 ./configure \
--prefix=/usr \
--enable-no-install-program=kill,uptime
EOF
The test script runs some tests first as root. A second set requires the ownership to be nobody and the tests ran as that user. The test is somewhat complicated
cat > $confs/test.coreutils << "EOF"
make NON_ROOT_USERNAME=nobody check-root
# Add a test user
echo "dummy:x:1000:nobody" >> /etc/group
chown -Rv nobody .
su nobody -s /bin/bash \
-c "PATH=$PATH make RUN_EXPENSIVE_TESTS=yes check"
# Delete the user
sed -i '/dummy/d' /etc/group
EOF
Make the install script which will make the binaries FHS compliant
cat > $confs/install.coreutils << "EOF"
make install
mv -v /usr/bin/{cat,chgrp,chmod,chown,cp,date,dd,df,echo} /bin
mv -v /usr/bin/{false,ln,ls,mkdir,mknod,mv,pwd,rm} /bin
mv -v /usr/bin/{rmdir,stty,sync,true,uname} /bin
mv -v /usr/bin/chroot /usr/sbin
mv -v /usr/share/man/man1/chroot.1 /usr/share/man/man8/chroot.8
sed -i s/\"1\"/\"8\"/1 /usr/share/man/man8/chroot.8
mv -v /usr/bin/{head,nice,sleep,touch} /bin
EOF
Then build with
./cci.pl -n coreutils -p coreutils-8.31.tar.xz -c config.coreutils -t test.coreutils -i install.coreutils
Step 12 - Check 0.12.0
Check uses the defaults except for the install which fixes a script. Make the installcat > $confs/install.check << EOF
make docdir=/usr/share/doc/check-0.12.0 install
sed -i '1 s/tools/usr/' /usr/bin/checkmk
EOF
Then create with
./cci.pl -n check -p check-0.12.0.tar.gz -i install.check
This package has a long delay in the testing where nothing seems to be occurring but it is running. Patience is required.
Step 13 - diffutils 3.7
This is a completely well behaved package. Just build with./cci.pl -n diffutils -p diffutils-3.7.tar.xz
Step 14 - gawk 5.0.1
There is optional documentation that can be installed. I have chosen not to install it.Create the config
cat > $confs/config.gawk << EOF
sed -i 's/extras//' Makefile.in
./configure --prefix=/usr
EOF
Then build with
./cci.pl -n gawk -p gawk-5.0.0.tar.xz -c config.gawk
Step 15 - findutils 4.6.0
The config needs to modify the test programs and apply a fix. Create it withcat > $confs/config.findutils << "EOF"
sed -i 's/test-lock..EXEEXT.//' tests/Makefile.in
sed -i 's/IO_ftrylockfile/IO_EOF_SEEN/' gl/lib/*.c
sed -i '/unistd/a #include <sys/sysmacros.h>' gl/lib/mountlist.c
echo "#define _IO_IN_BACKUP 0x100" >> gl/lib/stdio-impl.h
./configure --prefix=/usr --localstatedir=/var/lib/locate
EOF
Since our startup scripts (the default LFS scripts) need find it must be moved to the root partition. For this we need a custom install
cat > $confs/install.findutils << "EOF"
make install
mv -v /usr/bin/find /bin
sed -i 's|find:=${BINDIR}|find:=/bin|' /usr/bin/updatedb
EOF
Then build
./cci.pl -n findutils -p findutils-4.6.0.tar.gz -c config.findutils -i install.findutils
Step 16 - groff 1.22.4
The groff package is part of a page formatting system. It needs a paper size. For the US this is most likely "letter" but "A4" in the EU. There is a default that is compiled set by the environment variable PAGE. The default can be changed using a file called /etc/papersize. This example uses "letter" but if you prefer something else, change it in the config scriptecho 'PAGE=letter ./configure --prefix=/usr' > $confs/config.groff
This can not be built in parallel, so create a compile to disable it
echo "make -j1" > $confs/compile.groff
There is no test suite. Build it
./cci.pl -n groff -p groff-1.22.4.tar.gz -c config.groff -m compile.groff -t null
Step 17 - GRUB 2.04
GRUB version 2 is the boot loader we will use, like LFS. It is complex but very versatile and very standard.Create the config
cat > $confs/config.grub << EOF
./configure --prefix=/usr \
--sbindir=/sbin \
--sysconfdir=/etc \
--disable-efiemu \
--disable-werror
EOF
Make the install
cat > $confs/install.grub << EOF
make install
mv -v /etc/bash_completion.d/grub /usr/share/bash-completion/completions
EOF
The build with
./cci.pl -n grub -p grub-2.02.tar.xz -c config.grub -t null -i install.grub
Step 18 - less 551
This package only needs a configecho "./configure --prefix=/usr --sysconfdir=/etc" > $confs/config.less
Since there is no test suite build with-system
./cci.pl -n less -p less-530.tar.gz -c config.less -t null
Step 19 - gzip 1.10
Only the install is changedecho "make install && mv -v /usr/bin/gzip /bin" > $confs/install.gzip
Then build with
./cci.pl -n gzip -p gzip.tar.gz -i install.gzip
Step 20 -IPRoute2 5.2.0
This package requires the Berkeley DB for the arpd program and iptables. Per LFS we will disable them for now, and revisit them later is necessary.Create the config
cat > $confs/config.iproute2 << EOF
sed -i /ARPD/d Makefile
rm -fv man/man8/arpd.8
sed -i 's/.m_ipt.o//' tc/Makefile
EOF
and the install
echo "make DOCDIR=/usr/share/doc/iproute2-5.2.0 install" > $confs/install.iproute
Build with
./cci.pl -n iproute2 -p iproute2-5.1.0.tar.xz -c config.iproute2 -t null -i install.iproute2
Step 21 - kbd 2.1.0
The kbd package contains utilities to control the console which includes keyboard mapping and fonts. One program has the old svgalib as a dependency so LFS disables this since svgalib is now defunct. But a lot of older code, such as svgalib, can still be used on modern kernels but doing so is an experiment so for now, we will go with the LFS recommendation of disabling it. There is also an available patch to make the delete key consistent throughout the kbd utilities. Since cci.pl doesn't handle patches we will use an absolute path and fix it later.Make the config
cat > $confs/config.kbd << "EOF"
patch -Np1 -i /sources/kbd-2.1.0-backspace-1.patch
sed -i 's/\(RESIZECONS_PROGS=\)yes/\1no/g' configure
sed -i 's/resizecons.8 //' docs/man/man8/Makefile.in
PKG_CONFIG_PATH=/tools/lib/pkgconfig ./configure --prefix=/usr --disable-vlock
EOF
If you want additional documentation do the following
cat > $confs/install.kbd << "EOF"
make install
mkdir -v /usr/share/doc/kbd-2.1.0
cp -R -v docs/doc/* /usr/share/doc/kbd-2.1.0'
EOF
and add "-i install.kbd" to the cci.pl command below.
Build it with:
./cci.pl -n kbd -p kbd-2.0.4.tar.xz -c config.kbd
Step 22 - libpipline 1.5.1
This one uses all the defaults. Build it with./cci.pl -n libpipeline -p libpipeline-1.5.1.tar.gz
Step 23 - make 4.2.1
Make requires a change in the config and a different method of launching the tests.Make the config
cat > $confs/config.make << "EOF"
sed -i '211,217 d; 219,229 d; 232 d' glob/glob.c
./configure --prefix=/usr
EOF
And the test
echo 'make PERL5LIB=$PWD/tests/ check' > $confs/test.make
Then install with
./cci.pl -n make -p make-4.2.1.tar.bz2 -c config.make -t test.make
Step 24 - patch 2.7.6
All we need is the defaults./cci.pl -n patch -p patch-2.7.6.tar.xz
Step 25 - man-db 2.8.5
The application part of the online manual. The only change we are making for TTLP from LFS is to set the default browser to links instead of lynx. We have also modified the location of the browser, vgrind, and grap to /usr/local/bin which will be the location for TTLP when we add these tools.echo > $confs/config.man-db << EOF
./configure --prefix=/usr \
--docdir=/usr/share/doc/man-db-2.8.5 \
--sysconfdir=/etc \
--disable-setuid \
--enable-cache-owner=bin \
--with-browser=/usr/bin/links \
--with-vgrind=/usr/local/bin/vgrind \
--with-grap=/usr/local/bin/grap \
--with-systemdtmpfilesdir= \
--with-systemdsystemunitdir=
EOF
The build then uses the default
./cci.pl -n man-db -p man-db-2.8.5.tar.xz -c config.man-db
Please check www.linuxfromscratch.org/lfs/view/development/chapter06/man-db.html for information about manual pages in language other than English.
Step 26 - tar 1.32
Create the configcat > $confs/config.tar << EOF
FORCE_UNSAFE_CONFIGURE=1 \
./configure --prefix=/usr \
--bindir=/bin
EOF
This install doesn't install the additional HTML documentation. Build with
../cci.pl -n tar -p tar-1.32.tar.xz -c config.tar
The test suite is very slow.
Step 27 - texinfo 6.6
Make the configecho './configure --prefix=/usr --disable-static' > $confs/config.texinfo
We will install the TeK components because they are small and we might want to install TeK later.
cat > $confs/install.texinfo << EOF
make install
make TEXMF=/usr/share/texmf install-tex
EOF
Build with
./cci.pl -n texinfo -p texinfo-6.6.tar.xz -c config.texinfo -i install.texinfo
Step 28 - VIM 8.1.1535
VIM is one of the few packages that will explode into a directory with a name that doesn't match the file. In this case when you explode vim-8.1.tar.gz it creates a directory called vim81 when the standard is to use vim-8.1. This will be a problem we could handle with the package manager, but it is even easier to simply rename the tarball firstpushd /sources
mv vim-8.1.tar.bz2 vim81.tar.bz2
popd
We will only need to perform that one time and both *cci.pl* and the forth coming package manager will work.
Make the config
cat > $confs/config.vim << EOF
echo '#define SYS_VIMRC_FILE "/etc/vimrc"' >> src/feature.h
./configure --prefix=/usr
EOF
And the test
cat > $confs/test.vim << EOF
chown -Rv nobody .
su nobody -s /bin/bash -c "LANG=en_US.UTF-8 make -j1 test"
EOF
And the install which makes a link for age old vi users. Creating the links will fail on later installs, but that is okay.
cat > $confs/install.vim << "EOF"
make install
ln -sv vim /usr/bin/vi
for L in /usr/share/man/{,*/}man1/vim.1; do
ln -sv vim.1 $(dirname $L)/vi.1
done
EOF
The build with
./cci.pl -n vim -p vim81.tar.bz2 -c config.vim -t test.vim -i install.vim
Please be sure to enter ":help iccf" at the VIM prompt.
Step 29 Procps-ng 3.3.15
Create the configure (which disables the kill command which comes from util-linux)cat > $confs/config.procps-ng << EOF
./configure --prefix=/usr \
--exec-prefix= \
--libdir=/usr/lib \
--docdir=/usr/share/doc/procps-ng-3.3.15 \
--disable-static \
--disable-kill
EOF
In the partial build we need to modify the tests run per LFS
cat > $confs/test.procps-ng << "EOF"
sed -i -r 's|(pmap_initname)\\\$|\1|' testsuite/pmap.test/pmap.exp
sed -i '/set tty/d' testsuite/pkill.test/pkill.exp
rm testsuite/pgrep.test/pgrep.exp
make check
EOF
And finally the install
cat > $confs/install.procps-ng << "EOF"
make install
mv -v /usr/lib/libprocps.so.* /lib
ln -sfv ../../lib/$(readlink /usr/lib/libprocps.so) /usr/lib/libprocps.so
EOF
Build with
./cci.pl -n procps-ng -p procps-ng-3.3.15.tar.xz -c config.procps-ng -t test.procps-ng -i install.procps-ng
Step 30 - util-linux 2.34
Create the config which makes a directory necessary before the configure script is rancat > $confs/config.util-linux << EOF
mkdir -pv /var/lib/hwclock
./configure ADJTIME_PATH=/var/lib/hwclock/adjtime \
--docdir=/usr/share/doc/util-linux-2.34 \
--disable-chfn-chsh \
--disable-login \
--disable-nologin \
--disable-su \
--disable-setpriv \
--disable-runuser \
--disable-pylibmount \
--disable-static \
--without-python \
--without-systemd \
--without-systemdsystemunitdir
EOF
The install uses the nobody user
cat > $confs/test.util-linux << EOF
chown -Rv nobody .
su nobody -s /bin/bash -c "PATH=$PATH make -k check"
EOF
Then install with
./cci.pl -n util-linux -p util-linux-2.33.2.tar.xz -c config.util-linux -t test.util-linux
Step 31 - e2fsprogs 1.45.3
Though we aren't using ext type file systems, others will (you might have chosen ext4). We will install the utilities for administrating those file system as they are very standard.Create the config
cat > $confs/config.e2fsprogs << EOF
mkdir -v build
cd build
../configure --prefix=/usr \
--bindir=/bin \
--with-root-prefix="" \
--enable-elf-shlibs \
--disable-libblkid \
--disable-libuuid \
--disable-uuidd \
--disable-fsck
EOF
Create the install
cat > $confs/install.e2fsprogs << EOF
make install
make install-libs
chmod -v u+w /usr/lib/{libcom_err,libe2p,libext2fs,libss}.a
gunzip -v /usr/share/info/libext2fs.info.gz
install-info --dir-file=/usr/share/info/dir /usr/share/info/libext2fs.info
makeinfo -o doc/com_err.info ../lib/et/com_err.texinfo
install -v -m644 doc/com_err.info /usr/share/info
install-info --dir-file=/usr/share/info/dir /usr/share/info/com_err.info
EOF
Then build with
./cci.pl -n e2fsprogs -p e2fsprogs-1.45.2.tar.gz -c config.e2fsprogs -i install.e2fsprogs
Step 32 - Sysklogd 1.5.1
Though sysklogd is not our final log daemon it will be what we start with to stay LFS compliant.Create the config
cat > $confs/config.sysklogd << EOF
sed -i '/Error loading kernel symbols/{n;n;d}' ksym_mod.c
sed -i 's/union wait/int/' syslogd.c
EOF
And the install
echo 'make BINDIR=/sbin install' > $confs/install.sysklogd
And build with
./cci.pl -n sysklogd -p sysklogd-1.5.1.tar.gz -c config.sysklogd -i install.sysklogd
Step 33 - sysvinit 2.95
Again we need a patch with the absolute path for nowecho 'patch -Np1 -i /sources/sysvinit-2.95-consolidated-1.patch' > $confs/config.sysvinit
Then install with
./cci.pl -n sysvinit -p sysvinit-2.94.tar.xz -c config.sysvinit
Step 34 - eudev 3.2.8
Create the configcat > $confs/config.eudev << EOF
./configure --prefix=/usr \
--bindir=/sbin \
--sbindir=/sbin \
--libdir=/usr/lib \
--sysconfdir=/etc \
--libexecdir=/lib \
--with-rootprefix= \
--with-rootlibdir=/lib \
--enable-manpages \
--disable-static
EOF
Create the test script
cat > $confs/test.eudev << EOF
mkdir -pv /lib/udev/rules.d
mkdir -pv /etc/udev/rules.d
make check
EOF
Create the install
cat > $confs/install.eudev << EOF
tar -xvf ../udev-lfs-20171102.tar.xz
make -f udev-lfs-20171102/Makefile.lfs install
udevadm hwdb --update
EOF
Build with
./cci.pl -n eudev -p eudev-3.2.8.tar.gz -c config.eudev -t test.eudev -i install.eudev
That completes the system software. We have two very important tasks left. The first is some system configuration, including the boot process since the init program only launches processes from /etc/init. The second is to build a kernel and get it booted with our boot loader, GRUB. We also have a few packages to add that our not part of the LFS base, but we will need for The Toucan Linux Project.
Copyright (C) 2019 by Michael R Stute

No comments:
Post a Comment