When cross-compiling for RISC-V with Zig I believe you do something like this:
pub fn build(b: *std.Build) void {
const target = b.resolveTargetQuery(.{
.cpu_arch = .riscv32,
.abi = .ilp32,
.os_tag = .freestanding,
});
...
But how do you enable other extensions? There's a cpu_features_add field but it seems to be some kind of bitfield and I can't figure out what to do with it.
For example how would you set this -march ISA string?
RV64IMAFDC_Svinval_Zicsr_Zifencei_Zba_Zbb_Zbs_Zicbom_Zicbop
Bonus question: how do you set the ABI to ilp32f or ilp32d? Or even lp64 - that seems to be missing from Abi, though it does exist in CallingConvention?
To specify what CPU features you want in a target query, you use cpu_features_add:
b.resolveTargetQuery(.{
.cpu_arch = .riscv32,
.os_tag = .freestanding,
.cpu_features_add = Target.riscv.featureSet(&.{ .i, .m, .a, .f, .d, .c, .svinval, .zicsr, .zifencei, .zba, .zbb, .zbs, .zicbom, .zicbop }),
});
Although undocumented, a cursory glance at std.Target reveals RISC-V is unaffected by the ABI tag:
riscv32 is always a variant of ilp32; ilp32f or ilp32d seem, going by the glibc interpreter selection logic, to be implicit: it is ilp32d if your target feature set has d, ilp32f if you don't but have f, and ilp32 failing that.riscv64 is always lp64.