Description
Describe the bug
When attempting to build a minimal UEFI application using uefi-rs
v0.35.0 on a recent nightly Rust toolchain (specifically targeting x86_64-unknown-uefi
with -Zbuild-std
for core
and compiler_builtins
), basic items from uefi::prelude::*
(such as println!
, SystemTable
, Boot
, image_handle()
, system_table()
) are not found by the compiler. Additionally, the #[entry]
macro seems to have issues:
- If
efi_main
is defined to takeHandle
andSystemTable<Boot>
arguments (as per documentation), the build fails with "Entry function must have no arguments". - If
efi_main
is defined to take no arguments (and attempts to use the free functionsimage_handle()
andsystem_table()
), it fails because those functions (and other prelude items) are not found.
This issue is reproducible in a minimal example and also blocks a more complex project.
Environment:
uefi-rs
version:0.35.0
- Rust toolchain:
nightly
(specifically1.89.0-nightly (be19eda0d 2025-06-22)
as per build log, though therust-toolchain.toml
just specifiesnightly
) - Target:
x86_64-unknown-uefi
- Build host OS (if relevant, this is a sandboxed environment): Linux-based
build-std
configuration:build-std = ["core", "compiler_builtins"]
withbuild-std-features = ["compiler-builtins-mem"]
To Reproduce
Steps to reproduce the behavior:
-
Set up the following minimal project structure and files:
uefi_minimal_test/Cargo.toml
[package] name = "uefi_minimal_test" version = "0.1.0" edition = "2021" [dependencies] uefi = { version = "0.35.0", features = ["logger", "panic_handler"] } [profile.dev] panic = "abort" [profile.release] panic = "abort"
uefi_minimal_test/.cargo/config.toml
[unstable] build-std = ["core", "compiler_builtins"] build-std-features = ["compiler-builtins-mem"] [build] target = "x86_64-unknown-uefi"
uefi_minimal_test/rust-toolchain.toml
[toolchain] channel = "nightly"
uefi_minimal_test/src/main.rs
(this version hasefi_main()
taking no arguments)#![no_std] #![no_main] use core::panic::PanicInfo; use uefi::prelude::*; #[entry] fn efi_main() -> Status { let _image_handle = match image_handle() { Ok(h) => h, Err(_e) => { return Status::LOAD_ERROR; } }; let st_ptr = match system_table() { Ok(ptr) => ptr, Err(_e) => { return Status::LOAD_ERROR; } }; let mut _system_table = unsafe { SystemTable::<Boot>::from_ptr(st_ptr).unwrap() }; println!("Hello from UEFI Minimal Test!"); loop { unsafe { core::arch::asm!("pause") }; } } // Panic handler is provided by the "panic_handler" feature of the `uefi` crate. /* #[panic_handler] fn panic(_info: &PanicInfo) -> ! { loop {} } */
-
Ensure the target and
rust-src
are installed:rustup target add x86_64-unknown-uefi rustup component add rust-src --toolchain nightly
(These steps were performed in the environment)
-
Run the build command from the directory containing
uefi_minimal_test
(e.g.,/app
ifuefi_minimal_test
is in/app
):cargo +nightly build --manifest-path uefi_minimal_test/Cargo.toml --target x86_64-unknown-uefi
(Or
cd uefi_minimal_test && cargo +nightly build --target x86_64-unknown-uefi
)
Expected behavior
The minimal application should compile successfully. If efi_main
takes arguments, #[entry]
should handle it. If efi_main
takes no arguments, items from uefi::prelude::*
like println!
, image_handle()
, system_table()
, SystemTable
, Boot
should be resolved.
Actual behavior
The build fails with errors indicating that items from uefi::prelude::*
cannot be found.
Full Build Log:
Compiling uefi_minimal_test v0.1.0 (/app/uefi_minimal_test)
error: cannot find macro `println` in this scope
--> src/main.rs:26:5
|
26 | println!("Hello from UEFI Minimal Test!"); // Use prelude's println
| ^^^^^^^
|
help: consider importing this macro
|
4 + use uefi::println;
|
error[E0425]: cannot find function `image_handle` in this scope
--> src/main.rs:11:31
|
11 | let _image_handle = match image_handle() {
| ^^^^^^^^^^^^ not found in this scope
|
help: consider importing one of these functions
|
4 + use crate::boot::image_handle;
|
4 + use uefi::boot::image_handle;
|
error[E0412]: cannot find type `Boot` in this scope
--> src/main.rs:24:52
|
24 | let mut _system_table = unsafe { SystemTable::<Boot>::from_ptr(st_ptr).unwrap() };
| ^^^^ not found in this scope
|
help: you might be missing a type parameter
|
8 | fn efi_main<Boot>() -> Status { // No arguments
| ++++++
warning: unused import: `core::panic::PanicInfo`
--> src/main.rs:4:5
|
4 | use core::panic::PanicInfo;
| ^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(unused_imports)]` on by default
error[E0425]: cannot find function `system_table` in this scope
--> src/main.rs:18:24
|
18 | let st_ptr = match system_table() {
| ^^^^^^^^^^^^ not found in this scope
error[E0433]: failed to resolve: use of undeclared type `SystemTable`
--> src/main.rs:24:38
|
24 | let mut _system_table = unsafe { SystemTable::<Boot>::from_ptr(st_ptr).unwrap() };
| ^^^^^^^^^^^ use of undeclared type `SystemTable`
Some errors have detailed explanations: E0412, E0425, E0433.
For more information about an error, try `rustc --explain E0412`.
warning: `uefi_minimal_test` (bin "uefi_minimal_test") generated 1 warning
error: could not compile `uefi_minimal_test` (bin "uefi_minimal_test") due to 5 previous errors; 1 warning emitted
If src/main.rs is changed so efi_main takes _image_handle: Handle, mut system_table: SystemTable<Boot> arguments, the error changes to: error: Entry function must have no arguments
Additional context
This issue was encountered while trying to set up a more complex kernel project (torux), and the minimal example was created to isolate the problem. The torux project experiences the same uefi module/item resolution failures.
The torux project also consistently fails with "no global memory allocator found but one is required", even with a #[global_allocator] defined and extern crate alloc;. This error also appears in the minimal example if alloc types are used and uefi = { features = ["alloc"]} is enabled alongside build-std = [..., "alloc"]. For the provided minimal example, alloc usage was removed to focus on the prelude/entry macro issue.
The problem persists across various attempts to configure build-std (with/without "alloc") and uefi crate features.
The cargo tree for the minimal example (and the more complex project) shows uefi v0.35.0 as a direct dependency.
Any guidance on what might be causing this apparent failure to resolve standard uefi-rs prelude items and #[entry] macro behavior would be greatly appreciated.