1

I'm trying to cross compile C code for an embedded application that is running Xenomai (2.5.6 / Linux 2.6.35.9). I started with Xenomai examples and tried to compile them using their Makefiles, but they are not working properly (besides, I want to cross-compile for my ARM machine).

I've followed this tutorial and found a way to manually compile the sources, that happens to be this one:

arm-linux-gnueabi-gcc \
    -I/home/carles/.../xenomai-2.5.6/usr/xenomai/include \ 
    -D_GNU_SOURCE -D_REENTRANT -Wall -pipe -D__XENO__ \
    -lnative \
    -L/home/carles/.../xenomai-2.5.6/usr/xenomai/lib \
    -lxenomai -lpthread -lrtdk \
    rtprint.c -o rtprint

Where arm-linux-gnueabi-gcc is the toolchain I'm using to cross-compile for ARM, -I/home/... is the path where the headers are, and -L/home/... is the path where all libraries are located. Those headers and libraries where put in that folders during Xenomai's install (so they are built for ARM).

CFLAGS and LDFLAGS were generated using xeno-config as stated in the tutorial, but when I execute the command, I get the following linker error:

$ arm-linux-gnueabi-gcc -I/home/carles/Develop/xenomai-2.5.6/usr/xenomai/include -D_GNU_SOURCE -D_REENTRANT -Wall -pipe -D__XENO__ -lnative -L/home/carles/Develop/xenomai-2.5.6/usr/xenomai/lib -lxenomai -lpthread -lrtdk rtprint.c -o rtprint
/tmp/ccEpFEIl.o: In function `rt_task_spawn':
rtprint.c:(.text+0x34): undefined reference to `rt_task_create'
rtprint.c:(.text+0x54): undefined reference to `rt_task_start'
/tmp/ccEpFEIl.o: In function `task2_func':
rtprint.c:(.text+0x88): undefined reference to `rt_printf'
rtprint.c:(.text+0x98): undefined reference to `rt_task_set_mode'
rtprint.c:(.text+0xa4): undefined reference to `rt_task_sleep'
rtprint.c:(.text+0xb0): undefined reference to `rt_print_buffer_name'
rtprint.c:(.text+0xd4): undefined reference to `rt_fprintf'
/tmp/ccEpFEIl.o: In function `main':
rtprint.c:(.text+0x11c): undefined reference to `rt_print_auto_init'
rtprint.c:(.text+0x128): undefined reference to `rt_print_init'
rtprint.c:(.text+0x140): undefined reference to `rt_task_shadow'
rtprint.c:(.text+0x180): undefined reference to `rt_task_set_mode'
rtprint.c:(.text+0x18c): undefined reference to `rt_task_sleep'
rtprint.c:(.text+0x190): undefined reference to `rt_print_buffer_name'
rtprint.c:(.text+0x1b0): undefined reference to `rt_printf'
collect2: error: ld returned 1 exit status

All rt_... references are Xenomai's Kernel functions that are included in the libraries.


EDIT: Adding -lrt to the command line and ordering the arguments correctly (i.e. -L at the end of the command line) does not solve the problem. In order to assure that the library does contain the functions, I executed objdump and got the following result:

.../usr/xenomai/lib$ arm-linux-gnueabi-objdump -x librtdk.a | grep rt_print
00000000         *UND*  00000000 __rt_print_init
00000000         *UND*  00000000 __rt_print_exit
00000000 R_ARM_JUMP24      __rt_print_init
00000000 R_ARM_JUMP24      __rt_print_exit
librtdk_la-rt_print.o:     file format elf32-littlearm
rw-rw-r-- 1001/1001   6872 Apr  8 16:06 2013 librtdk_la-rt_print.o
00000000 l    df *ABS*  00000000 rt_print.c
00000350 g     F .text  0000012c rt_print_init
00000744 g     F .text  0000003c rt_printf
000007c8 g     F .text  00000010 rt_print_auto_init
000007d8 g     F .text  00000044 rt_print_cleanup
0000081c g     F .text  00000058 rt_print_buffer_name
00000874 g     F .text  00000190 __rt_print_init
00000a04 g     F .text  00000034 __rt_print_exit
000006b8 R_ARM_CALL        rt_print_init
00000850 R_ARM_CALL        rt_print_init

Other things I did that may help finding the problem:

  1. Installing xenomai-related packages (xenomai-runtime, libxenomai1, linux-patch-xenomai)
  2. Removed a different toolchain. Since I was first using the Ångström distribution in my target device I had a specialized toolchain for it. Now, I moved to Debian and I am using the arm-linux-gnueabi toolchain provided in the binutils-arm-linux-gnueabi package.
  3. Compiled a new Linux Kernel and Xenomai (for my target device). Kernel version is 2.6.35.9 and Xenomai's is 2.5.6. Should I use an earlier version? Anyway, Xenomai is installed correctly since I can run the pre-compiled programs (that were ironically compiled during Xenomai's installation, by myself...)
jww
  • 97,681
  • 90
  • 411
  • 885
Carles Araguz
  • 1,157
  • 1
  • 17
  • 37
  • 1
    Thanks @artlessnoise, but I tried both adding `-lrt` and moving `-L` and `-I` to the end of the command line and I still got the same error. Just as trial&error method I tried writing wrong library names (for instance `-ltnativeee`) and the linker has outputted a different error (_"cannot find -lnativeee"_), which makes me think there is something wrong with the libraries themselves... What do you think? – Carles Araguz Apr 09 '13 at 16:23
  • 1
    Hmm. Your code is not C++ correct? Can you run `file librtdk.a` in the *.../xenomai/lib* directory to double check you have an ARM xenomai there? Also getting `arm-linux-gnueabi-objdump -x librtdk.a | grep rt_print` output to confirm a function is in the library? – artless noise Apr 09 '13 at 16:30
  • Executing `file librtdk.a` I get `librtdk.a: current ar archive`, while if I execute `file librtdk.so.0.0.0` the output ends up being the expected `librtdk.so.0.0.0: ELF 32-bit LSB shared object, ARM, version 1 (SYSV), dynamically linked, ...`. Executing the last command I get around 15 lines containing the keyword, so I guess the function rt_printf is present. – Carles Araguz Apr 09 '13 at 16:39
  • Sure! I've added it to the question because it was too long for a comment entry. I'm as stumped as you, @artlessnoise... – Carles Araguz Apr 09 '13 at 17:10

1 Answers1

0

It appears that magic has happened here. After two days messing around with Makefiles, Xenomai CFLAGS and linker configuration I've come to a point in which both the compilation and linking works with no problem.

I really haven't done anything special. I haven't (un)installed any package (other than the ones I already had) nor modified any environment variable nor added any different flag or argument to my command line. I just rebooted my computer. I didn't even do that on purpose, I just left the lab yesterday with the command not working altogether and this morning everything works a treat. Strange? Yes.

I guess it is somehow related with exported variables in the terminal session. I remember I tinkered with LD_LIBRARY_PATH, CFLAGS, LDFLAGS, and so on, so I must have screwed something while trying to solve the problem. For those of you who are curious to know the final working command for cross-compiling Xenomai (2.5.6) applications for an ARM machine running Linux 2.6.39.5, this is it:

arm-linux-gnueabi-gcc file_name.c -o file_name         \
    -I/path/to/target/usr/xenomai/include              \
    -D_GNU_SOURCE -D_REENTRANT -Wall -pipe -D__XENO__  \
    -lnative -lxenomai -lrt -lpthread -lrtdk           \
    -L/path/to/target/usr/xenomai/lib 
Carles Araguz
  • 1,157
  • 1
  • 17
  • 37
  • Both `-l` and `-L` order is important. I'd suggest you always keep `-lnative` the first one, since my toolchain is only able to link if it is at the beginning. – Carles Araguz Apr 11 '13 at 14:49