【问题标题】:Undefined references when linking Xenomai programs for ARM?为 ARM 链接 Xenomai 程序时未定义的引用?
【发布时间】:2013-04-01 02:04:31
【问题描述】:

我正在尝试为运行 Xenomai (2.5.6 / Linux 2.6.35.9) 的嵌入式应用程序交叉编译 C 代码。我从 Xenomai 示例开始,并尝试使用他们的 Makefile 编译它们,但它们无法正常工作(此外,我想为我的 ARM 机器进行交叉编译)。

我已经按照this 教程找到了一种手动编译源代码的方法,恰好是这个:

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

arm-linux-gnueabi-gcc 是我用来交叉编译 ARM 的工具链,-I/home/... 是头文件所在的路径,-L/home/... 是所有库所在的路径。在 Xenomai 安装期间放入该文件夹的那些头文件和库(因此它们是为 ARM 构建的)。

CFLAGS 和 LDFLAGS 是使用 xeno-config 生成的,如教程中所述,但是当我执行命令时,出现以下链接器错误:

$ 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

所有rt_... 引用都是库中包含的 Xenomai 的内核函数。


编辑:-lrt 添加到命令行并正确排序参数(即-L 在命令行末尾)不能解决问题。 为了确保库确实包含这些函数,我执行了objdump,得到了以下结果:

.../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

我所做的其他可能有助于发现问题的事情:

  1. 安装 xenomai 相关包(xenomai-runtimelibxenomai1linux-patch-xenomai
  2. 删除了不同的工具链。因为我第一次在我的目标设备中使用 Ångström 发行版,所以我有一个专门的工具链。现在,我搬到了 Debian,我正在使用 binutils-arm-linux-gnueabi package 中提供的 arm-linux-gnueabi 工具链。
  3. 为我的目标设备编译了一个新的 Linux 内核和 Xenomai。内核版本是 2.6.35.9,Xenomai 是 2.5.6。我应该使用早期版本吗?无论如何,Xenomai 安装正确,因为我可以运行预编译的程序(讽刺的是,在 Xenomai 的安装过程中,我自己编译了这些程序......)

【问题讨论】:

  • 感谢@artlessnoise,但我尝试同时添加-lrt 并将-L-I 移动到命令行末尾,但我仍然遇到相同的错误。就像试错方法一样,我尝试编写错误的库名称(例如-ltnativeee)并且链接器输出了一个不同的错误(“找不到-lnativeee”),这让我觉得有问题图书馆本身......你怎么看?
  • 嗯。您的代码不是 C++ 正确的吗?您可以在 .../xenomai/lib 目录中运行file librtdk.a 来仔细检查您那里有 ARM xenomai 吗?还获取arm-linux-gnueabi-objdump -x librtdk.a | grep rt_print 输出以确认函数是否在库中?
  • 执行file librtdk.a我得到librtdk.a: current ar archive,而如果我执行file librtdk.so.0.0.0,输出最终是预期的librtdk.so.0.0.0: ELF 32-bit LSB shared object, ARM, version 1 (SYSV), dynamically linked, ...。执行最后一个命令,我得到大约 15 行包含关键字的行,所以我猜函数 rt_printf 存在。
  • 当然!我已将其添加到问题中,因为它对于评论条目来说太长了。我和你一样难过,@artlessnoise...

标签: gcc arm linker-errors xenomai


【解决方案1】:

看来这里发生了魔法。经过两天的 Makefile、Xenomai CFLAGS 和链接器配置,我已经到了编译和链接都没有问题的地步。

我真的没有做过什么特别的事情。我没有(卸载)任何包(除了我已经拥有的包),也没有修改任何环境变量,也没有在我的命令行中添加任何不同的标志或参数。我刚刚重新启动了我的电脑。我什至不是故意这样做的,我昨天刚离开实验室,命令完全不起作用,今天早上一切正常。奇怪的?是的。

我猜它与终端会话中的导出变量有某种关系。我记得我修改了 LD_LIBRARY_PATH、CFLAGS、LDFLAGS 等等,所以我在尝试解决问题时一定搞砸了。对于那些想知道为运行 Linux 2.6.39.5 的 ARM 机器交叉编译 Xenomai (2.5.6) 应用程序的最终工作命令的人来说,就是这样:

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 

【讨论】:

  • -l-L 的顺序都很重要。我建议您始终保留-lnative 第一个,因为我的工具链只有在开始时才能链接。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-04-03
  • 2021-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-15
  • 2020-12-14
相关资源
最近更新 更多