如何在 ARM 交叉编译时选择要链接的静态库? [英] How can I select a static library to be linked while ARM cross compiling?

查看:15
本文介绍了如何在 ARM 交叉编译时选择要链接的静态库?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have an ARM cross compiler in Ubuntu(arm-linux-gnueabi-gcc) and the default archtecture is ARMv7. However, I want to compile an ARMv5 binary. I do this by giving the compiler the -march=armv5te option.

到目前为止,一切都很好.由于我的 ARM 系统使用 BusyBox,我必须编译静态链接的二进制文件.所以我给 gcc -static 选项.

So far, so good. Since my ARM system uses BusyBox, I have to compile my binary statically linked. So I give gcc the -static option.

但是,链接器链接到我的 ARMv5 二进制文件的 libc.a 存在问题.该文件是使用 ARMv7 架构选项编译的.所以,即使我用 ARMv5 交叉编译我的 ARM 二进制文件,我也无法在基于 BusyBox 的 ARMv5 机器上运行它.

However, I have a problem with libc.a which the linker links to my ARMv5 binary. This file is compiled with the ARMv7 architecture option. So, even if I cross-compile my ARM binary with ARMv5, I can't run it on my BusyBox based ARMv5 box.

  1. 我该如何解决这个问题?
  2. 我在哪里可以获得 ARMv5 libc.a 静态库,如何链接它?
  1. How can I solve this problem?
  2. Where can I get the ARMv5 libc.a static library, and how can I link it?

提前谢谢你.

推荐答案

你有两个选择,

  1. 获取正确的编译器.
  2. 编写您自己的C"库.

获取正确的编译器.

让编译器与您的系统匹配,您总是是最安全的.这适用于 x86 Linux 和各种发行版.如果不同的编译器工作,你很幸运.当您交叉编译时会更加困难,因为编译器不会自动同步.尝试在 2014 Ubuntu 系统上编译的 1999 x86 Mandrake Linux 上运行程序.

Get the right compiler.

You are always safest to have a compiler match your system. This applies to x86 Linux and various distributions. You are lucky if different compilers work. It is more difficult when you cross-compile as often the compiler will not be automatically synced. Try to run a program on a 1999 x86 Mandrake Linux compiled on your 2014 Ubuntu system.

除了指令兼容性(您已确定)之外,还有 ABI 和操作系统依赖项.具体来说,armv7 很可能是 hardfloat(具有 浮点 FPU 和寄存器调用约定),您需要一个 softfloat(模拟 FPU).特定的glibc(或ucLibc)对Linux OS 有特定的调用和期望.例如,threads 的工作方式随着时间的推移发生了变化.

As well as instruction compatibility (which you have identified), there are ABI and OS dependencies. Specifically, the armv7 is most likely hardfloat (has floating point FPU and register call convention) and you need a softfloat (emulated FPU). The specific glibc (or ucLibc) has specific calls and expectations of the Linux OS. For instance, the way threads works has changed over time.

您始终可以使用 -fno-builtin-ffreestanding 以及 -static.那么你不能使用任何libc函数,但是你可以自己编程.

You can always use -fno-builtin and -ffreestanding as well as -static. Then you can not use any libc functions, but you can program them your self.

有外部来源,如 Mark Martinec 的 snprintf 等构建块write() 很容易实现,

There are external source, like Mark Martinec's snprintf and building blocks like write() which is easy to implement,

#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
	"
                "mov    r1, %2
	"
                "mov    r2, %3
	"
                "mov    r7, %4
	"
                "swi    #0
	"
                "mov    %0, r0
	"
                : "=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
	"
                "mov    r7, %1
	"
                "swi    #0
	"
                : : "r" (status),
                  "Ir" (__NR_exit)
                : "r0", "r7");
}

您必须添加由C"库负责的自己的启动机器,

You have to add your own start-up machinery taken care of by the 'C' library,

/* Called from assembler startup. */
int main (int argc, char*argv[])
{
    write(STDOUT, "Hello world
", sizeof("Hello world
"));
    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
"   /* Clear the link register. */
        " ldr     r0, [sp]
"     /* Get argc... */
        " add     r1, sp, #4
"   /* ... and argv ... */
        " b       estart
"       /* Let's go! */
        );
}

如果这太令人生畏了,因为您需要实现很多功能,那么您可以尝试获取各种库源并使用 -fno-builtin 重建它们,并确保库可以不与不兼容的 Ubuntu 库链接.

If this is too daunting, because you need to implement a lot of functionality, then you can try and get various library source and rebuild them with -fno-builtin and make sure that the libraries do not get linked with the Ubuntu libraries, which are incompatible.

crosstool-ng 这样的项目可以让你构建一个正确的编译器(也许有更高级的代码生成) 完全适合 armv5 系统.这可能看起来很痛苦,但上述替代方案也并不容易.

Projects like crosstool-ng can allow you to build a correct compiler (maybe with more advanced code generation) that suits the armv5 system exactly. This may seem like a pain, but the alternatives above aren't easy either.

这篇关于如何在 ARM 交叉编译时选择要链接的静态库?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