Nuxi CloudABI for Debian, Ubuntu and other Debian derivatives

Though CloudABI has initially been developed on FreeBSD, a fairly complete implementation for the Linux kernel has also been developed.

This document explains how to develop software for CloudABI on Debian-based systems and how these systems can be configured to run this software. Right now this still requires you to perform a significant number of manual steps, but work is underway to streamline this process by packaging and upstreaming most of these components.

1. Installing a C and C++ compiler for CloudABI

CloudABI uses a toolchain based on LLVM, Clang and LLD for building C and C++ software. CloudABI is supported out of the box by LLVM 3.7.0 and later. The following commands show how to install Clang and LLD, version 4.0:

$ sudo apt-get install clang-4.0 lld-4.0 ... The following NEW packages will be installed: binfmt-support clang-4.0 libclang-common-4.0-dev libclang1-4.0 libffi-dev libjsoncpp1 libobjc-6-dev libobjc4 libtinfo-dev lld-4.0 llvm-4.0 llvm-4.0-dev llvm-4.0-runtime ... Do you want to continue? [Y/n] y

After installing LLVM, we can create a number of symbolic links that point to the utilities provided by LLVM, having the CloudABI cross compilation target prefixed to their name. LLVM automatically acts like a cross compiler for CloudABI when invoked through these symbolic links.

for target in aarch64-unknown-cloudabi armv6-unknown-cloudabi-eabihf \ i686-unknown-cloudabi x86_64-unknown-cloudabi; do for tool in ar nm objdump ranlib size; do sudo ln -s ../lib/llvm-4.0/bin/llvm-${tool} /usr/bin/${target}-${tool} done sudo ln -s ../lib/llvm-4.0/bin/clang /usr/bin/${target}-cc sudo ln -s ../lib/llvm-4.0/bin/clang /usr/bin/${target}-c++ sudo ln -s ../lib/llvm-4.0/bin/lld /usr/bin/${target}-ld sudo ln -s ../../${target} /usr/lib/llvm-4.0/${target} done

The commands above set up the Clang C and C++ compiler for every architecture supported by CloudABI, thus making it very easy to cross compile software for other hardware:

