您尚未登录。

#1 2023-11-14 23:24:03

matrikslee
会员
注册时间: 2017-04-21
帖子: 441
个人网站

关于官方仓库的riscv bare-metal gcc交叉编译器工具链的一些碎碎念

官方仓库的riscv bare-metal 也就是裸金属 gcc 交叉编译器需要使用 extra/riscv64-elf-gcc 这个包

如果项目需要链接的c库要使用newlib的话,需要安装 extra/riscv64-elf-newlib, 如果是riscv32则是extra/riscv32-elf-newlib

不得不说这套东西简直没法用啊, 之前一直没搞懂怎么交叉编译目标是riscv32imac平台的项目,因为只是添加-march=rv32imac_zicsr -mabi=ilp32是不够的,在使用newlib-nano作为链接c库的时候,需要指定--specs=nano.specs (--specs=nosys.specs) 前者是必要的,后者是可选,然后编译器就会抱怨说找到nano.specs,如果加上后者,它也会抱怨说找不到,然后呢我尝试去掉--specs参数试试看,编译器又会抱怨说将32位的目标文件和64为的库文件进行链接。

以上这些是很长一段时间之前开始想直接使用archlinux 官方仓库提供的bare-metal riscv交叉编译工具链的时候遇到的问题,因为工具的使用不得要领,就暂时放下了。(一直以来都是使用的xpack打包的工具链 https://github.com/xpack-dev-tools/risc … -gcc-xpack  对我来说这个工具链是开箱即用的,所以我从aur抄了份打包预编译二进制包的PKGBUILD提了个PR到cn repo,希望好心的管理能通过一下)

今天晚上想着继续研究这个工具链的问题,突然想到是不是sysroot不对导致的,果然,简单的查阅了一下手册后使用riscv64-elf-gcc -print-sysroot检查一下默认的sysroot,然后我就不得不着重吐槽这个工具链的默认行为了,在指定了-march= 和 -mabi参数的情况下,编译器不会自动切换sysroot到32位目录(是因为它不知道默认的32位sysroot位置吗?)

然后,我手动指定了sysroot(通过添加--sysroot = /usr/riscv32-elf-gcc/ 这个参数),然后这个工具链又神奇的给我报链接错误了

 /usr/lib/gcc/riscv64-elf/12.2.0/../../../../riscv64-elf/bin/ld: /usr/riscv32-elf/lib/libg_nano.a(lib_a-errno.o): can't link double-float modules with soft-float modules 

在指定了-march的情况下,它没有去链接sysroot目录下 指令集对应子目录 lib,而是直接链接到默认拓展指令集的库(带浮点指令集的)

newlib包提供的库内容如下:

$ pacman -Ql riscv32-elf-newlib
... //省略头文件目录
riscv32-elf-newlib /usr/riscv32-elf/lib/
riscv32-elf-newlib /usr/riscv32-elf/lib/crt0.o
riscv32-elf-newlib /usr/riscv32-elf/lib/libc.a
riscv32-elf-newlib /usr/riscv32-elf/lib/libc_nano.a
riscv32-elf-newlib /usr/riscv32-elf/lib/libg.a
riscv32-elf-newlib /usr/riscv32-elf/lib/libg_nano.a
riscv32-elf-newlib /usr/riscv32-elf/lib/libgloss.a
riscv32-elf-newlib /usr/riscv32-elf/lib/libm.a
riscv32-elf-newlib /usr/riscv32-elf/lib/libnosys.a
riscv32-elf-newlib /usr/riscv32-elf/lib/libsim.a
riscv32-elf-newlib /usr/riscv32-elf/lib/nano.specs
riscv32-elf-newlib /usr/riscv32-elf/lib/nosys.specs
riscv32-elf-newlib /usr/riscv32-elf/lib/rv32i/ilp32/*(省略名字同上的.a和.specs文件名)
riscv32-elf-newlib /usr/riscv32-elf/lib/rv32iac/ilp32/*
riscv32-elf-newlib /usr/riscv32-elf/lib/rv32im/ilp32/*
riscv32-elf-newlib /usr/riscv32-elf/lib/rv32imac/ilp32/*
riscv32-elf-newlib /usr/riscv32-elf/lib/rv32imfc/ilp32f/*
... //省略下面的rv64拓展指令集库文件目录(虽然我也奇怪为什么32位包里面会放64位库)

研究了一番发现也就是说我还得想办法告诉编译器工具链,它需要使用/usr/riscv32-elf/lib/下子目录的库文件,而不是直接使用/usr/riscv32-elf/lib/目录下的库,没有发现办法。

哦对了,因为找错了要链接的c库目标,连接器还给报了 undefined reference to `__clzsi2' 找不到一个builtin 函数的错误,也是服了,检查了一下,这个好像是针对mcu平台才会实现?

还有一点就是,即是在正确指定了sysroot之后,如果只指定--specs=nano.specs而不指定--specs=nosys.specs,工具链还会先报找不到libgloss_nano库,因为riscv32-elf-newlib包没有提供这个库文件,也是绝了,nano.specs是riscv32-elf-newlib包提供的,然后它们自相矛盾?

现在这套工具链给我的感觉就是维护者自己其实也没使用它跑过bare-metal项目的交叉编译。

发个帖子将问题记录一下,也不知道究竟是我漏了相关参数(没有正确使用工具)导致的,还是这个工具链本身有问题。

最近编辑记录 matrikslee (2023-11-14 23:28:47)

离线

#2 2023-11-17 14:04:09

zsrkmyn
lazy...
注册时间: 2013-05-05
帖子: 331

Re: 关于官方仓库的riscv bare-metal gcc交叉编译器工具链的一些碎碎念

emm 不知道为什么 Arch 只提供了 rv64 gcc。我的认知里 rv32 和 rv64 一直是分开的两套 toolchain。

https://github.com/riscv-collab/riscv-g … n/releases

离线

页脚