当前位置: 首页 > 面试题库 >

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

宓弘壮
2023-03-14
问题内容

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

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

但是,链接器链接到我的ARMv5二进制文件的 libc.a
出现问题。该文件使用ARMv7体系结构选项进行编译。因此,即使我将ARM二进制文件与ARMv5交叉编译,也无法在基于BusyBox的ARMv5机器上运行它。

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

先感谢您。


问题答案:

您有两种选择,

  1. 获取正确的编译器。
  2. 编写自己的“ C”库。

获取正确的编译器。

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

除了指令兼容性(您已确定)外,还存在ABI和OS依赖性。具体来说, armv7 最有可能是 浮点 (具有 浮点FPU
和注册调用约定),您需要 软浮点 (模拟的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    #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
系统的正确编译器(也许使用更高级的代码生成)。这看起来似乎很痛苦,但是上面的替代方法也不容易。



 类似资料:
  • 本文档说明如何在kali linux上配置ARM交叉编译环境,是我们多份关于”定制ARM镜像”的文档的起点. 开发机的配置 编译内核生成镜象通常需要大量硬盘空间.确保你的开发机至少有50G可用硬盘空间以及足够的内存,CPU不要太差. 安装依赖 先安装ARM交叉编译所需的依赖. apt-get install git-core gnupg flex bison gperf libesd0-dev b

  • 我试图交叉编译一个linux系统的简单hello world程序。 我有以下资料: null 我试图运行/lib/libc.so.0来获取版本信息,但出现了一个分段错误。它似乎用-static编译解决了这个问题。所以我想这是libc库的问题。谢谢你的帮助。

  • 我正在尝试为Android ARM交叉编译llvm/clang。 我也尝试了这里列出的所有步骤,以及在这里找到的指南,但没有运气。 任何帮助都将不胜感激。谢了! 编辑:现在我正在使用以下命令: 错误消息:CLANG36++:警告:编译过程中未使用参数:'-bundle'/users/paschalis/androide/toolchains/gcc/bin/../lib/gcc/arm-linux

  • 问题内容: 我想修改setup.py文件,以便命令“ python setup.py build”编译基于C的扩展模块,该模块静态(而非动态)链接到库。 该扩展程序当前动态链接到许多库。除了静态链接到一个库外,我想保留所有内容。我已经成功地通过手动修改了对distutils运行的gcc的调用来完成了此操作,尽管它要求我明确列出相关库。 也许这是太多信息,但是为了清楚起见,这是在“ python s

  • 我正在努力使用Bazel为ARM处理器交叉编译一个程序。我遵循了Bazel的以下教程: https://github.com/bazelbuild/bazel/wiki/building-with-a-custom-toolchain 当我运行上述教程中编写的确切命令时,错误日志如下所示: 我对巴泽尔一无所知,因为我是新来的。任何帮助都将不胜感激。