如何在 ARM 交叉编译时选择要链接的静态库?
Posted
技术标签:
【中文标题】如何在 ARM 交叉编译时选择要链接的静态库?【英文标题】:How can I select a static library to be linked while ARM cross compiling? 【发布时间】:2014-08-28 06:26:00 【问题描述】:我在 Ubuntu (arm-linux-gnueabi-gcc) 中有一个 ARM 交叉编译器,默认架构是 ARMv7。但是,我想编译一个 ARMv5 二进制文件。我通过为编译器提供-march=armv5te
选项来做到这一点。
到目前为止,一切都很好。由于我的 ARM 系统使用 BusyBox,我必须编译静态链接的二进制文件。所以我给 gcc -static
选项。
但是,链接器链接到我的 ARMv5 二进制文件的 libc.a 存在问题。该文件是使用 ARMv7 架构选项编译的。所以,即使我用 ARMv5 交叉编译我的 ARM 二进制文件,我也无法在基于 BusyBox 的 ARMv5 机器上运行它。
-
我该如何解决这个问题?
我在哪里可以获得 ARMv5 libc.a 静态库,如何链接它?
提前谢谢你。
【问题讨论】:
【参考方案1】:你有两个选择,
-
获取正确的编译器。
编写您自己的“C”库。
获取正确的编译器。
让编译器与您的系统匹配,您总是是最安全的。这适用于 x86 Linux 和各种发行版。如果不同的编译器工作,你很幸运。当您交叉编译时会更加困难,因为编译器不会自动同步。尝试在 2014 Ubuntu 系统上编译的 1999 x86 Mandrake Linux 上运行程序。
除了指令兼容性(您已确定)之外,还有 ABI 和操作系统依赖项。具体来说,armv7 很可能是 hardfloat(具有 浮点 FPU 和寄存器调用约定),您需要一个 softfloat(模拟 FPU)。特定的glibc(或ucLibc)对Linux OS 有特定的调用和期望。例如,threads 的工作方式随着时间的推移发生了变化。
自己写
您始终可以使用-fno-builtin
和-ffreestanding
以及-static
。那么你就不能使用任何libc函数了,但是你可以program them your self.
有外部源,如Mark Martinec's snprintf 和易于实现的构建块如write()
,
#define _SYS_IOCTL_H 1
#include <linux/unistd.h>
#include <linux/ioctl.h>
static inline int write(int fd, void *buf, int len)
int rval;
asm volatile ("mov r0, %1\n\t"
"mov r1, %2\n\t"
"mov r2, %3\n\t"
"mov r7, %4\n\t"
"swi #0\n\t"
"mov %0, r0\n\t"
: "=r" (rval)
: "r" (fd),
"r" (buf),
"r" (len),
"Ir" (__NR_write)
: "r0", "r1", "r2", "r7");
return rval;
static inline void exit(int status)
asm volatile ("mov r0, %0\n\t"
"mov r7, %1\n\t"
"swi #0\n\t"
: : "r" (status),
"Ir" (__NR_exit)
: "r0", "r7");
您必须添加由“C”库负责的自己的启动机器,
/* Called from assembler startup. */
int main (int argc, char*argv[])
write(STDOUT, "Hello world\n", sizeof("Hello world\n"));
return 0;
/* Wrapper for main return code. */
void __attribute__ ((unused)) estart (int argc, char*argv[])
int rval = main(argc,argv);
exit(rval);
/* Setup arguments for estart [like main()]. */
void __attribute__ ((naked)) _start (void)
asm(" sub lr, lr, lr\n" /* Clear the link register. */
" ldr r0, [sp]\n" /* Get argc... */
" add r1, sp, #4\n" /* ... and argv ... */
" b estart\n" /* Let's go! */
);
如果这太令人生畏了,因为您需要实现很多功能,那么您可以尝试获取各种库源并使用-fno-builtin
重新构建它们,并确保这些库不与 Ubuntu 库链接,不兼容。
像crosstool-ng 这样的项目可以让您构建完全适合armv5 系统的正确编译器(可能具有更高级的代码生成)。这可能看起来很痛苦,但上述替代方案也并不容易。
【讨论】:
以上代码适用于 Linux 2.6.36 和 EABI 系统调用 Linux(不是 OABI)。您必须拥有 Linux 头文件才能编写自己的库。dmesg
或 cat /proc/version
应该告诉你你的 Linux 版本,而不是配置。以上是关于如何在 ARM 交叉编译时选择要链接的静态库?的主要内容,如果未能解决你的问题,请参考以下文章
cmake:arm-xm-linux交叉编译工具链文件及交叉支持HTTPS的curl静态库