I am having a lot of issues trying to properly cross compile Rust for UEFI platforms.
UEFI platforms work the same as x64 Windows platforms, except that there is no standard library, and the subsystem flag in the binary is set to a different value.
My workflow currently exists out of compiling a static library for Windows, and using the LLVM linker (lld-link
) to change the subsystem and setting the flag manually.
I would like to have rustc do the extra linking step for me, but this is way harder than I initially hoped it would be. I have created a x86_64-uefi.json
target specification, which is mostly based on x86_64-pc-windows-msvc
, with a few differences.
- I am trying to use
lld-link
as my linker. - I have
is-like-msvc
set to false (the default) as that makes rustc convinced it has to uselink.exe.
, which doesn't exist on a Linux system. - I removed some options which don't particularly matter.
This does not compile at all, it complains about a lot of duplicate symbols regarding __rustc_debug
which is apparently defined twice in the crate I am currently trying to compile.
lld-link: error: duplicate symbol: __rustc_debug_gdb_scripts_section__ in /home/jeroen/documents/code/krnl/target/x86_64-uefi/debug/deps/bootloader-ec23bf905be24708.170lmw1sqqfe80qo.rcgu.o andin /home/jeroen/documents/code/krnl/target/x86_64-uefi/debug/deps/bootloader-ec23bf905be24708.4ypvbwho0bu5tnww.rcgu.o
These are removed by compiling with --release
, which lead rustc to complain about things like memcpy not working. I don't use that function, but I understand that core requires it, which I had to pull in as a dependency to get it to even compile ("panic_fmt" language item depends on core). An inclusion of rlibc fixed this.
The error now moved on to the following:
= note: lld-link: warning: <root>: undefined symbol: mainCRTStartup
lld-link: warning: libcore-05daa184684cea15.rlib(core-05daa184684cea15.core0-27b18eff33e66842f5421e6bbff77609.rs.rcgu.o): undefined symbol: __udivti3
error: link failed
This is an error I cannot solve, and I have no idea how this is possible either. The mainCRTStartup
symbol is presumably called by rustc to start the C runtime, which I don't want. The __udivti3
symbol is apparently used by the core crate, and unsure how to fix that.
TL;DR: I want to get rust to compile some code without any runtime or any dependencies. Just bare metal. How do I achieve this?