Install packages required for building Debian packages with Docker

These instructions assume that you have sudo rights and that you can execute bash scripts on your machine. You can build the Machinekit-HAL debian package this way which can be then installed on target machine by the apt utility. You will also need to have installed Git executable and for container specific instructions also Docker CLI and Docker daemon. Directions for both can be found in Set up common development environment for all Machinekit projects.

Another dependency is the Python SH module which is extensively used in the Python 3 scripts functioning as wrappers around the calls to programs actually doing the build. The official documentation has a tutorial how to install it by invoking Pip, but for standard Debian system you can just get it by running standard APT installation:

sudo apt install python3-sh

After test that you can successfully use Python SH by running:

machinekit@machinekit:~$ python3
Python 3.7.3 (default, Dec 20 2019, 18:57:59)
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import sh
>>> sh.whoami(_output_tty=False).strip()

This is all you actually need for building Machinekit-HAL Debian packages in Docker containers.

Get and build the Debian packages

Download (clone) the latest Machinekit-HAL repository locally and navigate to its folder.

git clone
cd machinekit-hal

Now we need to build the Docker images used as builders in following steps. We will discuss only native building of the Docker images as the system is as of time of writing this not adjusted to compiling multiarch Docker images with QEMU (Docker blog). However, you can try on your own, but be aware that there is a bug which will cause a certificate validation error when using SSL with curl.

Invoke the scripts/ script with arguments:


Where DISTRIBUTION is the Operating System for which you want to assemble the packages (currently only Debian is supported), VERSION is the version of the Operating system (currently supported are Stretch and Buster, respective 9 and 10) and ARCHITECTURE is the so-called HOST_ARCHITECTURE on which you want to install the built packages. Operatively, you can also pass the -d PREFIX option, which defines the PREFIX of the image tag.

When the ARCHITECTURE is the same as the architecture of the system on which you are building the Docker images, you are natively compiling the packages. Otherwise, you are cross-compiling the packages. Cross- compilation is currently supported from amd64 to one of i686, armhf or arm64 by Machinekit organization. Cross-compilation between other architectures (for example from arm64 to amd64) is on the best effort basis and dependent on upstream Operating system support. Machinekit-HAL build flow abstract away the differences between cross-compilation and native compilation.

Building new Docker image will take few minutes (depending on your internet connection probably about 10 minutes). After successful build new image named ${PREFIX}/machinekit-hal-${DISTRUBUTION}-builder-v.${ARCHITECTURE}_${OS_VERSION_NUMBER}:latest will be created. For example machinekit-hal-debian-builder-v.arm64_10:latest with invoking a call to scripts/ Debian Buster arm64.

Now we need to bootstrap the Machinekit-HAL repository with call to:

docker run -it --rm -u "$(id -u):$(id -g)" -v "$(pwd):/home/machinekit/build/machinekit-hal" -w "/home/machinekit/build/machinekit-hal" ${PREFIX}/machinekit-hal-${DISTRUBUTION}-builder-v.${ARCHITECTURE}_${OS_VERSION_NUMBER}:latest debian/bootstrap

Then we need to configure the Machinekit-HAL repository with call to:

docker run -it --rm -u "$(id -u):$(id -g)" -v "$(pwd):/home/machinekit/build/machinekit-hal" -w "/home/machinekit/build/machinekit-hal" ${PREFIX}/machinekit-hal-${DISTRUBUTION}-builder-v.${ARCHITECTURE}_${OS_VERSION_NUMBER}:latest debian/ -c

This step will create the changelog file (as specified by the -c flag option).

As a last step we need to cd to a parent directory (making sure the current user has a write access rights) and execute the build (we are presuming that the Machinekit-HAL repository is in directory machinekit-hal):

docker run -it --rm -u "$(id -u):$(id -g)" -v "$(pwd):/home/machinekit/build" -w "/home/machinekit/build" ${PREFIX}/machinekit-hal-${DISTRUBUTION}-builder-v.${ARCHITECTURE}_${OS_VERSION_NUMBER}:latest /bin/bash -c "debian/; cp ../*.deb ."

This step will create multitude of .deb or .ddeb packages in the current working directory.

Install packages required for building from source

This is called Run-In-Place build and it means that Machinekit-HAL will be build in the source-tree (from which it will also need to be run).

These instructions assume you have a pristine Debian installation, and you have made sure you have sudo rights. Do not build Machinekit-HAL as the root.

