MIPS交叉编译器中的crt1.o错误

3
我希望在x86机器上使用gcc生成MIPS二进制文件。为了安装MIPS交叉编译器,我按照this page上的说明进行操作。我成功地安装了gcc和binutils。我尝试使用交叉编译器编译一个简单的hello world程序。
/opt/cross/bin/mipsel-unknown-linux-gnu-gcc -mips1 hi.c 

我收到了以下错误。

/opt/cross/lib/gcc/mipsel-unknown-linux-gnu/4.8.2/../../../../mipsel-unknown-linux-gnu/bin/ld: cannot find crt1.o: No such file or directory
/opt/cross/lib/gcc/mipsel-unknown-linux-gnu/4.8.2/../../../../mipsel-unknown-linux-gnu/bin/ld: cannot find crti.o: No such file or directory
/opt/cross/lib/gcc/mipsel-unknown-linux-gnu/4.8.2/../../../../mipsel-unknown-linux-gnu/bin/ld: cannot find -lc
/opt/cross/lib/gcc/mipsel-unknown-linux-gnu/4.8.2/../../../../mipsel-unknown-linux-gnu/bin/ld: cannot find crtn.o: No such file or directory
collect2: error: ld returned 1 exit status

我在网上进行了一些研究,以确定问题所在,并将我使用的命令更改为以下内容。
/opt/cross/bin/mipsel-unknown-linux-gnu-gcc -B/usr/lib/i386-linux-gnu -mips1 hi.c

现在我收到了这个错误消息:
/opt/cross/lib/gcc/mipsel-unknown-linux-gnu/4.8.2/../../../../mipsel-unknown-linux-gnu/bin/ld: /usr/lib/i386-linux-gnu/crt1.o: Relocations in generic ELF (EM: 3)
/usr/lib/i386-linux-gnu/crt1.o: error adding symbols: File in wrong format
collect2: error: ld returned 1 exit status

我不确定问题出在哪里。我能想到的唯一可能就是在构建gcc时,使用了configure程序中的"--without-headers"选项。在linux-mips页面上提供的gcc配置命令如下。
% ../gcc-3.8.2/configure --target=$TARGET --prefix=$PREFIX \
  --enable-languages=c --without-headers \
  --with-gnu-ld --with-gnu-as \
  --disable-shared --disable-threads \
  --disable-libmudflap --disable-libgomp \
  --disable-libssp --disable-libquadmath \
  --disable-libatomic

我需要帮助。我生成交叉编译器的系统使用的是gcc4.7.2-5。我使用gcc-4.8.2和binutils-2.24的源代码来生成交叉编译器。


如果您只想交叉编译为mips-linux,您可能希望查看http://ellcc.org。 二进制文件也可供下载。 - Richard Pennington
你缺少一个运行时库。完整的开发环境需要为MIPS构建的库,除了编译器和binutils。 - Richard Pennington
2个回答

3

/opt/cross/bin/mipsel-unknown-linux-gnu-gcc -mips1 hi.c

在编译命令中添加SYSROOT。应该类似于:

/opt/cross/bin/mipsel-unknown-linux-gnu-gcc -mips1 --sysroot=/opt/cross/... hi.c

SYSROOT会自动提供头文件和库路径,而不是单独添加-I-L选项。

当你有一个SYSROOT时,你会发现路径中有bin/include/lib/文件夹。例如,这里有一个用于arm-linux-gnueabi(即arm-linux-gnueabi-gccarm-linux-gnueabi-g++)的SYSROOT

$ ls /usr/arm-linux-gnueabi
bin  include  lib

所以,在这个例子中,您需要使用--sysroot=/usr/arm-linux-gnueabi
如果您需要帮助查找SYSROOT,则执行find命令:
$ find /usr -name crt1.o
/usr/arm-linux-gnueabi/lib/crt1.o
/usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o
/usr/lib/x86_64-linux-gnu/crt1.o

在您的情况下,您可能会从/opt/cross搜索。显然,您需要针对目标(arm-linux-gnueabi)而不是主机(x86_64-linux-gnu)的版本。

当我使用sysroot选项时,我会收到以下错误信息。 /opt/cross/lib/gcc/mipsel-unknown-linux-gnu/4.8.2/../../../../mipsel-unknown-linux-gnu/bin/ld: this linker was not configured to use sysroots 我猜我必须重新编译整个东西并使用sysroot选项。 - nlogn
抱歉,Puck,我从未见过那个。但是我不建立自己的工具链。 - jww

0

添加 --sysroot= 可以解决这个问题。 由于您正在进行交叉编译,因此不应选择任何其他具有 crt1.o 或 crtX.o 作为 sysroot 目录的文件夹。它可能是您主机上的文件。(如果您在 x86 上运行,则会针对 x86)。同样,它因32位和64位而异。

使用更新版本的 GCC 工具链,您需要拥有一个 sdk 部分,其中包含适当的 sysroot 和 crt1.o。这应该与您的 ABI 和目标架构相匹配。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接