Alpine build and packaging
==========================

Alpine build system (abuild) is used for native Alpine linux packages, such as LXC binaries, SPOC and VMMgr virtual machine manager.

Alpine wiki references
----------------------

Usage of abuild, APK (*Alpine Package Keeper*) manager and syntax of ``APKBUILD`` files is best described on Alpine wiki.

- `Abuild and Helpers <https://wiki.alpinelinux.org/wiki/Abuild_and_Helpers>`_
- `Creating an Alpine package <https://wiki.alpinelinux.org/wiki/Creating_an_Alpine_package>`_
- `APKBUILD Reference <https://wiki.alpinelinux.org/wiki/APKBUILD_Reference>`_
- `APKBUILD Examples <https://wiki.alpinelinux.org/wiki/APKBUILD_examples>`_

Abuild in a nutshell
--------------------

Building with abuild requires ``alpine-sdk`` package installed, ``/etc/abuild.conf`` configured and an RSA private key created in ``/root/repo.spotter.cz.rsa`` and subsequently registered by ``abuild-keygen`` command. All these are taken care of in ``install-toolchain.sh`` script as part of `Build environment installation <virtual-machine-creation.html#build-environment-installation>`_.

Abuild toolchain is intended to be used in automated builds, therefore it requires some dependencies normally not found in other packaging systems. Abuild expects that ``APKBUILD`` files are a part of git repository and tries to read current commit hash. Then it tries to automatically download, build (compile), strip symbols binaries, find out dependencies, and generally perform a lot of tasks normally useful when you are compiling binaries from sources. Finally it packages the result to one or more subpackages, according to the build recipe. For purposes of SPOC containers packaging, this is mostly useless, which is the reason why we have a `custom package manager <spoc-overview.html#package-manager>`_. It is however perfectly suitable for packages installed directly on the basic VM.

APKFILE and build example
-------------------------

Following is an ``APKFILE`` example with some commonly used options to skip or bypass the default features of abuild in case you simply need to package a bunch of existing files without any compilation or other build tasks.

.. code-block:: bash

    # Contributor: Disassembler <disassembler@dasm.cz>
    # Maintainer: Disassembler <disassembler@dasm.cz>
    pkgname=somepackage
    pkgver=0.0.1
    pkgrel=0
    pkgdesc="Some description"
    url="https://spotter.vm/"
    arch="noarch"
    license="GPL"
    depends="python3"
    options="!check !strip"

    build() {
        return 0
    }

    package() {
        mkdir -p ${pkgdir}
        cp -rp mydir ${pkgdir}
    }

The directive ``options="!check !strip"`` requests abuild not to run post-build checks and not to strip symbols from binaries. The ``build()`` function is mandated by the abuild documentation and simply returns success exit code without doing anything. Finally in ``package()`` function, the desired existing files are copied to ``${pkgdir}`` (which is a variable automatically set by abuild) and packaged.

Such ``APKFILE`` recipe is then executed using ``abuild`` command. Abuild normally uses ``fakeroot`` to isolate the build environment and discourages using root user for packaging, however our build instance is highly specialized for this purpose, so we package as root anyway. Any user (including root) needs to be a member of ``abuild`` group in order to perform the task. For our root user, this is again handled in ``install-toolchain.sh``. If you do the packaging as root, you need to run ``abuild -F`` as seen in ``build-all.sh``.