$ ls /usr/bin/*-unknown-cloudabi*-{cc,c++} /usr/bin/aarch64-unknown-cloudabi-c++ /usr/bin/aarch64-unknown-cloudabi-cc /usr/bin/armv6-unknown-cloudabi-eabihf-c++ /usr/bin/armv6-unknown-cloudabi-eabihf-cc /usr/bin/i686-unknown-cloudabi-c++ /usr/bin/i686-unknown-cloudabi-cc /usr/bin/x86_64-unknown-cloudabi-c++ /usr/bin/x86_64-unknown-cloudabi-cc

2. Accessing the CloudABI Ports Collection

The CloudABI Ports Collection provides copies of precompiled libraries that you can use to build complex CloudABI applications. Software that is part of the CloudABI Ports Collection is automatically packaged for a variety of systems, including Debian's apt-get.

The CloudABI Ports Collection can be accessed by adding both a repository to sources.list and a public signing key to apt-get's keyring:

$ sudo apt-get install apt-transport-https $ echo deb cloudabi cloudabi | sudo tee /etc/apt/sources.list.d/cloudabi.list deb cloudabi cloudabi $ wget -qO - '' | sudo apt-key add - OK $ sudo apt-get update Hit cloudabi InRelease Hit cloudabi/cloudabi amd64 Packages ...

It typically makes sense to at least install the standard C++ runtime environment package, so that it is possible to compile C and C++ applications that depend on just core C, C++ and POSIX interfaces:

$ sudo apt-get install x86-64-unknown-cloudabi-cxx-runtime ... The following NEW packages will be installed: x86-64-unknown-cloudabi-cloudlibc x86-64-unknown-cloudabi-compiler-rt x86-64-unknown-cloudabi-cxx-runtime x86-64-unknown-cloudabi-libcxx x86-64-unknown-cloudabi-libcxxabi x86-64-unknown-cloudabi-libunwind ... Do you want to continue? [Y/n] y

A full list of packages provided by the CloudABI Ports Collection can be obtained by running the following command:

$ grep -h ^Package: /var/lib/apt/lists/* | sort -u Package: aarch64-unknown-cloudabi-boost Package: aarch64-unknown-cloudabi-bzip2 Package: aarch64-unknown-cloudabi-c-runtime Package: aarch64-unknown-cloudabi-cairo ...

3. Executing CloudABI applications

Our eventual goal is to provide support for CloudABI in the form of a kernel module that can be used in combination with a stock Linux kernel. Unfortunately we still depend on a fair number of local changes to the kernel that need to be upstreamed first, meaning that support for CloudABI is currently only available in the form of a modified Linux kernel with integrated CloudABI support.

The following instructions show how this kernel can be checked out, built, packaged and installed, all using the standard Debian kernel build scripts:

$ sudo apt-get install fakeroot git libssl-dev kernel-package $ git clone Cloning into 'linux'... $ cd linux $ git branch -l * cloudabi $ cp /boot/config-$(uname -r) .config $ make oldconfig ... Enable clone4() system call (CLONE4) [Y/n/?] (NEW) y Enable CLONE_FD flag for clone4() (CLONEFD) [Y/n/?] (NEW) y ... Kernel support for CloudABI ELF binaries (BINFMT_ELF_CLOUDABI) [N/y/?] (NEW) y ... Capsicum capabilities (SECURITY_CAPSICUM) [Y/n/?] (NEW) y ... # configuration written to .config $ make-kpkg clean $ fakeroot make-kpkg -j4 --initrd --revision=1.0.cloudabi kernel_image ... dpkg-deb: building package 'linux-image-4.5.0-rc1-capsicum+' in '../linux-image-4.5.0-rc1-capsicum+_1.0.cloudabi_amd64.deb'. $ sudo dpkg -i ../linux-image-4.5.0-rc1-capsicum+_1.0.cloudabi_amd64.deb Selecting previously unselected package linux-image-4.5.0-rc1-capsicum+. Preparing to unpack linux-image-4.5.0-rc1-capsicum+_1.0.cloudabi_amd64.deb ... ... done $ sudo reboot

After rebooting, CloudABI executables can be executed directly:

$ cat hello.c #include <stdio.h> int main(void) { dprintf(1, "Hello, world\n"); } $ x86_64-unknown-cloudabi-cc -o hello hello.c $ ./hello Hello, world

It also makes sense to install the cloudabi-utils package that contains the cloudabi-run utility. This tool can be used to spawn CloudABI applications safely, ensuring that no resources are accidentally leaked into the process. It can be installed as follows:

$ sudo apt-get install build-essential cmake git libyaml-dev pkg-config $ git clone Cloning into 'cloudabi'... $ sudo install -m 444 cloudabi/headers/* /usr/local/include/ $ git clone Cloning into 'argdata'... $ cmake . $ make ... [100%] Linking C shared library [100%] Built target argdata $ sudo make install $ cd .. $ git clone Cloning into 'cloudabi-utils'... $ cd cloudabi-utils $ cmake . $ make ... [100%] Linking C executable cloudabi-run [100%] Built target cloudabi-run $ sudo make install ... -- Installing: /usr/local/bin/cloudabi-run $ sudo ldconfig

The shell commands below show how cloudabi-run can be used to execute the CloudABI test suite. Please refer to cloudabi-run's manual page for more examples.

$ mkdir tmp-unittest $ cloudabi-run /usr/x86_64-unknown-cloudabi/bin/cloudlibc-unittests << EOF %TAG !,2015:cloudabi/ --- tmpdir: !file path: tmp-unittest logfile: !fd stdout nthreads: !!int 8 EOF