交叉编译之为RISC v平台编译x86的gcc

 

读者应该比较了解交叉编译的概念,一般都是在x86平台下使用gcc编译出其它平台的代码,这里我尝试在RISC v平台下编译出可以在x86平台使用的代码。

环境#

  1. 在 x86_64 平台上编译 riscv64-unknown-linux-gnu-gcc 编译器,网上教程很多不再赘述
  2. 在 x86_64 平台上使用 riscv64-unknown-linux-gnu-gcc 编译出能够在RISC v平台上使用的 x86_64 gcc

请在命令行中输入以下命令测试riscv编译器是否能够正常工作:

Copy
riscv64-unknown-linux-gnu-gcc -v

下载源码#

根据 https://gcc.gnu.org/install/prerequisites.html 中的说明下载对应版本的MPFR\MPC\ISL\GMP源码和gcc的源码。

Copy
wget http://ftpmirror.gnu.org/binutils/binutils-2.38.tar.gz wget http://ftpmirror.gnu.org/gcc/gcc-11.1.0/gcc-11.1.0.tar.gz wget https://mirrors.tuna.tsinghua.edu.cn/kernel/v5.x/linux-5.10.5.tar.xz wget http://ftpmirror.gnu.org/glibc/glibc-2.33.tar.xz wget ftp://gcc.gnu.org/pub/gcc/infrastructure/cloog-0.18.1.tar.gz

解压缩

Copy
for f in *.tar*; do tar xf $f; done

设置变量#

下面的变量的设置一定不要使用export,这里只是设置的变量,而非环境变量。如果使用环境变量,可能会出错!!!

Copy
# ROOT 是 源码文件的跟路径 ROOT=/root/x86-gcc GCCSRC=$ROOT/gcc-11.1.0 BINUTILS=$ROOT/binutils-2.38 LINUX=$ROOT/linux-5.10.5 GLIBC=$ROOT/glibc-2.33 BUILD=x86_64-linux-gnu HOST=riscv64-unknown-linux-gnu TARGET=x86_64-linux-gnu TARGET_ARCH=x86_64 # PREFIX 是把交叉编译器安装到哪里 PREFIX=/opt/$TARGET SYSROOT=$PREFIX/sysroot

创建文件夹

Copy
rm -rf $PREFIX mkdir -p $SYSROOT

编译binutils#

Copy
rm -rf $BINUTILS/build-${TARGET} mkdir $BINUTILS/build-${TARGET} cd $BINUTILS/build-${TARGET} ../configure --host=$HOST --target=${TARGET} \ --prefix=${PREFIX} --with-sysroot=$SYSROOT \ --disable-multilib --disable-werror make -j32 make install

安装Linux头文件#

Copy
cd $LINUX make mrproper make ARCH=${TARGET_ARCH} INSTALL_HDR_PATH=$SYSROOT/usr headers_install

编译 gcc#

准备文件#

下载gmp、mpfr、mpc和isl:

Copy
cd $GCCSRC ./contrib/download_prerequisites

如果下载成功将会看到如下输出:

Copy
gmp-6.1.0.tar.bz2: OK mpfr-3.1.4.tar.bz2: OK mpc-1.0.3.tar.gz: OK isl-0.18.tar.bz2: OK All prerequisites downloaded successfully.

将cloog链接到GCC目录:

Copy
cd $GCCSRC ln -s $ROOT/cloog-0.18.1 cloog file cloog # 确认一下软链接是否成功

编译#

这里会出现 fenv.h:58:11: error: ‘::fenv_t’ has not been declared,解决方法见链接的 comment13。这里直接给出解决方案:
修改$GCCSRC/configure,找到RAW_CXX_FOR_TARGET="$CXX_FOR_TARGET",将其修改为RAW_CXX_FOR_TARGET="$CXX_FOR_TARGET -nostdinc++";修改$GCCSRC/configure.ac,找到RAW_CXX_FOR_TARGET="$CXX_FOR_TARGET",将其修改为RAW_CXX_FOR_TARGET="$CXX_FOR_TARGET -nostdinc++"

Copy
rm -rf $GCCSRC/build-${TARGET} mkdir $GCCSRC/build-${TARGET} cd $GCCSRC/build-${TARGET} # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80196 # 这里会出现 fenv.h:58:11: error: ‘::fenv_t’ has not been declared # 解决方法见链接的 comment13 ../configure --host=$HOST --target=${TARGET} \ --prefix=${PREFIX} --with-sysroot=$SYSROOT \ --enable-languages=c,c++ \ --enable-threads=posix \ --disable-multilib --disable-werror --without-selinux --disable-libstdcxx-pch \ --disable-libmudflap --disable-libssp --disable-libquadmath \ --disable-libsanitizer --disable-nls make -j32 make install

编译glibc#

Copy
rm -rf $GLIBC/build-${TARGET} mkdir $GLIBC/build-${TARGET} cd $GLIBC/build-${TARGET} ../configure --build=$BUILD --host=$TARGET --target=${TARGET} \ --prefix=$SYSROOT/usr \ --with-headers=$SYSROOT/usr/include \ --enable-threads=posix \ --without-selinux \ --disable-multilib libc_cv_forced_unwind=yes --disable-libstdcxx-pch \ --disable-libmudflap --disable-libssp --disable-libquadmath \ --disable-libsanitizer --disable-nls make -j64 make install_root=$SYSROOT install

测试#

测试文件#

main.c

Copy
#include <stdio.h> int main(int argc, char *argv[]) { printf("Hello, world!\n"); return 0; }

hello.cpp

Copy
#include <iostream> #include <string> #include <vector> #include <algorithm> int main(int argc, char const *argv[]) { std::cout << "Hello, world!" << std::endl; std::vector<int> v = {1, 2, 3, 4, 5}; std::for_each(v.begin(), v.end(), [](int i) { std::cout << i << std::endl; }); return 0; }

测试#

Copy
export LD_LIBRARY_PATH=/opt/riscv-gnu-toolchain/sysroot/lib64/lp64d cd $ROOT/test $PREFIX/bin/x86_64-linux-gnu-gcc -o main main.c $PREFIX/bin/x86_64-linux-gnu-g++ -o hello hello.cpp

参考文献#

Ubuntu构建ARM交叉编译器
insall gcc
编译工具链

posted @   LightningStar  阅读(827)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示
CONTENTS