If you have previously installed the machinekit* runtime packages, make sure you have completely removed all the runtime packages before you continue. To do so, execute sudo apt-get remove --purge machinekit* .

As a first step, clone Machinekit-HAL, cd into the root of Machinekit-HAL repository and bootstrap it:

git clone
cd machinekit-hal

If you don’t have build package installed, install it by following the official Debian wiki. You may also need to have installed the official][Machinekit dependencies repository], install it by following the instructions.

Then install all build dependencies for your architecture by running mk-build-deps:

mk-build-deps -irs sudo

Now you should have all needed dependencies and tools installed on your system. You should be able to cd into the src folder and run and configure script:

cd src
# for the Beaglebone, add --with-platform-beaglebone to ./configure
# for the Raspberry2, add --with-platform-raspberry to ./configure

You should see on standard output that everything was configured correctly and you can actually build the software. So now invoke make and make setuid:

sudo make setuid

Now everything should be compiled. Please, check it!

# this script checks for missing configuration files
# and will give hints how to remedy:

If you wish to run this installation by default, add the next lines to your ~/.bashrc file, so that every new terminal is set up correctly for running Machinekit-HAL.

echo 'if [ -f ~/machinekit-hal/scripts/rip-environment ]; then
    source ~/machinekit/scripts/rip-environment
    echo "Environment set up for running Machinekit-HAL"
fi' >> ~/.bashrc

However, if you are installing a RIP build onto a system that already has a version of Machinekit* installed as a binary install from packages, or has other RIP builds, you should invoke from the root dir of the RIP,

. ./scripts/rip-environment

only in terminal sessions where you specifically want to run this RIP.

Users who wish to invoke machinekit-hal (built with Xenomai 2 threads enabled) on a Xenomai 2 realtime kernel must ensure they are members of the xenomai group. If that wasn’t already done when installing the kernel, then add each such user now

sudo adduser <username> xenomai

Logout and login again thereafter. (Machinekit-HAL supports only the 2.x version of Xenomai. For most uses use the Preempt_RT patched kernel only.)

To build both Machinekit-HAL and Machinekit-CNC in one step, please be advised that this is currently not possible. The development on that front is continuing and hopefully this will be possible in short while.

A Note on machinekit.ini and the MKUUID

Since inception, /etc/machinekit/machinekit.ini has contained a hard coded UUID under the 'MKUUID=' field

This despite the text above it stating that all machines should have a unique MKUUID to enable the zeroconf browsing for particular instances to work.

This has now actually caused problems, with some users exploring the networked communications aspect of machinekit, as perhaps it was originally envisaged.

So, from 16th Jan 2019 onwards, there are a couple of wrinkles to be aware of, if you actually intend using the MKUUID for anything.

RIP builds

A fresh clone will generate a new UUID when built. If you want to use a particular UUID, keep it in a separate system file called /etc/machinekit/mkuuid [1] and manually edit ${RIP_DIRECTORY}/etc/machinekit/machinekit.ini to use it. When you rebuild the machinekit.ini UUID will be preserved, however be aware doing a complete ' git clean -xdf && ./ && ./configure' will wipe it.

([1] For RIPs, this file is just a suggested fail-safe storage option for now, it will actually be used by package installs)

Package installs

A package installation onto a blank system will generate a new UUID.

If you are updating and do not purge your configs:

  • If the package finds an /etc/machinekit/mkuuid file [1], it will use the MKUUID within if valid, over any other option.

  • If machinekit.ini exists with a valid UUID, it will use that. Otherwise, it will update with the generated UUID.

  • If machinekit.ini is missing even though the previous package was not purged, it will generate one with a valid UUID.

For the vast majority of users, this change will have no impact, their configs just use whatever UUID is in machinekit.ini, if at all, without consequence.

Additional runtime packages you may need


Documentation has been almost completely split from the Machinekit-HAL build.

Drivers and components built with comp or instcomp, can still be configured to provide documentation for those items only using

./configure --enable-build-documentation

when building Machinekit-HAL.

The complete documentation is available as below, so this option is only really of interest to developers writing components who wish to check the generated manual page for it.

Additional runtime packages

The above steps outline only the build requirements. There might be some runtime support packages missing if machinekit was never installed before.

The easiest way to fetch all the machinekit runtime packages is to install a current package, and then delete it - the process pulls in all current runtime prerequisites:

sudo apt install machinekit-hal
sudo apt remove --purge machinekit*