any-guide – step-by-step tutorial on any(1), the build system for POSIX programs.


any is the tool to build and maintain software in a distribution. It allows to form binary packages for your operating system on your own. The packages are correctly incorporated and administered. Your software will be symmetric to the content of operating system distro and will not cause troubles of command sudo make install, stated in many tutorials on autonomous building from source.

The any engine does not rely on features of specific distro. It is written in shell and POSIX utilities, so it is highly portable between environments, requires minimum dependencies and does not need the compilation. Installation to system directories is not required as well (though possible). The build occurs inside local directory of a plain user. To begin the work just unpack the release archive.

any is not additional package management system like pkgsrc from NetBSD, working in parallel with original one. any does package building for already existing package management systems. At the moment the following formats of binary packages are supported:

for Linux distros Debian, Ubuntu and their derivatives;
for Linux distro Slackware;
plain tgz
binary files in plain compressed tar-archive.
In other distros and operating systems the build will work with packaging of results into plain tgz archives, without integration with system package manager.

There may be support of other formats in the future. Each format is implemented in separate module with determined interface. Such modules can be added apart from each other.

The build is executed through shell scripts, called anybuilds (.build). any provides API for typical actions during the build, along with flexible tuning depending on configuration, platform and wide range of conditions. API functions are implemented in engine libraries separately from outer filesystem and environment. With given approach the work with any is close as much as possible to literal execution of classic commands:

        make install
Meanwhile the user gets functionality, automatization and flexibility, unavailable previously.

any localizes its work inside directory, chosen by the user inside his home catalogue. There is no writing to system directories like /var/, /tmp/. Likewise git(1) works with repositories of sources, and IDE creates project directory. The files of a project are stored in each created working directories. You may create several working directories at the same time for various projects, make independent changes there - they will not interfere with each other.

Besides direct building, any includes tools for version accounting, tracking of dependency trees, checking on correctness of archives contents by given rules, and other maintenance tasks.

The engine allows to support software autonomously with the aprroach, adopted for distros. It may be useful for:

a person, willing to fix or modify the package in his operating system;
an application developer.
He recieves the tool for coherent distribution of his product to a number of operating systems and platforms. Herewith he does not depend on system developers, maintaining each of that platforms.
authors of their own distro of full fledged software platform.

Configuring the machine


Contents for source building occupy quite a plenty of disk space. Sensible minimum for non-large projects amounts to about 10 GB.

The build rate depends significantly on the bandwith of the disk system. The usage of SSD, NVME disks delivers noticeable improvement of build times.

Build environment

To execute first build commands from this guide, where there is no chrooting, you will need the compiler and basic includes, installed at your main system. They may be absent by default.

The installation of the named components depends on operating system you use. For Linux family, based on Debian or Ubuntu infrastructure, the installation may look like so:

        apt install gcc clang libc6-dev

Users permissions

If you do not plan to use isolation of build environment, the system does not require any additional permissions in regard to an account of plain user.

For environment isolation you will need corresponding permissions. Default settings in this guide use launch of sudo chroot. Your user should be granted the privileges for that command.

Optional functionality in build commands require privileges for sudo mount, sudo umount. It is avoidable.

Other mechanics of program isolation are usable, they will require their own permissions.

Directory installation and configuration

The creation of new directory for the work with any comes down to plain unpacking of one or several archives with its contents.

Availability of build commands, shipped with program, is required.

It is possible to launch them directly from working directory without installation.
The build commands may be installed permanently into dedicated location inside home directory or into the operating system. In case of installation by scenarios above the build commands will be available regardless of the state of individual working directories.

The creation of working directory is done anew for each project.

Preparation of main directory

