Builds a UEFI application from real TianoCore EDK II MdePkg sources with badc, for X64 and AArch64, and boots each under OVMF/QEMU.
badc compiles the MdePkg library closure and links a PE32+ EFI
application with its own linker – no external ld/lld, no
GenFw – that a UEFI firmware loads and runs.
The app (MyApp.c) formats through EDK II’s own UnicodeSPrint
(BasePrintLib) and writes to ConOut, so a correct boot exercises the whole
closure end to end.
cargo build --release --features full # build badc
python3 demos/edk2/setup.py # fetch the MdePkg subset
python3 demos/edk2/smoke.py # build the .efi + boot it
Committed: the hand-written glue that a full EDK II build would generate with
BaseTools AutoGen – AutoGenGlue.c (the module entry glue, PCD database, and
library constructor/destructor lists), MiniAutoGen.h (the FixedAtBuild PCD
defaults), and the application MyApp.c – plus the qemu_efi.py boot
harness. setup.py fetches the MdePkg source subset (headers + the closure’s
C files, ~1.8 MB) from the vendor mirror into src/.
badc uses the MSVC compiler identity on X64 (EFIAPI = the MS x64 ABI, which
badc’s windows-x64 target already emits):
badc --freestanding --target=windows-x64
-I MdePkg/Include -I MdePkg/Include/X64
-D_MSC_EXTENSIONS -D_MSC_VER=1900 -Dstatic_assert=_Static_assert
-include MiniAutoGen.h <MyApp.c + AutoGenGlue.c + MdePkg closure> -o app.efi
The library closure (UefiApplicationEntryPoint, the boot/runtime services
table libs, BasePrintLib, BaseMemoryLib, and the BaseLib math / string /
unaligned helpers) was resolved iteratively – link, read the first undefined
symbol, add the MdePkg C file that defines it, repeat – and is fixed in
smoke.py.
smoke.py verifies the output is a PE32+ EFI application (machine x64,
subsystem 10). If qemu-system-x86_64 and OVMF firmware are present it also
boots the image (placed as EFI/BOOT/BOOTX64.EFI on a virtual FAT volume that
OVMF auto-boots) and checks the serial output for the app’s banner; otherwise
the boot check is skipped and the build stands on its own.