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-linkas my linker.
- I have
is-like-msvcset to false (the default) as that makes rustc convinced it has to use
link.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?