This page describes an effort at cross compilation using GNU make. The currently supported method uses BSD make and is described in [[DevelopersGuide:Crosscompiling]].
====== 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 ==== * Compilation with other compilers (not only [[http://en.wikipedia.org/wiki/Amsterdam_Compiler_Kit|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 * [[http://en.wikipedia.org/wiki/Executable_and_Linkable_Format|Elf-based]] as well as [[http://en.wikipedia.org/wiki/A.out|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 ([[http://en.wikipedia.org/wiki/Intel_C%2B%2B_Compiler|Intel C compiler]]) * Tested with [[http://en.wikipedia.org/wiki/Clang|clang]] and llvm-gcc compilers * Experimental support for cross installation * Experimental support for LLVM passes * tested on 64-bit Linux ====== HOWTOs ====== ==== How to get it ==== svn checkout https://gforge.cs.vu.nl/svn/minix/branches/src.r4508.buildsystem ==== 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 ====== 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 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 ==== |<878px>| |< 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-** 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|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= CC= make clean all or LLVM_LPASS= CC= make clean all where //// is a built-in or custom LLVM pass, and //// 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. //=-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 ===== * 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