孙老师的CLFS指南中提到的交叉编译器制作方式貌似在旧世界Loongnix上无法制作出完整版GCC.
经过几天的研究,本人拼凑起了一个能用的GCC12.1,X86_64到Loongarch的交叉编译器
旧世界:Kernel4.19,自带GCC8和glibc2.28. 而这个修改过的glibc2.28的源码我是怎么也没找到*(github 仓库里那个看起来是新世界的)*
1.准备工作
1.配置环境变量,工作文件夹
这一步与孙老师的教程类似.
创建一个source.sh
#!/bin/bash
set +h
umask 022
export SYSDIR="<你喜欢的工作目录>"
export LC_ALL=POSIX
export CROSS_HOST="x86_64-cross-linux-gnu"
export CROSS_TARGET="loongarch64-unknown-linux-gnu"
export MABI="lp64d"
#it can only be lp64d
export BUILD_ARCH="-march=loongarch64"
export BUILD_MABI="-mabi=${MABI}"
export BUILD64="-mabi=${MABI}"
export LD_LIBRARY_PATH="${SYSDIR}/opt/cross/lib:${SYSDIR}/opt/cross/${CROSS_HOST}/lib"
export PATH=${SYSDIR}/opt/cross/bin:${PATH}
unset CFLAGS
unset CXXFLAGS
- 在工作目录内创建 opt/cross 文件夹.我们的交叉编译器会安装到这里
- 每次开始工作时,只需要
source source.sh
即可配好环境变量
2.准备源码
- GCC的源码获取比较简单,直接去这里下载最新的12.1源码即可.我是直接克隆的仓库(实际上仓库里的是13.0 汗)
- Binutils的获取就只能去仓库克隆最新版了,因为当前Binutils(2.38)的龙芯ABI名称有一些问题(和GCC那边对不上)
2.开始编译
1.Binutils
cd binutils
mkdir buildL
cd buildL
../configure --prefix=${SYSDIR}/opt/cross --build=${CROSS_HOST} --host=${CROSS_HOST} \
--target=${CROSS_TARGET} --disable-gdb --disable-multilib --disable-werror --disable-static
make
make install
2.Kernel Headers
- 首先找一台正在运行的旧世界Loongnix,在/usr/src中获得内核源码. 下载到本地
- 开始前patch一下 arch/loongarch/Makefile 注释14-16行(因为我们不需要 而且默认的makefile好像对这俩的规则有问题)
cd kernel
make ARCH=loongarch INSTALL_HDR_PATH=${SYSDIR}/opt/cross/${CROSS_TARGET} headers_install
3.GCC stage1
cd gcc
./contrib/download_prerequisites
mkdir buildL
cd buildL
../configure --prefix=${SYSDIR}/opt/cross --target=${CROSS_TARGET} --enable-languages=c,c++ --disable-multilib --disable-libsanitizer #todo:这里是不是指定sysroot会好一些
#我只开了c和c++的支持,如果需要更多请修改configure选项
make -j8 all-gcc
make -j8 install-gcc
4. Glibc
由于实在是找不的旧世界用的Glibc的源码,所以只能从运行旧世界的机子上直接扒文件下来
- Headers文件,存在于
/usr/include/
中 下载全部到 ${SYSDIR}/opt/cross/${CROSS_TARGET}/include中
- .o文件
crt1.o
crti.o
crtn.o
存在于/lib64
中 下载到${SYSDIR}/opt/cross/${CROSS_TARGET}/lib\
- so文件
libc.so
libc-2.28.so
下载到同2的位置 软链libc.so.6
到libc-2.28.so
下载ld-2.28.so
,然后创建软链ld.so.1
下载libc_nonshared.a
下载libm
下载libdl.so
系列 下载libevent_pthreads-2.1.so.6.0.2
并按照原本的样式创建软链
- a文件
libc_nonshared.a
下载到同2的位置
- 调整:用文本编辑器打开下载好的
libc.so
,将里面出现的三个路径替换成当前目录。然后在AS_NEEDED中再追加(同样需要绝对路径)libdl.so.2
- 下载
libpthread
和libm
的相关文件,并按照/lib64
内的形式创建对应的软链
5.GCC stage2
cd gcc
cd buildL
make -j8 all-target-libgcc
make install-target-libgcc
6.Libstdc++
cd gcc
cd buildL
make -j8
make install
至此所有编译结束,使用loongarch64-unknown-linux-gnu-gcc -v
命令应该找到GCC
3.不足
唯一的一个不足,就是编译出来的程序总觉得自己的interpreter是 /lib64/ld-linux-loongarch-lp64d.so.1
但正确的应该是/lib64/ld.so.1
这个问题我目前没有特别好的办法,感觉是链接脚本出了问题,但是又不知道究竟是哪里.有一个简单的解决方案就是直接软链一份ld-linux-loongarch-lp64d.so.1
到/lib64/ld.so.1
附:成品截