User Tools

Site Tools


The GNU Minix 3 build system for cross-compilation

The new build system is a remake of the previous one using GNU make (gmake) to allow compilation of minix on various system using various compilers. The goal is to make development as simple as possible.


  • Compilation with other compilers (not only ACK) on Minix and other systems (Linux, BSD, …)
  • Everything is built from the top level Makefile
  • A quiet mode is used by default to reduce the amount of printed messages (e.g. to expose warnings). Verbose mode is available for tracking what actions are taken during the build process
  • Elf-based as well as a.out-based output
  • All dependencies are generated on the fly (no need for a separate “depends” target)
  • Switch from the default ack assembly syntax to gnu syntax as more compilers can process i
  • Tested with icc (Intel C compiler)
  • Tested with clang and llvm-gcc compilers
  • Experimental support for cross installation
  • Experimental support for LLVM passes
  • tested on 64-bit Linux


How to get it

svn checkout

Compiling on Linux

  • Make sure that yacc and flex are installed. On Debian and Ubuntu, the former can be installed from the package called bison.
  • Building a bootable image on Linux using the default gcc :
make all
  • Using different gcc :
CC=gcc-4.1 make all

Compiling on FreeBSD

  • Follow the Linux instructions using gmake

Compiling on Minix

  • Building a bootable image on Minix using ack (default) :
  • As all assembly which is compiled by gcc as well as ack is now translated to gnu (at&t) syntax, the new version of asmconv tool must be installed to convert the gnu assembly to ack on the fly :
cd commands/i386/asmconv
gmake /usr/lib/asmconv
  • And here we go :
gmake all
  • To build an image using gcc on Minix, a libgcc library without leading '_' is required. It is easily generated like this :
cd /usr/gnu/lib/gcc/i386-pc-minix/4.1.1/
objcopy --remove-leading-char libgcc.a libno_gcc.a
  • Building a bootable image on Minix using gcc :
CC=gcc gmake all

If running out of space because there is not much space in /tmp (e.g. the root partition is small) set TMPDIR to point to a directory on a more spacious partition

TMPDIR=/usr/tmp gmake all

Installing the new image

Copy the resulting image.aout to the /boot/image directory of your Minix installation

Build system options

< tableheight=“87px”>CC compiler to use (e.g. CC=gcc)
V=1 turns on the verbose mode
SERIAL_CONSOLE=clone only clone or redirects all output to serial console (for debugging)
BOOT_IMAGE_TYPE=aout elf selects the output format used. aout is default and the only well supported so far
TMPDIR selects directory for temporary files
CROSS_COMPILE cross-compiler prefix

Makefiles format for userspace programs

To compile userspace programs in the Minix tree the Makefile in each directory has to include from the root directory. This sets up the environment for the build, e.g. how to generate dependencies, convert from ELF from a.out, or link the final target.

include $(ROOT)/

The environment expects some variables to be set :

TARGETS contains names of the final binaries to build (targets):

TARGETS := anm asize

OBJS-<target> tells the system which object files to generate for each target :

OBJS-anm := anm.o rd.o rd_arhdr.o rd_bytes.o rd_unsig2.o

OBJS-asize := asize.o

To change the compilation parameters add options to he standard variables like CFLAGS or LDFLAGS. It is highly recommended to use += as some defaults are already set by the system, e.g. where to get system includes etc.


To generate dependencies for extra object files, set the OBJS variable. These extra object files are not linked to anything by default unless they are used in other rules in the Makefile in case of a more complex compilation.

Cross compilation

Cross compilation is an experimental feature and not really required when compiling on x86-32. The cross-compilation mode is triggered when CROSS_COMPILE is set to the cross-compiler prefix. It also assumes that gcc is the compiler of your choice.

How to build a cross-compiler

Cross installation

Cross installation is another experimental feature that allows you to install the output of a build to a different system. The following command

CI_HOST=my.minix.machine make cross-install

copies over and installs all the commands, drivers, servers, and the boot image to the host my.minix.machine. It is assumed that the host my.minix.machine is reachable, has a compatible Minix distribution installed, and the Minix source tree already compiled in /usr/src. To selectively install single components, use the targets: cross-install_drivers, cross-install_servers, cross-install_commands, cross-install_image.

clang / llvm-gcc

CC=clang make clean all


CC=llvm-gcc make clean all

Minix in this branch is now compilable with clang and llvm-gcc compilers. You can use one of them as a drop-in replacement for gcc.

LLVM passes

The support for LLVM passes has been integrated in the toolchain for this branch. This only works in cross-compilation mode for now. Everything is still experimental and relatively slow, but will be faster in the future with a more tight integration with LLVM. For this to work, you need a recent version of LLVM installed (tested with LLVM 2.6 on Linux) including a valid LLVM frontend (e.g. llvm-gcc or clang). We support both LLVM compile-time passes and link-time passes over the entire OS code (libraries, servers, drivers, kernel). An exception is LLVM link-time pass for the kernel, which is not yet functional. To run a compile-time pass or link-time pass use:

LLVM_CPASS=<pass> CC=<frontend> make clean all


LLVM_LPASS=<pass> CC=<frontend> make clean all

where <pass> is a built-in or custom LLVM pass, and <frontend> is a valid LLVM frontend (tested with llvm-gcc 4.2.1 and clang 1.1). For the list of built-in passes or how to write a custom LLVM pass, see the LLVM documentation. Multiple passes, e.g. <pass>=-inline -adce, are also allowed. To run a compile-time pass and a link-time pass at the same time, specify both LLVM_CPASS and LLVM_LPASS or use LLVM_PASS if the set of passes is the same in both cases.

To see what happens behind the scenes and for debugging purposes in general, use the additional LLVM_DEBUG variable. Valid options are 0 (default, no LLVM debug), 1 (verbose output), 2 (verbose output + unoptimized and easy-to-read bitcode/code), 3 (verbose output + optimized code generation).

Be aware that the current toolchain supports LLVM link-time passes with incremental linking. As a result, not only are all the assembly files excluded from the link-time pass (as they normally would), but also all the .c files that are only referenced by assembly code at linking time. This limitation will go in the future with a more tight integration with LLVM.


  • Not all commands get compiled
  • Not all libraries are recompiled when using ACK
  • install and cross-install targets not tested
  • Set 'TMPDIR=/usr/tmp' in the makefile
  • Install asmconv in '/usr/bin'
  • Install target for ACK
  • Faster and more comprehensive LLVM passes with custom LTO
  • LLVM link-time pass for the kernel
releases/3.2.0/developersguide/newbuildsystem.txt · Last modified: 2014/11/14 18:15 by lionelsambuc