-
-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make Zig code compile for riscv64-linux target (with or without glibc) #18815
Conversation
To provide a baseline, on master I can build a riscv64 hello-world and run it w/ qemu: [master] marcus▸ zig version
0.12.0-dev.2540+776cd673f
[master] marcus▸ cat z0.zig
const std = @import("std");
pub fn main() !void {
std.log.debug("hello", .{});
}
[master] marcus▸ zig build-exe z0.zig -target riscv64-linux
[master] marcus▸ qemu-riscv64 --version
qemu-riscv64 version 8.2.0
Copyright (c) 2003-2023 Fabrice Bellard and the QEMU Project developers
[master] marcus▸ qemu-riscv64 ./z0
debug: hello |
Thanks for the detailed steps for ensuring I've got qemu-riscv64 working. I'm able to run statically linked a "hello world" Zig binary (and even if I use the statically linked Musl C library instead of the Zig library). After some Googling (and hints in some of the other ongoing Zig PRs for riscv64), I can run the dynamic executables by first doing:
(To specify the "d" flavor of linker, instead of the Zig default "...lp64.so.1", see #18803 (comment)). Then
seems to work! (At least for simple hello-world binaries.) Anyone know how to express to Zig that you want to target the different floating point ABIs? (I believe that is the only source of ABI differentiation that we need to capture for the linker?) |
@rootbeer I think we'll have to look at the difference features set in target and just "figure it out". |
Borrow the ucontext layout from Go (probably reasonable?) and fix up some missing imports for shared structures. I can compile a glibc-linked hello.zig with: zig build-exe hello.zig -lc -target riscv64-linux-gnu.2.38 -mcpu=generic_rv64 or a native Zig binary with: zig build-exe hello.zig -target riscv64-linux -mcpu=generic_rv64 But the resulting binary segfaults immediately in my (perhaps broken) qemu setup. I've no experience in riscv64, so this maybe be broken in subtle ways, but perhaps its a useful point for someone with the right hardware to make more progress. Builds on ziglang#18803
Riscv64 supports multiple ABIs, depending on how floating-point values are supported. Each ABI has its own dynamic linker, so decode the CPU and ABI features to build the right linker path.
f46e9a6
to
ff5cea3
Compare
I've (force) pushed an updated tree that builds the target dynamic linker path based on the CPU/ABI for riscv{32,64} dynamic binaries. With my tree I can use zig to build Zig-source or C-source "hello world" binaries and run them with qemu. The Zig code can be standalone or linked to glibc or musl, and the C-source can be linked to glibc or musl. AFAICT, I can only target the double-float register ABI with Zig, via the "riscv64-linux-gnu" or "riscv64-linux-musl" targets. I'm not sure if that list of targets needs to be expanded (e.g., with "*-gnueabihf" flavors), or if the It also isn't clear to me which variations fp ABIs glibc supports. (I assume Zig wants to support all the variations.) Finally, I'm "testing" the floating-point ABI by invoking |
Still a draft, has conflicts with master branch, not touched for over 30 days. Feel free to reopen when you have something ready for review. |
(Probably incomplete) patches to make Zig code compile for riscv64-linux target (with or without glibc). Builds on #18803.
With these patches I can compile a glibc-linked
hello.zig
with (I'm on an x86_64 Linux host):or a native Zig binary with:
But the resulting binary segfaults immediately in my (perhaps broken) qemu setup. I've no experience in riscv64, so this maybe be broken in subtle ways, but perhaps its a useful point for someone with the right hardware to make more progress.