# cclfs It's a compliant bash script that builds Linux From Scratch. If you don't know what this is, or haven't built Linux From Scratch on your own before, you should go through the LFS [book](https://linuxfromscratch.org) before using this script. This is a script based on . It was developped on debian (bookworm i686, trixie x86_64). ## Requirements The requirements are those of the book : The **/mnt/lfs** partition is not created by the script. You have to create it by yourself. Some commands are provided by the script. The lfs user is mandatory : ```bash groupadd lfs useradd -s /bin/bash -g lfs -m -k /dev/null lfs passwd lfs ``` Some additionnal requirements : * the **lfs** user is mandatory * The script should by executed by **lfs** user * sudo command is necessary * a sudoers file is provided for **lfs** user to restrict rights to stricts requirements. * this sudoers file allow to protect the host and restrict command only to **/mnt/lfs** directory * it allow the following commands on **/mnt/lfs** : chown mount install chroot * build directory is hardcoded : /mnt/lfs * mount |grep -q "/mnt/lfs type ext4" should return ok * /etc/bash.bashrc should not be used on host * sudo mv -v /etc/bash.bashrc /etc/bash.bashrc.NOUSE * cross compilation for glibc seems to need some specific packages * sudo apt install flex libzstd-dev pkgconf * you can't execute in parallel the script on the same namespace. ## How It Works Copy the repository under any location . The script do some writings only under : * * LFS_PACKAGE_DIR if it does not contains all required packages * ~lfs/ * /tmp/lfs* * /mnt/lfs/ * /mnt/lfs/sources/ The script builds LFS by completing the following steps: 1. Download package source code and save to the _packages_ directory. 2. Build initial cross compilation tools. This corresponds to chapter 5 in the LFS book, and "phase 1" of the script. 3. Begin to build tools required for minimal chroot environment. (chapter 6/phase 2) 4. Enter chroot environment, and build remaining tools needed to build the entire LFS system. (chapter 7/phase 3) 5. Build the entire LFS system from within chroot envirnment, including the kernel, GRUB, and others. (chapter 8+/phase 4) The script ask for validation for each step. You can disable validation until desired step with a number as argument. The _number_ is the chapter (of the books) on 5 digits until you validate. If you want to start validation at _5. Compiling a Cross-Toolchain_, it's _50000_. To configure it, execute a first time the _make_ command. A file **~lfs/.lfsbuild_config** will be created. You can customize it by setting the BREAKPOINT var. Or create and customize the file before : ```bash cat /home/lfs/.lfsbuild_config << EOSF # location of local package sources LFS_PACKAGE_DIR=/home/lfs/packages # Number of processors to use LFS_NPROC=$(nproc) # Bypass step by step validation until a breakpoint LFS_BREAKPOINT=1 # strip binaries or not LFS_STRIP_BINARIES=true # bypass network config validation by taking network config from host LFS_NETWORKSAMEASHOST=false # bypass network configuration for full offline build LFS_NETWORKOFFLINE=false # bypass linux config validation by taking linux config from host LFS_LINUXCONFIGPROVIDED=false EOSF ``` ## Examples Execute as **lfs** user. ```bash make ``` ## Grub config Grub is initiated with the following menu : ```bash $ cat /mnt/lfs/boot/grub/grub.cfg # Begin /boot/grub/grub.cfg set default=0 set timeout=5 insmod part_gpt insmod ext2 search --set=root --fs-uuid=8c137b8d-3612-4715-94c2-8203e273318f set gfxpayload=1024x768x32 menuentry "GNU/Linux, Linux 6.18.10-lfs-13.0-systemd with blockdevice" { linux /boot/vmlinuz-6.18.10-lfs-13.0-systemd root=/dev/vdb1 ro } menuentry "GNU/Linux, Linux 6.18.10-lfs-13.0-systemd with partuuid" { linux /boot/vmlinuz-6.18.10-lfs-13.0-systemd root=PARTUUID=001cdfe1-01 ro } ``` The _partuuid_ section is not required, but can be helpful if you add another disk or change boot order in bios. partuuid is _more_ immutable than _vdx_. Devices are extracted from the following command : ```bash $ lsblk -o UUID,PARTUUID,PATH,MOUNTPOINT UUID PARTUUID PATH MOUNTPOINT /dev/sr0 /dev/vda e46c1c50-d494-44f2-a826-41afc1b76eae 9ffe027f-01 /dev/vda1 / 9ffe027f-02 /dev/vda2 cae0487a-2eca-44c7-aa5f-060ea258f30c 9ffe027f-05 /dev/vda5 [SWAP] /dev/vdb 8c137b8d-3612-4715-94c2-8203e273318f 001cdfe1-01 /dev/vdb1 /mnt/lfs ``` In this configuration extracted from a libvirt host ( _/dev/vdxn_ ) with a second disk dedicated to LFS, /mnt/lfs device entry is filtered. The grub config is made with it. **cclfs** doesn't install the bootloader. It use the bootloader of the host. You can install it if you want before or after the first boot. See instruction in _LFS_ book and _BLFS_ book. There is only one bootloader _by default_ at boot nonetheless. ### Debian configuration On Debian Trixie (13) (at least), OS_PROBER is disabled. Just uncomment the line in /etc/default/grub or customize a config file in /etc/grub.d/ . And reinstall the bootloader. ```bash $ sudo vim /etc/default/grub $ grep PROBER /etc/default/grub GRUB_DISABLE_OS_PROBER=false $ sudo update-grub ``` In default configuration, libvirt/kvm doesn't activate a second disk, so it won't boot. You have to activate the second disk in the boot options. You can find devices seen by _bios_ with the grub console : type **c** at grub general menu ```bash ls (hd0,msdos1) (hd0,msdos5) (hd1,msdos1) ``` If you don't see your LFS partition, it won't boot. ## Automated LFS is not LFS The goal of LFS is to learn how to build a GNU/Linux OS. Read the book is a very convenient way to learn. That's why the script follow _at most_ the book. Copy and paste command is not learning, it learn to copy/paste, maybe. Manual commands with modification may generate errors you don't see. You don't know where you made the mistake, you restart, you fail, you don't understand, and you give up. Or you write a small bash script to avoid copy/paste errors. And you write this. Writing a script like this _is_ a lot of learning. And automation may help to encourage in LFS development. Forking the repo and personnal appropriation seems _IMHO_ a good choice. ## Why not use _alfs_ , _jhlfs_ and reinvent the wheel ? The following section of the README is not convenient for my personnal usage. ```md 5. RUNNING:: IMPORTANT:: You must be logged as a normal user with sudo privileges to run the Makefile. Furthermore, you are supposed to have enough privilege to become any user. If you are not bothered about security issues, the entry for the user running the tool in /etc/sudoers could be ALL=(ALL) NOPASSWD:ALL ``` On a dedicated VM for tests, ok. On a real computer with other roles, give all **root** rights is **NOT** acceptable. _cclfs_ works with a dedicated lfs user with only **required** rights **only** on /mnt/lfs. There is absolutely no possibility to break anything else on the host than **/mnt/lfs**.