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

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

问题描述

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



到目前为止,这样做很好。由于我的ARM系统使用BusyBox,我必须编译我的二进制静态链接。所以我给gcc -static 选项。



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


  1. 我可以解决这个问题吗?

  2. 在哪里可以获得ARMv5 libc.a 静态库,以及如何链接它?

预先感谢您。 您有两种选择,


  1. 获得正确的编译器。

  2. 编写您自己的'C'库。
  3. >



获取正确的编译器。



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


$ b 除了指令兼容性(您已经识别)之外,还有ABI和OS依赖。具体而言, armv7 很可能是 hardfloat (具有浮点FPU 和注册调用约定),您需要 softfloat (仿真FPU)。特定的 glibc (或 ucLibc )对Linux操作系统有特定的调用和期望。例如,线程的工作方式随着时间而改变。



编写自己的



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

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

  #define _SYS_IOCTL_H 1 
#include< linux / unistd.h>
#include< linux / ioctl.h>
static int inline int(int fd,void * buf,int len)
{
int rval;
asm volatile(mov r0,%1 \\\
\t
mov r1,%2\\\
\t
mov r2,%3 \\\
\ t
mov r7,%4 \\\
\t
swi#7 \\\
\t
mov%0,r0\\\
\\ \\ t
:= r(rval)
:r(fd),
r(buf),
r b $ bIr(__NR_write)
:r0,r1,r2,r7);
return rval;


static inline void exit(int status)
{
asm volatile(mov r0,%0\\\
\t
mov r7,%1 \\\
\t
swi#7 \\\
\t
::r(status),
Ir(__NR_exit )
:r0,r7);
}

您必须添加您自己的启动机器, C'库,

  / *从汇编程序启动调用。 * / 
int main(int argc,char * argv [])
{
write(STDOUT,Hello world \\\
,sizeof(Hello world \\\
)) ;
返回0;
}

/ *主返回码的包装。 * /
void __attribute__((未使用))estart(int argc,char * argv [])
{
int rval = main(argc,argv);
exit(rval);
}

/ *为estart设置参数[比如main()]。 * /
void __attribute__((naked))_start(void)
{
asm(sub lr,lr,lr\\\
/ *清除链接寄存器* /
ldr r0,[sp] \\\
/ *获取argc ... * /
add r1,sp,#4 \\\
/ * ...和argv ... * /
b estart \\\
/ *我们走吧!* /
);





$ b

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

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


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.

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.

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. How can I solve this problem?
  2. Where can I get the ARMv5 libc.a static library, and how can I link it?

Thank you in advance.

解决方案

You have two choices,

  1. Get the right compiler.
  2. Write your own 'C' Library.

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.

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.

Write your own

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.

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\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");
}

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\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! */
        );
}

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.

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天全站免登陆