[CLUE-Cert] build engine for automating building of LFS
Dennis J Perkins
djperkins at americanisp.net
Sun Apr 27 22:04:53 MDT 2003
I played around a bit more on how to make a build engine to automate
building LFS. I concentrated on resolving dependencies to build the
packages in the correct order. This is very preliminary!
The real trick will be making sure the toolchain is built cleanly.
Comments?
I'm still sticking with shell scripts, but awk might be very useful in
handling the meta-information files. I think we could teach people a
lot about shell scripts doing this. And I haven't even gotten to dialog
or cdialog yet.
Package Format
A package contains two files, a meta-information file (packagename.desc)
and a shell script (packagename.conf).
meta-information file for bash
------------------------------
PACKAGE bash
VERSION 2.051
NEEDS ncurses
END
NEEDS is optional. Multiple dependencies can be listed after NEEDS or
multiple NEEDS lines can be used.
Additional tags could include URL, DESC, etc.
The shell script is used to provide additional information to the build
engine for configuring and building a package. This includes
configuration and make options, and hooks for providing custom code at
certain points of the build process.
package shell script for bash
-----------------------------
# bash
confoptions="--enable-static-link --with-curses"
I played with bash's eval function and found that code can be linked to
the hooks in the build function in the following manner:
link_gcc() { ln -s gcc $LFS/static/bin/cc }
postmake=link_gcc
Build Engine Layout
The build engine reads lfs.files to determine which packages to compile
and install. It also reads the meta-information file for each package
listed in lfs.files to resolve any dependencies. The package order in
lfs.files is not important because the build engine will create the
proper package order. It will also try to include any packages
specified by NEEDS, even if that package is not included in lfs.files.
pkgs/packagename.desc metainformation about package
pkgs/packagename.conf bash shell script to build package. This file can
contain variables, parameters, and functions.
lfs.files --- list of packages to build
---------------------------------------
bash
binutils
bzip2
diffutils
fileutils
findutils
gawk
sh-utils
gcc
grep
ncurses
gzip
make
patch
sed
texinfo
textutils
util-linux
Sample Code
#!/bin/bash
#
# Program name: build
#
declare -a build_order
# build has not been tested!!!
build() { # $1=package
for patch in $patches
do
patch $patchoptions ${patchdir}/$patch
done
if [ $builddir = "y" ]; then
bdir=${srcdir}-build
test -d $bdir && rm -rf $bdir
mkdir ../$bdir
cd ../$bdir
else
cd $srcdir
fi
eval $preconfigure
if [ -z $bdir ]; then
./configure --prefix=$prefix $confoptions
else
../${srcdir}/configure --prefix=$prefix $confoptions
fi
eval $premake
make $makeflags $makeoptions
if [ $do_checks = "y" ]; then
make check
fi
eval $postmake
make install $makeinstallflags
}
# check_dep and build_deptree seem to be working properly.
check_dep() { # $1=package
local found
local i
local needs
local pkg
# Return error if package not found.
if [ ! -f pkgs/${1}.desc ]; then
errmsg="Cannot find ${1}.conf"
return 1
fi
# Read list of dependencies from conf file.
while read keyword param
do
case $keyword in
NEEDS)
needs="$needs $param"
;;
esac
done < pkgs/${1}.desc
# No dependencies found.
if [ -z "$needs" ]; then
return 0
fi
for pkg in $needs
do
found="n"
if [ ${#build_order[@]} -gt 0 ]; then
for i in $( seq 0 $((${#build_order[@]} - 1 )) )
do
# Needed package is already in build_order.
if [ ${build_order[i]} = $pkg ]; then
found="y"
break
fi
done
fi
if [ $found = "n" ]; then
if check_dep $pkg
then
i=${#build_order[@]}
build_order[$i]=$pkg
i=$((i + 1))
else
errmsg="$1 needs $pkg."
return 1
fi
fi
done
return 0
}
build_deptree() {
local i
while read line
do
# Skip if package is commented out.
if echo $line | grep '^#' 2>&1 > /dev/null
then
continue
fi
if check_dep $line
then
build_order[$i]=$line
i=$((i + 1))
else
echo $errmsg
exit 1
fi
done < lfs.files
# For loop is used to verify that build order is correct.
# Remove when done testing.
for i in $( seq 0 $((${#build_order[@]} - 1 )) )
do
echo ${i}: ${build_order[i]}
done
}
More information about the clue-cert
mailing list