At work we are building systems based on the L4Re microkernel.
It is possible to build applications for that system using regular C files like this hello world example.
The build system is quite complex, but at the end the Code is simply build against a special version of uclibc, which uses a special c-backend which translates regular system calls to appropriate IPC messages, which is the only way to call to the microkernel.
Now I would really like to build applications for that system using Rust. In theory this should probably simply work by something like rustc --target x86_64-l4re-uclibc hello.rs
.
However for this to work I first need to define that target and build the stdlib for it.
I already found the documentation for target specification files on rust-cross. However I am not sure if this is really the right way and what exactly I need to specify in my case.
I also found target definitions in the rust source, which look more promising. Maybe adapting these might be the better way.
Can you give me a hint on what I should do next in order to define an appropriate target?
The above mentioned hello world example is internally build this way:
$ make -n hello
[...]
echo -e " [hello] ... Compiling main.o"
gcc -c -MD -MP -MF ./.main.o.d -DSYSTEM_amd64_K8_l4f -DARCH_amd64 -DCPUTYPE_K8 -DL4API_l4f -D_GNU_SOURCE -I/l4/obj/l4/include/contrib/libstdc++-v3 -I/l4/obj/l4/include/amd64/l4f -I/l4/obj/l4/include/amd64 -I/l4/obj/l4/include -isystem /l4/obj/l4/include/sys/amd64/l4f -isystem /l4/obj/l4/include/sys/l4f -isystem /l4/obj/l4/include/sys/amd64 -isystem /l4/obj/l4/include/sys -nostdinc -I/l4/obj/l4/include/contrib/libstdc++-v3 -I/l4/obj/l4/include/uclibc -I/path/to/l4re/include/uclibc -isystem /usr/lib/gcc/x86_64-linux-gnu/4.9/include -isystem /usr/lib/gcc/x86_64-linux-gnu/4.9/include-fixed -fno-omit-frame-pointer -g -O2 -fno-strict-aliasing -Wextra -Wall -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -fno-common -std=gnu99 -m64 -mno-red-zone -march=k8 -fstack-protector /l4/src/l4/pkg/hello/server/src/main.c -o main.o
echo -e " [hello] ==> Linking hello"
LD_PRELOAD=libgendep.so LD_LIBRARY_PATH=/l4/obj/l4/tool/gendep/64:/l4/obj/l4/tool/gendep/32 GENDEP_TARGET=hello GENDEP_BINARY=ld GENDEP_BINARY_ALT1=ld ld -m elf_x86_64 -o hello /l4/obj/l4/lib/amd64_K8/crti.o /usr/lib/gcc/x86_64-linux-gnu/4.9/crtbeginT.o /l4/obj/l4/lib/amd64_K8/crt1.o \
--whole-archive main.o --no-whole-archive \
-Bstatic --defsym=__executable_start=0x01000000 -m elf_x86_64 -z max-page-size=0x1000 -z common-page-size=0x1000 --defsym __L4_KIP_ADDR__=0x6ffff000 --defsym __L4_STACK_ADDR__=0x70000000 -L/l4/obj/l4/lib/amd64_K8/l4f -L/l4/obj/l4/lib/amd64_K8 -L/l4/obj/l4/lib -T/l4/obj/l4/lib/amd64_K8/main_stat.ld --start-group -static -nostdlib /l4/obj/l4/lib/amd64_K8/l4f/libgcc.a /usr/lib/gcc/x86_64-linux-gnu/4.9/libgcc_eh.a -l4re-util -lc_be_l4refile -lsupc++ -luc_c -luc_c_nonshared.p -lssp_nonshared.p -lc_be_l4re -l4re -ll4util -ll4sys -ll4re-vfs.o --end-group --warn-common --defsym=__executable_start=0x01000000 -gc-sections /usr/lib/gcc/x86_64-linux-gnu/4.9/crtend.o /l4/obj/l4/lib/amd64_K8/crtn.o
echo -e '\033[34;1m'' [hello] ==> hello built''\033[0m'
This creates a statically linked ELF binary with a custom programm header (using the -T
linker script). It also links against modified crt files, the already mentioned c-backend layer (*_be_*
), and the l4re libraries, which are the interface to the microkernel.
At the end no big magic. Shouldn't it be possible to tell rust to build the same way?