SliTaz Cook & Cooker
The SliTaz Cookutils provide tools and utils to help build SliTaz packages.
They are easy to use and learn, fast and light. You will be able to create
SliTaz packages in a few commands. The cookutils suite is split BSD-style,
one tool for one task, around the central cook command and the
Cooker.
cook compiles a receipt and produces a tazpkg. Around it, a
handful of focused sub-tools handle the wok queries, the packages database,
the build environment setup, batch building, dependency analysis,
diagnosis, cleaning and receipt creation. The Cooker is a build bot with
more automation and can be used as a frontend to cook since it provides a
CGI/web interface to view logs in a colored way. All tools share the same
DB files and wok, and they all share blocked and
broken package lists as well as activity.
For technical information (coding style, repo layout, etc), refer to the README found in the source tree or in /usr/share/doc/cookutils. The receipt format is described in Receipts v2 and the receipt build options in COOKOPTS.
- Tools overview
- Cook usage
- Howto
- Getting started
- cook.conf
- Test your environment
- Create and cook
- Receipts
- Install a cooked package
- Get sources, repack, debug
- Clean packages
- Search and list the wok
- Receipt functions
- Packages DB list
- Batch builds
- Runtime dependencies
- Diagnosis
- The Cooker
Tools overview
The cookutils suite is composed of the following user-facing tools, all
available under /usr/bin/:
cook Compile and package a single receipt
cook-all Batch-cook packages from a list / cookorder
cook-clean Wipe wok artefacts (taz/, install/, source/)
cook-deps Analyze runtime dependencies of a cooked package
cook-doctor Diagnose the build environment or a package (read-only)
cook-new Create a new package skeleton in the wok
cook-pkgdb Build the package DB for $PKGS plus split.db / maint.db
cook-setup Bootstrap a build chroot or cross-compile environment
cook-tui Ncurses front-end: type a package name, watch it build
cook-wok Read-only queries on the wok (list / search / uncook / …)
cooker Build bot with CGI web interface
cookiso ISO image builder
cooklinux Kernel build wrapper
cooks Cook a package, then its split packages that have their
own wok directory (v1 receipts)
cross Cross-compilation toolchain builder (make install-cross)
The internal modules run by cook itself (precheck,
postcheck, compressor,
fix-desktop-file) live in /usr/libexec/cookutils/
and are not meant to be called by hand.
Every cook-* tool understands help,
--help, -h or usage for its
built-in usage screen with examples. cook and
cooker take usage, help or
-h (a cook --help is read as a package name).
For backwards compatibility, cook keeps transparent shims for
the legacy sub-commands. They exec the matching
cook-* tool, so existing scripts and habits keep working:
cook setup [opts] -> cook-setup [opts] cook <arch>-setup -> cook-setup <arch> cook new <pkg> [-x] -> cook-new <pkg> [-x] cook doctor [...] -> cook-doctor [...] cook list <file> -> cook-all <file> cook all [opts] -> cook-all [opts] cook clean-wok -> cook-clean wok cook clean-src -> cook-clean src cook list-wok -> cook-wok list cook search <query> -> cook-wok search <query> cook uncook -> cook-wok uncook cook wanted -> cook-wok wanted cook build_depends -> cook-wok build_depends cook build_loop -> cook-wok build_loop cook pkgdb [--flavors] -> cook-pkgdb [--flavors] cook splitdb -> cook-pkgdb --splitdb cook maintdb -> cook-pkgdb --maintdb cook <pkg> --deps -> cook-deps <pkg>
Cook usage
Cook provides a small built-in help that you can display with the command
usage, and a page of examples with howto. It
also has options to perform special tasks on a package before cooking it
or afterwards. To get help and usage:
# cook usage # cook howto
The options of cook <pkg>:
--clean -c Clean the package in the wok
--getsrc -gs Get the package source tarball
--block -b Block a package so cook will skip it
--unblock -ub Unblock a blocked package
--pack Repack an already built package (install/ must exist)
--continue Keep the source tree and patches already applied,
run compile_rules again
--debug Display debugging messages
--deps, --cdeps Check the dependencies of a cooked package (cook-deps)
The short forms (-c, -gs, -b,
-ub) must come right after the package name.
Howto
The first thing you will have to do before building packages is setup your environment. The 2 recommended ways of working: cook directly on host or cook in chroot to protect your host. In the case you want to work in a chroot you can install and use Tazdev to create one and chroot into it:
# tazdev gen-chroot && tazdev chroot
By default Tazdev creates a chroot in /home/slitaz/cooking/chroot but you
can specify a custom path in the argument (--arch=x86_64 puts
it in /home/slitaz/cooking/x86_64/chroot). The chroot location is not
important, when you will be in the chroot you will use standard SliTaz
paths such as /home/slitaz/wok for the wok directory or /home/slitaz/log
for all the cook logs. As usual you can display tazdev help usage with
tazdev usage.
When you use a chroot there are 2 special directories mounted with the bind option: src and packages. The sources for all packages are stored by default in /home/slitaz/src, this directory is mounted into the chroot so the utils can use them. This method lets you share sources between many chroots such as one for cooking and one for stable. The packages directory default location is: /home/slitaz/[version]/packages so they are not in the chroot and are safe in case the chroot is removed by error.
When you cook directly on the host, cook protects it with a jail: an
overlayfs with the running system read-only below and a throw-away branch
in /dev/shm on top. Build dependencies are installed in the
branch and vanish with it, only the wok, the logs and the packages are
written for real. The bound filesystems are listed in
JAIL_MOUNTS (cook.conf). A receipt can ask for its branch on
disk instead of RAM with JAIL_NOT_RAMFS, or for no jail at
all with JAIL_NOT_SUPPORTED. Without overlayfs (inside a
plain chroot, for example) cook silently builds without a jail.
Getting started
Cook uses the /etc/slitaz/cook.conf configuration file, if
you want to use custom paths for SliTaz directories and files, you'll have
to modify it (a cook.conf in the current directory is read
after it and overrides it). Setup creates some directories and files to
keep trace of activity and errors, all files are pure plain text files
that you can open in a text editor. It also installs the
SETUP_PKGS and gives the slitaz group write
access to $SLITAZ. To prepare your environment:
# cook-setup
The cook-setup command has a --wok option which
lets you clone a SliTaz wok while setting up your cook environment. Even
if you are not yet an official developer you can clone it and use existing
packages as an example to create your own. To setup and clone the default
cooking wok or the undigest wok (--stable and
--tiny clone the other woks, --forced
reinstalls the setup packages):
# cook-setup --wok # cook-setup --undigest
For cross-compilation environments, pass the target architecture. This
installs CROSS_SETUP and rewrites ARCH,
CROSS_TREE, CFLAGS and
HOST_SYSTEM in /etc/slitaz/cook.conf:
# cook-setup arm # cook-setup armv6hf # cook-setup armv7 # cook-setup x86_64
cook.conf
The main settings of /etc/slitaz/cook.conf. The package
keeps a local cook.conf on upgrade, and code defaults handle a missing
variable, so an upgraded cookutils works with an existing cook.conf
without any manual change.
SLITAZ="/home/slitaz" Root of WOK, PKGS, SRC, CACHE, LOGS, FEEDS.
ARCH="i486" Target arch: i486, x86_64 or arm*. Sets CFLAGS
and the package names (-x86_64, -any suffixes).
SETUP_PKGS="..." Packages installed by cook-setup / cooker setup.
SETUP_MD5="" md5 of "ls $INSTALLED": when set, cook refuses to
start on a base that drifted (bdeps left over).
QA="0" Any non-empty value (even "0") checks the receipt
before the cook (precheck); empty disables it.
KEEP_BUILD_TREE="" "yes" keeps source/ and install/ after a
successful cook (local development).
LOCALE="" Translations kept in packages (empty: the
supported SliTaz locales).
JAIL_MOUNTS="/ /proc …" Filesystems bound into the build jail (was
AUFS_MOUNTS before 4.13, the old name stops cook).
MAKEFLAGS, CFLAGS, CPPFLAGS, LDFLAGS, CONFIGURE_ARGS
Build flags exported to every receipt.
DEFAULT_LOG_LIMIT=50 Max log size in MB per receipt function.
HOST_WGET="wget" wget used for Repology (needs HTTPS).
MAKE_BUNDLE="no" cook-pkgdb builds bundle.tar.lzma (build host
only, bakes upstream mirrors + extra.list).
REPOLOGY_CHECK="no" postcheck queries repology.org for "outdated"
badges. Requires HTTPS-capable wget.
DEPS_CHECK="no" postcheck runs cook-deps on the packed files and
prints the DEPENDS the receipt seems to lack.
DEPS_MIRROR_LIST="yes" cook-deps also reads the mirror files list; "no"
on a build host whose packages dir is the mirror.
The network toggles default to "no" so a fresh chroot
doesn't try to reach the network during cook / cook-pkgdb. Build hosts
flip them to "yes". Missing build dependencies are
installed from the local packages, never cooked automatically.
Test your environment
Cook provides a test command which will create a package and cook it. This lets you see if your environment is working and it provides an example package with a receipt. The dummy package is named 'cooktest' and can be removed after testing. To cook the test package:
# cook test
Create and cook
If your environment is setup correctly you can start creating and compiling SliTaz packages from your wok. To create a new package with an empty receipt (you can also create one interactively):
# cook-new pkgname # cook-new pkgname --interactive
If you have just created a new package, you'll have to edit the receipt with your favorite text editor: the template is a receipt v2. When the receipt is ready or if you have an existing package, you can cook it:
# cook pkgname
If all went well you will find your package in the
$SLITAZ/packages directory and the cook log in
$SLITAZ/log/pkgname.log. After a successful cook the wok
keeps only the receipt, stuff/ and taz/ (the
packed tree, shown by the Cooker web interface): source/
and install/ are removed, unless
KEEP_BUILD_TREE="yes". A failed cook keeps everything for
debugging.
Receipts
A receipt is a shell script with variables (PACKAGE,
VERSION, DEPENDS, BUILD_DEPENDS...)
and functions: compile_rules() builds the sources into
$install, genpkg_rules() copies the files of
each package from $install to $fs. There are
two formats:
- v1 (first line
# SliTaz package receipt.): one receipt per package; a-devor other split has its own wok directory withWANTED="parent". - v2 (first line
# SliTaz package receipt v2.): one receipt builds the main package and every package listed inSPLIT, andgenpkg_rules()picks the files of each one with acaseon$PACKAGE:
# SliTaz package receipt v2.
PACKAGE="attr"
SPLIT="attr-dev"
genpkg_rules() {
case $PACKAGE in
attr) copy @std ;;
attr-dev) copy @dev ;;
esac
}
In v2, split packages do not inherit DEPENDS,
TAGS, CONFIG_FILES... from the top of the
receipt, and a plain post_install() goes into every
package: suffix it with the package name. Read
Receipts v2 for the details, the
copy() patterns, compiling sets and the checklist to
convert a v1 receipt.
Install a cooked package
There is no install option: cook produces packages, installing them is the job of the package manager. In a build chroot, cook updates the packages that are already installed there with the fresh build, so the build environment stays current. On a native host it never does: the running system boots on what was just cooked (kernel, glibc, boot scripts). Install the package yourself:
# tazpkg install $SLITAZ/packages/pkgname-version*.tazpkg
Get sources, repack, debug
If you want or need to download only the source of a package without
building it, you can use the option --getsrc as below. The
cook checks the tarball against TARBALL_SHA256 (or
_SHA1, _SHA3, _SHA512,
_MD5) and, when the receipt has none, prints the line to
paste in it:
# cook pkgname --getsrc
To pack again an already built package after a genpkg_rules
change, without compiling, or to run compile_rules again on
the existing source tree (patches already applied are skipped):
# cook pkgname --pack # cook pkgname --continue
Clean packages
After compilation and packaging there are several files in the wok that take up disk space. To clean a single package:
# cook pkgname --clean
You can also clean the full wok at once or just remove the sources to
reclaim disk (src keeps the trees of broken packages for
debugging):
# cook-clean wok # cook-clean src
Search and list the wok
cook-wok handles read-only queries on the wok. It uses grep
and so supports regular expressions:
# cook-wok list # list packages in the wok (ARCH-filtered) # cook-wok search libssh # grep package names # cook-wok uncook # full inventory of packages without a tazpkg # cook-wok wanted gtk # cooker tasks for gtk* receipts (incremental) # cook-wok build_depends # idem driven by BUILD_DEPENDS # cook-wok build_loop # receipts with a build dependency loop (slow)
Receipt functions
Many packages provide the same kind of files such as *-dev packages with
static libs, pkgconfig files and include headers. cook provides functions
to be used in a receipt. In genpkg_rules:
copy PATTERN... Copy files from $install to $fs: @std, @dev,
folder/, file, wildcards, @rm, @ico
(see receipts v2)
get_dev_files Copy /usr/include, /usr/lib/pkgconfig and the
static libs (/usr/lib*/*a) to $fs
cook_copy_files NAME... Copy the files matching NAME, keeping paths
cook_copy_folders NAME... Copy the folders matching NAME, keeping paths
cook_copy_icons [SIZE...] Copy hicolor icons (default: 16 48)
remove_already_packed Remove from $fs files already packed by a
previous package of the same receipt (v2)
In compile_rules:
fix ld Add -Wl,--as-needed to LDFLAGS fix libtool Same in the generated libtool (after configure) fix math C++ std::isnan... build fix for recent glibc fix symlinks Make absolute symlinks in $install relative fix utf-8 Install the en_US.UTF-8 locale for the build fix gem Tidy a Ruby gem install (docs, man pages) cook_pick_manpages FILE.. Copy man pages to $install/usr/share/man/manN cook_pick_docs FILE... Copy docs to $install/usr/share/doc/$PACKAGE-$VERSION cook_perl Build and install a Perl module (Makefile.PL)
Patches listed in stuff/patches/series are applied
automatically before compile_rules (one per line,
[options|]name-or-URL[|sha256=...]). The receipt paths
are $src (sources), $install (also
$DESTDIR), $fs (the package file system) and
$stuff. COOKOPTS tunes the packing steps
(strip, compressors, desktop files...), see
cookopts.txt.
Packages DB list
cook-pkgdb generates the package database for the
$PKGS directory and refreshes the wok-wide
split.db and maint.db. This lets you create a
local packages repository quite easily and is used to create the official
SliTaz packages list found on the mirrors. To create a packages list and
the Live flavors files:
# cook-pkgdb # full rebuild # cook-pkgdb /path/pkgs # full rebuild against another packages dir # cook-pkgdb --flavors # full rebuild + regenerate TazLiTo flavors # cook-pkgdb --rmpkg # full rebuild + remove stale tazpkg files # cook-pkgdb --splitdb # refresh just $cache/split.db # cook-pkgdb --maintdb # refresh just $cache/maint.db
When called via --flavors, cook-pkgdb checks for a flavors
repo in /home/slitaz/flavors and packs all flavors in /home/slitaz/live
using the latest packages list available.
Batch builds
cook-all cooks packages listed in a plain text file, one
per line. Lines starting with # and blank lines are skipped.
With no file argument, ./cookorder is tried first, then
/etc/slitaz/cookorder:
# cook-all # use the default cookorder # cook-all my.list # cook from a custom list # cook-all --resume # restart a broken full rebuild
The --resume flag skips packages that already have a
taz/ dir, which lets you continue after an interrupted
rebuild without recooking what's already done. Each result is logged in
$SLITAZ/log/cook-all.log, and the exit status is non-zero
when a package failed.
Runtime dependencies
cook-deps analyzes runtime dependencies of a cooked package
by reading its files.list and resolving each binary,
shared library, pkg-config or libtool reference back to the package that
ships it:
# cook-deps libssh # pretty per-sub-package output # cook-deps libssh -q # one line per sub-package, machine-friendly # cook-deps libssh --la # also follow *.la dependency_libs # cook-deps libssh --incl # also show glibc-base / gcc-lib-base
Diagnosis
cook-doctor runs read-only health checks: config, cache DB
files, disk space, orphan jails, toolchain and SETUP_MD5,
arch coherence, permissions. For each problem it prints a suggested fix
command, but never runs it. On a package it checks the receipt, the
build dependencies, the broken state with a log tail, the cooked tazpkg
and the source tarball. The exit status is 1 when a problem is found:
# cook-doctor # the build environment # cook-doctor busybox # one wok package # cook-doctor all lib # scan $WOK/lib*, one line per problem
The Cooker
The Cooker is a Build Bot, its first function is to check for commits in a wok, create an ordered cooklist and cook all modified packages. It can also be used as a frontend to cook since they both use the same files. The Cooker can also be used to cook a big list of packages at once such as all the packages in a flavor. The Cooker provides a nice CGI/Web interface that works by default on any SliTaz system since it provides CGI support via the Busybox httpd web server.
The Cooker provides a small built-in help usage and short command switch. For example to display usage you can use:
# cooker usage # cooker -u
The Cooker commands (short switch first):
-u usage Display the usage
-s setup Setup the Cooker environment
setup-cron [hours] Add the Cooker to root's crontab (default: 2)
check-cron Show the Cooker cron jobs
arch-db Create the host arch packages DB
-n note "text" Add a note to the cooknotes
-ns notes Display all the cooknotes
-b block pkg Block a package so cook will skip it
-ub unblock pkg Unblock a blocked package
-R reverse pkg Cook all reverse dependencies of a package
-p pkg pkg Same as 'cook pkg' but with cooker log
-f flavor name Cook all packages of a flavor
-l list file Cook all packages in the given list
-c cat category Cook all packages of a category
-r rev number Cook packages of a specific Hg revision
-a all Find and cook all unbuilt packages
-T tasks List existing cooker tasks
-t task name Execute the specified task
-o outgoing Find changes in wok that we can move to wok-hg
autodeps Find dependencies for all packages in wok
Cooker setup
Like cook, the Cooker needs a working environment before starting to use
it. The main difference with the cook environment is that the Cooker
needs 2 woks. One Hg and clean wok as a reference
($SLITAZ/wok-hg) and one build wok
($SLITAZ/wok). In this way it is easy to compare both woks
and get modifications. If you already have a cook environment, you must
move your wok before setting up the Cooker or it will complain. Setup
will also install a set of development packages that can be configured
in the cook.conf configuration file and the variable SETUP_PKGS, plus
mercurial, rsync and tazlito, and clone the flavors repo. To setup your
cooker environment:
# cooker setup
If all went well you now have 2 woks, base development packages installed and all needed files created. The default behavior is to check for commits, you can run a test:
# cooker
Cooker cook
Again, 2 ways to work now: make changes in the clean Hg wok and launch the cooker without any arguments or cook packages manually. The cooker lets you cook a single package or all packages of a category or a flavor. You can also try to build all unbuilt packages, but be aware the Cooker was not designed to handle thousands of packages.
To cook a single package which is the same as cook pkgname
but with more logs:
# cooker pkg pkgname
To cook more than one package at once you have different kind of choices. You can use an existing package list such as used for Live flavors, you can also use a custom list using the package names listed line by line. You can build all packages of a category, all the packages that depend on a package, or all unbuilt packages.
# cooker flavor [name] # cooker list [/path/to/cooklist] # cooker cat [category] # cooker reverse [pkgname] # cooker all
The Cooker lets you also recook a specific Hg revision. It's useful in production so that if the Build Bot was interrupted while cooking commits, you can then cook packages manually:
# cooker rev 9496
Blocked packages
Cook and the Cooker handle a file with a list of blocked package so they will not cook when commits happen or if a cooklist is used. This is very useful for a Cooker Build Bot in production. When you block or unblock a package you can add a note to the cooknotes. Blocking packages example:
# cook pkgname --block # cooker block pkgname # cooker -n "Blocked pkgname note"
The list of blocked packages are also displayed on the Cooker web interface. To unblock a package you have to use the unblock command or cook --unblock option:
# cook pkgname --unblock # cooker unblock pkgname
Cooker CGI/Web
To let you view log files in a nice way, keep trace of activity and help find errors, you can use the Cooker Web interface installed by default in /var/www/cgi-bin/cooker (with a /var/www/cooker link). If you don't use a chroot and the Busybox httpd web server is running, the web interface will work without configuration and should be reachable at: http://localhost/cooker/cooker.cgi
If you used a chroot environment, you should also install cookutils on your host and modify the SLITAZ path variable. A standard working way is to have a chroot in:
/home/slitaz/cooking/chroot
With /etc/slitaz/cook.conf modified as below:
SLITAZ="/home/slitaz/cooking/chroot/home/slitaz"
Note: It's not obligatory to install the cookutils on your host to use the web interface. If you use Lighttpd you can also copy the cooker.cgi and style.css files for example into your ~/Public directory and use a custom cook.conf with it. The advantage of installing cookutils on the host is to get regular updates via the Tazpkg packages manager. Say you have cloned or downloaded the cookutils:
$ cp -a cookutils/web ~/Public/cgi-bin/cooker $ cp -f cookutils/configs/cook.conf ~/Public/cgi-bin/cooker
Edit the configuration file: ~/Public/cgi-bin/cooker/cook.conf to set your SLITAZ path and you're all done!
Cooknotes
The cooknotes feature lets you write small personal notes about packaging and is useful for collaboration. The cooknotes was coded to let the SliTaz Cooker bot maintainers share notes between themselves and other contributors. The Cooker can block a package's build or recook packages manually, for example it's nice to make a note if a package is blocked so that the maintainer knows why admin did that. Cooknotes are displayed on the web interface and can be checked from a cmdline:
# cooker note "Blocked pkgname due to heavy CPU load" # cooker notes
Cooker as a Build Bot
The Cooker is designed to be a Build Bot for SliTaz, this means it monitors 2 woks, updates the Hg wok, gets the differences and cooks all packages that have been committed. The safer and cleaner way to run the Cooker as a Build Bot with cron is to use a chroot environment, but it can run directly on the host if you want.
To run The Cooker automatically you must use cron from the chroot. The
setup-cron command adds the jobs to the root crontab
(/var/spool/cron/crontabs/root) and restarts crond. Say you would like
to run the Cooker every 2 hours:
# cooker setup-cron 2 # cooker check-cron
It does not run the Cooker directly: every 2 hours cron touches
$CACHE/cooker-request, and a job run every 5 minutes starts
the Cooker when a request is pending. Another job cooks the packages
listed in $CACHE/recook-packages, which the web interface
fills.
Cooker BB started at boot
The Cooker environment and cron task can automatically be started at boot time. You must have the cookutils-daemon installed on the host and use a standard SliTaz installation to make it work properly (cooking goes in /home/slitaz/cooking). The daemon script will mount any virtual filesystems if needed as well as source and packages. Source files are in /home/slitaz/src and bound into the chroot so you can share package's sources between several versions (stable, cooking, undigest). If the package is not yet installed:
# tazpkg get-install cookutils-daemon
To start the daemon you must have a cron file definition for root in the chroot, the daemon script works like all other system daemons and can be handled with:
# /etc/init.d/cooker [start|stop|restart]