如何在ARM交叉编译时select要链接的静态库?

我在Ubuntu有一个ARM交叉编译器(arm-linux-gnueabi-gcc),默认架构是ARMv7。 不过,我想编译一个ARMv5二进制文件。 我通过给编译器-march=armv5te选项来做到这一点。

到现在为止还挺好。 由于我的ARM系统使用BusyBox,我必须编译我的二进制静态链接。 所以我给gcc -static选项。

但是,我有一个链接器链接到我的ARMv5二进制文件libc.a的问题。 该文件是使用ARMv7体系结构选项编译的。 所以,即使我用ARMv5交叉编译我的ARM二进制文件,我也无法在基于BusyBox的ARMv5框中运行它。

  1. 我怎么解决这个问题?
  2. 我在哪里可以获得ARMv5 libc.a静态库,以及如何链接它?

先谢谢你。

Solutions Collecting From Web of "如何在ARM交叉编译时select要链接的静态库?"

你有两个选择,

  1. 得到正确的编译器。
  2. 写你自己的'C'图书馆。

得到正确的编译器。

编译器与您的系统相匹配总是最安全的。 这适用于x86 Linux和各种发行版。 如果不同的编译器工作,你是幸运的。 交叉编译比较困难,因为编译器经常不会被自动同步。 尝试在您的2014 Ubuntu系统上编译的1999年x86 Mandrake Linux上运行程序。

除了指令兼容性(您已经识别)之外,还有ABI和OS依赖关系。 具体来说, armv7最有可能是hardfloat (具有浮点FPU和寄存器调用约定),您需要softfloat (模拟FPU)。 具体的glibc (或者ucLibc )对Linux操作系统有特定的调用和期望。 例如, 线程的工作方式随着时间而改变。

写你自己的

你总是可以使用-fno-builtin-ffreestanding以及-static 。 那么你不能使用任何libc函数,但你可以编程他们自己 。

有像Mark Martinec的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 #7\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 #7\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系统。 这可能看起来像一个痛苦,但上述替代方案也不容易。