【问题标题】:MIPS GCC cross-compiler build fails: "cannot find -lc"MIPS GCC 交叉编译器构建失败:“找不到 -lc”
【发布时间】:2018-06-01 14:10:12
【问题描述】:

我正在尝试使用 Linux 2.6.31 为基于 QCA955X 的路由器设置 GCC 4.9.4 交叉编译器。这是一个使用uClibc-0.9.30.1 的MIPS32R2-abi CPU(在/lib 中找到)。因此,我决定用匹配的uClibc 和binutils-2.19.1a 编译一个GCC 4.x。我的主机系统是 Ubuntu 18.04,带有 Linux 4.17-rc5 和 gcc version 7.3.0 (Ubuntu 7.3.0-16ubuntu3)

~/mips-cross-gcc/staging_dir 是我的前缀,~/mips-cross-gcc/staging_dir/sysroot 是我系统的临时 sysroot。

1) 我将binutils-2.19.1a.tar.bz2gcc-4.9.4.tar.bz2linux-2.6.31.9.tar.xzuClibc-0.9.30.1.tar.bz2 下载到~/mips-cross-gcc/sources

2) 我解压了所有来源。

3) 安装 linux 头文件:

make ARCH=mips INSTALL_HDR_PATH=/home/user/mips-cross-gcc/staging_dir/sysroot/usr headers_install

4) 构建 binutils:

cd binutils-2.19.1
./configure --prefix=/home/user/mips-cross-gcc/staging_dir --target=mips-linux-uclibc --disable-multilib --disable-werror --enable-shared --without-newlib --with-sysroot=/home/user/mips-cross-gcc/staging_dir/sysroot --enable-languages=c,c++ --disable-libgomp

make all-binutils
make all-ld
make all-gas
make install-binutils
make install-ld
make install-gas

5) 构建“阶段 1”gcc,以引导 uClibc:

cd gcc-4.9.4
mkdir -p build/gcc-stage1
../../configure --target=mips-linux-uclibc --prefix=/home/user/mips-cross-gcc/staging_dir --disable-werror --disable-libgomp --without-newlib --disable-multilib --enable-languages=c,c++ --enable-shared --disable-__cxa_atexit --enable-target-optspace --disable-nls --disable-libmudflap  --disable-libssp --with-float=soft --with-sysroot=/home/user/mips-cross-gcc/staging_dir/sysroot --with-gnu-ld --without-headers
make all-gcc
make install-gcc

6) 安装 uClibc 头文件:

cd uClibc-0.9.30.1
make PREFIX=/home/user/mips-cross-gcc/staging_dir/sysroot install_headers

7) 为目标架构构建 libgcc: cd gcc-4.9.4 制作全目标libgcc

Libgcc 一直编译到最后的 libgcc_s 链接阶段:

/home/daniel/mips-cross-gcc/staging_dir/mips-linux-uclibc/bin/ld: cannot find -lc
collect2: error: ld returned 1 exit status
Makefile:937: recipe for target 'libgcc_s.so' failed

我认为引导GCC 不需要libc,因为它还没有被编译,对吧?我可能做错了什么?我会使用这个编译的GCC 来构建uClibc,然后我会用我的新uClibc 再次编译GCC,这样我就可以交叉编译软件。 GCC 在第一次构建中需要 libc 的事实似乎是错误的。

我尝试使用第一个 gcc 而不编译 libgcc 来构建 uClibc,但我几乎立即收到了:

LD ld-uClibc-0.9.30.1.so
mips-linux-uclibc-gcc: error: libgcc.a: No such file or directory
ldso/ldso/Makefile.in:54: recipe for target 'lib/ld-uClibc.so' failed

所以,uClibc 需要 libgcc 来链接自己,而 gcc 需要 libc(任何类型,包括 uClibc)来链接自己的 libgcc。这似乎是一个先有鸡还是先有蛋的问题。如何解决这个问题?

【问题讨论】:

  • 路由器固件是否有“官方”构建机制来负责设置工具链?例如,OpenWrt 使用基于 Buildroot 的构建系统。或者您是否正在尝试构建将在路由器本身上运行的 C 编译器?
  • 有,但是这是一个使用 Openwrt "Kamikaze" 衍生固件的路由器,未发布修改。 Openwrt buildroot 使用旧脚本,并且在现代计算机上调试的错误太多,遗憾的是。 Kamikaze 已经很老了,它使用的 svn 服务器也永远消失了。所以,这是我目前唯一的选择:(
  • 关于在最新主机上使用旧的构建系统,我偶尔会为此设置 Docker 容器(基于一些旧的 Linux 发行版)。但是,缺少 svn 服务器也无济于事!

标签: c linux gcc cross-compiling uclibc


【解决方案1】:

我修好了。显然,GCC 必须在没有启用共享库的情况下构建(--disable-shared),这样它就不会动态链接生成的库,如libgcc(即到libc,),但这仍然不起作用。 -lc 仍然没有找到。

我做了更多的谷歌搜索,发现这条来自 eglibc 的有用信息,关于使用 gcc 制作自己的工具链:eglibc.org

第一个海合会

对于我们的工作,我们需要一个针对 PowerPC Linux 的交叉编译器 系统。但是,该配置包括共享库 'libgcc_s.so',它是针对 EGLIBC 头文件(我们 尚未安装)并链接到“libc.so”(我们还没有 尚未建成)。

幸运的是,GCC 有一些配置选项告诉它不是 构建'libgcc_s.so'。 '--without-headers' 选项应该是 照顾这个,但它的实现是不完整的,所以你必须 还可以使用“--with-newlib”选项进行配置。而'--with-newlib' 似乎是“使用 Newlib C 库”的意思,它的作用是告诉 GCC 构建机器,“不要假设有可用的 C 库。”

看起来,只要挖掘得够多,就一定有人能找到确切的问题。

简而言之,将--enable-shared 更改为--disable-shared 并将--with-newlib 添加到GCC 的 ./configure 解决了这个问题并编译 + 链接了我用来编译 uClibc 的 libgcc_s.so,然后使用来自 uClibc 的新生成的 libc 重新编译 gcc。实际上,可以在 2018 GCC 7.x 上使用 2011 uClibc 编译 2016 GCC 4.x。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-03
    • 1970-01-01
    • 1970-01-01
    • 2014-09-30
    • 2013-10-09
    • 2013-02-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多