Table of Contents

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.

Changes

HOWTOs

How to get it

svn checkout https://gforge.cs.vu.nl/svn/minix/branches/src.r4508.buildsystem

Compiling on Linux

make all
CC=gcc-4.1 make all

Compiling on FreeBSD

Compiling on Minix

cd commands/i386/asmconv
gmake
gmake /usr/lib/asmconv
gmake all
cd /usr/gnu/lib/gcc/i386-pc-minix/4.1.1/
objcopy --remove-leading-char libgcc.a libno_gcc.a
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 Makefile.user.inc 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)/Makefile.user.inc

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.

CFLAGS += -I. -D_MINIX -D_POSIX_SOURCE

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

or

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

or

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.

TODO