Creating Targets
From RockWiki
First, you should think about whether you really want to create a target. To answer this, the word target must be explained first.
A target in ROCK terms is a set of rules to build a distribution. This can range from a simple selection of packages to be built over a more complex target that changes the default rules of single packages (for example, removes GNOME support in licq because it's a KDE target) to a sophisticated, small size livesystem that fits an all-purpose X server, an OpenGL GUI and mplayer into just 25 MB of space.
If that's not really what you want to do, but you only want to, say, add a package to your default installation, then please read Changing The Package Selection.
Contents |
Getting started
The ROCK build process is centered around the target directory which is located in rock-src/target/<targetname>. For the purpose of this documentation, we'll create a target called ROCKDoc. So the first step is to create its directory:
root@ceres:/usr/src/rock-src# mkdir target/rockdoc
preconfig.in
The ROCK scripts need information about this target, for example its name. This has to be put into the file preconfig.in which is used by the scripts/Config tool to create the configuration. For the ROCKDoc target we add this line into rock-src/target/rockdoc/preconfig.in:
root@ceres:/usr/src/rock-src/target/rockdoc# cat preconfig.in
CFGTEMP_TARGETLIST="${CFGTEMP_TARGETLIST} rockdoc ROCK_Documentation"
CFGTEMP_TARGETLIST is a variable inside the scripts/Config tool that holds a list of targets and a short explanation of it. Underscores _ are converted to spaces for this purpose.
config.in
The next file you should create is the config.in file. As you can probably guess, this is executed next after the preconfig.in file and holds the rest of the target-specific configuration. In most targets, it holds default values for configuration items, the default package selection and other stuff like this. Here's what an example config.in might look like:
pkgfilter sed '
# Select some packages explicitly
/ 00-dirtree / { p; d; };
/ autoconf / { p; d; };
/ automake=automake19 / { p; d; };
/ bash / { p; d; };
/ bin86 / { p; d; };
/ binutils / { p; d; };
/ bison / { p; d; };
/ bzip2 / { p; d; };
/ ciphers / { p; d; };
/ coreutils / { p; d; };
/ diffutils / { p; d; };
/ ed / { p; d; };
/ eject / { p; d; };
/ expat / { p; d; };
/ findutils / { p; d; };
/ flex / { p; d; };
/ freeglut / { p; d; };
/ freetype / { p; d; };
/ gawk / { p; d; };
/ gcc / { p; d; };
/ glibc / { p; d; };
/ grep / { p; d; };
/ groff / { p; d; };
/ gzip / { p; d; };
/ kbd / { p; d; };
/ less / { p; d; };
/ libebml / { p; d; };
/ libgli / { p; d; };
/ libjpeg / { p; d; };
/ libmatroska / { p; d; };
/ libpng / { p; d; };
/ libtiff / { p; d; };
/ libtool / { p; d; };
/ libungif / { p; d; };
/ linux / { p; d; };
/ loop-aes / { p ; d; };
/ lvp / { p; d; };
/ m4 / { p; d; };
/ make / { p; d; };
/ mdadm / { p; d; };
/ mktemp / { p; d; };
/ module-init-tools / { p; d; };
/ mplayer / { p; d; };
/ nasm / { p; d; };
/ ncurses / { p; d; };
/ ogg-vorbis / { p; d; };
/ patch / { p; d; };
/ pciutils / { p; d; };
/ perl5 / { p; d; };
/ sed / { p; d; };
/ sysfiles / { p; d; };
/ syslinux / { p; d; };
/ tar / { p; d; };
/ termcap / { p; d; };
/ texinfo / { p; d; };
/ ucl / { p; d; };
/ upx / { p; d; };
/ util-linux / { p; d; };
/ w32codec / { p; d; };
/ xfree86 / { p; d; };
/ zlib / { p; d; };
# Disable all other packages
/.*/ { s/^X /O /p; d; };'
# Disable perl5 in stage 7
pkgfilter sed '/ perl5 / { s/^\([^7]*\)7\(.*\)perl5/\1-\2perl5/; }'
ROCKCFGSET_CREATE_TARBZ2=1
ROCKCFGSET_CREATE_GEM=0
ROCKCFGSET_PKGFILE_VER=0
ROCKCFGSET_PKG_TERMCAP_USEIT=1
ROCKCFGSET_PKG_LOOP_AES_USEIT=1
ROCKCFGSET_PKG_GCC32_NO_JAVA=1
ROCKCFGSET_PKG_GCC33_NO_JAVA=1
ROCKCFGSET_PKG_GCC34_NO_JAVA=1
ROCKCFGSET_PKG_BASH_PROGCOMP=0
ROCKCFGSET_PKG_BASH_INST_RLL=0
ROCKCFGSET_PKG_BASH_DEFAULT='bash2'
ROCKCFGSET_PKG_LINUX_SRC26=1
ROCKCFGSET_PKG_LINUX_IMG26=1
ROCKCFGSET_SPLIT_DOC=0
ROCKCFGSET_SPLIT_DEV=0
ROCKCFGSET_DO_REBUILD_STAGE=0
ROCKCFGSET_CREATE_DOCS=0
ROCKCFGSET_DISABLE_NLS=1
ROCKCFGSET_CREATE_CACHE=0
ROCKCFGSET_PKGSEL_TPL=none
ROCKCFGSET_PKG_BASH_HELP_CMD=0
ROCKCFGSET_DEBUG=0
pkgfilter
Now, that's a whole lot of lines at a time, let's look at them individually:
pkgfilter sed '
# Select some packages explicitly
/ 00-dirtree / { p; d; };
/ autoconf / { p; d; };
/ automake=automake19 / { p; d; };
...
/ xfree86 / { p; d; };
/ zlib / { p; d; };
# Disable all other packages
/.*/ { s/^X /O /p; d; };'
The pkgfilter command takes any program that reads from standard input and writes to standard output. So all these would be valid:
pkgfilter cat pkgfilter grep -v xfree
And whatever else you might think of. The input of the command will look like this:
X -1---5---- 100.000 base 00-dirtree 0000 / base/system DIETLIBC CORE 0
This data is taken from the packages' directory, in this case from package/base/00-dirtree. The pkgfilter command can munch this line any way it wants to. Here's an explanation of the line:
- X
Build this package (X) or do not build it (O) - -1---5----
Stages in which the package is built (0123456789) - 100.000
Priority of this package. Lower number means build earlier - base
The repository of this package (package/base) - 00-dirtree
The package name - 0000
The package's version - /
Just a slash - base/system
The package's category. See Desc file syntax - DIETLIBC CORE
The package's flags. See Desc file syntax - 0
Just a zero to terminate the line
setting default values
The next part of the config.in file from above is this:
ROCKCFGSET_CREATE_TARBZ2=1 ROCKCFGSET_CREATE_GEM=0 ROCKCFGSET_PKGFILE_VER=0
This sets some defaults for config variables. To be more exact, it sets defaults for ROCKCFG_CREATE_TARBZ2, ROCKCFG_CREATE_GEM and ROCKCFG_PKGFILE_VER. Putting SET after ROCKCFG makes this the standard value. To get the name of the setting you can select <HELP> from within scripts/Config.
Manipulating the build system
After you have your configuration files done, you need a build.sh script. This is the script that defines and controls the behaviour of scripts/Create-Target. The shortest possible build.sh looks like this:
# This is the shortest possible target build.sh script. Some targets will
# add code after calling pkgloop() or modify pkgloop's behavior by defining
# a new pkgloop_action() function.
#
pkgloop
echo_header "Finishing build."
echo_status "Selecting bin packages ..."
rm -rf build/${ROCKCFG_ID}/ROCK/pkgs_sel
mkdir -p build/${ROCKCFG_ID}/ROCK/pkgs_sel
(cd build/${ROCKCFG_ID}/ROCK/pkgs/;
ls | xargs ln --target-directory="../pkgs_sel";)
echo_status "Selecting info files ..."
rm -rf build/${ROCKCFG_ID}/ROCK/info_sel
mkdir -p build/${ROCKCFG_ID}/ROCK/info_sel
cp -rl build/${ROCKCFG_ID}/var/adm/`
`{cksums,dependencies,descs,flists,md5sums,packages} \
build/${ROCKCFG_ID}/ROCK/info_sel/.
grep -hr '^Package Name and Version:' \
build/${ROCKCFG_ID}/ROCK/info_sel/packages |
awk '{ print $5 " " $6 "-" $7; }' |
while read p v; do
if [ ! -f build/${ROCKCFG_ID}/ROCK/pkgs_sel/$p-$v.gem ]; then
echo build/${ROCKCFG_ID}/ROCK/info_sel/*/$p
fi
done | xargs -r rm
echo_status "Creating package database (everything) ..."
admdir="build/${ROCKCFG_ID}/var/adm"
create_package_db $admdir build/${ROCKCFG_ID}/ROCK/pkgs \
build/${ROCKCFG_ID}/ROCK/pkgs/packages.db
echo_status "Creating package database (install media) ..."
admdir="build/${ROCKCFG_ID}/ROCK/info_sel"
create_package_db $admdir build/${ROCKCFG_ID}/ROCK/pkgs_sel \
build/${ROCKCFG_ID}/ROCK/pkgs_sel/packages.db
echo_status "Creating isofs.txt file .."
cat << EOT > build/${ROCKCFG_ID}/ROCK/isofs.txt
DISK1 $admdir/cksums/ ${ROCKCFG_SHORTID}/info/cksums/
DISK1 $admdir/dependencies/ ${ROCKCFG_SHORTID}/info/dependencies/
DISK1 $admdir/descs/ ${ROCKCFG_SHORTID}/info/descs/
DISK1 $admdir/flists/ ${ROCKCFG_SHORTID}/info/flists/
DISK1 $admdir/md5sums/ ${ROCKCFG_SHORTID}/info/md5sums/
DISK1 $admdir/packages/ ${ROCKCFG_SHORTID}/info/packages/
EVERY build/${ROCKCFG_ID}/ROCK/pkgs_sel/packages.db ${ROCKCFG_SHORTID}/pkgs/packages.db
SPLIT build/${ROCKCFG_ID}/ROCK/pkgs_sel/ ${ROCKCFG_SHORTID}/pkgs/
EOT
Please note that you can literally do everything to the distribution from within the build.sh script and explaining it all here would be difficult to say the least. You should read some of the available build.sh files and learn what they do, tinker with them a bit and see what happens.
Let's split the above example up:
# This is the shortest possible target build.sh script. Some targets will # add code after calling pkgloop() or modify pkgloop's behavior by defining # a new pkgloop_action() function. # pkgloop
pkgloop is the command to compile all packages. It's the command that usually takes the most time.
echo_status "Selecting bin packages ..."
rm -rf build/${ROCKCFG_ID}/ROCK/pkgs_sel
mkdir -p build/${ROCKCFG_ID}/ROCK/pkgs_sel
(cd build/${ROCKCFG_ID}/ROCK/pkgs/;
ls | xargs ln --target-directory="../pkgs_sel";)
Here the preparations for use with the bootdisk target begin and they only end at the end of the build.sh file. Anything else you might want to do should go between there or - if you don't want to use the bootdisk target and scripts/Create-ISO - you can roll your own iso creation. See the livecd target for an example.
Manipulating individual packages
Just as you can manipulate packages from within the package/<repository>/<package> directory you can do a lot of this from within the target/<target> directory. Here's a reference list of files that manipulate packages. We'll use the ROCKDoc target from above.
- target/rockdoc/pkg_<package>.patch
This patch will be applied to the package's sources before compilation. - target/rockdoc/pkg_<package>.patch.<architecture>
This patch will be applied to the package's sources before compilation if building for the specified <architecture>. - target/rockdoc/xpkg_<xpackage>.patch
- target/rockdoc/xpkg_<xpackage>.patch.<architecture>
Same as above but for forked packages. See Package Forking for details. - target/rockdoc/pkg_<package>.conf
If this file exists (for example: target/rockdoc/pkg_mplayer.conf) then this will be used instead (for example: instead of package/jimmy/mplayer.conf) - parse-config
This file will be run at the start of every package build.
Depending on your build.sh script, there can be many more files in the target directory, but these are the files that are automatically recognized.