Download the archive with the release of any (
Unpach the archive:
                tar xzf any-<version>.tgz
Rename the directory into your project name.
                mv any-<version> dev_dir
Get inside.
                cd dev_dir/

Preparation of executables

As the build system is completely installed into each working directory, the easiest way is to set up paths there:

        export PATH=$(pwd)/rrr/bin:$PATH
The given command should be executed in each terminal session, where build actions are needed. All needed components will be taken from local directory.
The method above fits well, if there is just single project at the machine and it does not change its location.

Default project

In the following guides the examples would be from Linux From Scratch project. Scripts for that distro are provided in a release of any as spectacular implementation of complex build project with the given system.

To install LFS as the default project:

        mkdir -p ports/
        cp -Rf lfs/ports/* ports/

In case of usage of another project, you should install it into ports/ instead of LFS:

        mkdir -p ports/
        cp -Rf another-project/ports/* ports/

Advanced configuration

Configuration above is fairly enough for generic cases. You better skip the section below, unless you face complex usage cases.

Extensions, updates

According to your aims you may need additonal stuff: build files of new projects, host environment, toolchain. All that stuff, distributed along with any, has plain archives format and is installed by plain unpacking into root of working directory:

        tar xzf additional-pack.tgz
The stuff update goes with similar unpacking, unless instructions with new archives do not say something different.

Files from other sources and vendors may require other steps for installation. For example, archive files are located in nested directory, named after the archive. In that case it is needed to move them to the root of working directory:

        tar xzf new-toolchain.tgz
        mv new-toolchain/* .
        rmdir new-toolchain

Installation of engine commands

If there are several projects, they are moving or several machines are in use, then it is more preferable to install commands permanently. The installation of engine into home directory, default prefix ~/rrr/:

Executables will be located at ~/rrr/bin/. To make them available for launch, the path ~/rrr/bin/ should be added to the variable PATH in the settings file of your shell. In common case it is the file ~/.profile, depending on used shell it could be ~/.zshrc, ~/.bashrc, ~/.kshrc and so on. Add the string to the end of the file:

For installation into another home subdir:

        ./ DESTDIR=~/other/dir
The example above needs to add the path ~/other/dir/bin/ to the variable PATH in a similar way.

For installation into system directory:

        sudo ./ DESTDIR=/opt/any
Executables will be located at /opt/any/bin/ for the example above.

New directory with anyinit

After the command any has become available (with temporal setting to working directory or with permanent installation), you may create new working directories with the command anyinit(1):

        anyinit my_dir
        cd my_dir
The given command creates a new directory from preinstalled template. The template is stored inside personal user or global system directory.

If the project uses specialized extensions of the build system, this command may implement the creation of directory from remote servers and repositories. It is possible for the new directory to fetch automatically new host environment, toolchain and other base components, needed for the project.

Data extraction

There may be useful data for the project, which is not distributed as tar archives and is not installed with simple unpacking. The example is install images .iso or directories with binary archives repositories. One may extract libraries from such entities, which will be used as dependencies in your build.

Types and formats of such data sources may differ for each project. There is the form of typical script for the extraction of data from outer sources to the working directory. If it is present in your directory, launch it and study its usage.

        ./any/bin/ --help
It will print expected input arguments for supported archives, images or directories, which are available for extraction into the working directory.


After commands of the build system have become available for you, you may view local manual pages:

        any man <subject>
The command any-man(1) will display man-documentation, referring to the build system and residing in local directory. Its syntax is the same as of system man(1).

Local documentation in HTML format is placed at doc/html/index.html.

Build project

Build project:
product or concept, developed by the user. The project is defined with configuration set, used modules of build system, included package base, and also general development politics, accepted inside.

Working directory:
separate directory with all stuff for the build. It contains sources, build directories, all temporary files, built binaries, install-ready archives and the copy of build system itself.

It is possible to create several workind directories for single project and work independently in each one.

The build is intended for users with permissions on container usage, one of implementations. In case of the current guide that is chroot(1) command. Other tools of program isolation are possible as well.

Build process does not influence the filesystem outside the working directory. Different users on a single machine may create arbitrary number of working directories.

In ports/ directory all sources are gathered with reference to the current project. At most they are package stuff: sources, patches, anybuilds, auxiliary information to form the packages and maintenance.

The rdd.conf.d/ directory and the rdd.def file keep all project settings. They are options in form of key=value. The given values set up which platform or set of platforms the project deals with. The platform is defined by the combination: toolchain + operating system + machine architecture. Here are all other settings: which format for binary package is used, which engine modules are included, which checks are done, and many others.

The current guide uses project LFS as an example, which is shipped with any infrastructure. Its contents we had copied into default project directory ports/ while performing the instructions above from the section Default project.

Detailed description of all directories inside working directory is contained in any-workdir(7).

Project configuration

set of all options, included by a project.

It is needed to assign the project configuration before the work. There could be several configurations as well, if you need to work with distro for several platforms inside single working directory.

The main configuration characteristic is its name. In simple case it is a word from latin letters of lower register, digits and underscore symbol _. The examples of the current guide use word default as the main name.
The configuration may be concatenated - its name consists of several words, separated with comma.

The essential definition for configuration content concerns the platform. In the rdd.conf.d/ directory the settings are kept for various toolchains, operating systems and machine architectures. In the rdd.def file there are commented examples of settings like these:

# [default]
# rdd_prf_id = any, amd64, gcc, linux

# [default]
# rdd_prf_id = any, amd64, clang, openbsd

Choose the platform to work with and uncomment the corresponding strings in config:

rdd_prf_id = any, amd64, gcc, linux

After that the name default will engage your needed configuration set.

The current guide provides examples for the configuration:

amd64, gcc, linux
It is possible to follow the guide with other configurations as well, for example:
amd64, clang, linux
amd64, clang, openbsd
In case of choice of alternative configuration the paths and names of files, built by the system, may vary.

It is possible to store the configuration not under the keyword default, but under arbitrary words. For example, you wish to set up the simultaneous work with two platforms, which further requires to assign explicitly one or another platform in commands. That may be done in such a way:

rdd_prf_id = any, i686, gcc, linux

rdd_prf_id = any, amd64, gcc, linux

In the example above one platform is available from command line under the name my32, the second one under the name my64.

With datardd(1) command it is possible to view the values of all options, which are set up for your configuration.

        datardd default
If there are quite a few options, the default configuration is not set up correctly.

For his own configuration names, assigned by the user himself in the example above, data view will be called like this:

        datardd my32
        datardd my64

The settings assignment works by the following scheme:

The key option rdd_prf_id contains new sections of configuration files, which we want to include to our configuration. Section names are separated by comma.

The example: in the initial section [default] there is the string rdd_prf_id = linux. If there is data section [linux] inside all configs from rdd.conf.d/ or inside rdd.def, then options from that section are read and added to our configuration. If the section [linux] contains new assignment of rdd_prf_id, then next section names are read from there. For the names, just recieved and not checked earlier, the search for new sections continues.

In that way by assigning just single word with data (default in the example above), we gather extensive data set via access to linked chains of sections with data. More details about reading of options from config files and command line one can find in any-do(1).

To review all settings, prepared in the engine for different platforms, see file rdd.conf.d/build.conf. It is possible to exploit the rest of platforms, missing in the file above. One should assign explicitly some parameters for them, for example, name of OS or compiler executable.

Review of existing packages

To review all build stuff of the project, one may have a look into the ports/packages/ dir:

        ls ports/packages/
Each package with directory and anybuild inside it is available for the build.

The lspkg(1) utility prints the packages which distinctly concern the project.

        lspkg default
It would print the package names, included in distro and ready for the build at the current configuration. The argument default refers to the default configuration of the project.

Package sets, grouped by some relations, are kept in plain text files in the ports/list/ directory. The files are called lists. There may be arbitrary quantity of them. Comments (the beginning of the string from the symbol #) and empty strings are supported in the lists. Lists serve to assign explicitly the sets of packages with certain purposes: packages with graphics system implementation xorg.src, wayland.src, packages of desktop kde.src, packages for host environment host.src and so on.

The program lspkg(1) reads the given text files and outputs package names one at a string. With the call with single argument, as in the example above, lspkg(1) prints the content of key list ports/list/all.src. That is the file with reserved name all.src, which must contain overall package base, available for the build at the moment.

It is possible to assign another package list to output:

        lspkg default tools.src
In that case packages from the list ports/list/tools.src will be printed.

The difference between the content of ports/packages/ and the file ports/list/all.src:

The list allows to set up explicitly those packages, which are included in release or the distribution of the project.
It is possible to add arbitrary stuff into ports/packages/ (for example, debugging or experimental), but the set of built packages will not be changed from that.
The changes in the content of the project will occur only after the addition or removing of something from text lists in ports/list/.

Review of existing anybuilds

file in shell language (bourne-compatible) with commands to build the package. That is the main technic to form distro projects from separate programs.

For the package zlib-1.2.11 its build will be located here:

Let's examine the contents of the file.

# Copyright © 1999-2017 Gerard Beekmans
# Copyright © 2017-2018 Random Crew
# Distributed under the terms of MIT License.

eval "$(dumpbuild "${@}")"

    ./configure \

    make ${MAKEOPTS}

    make install ${MAKEOPTS} DESTDIR=${D}


First string contains the command interpreter: #!/bin/sh
Mind the usage of more universal variant sh instead of bash. Anybuilds from the following examples do not use the language constructions, specific for bash.

The next string under the comment # contain supplementary information about authors and license.

The string with eval construction is needed for the possibility to launch the anybuild directly from command line like classic script. In that case the call of dumpbuild will load the library data from any build system.
For the majority of examples in the current guide anybuild will not be launched directly, but will be used as a library during the launch of specialized build command. In such a manner the string with eval will not do anything.

The function src_config(3) is dedicated to package configuration. It performs setting, which precedes the main stage of the build. In the given case there is the simple launch of typical script configure with one argument.
The variable PREFIX is set up by the engine. Its value is initialised with option any_program_prefix. That option is already set inside rdd.conf.d/, and it can be changed in file rdd.def or in command string.
The value defaults to PREFIX=/usr

Global variables, set up by the engine, completely consist of capital letters. That way they can be distinguished from local and inner variables. Detailed description of all global variables, representing API, is given in any-api(7). Let's also call such variables the interface ones, as they are part of program agreement, provided by the system.

Why to assign the value of --prefix with variable? It could be assigned directly:

    ./configure \
The main advantage of interfaces in the ability to change the behaviour without editing of connected parts. If there will be a further need to change the value of --prefix, then with direct assignment --prefix=/usr one will need to edit each anybuild (there could be very much of them).
If otherwise the value in anybuild has been assigned with interface variable, then it will be enough for adaptation to change for one time the value of that variable in config file, and changes will be applied centrally to all packages.

The function src_compile(3) launches the main build stage. In the example above that is traditional launch of make. MAKEOPTS is one more interface variable, which contains typical parameters for any launch of make. The example of such parameters - the values for parallelization: MAKEOPTS=-j8
With MAKEOPTS we get centralized management of build parallelization inside single package.

The function src_install(3) installs package stuff into destination dir. The key role in that function plays the variable D. It contains the path to a place of package installation. The path is composed automatically by the engine.
For each package the separate directory D is created, which does not intersect with other packages. After installation it contains only files, belonging to the current package. That property is used afterwards during the creationg of binary archives and build context for other packages.

In the end the function map_direct is called. Likewise string with eval, the given function works only during the direct call of anybuild as an executable script. In that case it launches the entire sequence of the build. With the way of the launch the current guide deals with, the function does not perform any actions.

Build of single package

Launch and results for single package

Let's examine how to launch the build for the package zlib-1.2.11:

        any do default zlib-1.2.11
any do
is the command to launch the build.
is the name of used configuration.
is the name of the package to build (including version).

Data with build session will be printed. At the output the following will be seen: data on a build session, package name and build result. If the build has ended unsuccessfully, the path to the log with happenned events is printed. For the given example the log is written to build/log/amd64/zlib-1.2.11.log.

To output the build log not to a file, but to a screen, it is needed to add word output to configuration:

        any do default,output zlib-1.2.11

If there was no copy of main sources into the working directory, then the build will be terminated with FAIL status, and we will see messages in the log:

Source zlib-1.2.11 for zlib-1.2.11 has not been found.
+ src_config
+ ./configure --prefix=/usr
/bin/sh: 9: ./configure: not found

If you have got the prepared archive with sources of all packages in the project, unpack it to the working directory. You may also fetch the source archive zlib-1.2.11.tar.xz separately and place it into the ports/srcstatic/ dir.

Repeat the build with package sources available. If everything is set up allright, and you have compiler and base libc includes in your environment, the build should finish successfully. After the complete build the following will be found in the working directory:

the build/pack/amd64/zlib-1.2.11-x86_64-linux.tgz file, built installable archive with the package.
the build/image/amd64/zlib-1.2.11/ directory, where binary stuff of the package had been installed. That is the variable D inside anybuild text.
the build/work/amd64/zlib-1.2.11/ directory, where the build has taken place. Object files were compiled there, configure was launching. All intermediate data from the build lie here.
the file with the log build/log/amd64/zlib-1.2.11.log.

Build concept

During the build any performs the next essential steps:

reads the data from configs and command line;
builds the shell script for building. It has all data from options as variables, and it has libraries of the engine with build functions; that is not anybuild from ports/packages/;
saves the given script into file;
calls functions for building in order.

The principle of build process with any remains the same as with manual execution of all needed commands. The difference is just in automatization through functions and in flexible handling of input data.


After the work of any all dynamically generated scripts remain. They are stored in reserved directory var/dump/.

It is possible to use the generated scripts manually from command line. In that case we will recieve in current shell session the same environment as has been available to the build process. Interface variables like D or MAKEOPTS become initialised, the build functions of any-api(7) from libraries are callable.

To execute manually the elements of building the package zlib-1.2.11 in configuration default one needs to execute:

    # 1
    . var/dump/zlib-1.2.11_default/
    # 2
    set +e
    # 3

Command 1 includes the script with build environment, which any has generated. It does not launch any actions by itself, just sets up the variables and includes functions. The given script is generating during the call of any do.
Command 2 turns off the shell mode "exit on error". The given mode is set up by the engine for correct work and timely diagnostics. The mode will disturb during the debug.
Command 3 moves to the directory with package sources, where the build has taken place.

After the actions above we may manually repeat the build commands, interesting to us: launch anew configure, launch separate tests from configure inners, repeat the compilation strings of particular object files and all the rest, useful to us. The shell environment will be identical to the one, used by the engine during the build, when launch of entire process has been done from command line.

It is possible to launch large functions of the anybuild in one piece, if we want to reach step-by-step more late stages:

    # preparation
    . var/dump/zlib-1.2.11_default/
    set +e

    # repeat
    make install DESTDIR=${D}

    # new debug actions

Data and lists

Package lists

It is possible to assign several packages at once in command line for the build.

        any do default zlib-1.2.11,bzip2-1.0.6
They are given as the second argument of command any do, delimited with comma without spaces. There would be built two packages at the single build session in the example above.

For the work with large package sets one may write them into text files, which are stored in ports/list/. They represent package lists by one at a line. The comments with the symbol # at the beginning of a string and empty lines are allowed.

        any do default pack.src
In the example above the build goes for packages from the file ports/list/pack.src.

Lists support nesting: they may contain another lists.

        cat big-list.src


Lists may be united in command string as well:

        any do default pack.src,more.src

The convention on file names: permanent lists end with .src, temporary or generated ones end with other extensions (for example, .txt) .

Data assignment

The given section lists parallel examples with the launch of two commands.

any do
performs the build with assigned data.
allows to view resulting data on the terminal.
Given commands have the same syntax and principles of data assignment.

One may add data into configuration in the following ways:

with command line option:
            any do default zlib-1.2.11 any_newdata=1
            datardd default zlib-1.2.11 any_newdata=1
Options may be put into any position at the command string after the command any do itself.

with the record of a new option into rdd.def:
After that the usual call with configuration default:
            any do default zlib-1.2.11
            datardd default zlib-1.2.11
will cause the section [default] inside config will be read and the new option any_newdata=1 will be added to overall data array.

with adding of a new word to the called configuration:
            any do default,new zlib-1.2.11
            datardd default,new zlib-1.2.11
In that case the section new will be added to the list of sections in configuration files, which will be read. If a configuration file has section [new], all data from there will be added to overall array:
            # something

In the example above the option any_fromfile=1 will be added.

with the record of a new option into one of the configs in directory rdd.conf.d/:
            any do default,new zlib-1.2.11
            datardd default,new zlib-1.2.11
The files from rdd.conf.d/ follow the same conventions as the file rdd.def. The difference between them is: rdd.conf.d/ keeps universal library values, and rdd.def keeps the choice for the current working directory, temporary and debug values.

Data priorities are defined in the following way:

command line options have the highest priority.
data from rdd.def has the next priority. Also the data with sections, specified closer to the right, have more priority. For example:
            any do default,new zlib-1.2.11
            datardd default,new zlib-1.2.11
The value any_conflict=right will be chosen, because the word new is specified closer to the right in command line, the the word default.

The same is applied concerning the rdd_prf_id:

            rdd_prf_id = one, two
The value any_conflict=right will be chosen, as the word two is specified closer to the right in the key option rdd_prf_id.

personal config for a package ports/packages/packagename/atom.conf has the next priority.
data from files rdd.conf.d/*.conf has the next priority. The same order principle behaves for the configs .conf, as for rdd.def.

Along with that all values, read from any section of rdd.def or atom.conf, are not changed anymore by the reading from rdd.conf.d, even by the most priority section. So the working config rdd.def or personal config atom.conf are not influenced by deeply nested data from library files.

See also:

Detailed description of any-do(1).
Low-level details about data reading are listed in rdd(1).
The individual description datardd(1).

Methods call

One may call separate methods from command line:

        any do default zlib-1.2.11 src_config
The name of method is the third argument to any do. The limitation on called methods is the absence of input arguments for a method.

One may call several methods as well:

        any do default zlib-1.2.11 src_config,src_compile

When third agrument is not assigned, by default the key method map is called. It resides in file any/corelib/ and contains sequence of all methods, which are actually performing the build.

Detailed sequence of all actions, happening during the build, is listed in any-map(7).

Environment isolation

One of the severe problems of reliable build is context, influencing the processes of binary packages creating. Uncontrolled context leads to the builds, which are unreproducible and prone to errors. The wider context is and more implicit character it has, the more difficult it is to control and account. Thereby the detection and minimization of context are the tasks of first importance to provide the reliable build.

The underlying technic to control the context is the isolation of environment inside a container. That may be done with varying tools, and chroot(1) became the first of them. Now the other mechanisms for containerisation are available as well. From the point of isolation view they all perform the same: move build process into closed filesystem, composed especially for that purpose. That means not entire operating system affects the build, but the limited and fitted environment instead. We call the following environment as host in the current guides.

The key advantages of host in comparison with building in main operating system:

Host contains needed programs of correct versions. There are no excess programs.
The same host is installed into all working directories - the relation on operating system and machine is much lower.
The host composition may be administered separately for each dir.

Along with advantages host bears complications as well:

The full host environment must be composed and maintained.
Host must match the environment, where the built apllication will work.
Users need the permissions for isolation commands (like chroot(1)).
Host occupies space, its deployment into each working directory takes time.

Ready hosts

You may download the ready to use host at

Build in isolation

Typical command to build in isolated environment:

        anch do default zlib-1.2.11
anch do
the command for isolated build.
default, zlib-1.2.11
arguments of the build in the same format and with the same syntax, as for any do.

The anch program shifts to isolated environment with chroot(1), and performs the next command. anch may launch not only the do command for direct build, but other commands from any set as well.

All conventions and rules for any do, addressed above, are exactly applied on anch do.

Manual chroot

It may be needed quite often to enter the isolated environemnt manually to debug there. Perform that inside the root of working directory:

        sudo chroot `pwd` /bin/sh -l
The option -l is needed for the shell to read the file /etc/profile inside host, leading to the path /rrr/bin added to PATH, which is needed for the work with any.

Settings of isolated environment

While entering the environment with anch command, the specialized scripts are performed:

is launched out of environment before the shifting inside.
is launched inside isolated environment in a separate process before the target command (like do).
is launched out of environment after the target command has finished.
The scripts above set up the host automatically so that filesystem would be suitable for the build: mount virtual filesystems (proc in Linux), create device files in ./dev/.

With the any-choff(1) command one may remove the traces of host settings. The host will become back the usual directory after that without virtual filesystems, device files in ./dev and other such stuff.

        any choff
Before removing of working directory it is required to perform any choff, if the isolated build had been launched there before.

The variables are used with the settings for isolation:

keeps the command to enter the host environment.
Defaults to sudo chroot.
keeps the command to change the user inside host. It is applied to run process inside environment under the same user, as outside.
Defaults to /usr/bin/sudo.

See more details about isolated launches in any-do(1).

Isolation requirements

More or less significant host occupies not less then 1GB in uncompressed state, more probably about 4-5 GB.

To enter the chroot the permissions are required for that command, as it is not available without additional privileges. If you have set up another way of isolation with the PROGCHROOT variable, the required privileges will be changed accordingly.

See also

brief description of typical build tasks.
navigation across the detailed manual documentation of the build system.