efi.mk(3)

πŸ“¦ version 3.0.11, in centos-stream 9

πŸ’… efi.mk(3) β€” the group-chat guide

okay so bestie, welcome to efi.mk(3), straight out of the Library Functions Manual ✨ this whole page is literally about one makefile include that makes EFI binaries happen. buckle up πŸŽ€


🌸 NAME 🌸

efi.mk β€” the makefile include that builds EFI binaries for you, no cap πŸ‘‘


✨ SYNOPSIS ✨

include efi.mk

that's it. that's the whole vibe check. one line and you're in 🫢


πŸ’– DESCRIPTION πŸ’–

So the gnu-efi library ships a set of makefiles that produce EFI binaries on the supported platforms, plus a whole bunch of make variables you can set to control how each step gets built πŸ”₯ You can set these in your makefile or on the command line β€” but ngl they're normally set to reasonable defaults already, so most of the time you're just gonna use the += operator (like in the EXAMPLES section below) rather than fully replacing them. Replacement is a whole thing; appending is the main character move πŸ’…


🧚 make variables

  • EFI_ARCH_CFLAGS β€” architecture-specific gcc command line options for building a .efi.o πŸ¦‹
  • EFI_ARCH_LDFLAGS β€” architecture-specific ld command line options for building the .efi.so 🌈
  • EFI_ARCH_FORMAT β€” architecture-specific objcopy arguments for building the final .efi binary ⭐
  • CROSS_COMPILE β€” the compiler prefix for cross-compilation. like, for example, "aarch64-linux-gnu-" πŸ’€
  • EFI_CC β€” the C compiler. defaults to either $(CROSS_COMPILE)gcc or $(CROSS_COMPILE)clang, depending on what $(CC) was set to when gnu-efi was built πŸ“
  • EFI_HOSTCC β€” defaults to whatever $(CC) was set to when gnu-efi was built πŸ‘€
  • EFI_HOSTARCH β€” one of aa64, arm, ia32, ia64, x64, or mips64el, representing the EFI architecture name of the host machine during the build πŸ–₯️
  • EFI_ARCH β€” one of aa64, arm, ia32, ia64, x64, or mips64el, representing the EFI architecture name of the target 🎯
  • EFI_BFDARCH β€” the architecture name for the BFD target for objcopy πŸŽ€
  • EFI_ARCH_3264 β€” usually empty; if you're cross compiling, this will default to e.g. -m64 if you're building for an x64 target on an i686 host 🀯
  • EFI_CC_INCLUDES β€” the list of default include paths for the compiler, as a gcc command line argument. defaults to the output of $(EFI_CC) $(EFI_ARCH_3264) -print-file-name=include, for example /usr/lib/gcc/x86_64-redhat-linux/9/include. note that there is no -I prefix on these ⚠️
  • EFI_INCLUDES β€” the gnu-efi include paths. note that there is no -I prefix on these either πŸ™ˆ
  • EFI_CPPFLAGS β€” flags passed to gcc regardless of the build target πŸ’œ
  • EFI_CFLAGS β€” flags passed to gcc for building any binary target. defaults to $(EFI_CPPFLAGS) $(EFI_ARCH_CFLAGS) πŸ”₯
  • EFI_LDSCRIPT β€” the linker script passed to ld -T for linking .efi.so build targets. defaults to /usr/lib/gnuefi/$(EFI_ARCH)/efi.lds πŸ“œ
  • EFI_LIBGCC β€” the path to libgcc. defaults to the result of $(EFI_CC) $(EFI_ARCH_3264) -print-libgcc-file-name 🧚
  • EFI_LDFLAGS β€” other command line to pass to ld before object names. defaults to -nostdlib --warn-common --no-undefined --fatal-warnings --build-id=sha1 -shared -Bsymbolic -L/usr/lib/gnuefi/$(EFI_ARCH) /usr/lib/gnuefi/$(EFI_ARCH)/crt0.o πŸ’…
  • EFI_CCLDFLAGS β€” normally derived from $(EFI_LDFLAGS) 🌸
  • EFI_LDLIBS β€” libraries to pass to ld after target object names. defaults to -lefi -lgnuefi $(EFI_LIBGCC) -T $(EFI_LDSCRIPT) πŸ“š
  • EFI_CCLDLIBS β€” derived from $(EFI_LDLIBS) 🫢
  • EFI_ARFLAGS β€” flags to pass to ar to make a .efi.a target. defaults to "rDv" πŸ—ƒοΈ
  • EFI_ASFLAGS β€” flags to pass to gcc to make a .efi.o object from a .S file βš™οΈ
  • EFI_OBJCOPY_FLAGS β€” flags to pass to objcopy to make a .efi binary target. defaults to --file-alignment 512 --section-alignment 4096 -D βœ‚οΈ
  • EFI_BIN_SECTIONS β€” names of sections to go into .efi binary targets. if you have special sections, add them here πŸ‘‘
  • EFI_DEBUG_SECTIONS β€” names of sections to go into .efi.debug targets. if you have special debug sections, add them here πŸ”

πŸ¦‹ the make rules

in addition, there are several make rules defined, which those variables affect as appropriate:

  • %.efi : %.efi.so β€” build a .efi binary ✨
  • %.efi.debug : %efi.so β€” build debuginfo πŸ›
  • %.efi.so : β€” build the intermediate .efi.so to be linked as a .efi binary. add .o files as dependencies to a concrete .efi.so rule in order to define targets 🧩
  • %.efi.a : β€” build an intermediate archive file for linking into a .efi.so πŸ“¦
  • %.efi.o : %.c β€” build an object file from a .c file πŸ’œ
  • %.efi.o : %.S β€” build an object file from a .S file πŸ’œ
  • efi_clean : β€” remove all files in the current working directory with the suffixes .efi, .efi.a, .efi.debug, .efi.o, or .efi.so. the ultimate glow-up cleanse 🧼

πŸŽ€ EXAMPLES πŸŽ€

ok so here's a simple makefile used to build an EFI binary named foo.efi from source files foo.c and bar.c πŸ’– It includes the special section .weird in the final binary, and the name of that is defined within the .c source files using the macro WEIRD_SECTION_NAME:

include efi.mk
all : foo.efi
%.efi.o : | EFI_CFLAGS+=-DWEIRD_SECTION_NAME=\".weird\"
foo.efi : | EFI_BIN_SECTIONS+=.weird
foo.efi.so : foo.efi.o bar.efi.o
clean : efi_clean

the following example shows how to cross-compile a binary for another architecture (in this case, ARM Aarch64, which EFI calls aa64). this assumes that you have the crt0.o, efi.lds, libgnuefi.a, and libefi.a files for Aarch64 installed in /usr/lib/gnuefi/aa64/ 🌍

$ make CROSS_COMPILE=aarch64-linux-gnu- EFI_ARCH=aa64 foo.efi

πŸ‘‘ AUTHORS πŸ‘‘

Peter Jones <pjones@redhat.com> β€” thank you icon, we stan 🫢


and that's the whole page bestie, go forth and build some EFI binaries πŸ’…βœ¨

okay and for the cute sign-off β€” this page is dated Thu Nov 21 2019, and it's from the efi.mk(3) manual, so that's the source + version + date combo, mwah πŸŽ€ bye!!

πŸ“¦ where this page comes from