Appendix A: EDK2 Build System
This appendix provides a comprehensive reference for the four core file formats used by the EDK2/Project Mu build system: INF (module description), DEC (package declaration), DSC (platform description), and FDF (flash description). It also covers build commands and how stuart wraps the traditional build flow.
A.1 Build System Overview
The EDK2 build system transforms source code and metadata files into firmware images. The flow is:
- DSC (Platform Description) defines what modules to build, which packages to use, and how libraries are resolved.
- INF (Module Information) describes each individual module – its sources, dependencies, and GUIDs.
- DEC (Package Declaration) defines what a package exports – protocols, GUIDs, PCDs, include paths.
- FDF (Flash Description) describes the firmware volume layout and how built modules are placed into the final flash image.
The build command (or stuart_build) reads these files, generates Makefiles, compiles sources, and links binaries.
A.2 INF File Format (Module Information)
The INF file describes a single buildable module (driver, application, library, etc.).
[Defines] Section
[Defines]
INF_VERSION = 0x00010017
BASE_NAME = MyDriver
FILE_GUID = 12345678-1234-5678-9ABC-DEF012345678
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = MyDriverEntryPoint
# Optional defines:
# UEFI_SPECIFICATION_VERSION = 0x00020070
# PI_SPECIFICATION_VERSION = 0x00010032
# LIBRARY_CLASS = MyLib|DXE_DRIVER
# CONSTRUCTOR = MyLibConstructor
# DESTRUCTOR = MyLibDestructor
# UNLOAD_IMAGE = MyDriverUnload
| Field | Required | Description |
|---|---|---|
INF_VERSION |
Yes | INF specification version (use 0x00010017 or later) |
BASE_NAME |
Yes | Module name used in build output |
FILE_GUID |
Yes | Unique GUID identifying this module in firmware volumes |
MODULE_TYPE |
Yes | One of: BASE, SEC, PEI_CORE, PEIM, DXE_CORE, DXE_DRIVER, DXE_RUNTIME_DRIVER, DXE_SMM_DRIVER, SMM_CORE, UEFI_DRIVER, UEFI_APPLICATION |
VERSION_STRING |
No | Human-readable version |
ENTRY_POINT |
Yes* | Entry point function name (*not for BASE library modules) |
LIBRARY_CLASS |
No | Declares this module as a library implementation |
CONSTRUCTOR |
No | Library constructor called at module load |
DESTRUCTOR |
No | Library destructor called at module unload |
UNLOAD_IMAGE |
No | Function called when driver is unloaded |
[Sources] Section
Lists all source files for the module. Architecture-specific sections are supported.
[Sources]
MyDriver.c
MyDriver.h
Utils.c
[Sources.X64]
X64/AsmHelper.nasm
[Sources.IA32]
Ia32/AsmHelper.nasm
[Sources.AARCH64]
AArch64/ArmHelper.S
[Packages] Section
Lists package DEC files that provide includes, protocols, and GUIDs.
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
MyPlatformPkg/MyPlatformPkg.dec
[LibraryClasses] Section
Lists library class dependencies. The DSC file resolves these to concrete implementations.
[LibraryClasses]
UefiDriverEntryPoint
UefiBootServicesTableLib
UefiLib
BaseMemoryLib
DebugLib
MemoryAllocationLib
[Protocols] Section
Lists protocol GUIDs consumed or produced by this module.
[Protocols]
gEfiPciIoProtocolGuid ## CONSUMES
gEfiDriverBindingProtocolGuid ## PRODUCES
gEfiComponentNameProtocolGuid ## PRODUCES
The ## CONSUMES / ## PRODUCES comments are conventions for documentation; the build system does not enforce them.
[Guids] Section
Lists non-protocol GUIDs used by the module (configuration table entries, variable namespaces, etc.).
[Guids]
gEfiGlobalVariableGuid
gEfiAcpi20TableGuid
gEfiFileInfoGuid
[Ppis] Section (PEI modules only)
[Ppis]
gEfiPeiReadOnlyVariable2PpiGuid ## CONSUMES
gEfiPeiMemoryDiscoveredPpiGuid ## SOMETIMES_CONSUMES
[Pcd] Sections
PCDs (Platform Configuration Database) are build-time and run-time configurable values.
[Pcd]
gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask
[FixedPcd]
gEfiMdePkgTokenSpaceGuid.PcdMaximumUnicodeStringLength
[FeaturePcd]
gEfiMdePkgTokenSpaceGuid.PcdComponentNameDisable
[PatchPcd]
gMyPkgTokenSpaceGuid.PcdMyPatchableValue
| PCD Type | Description | Set At |
|---|---|---|
FixedAtBuild |
Compiled as constants | Build time |
PatchableInModule |
Stored in PE data section, patchable post-build | Build or flash tool |
DynamicDefault |
Stored in PCD database | Boot time |
DynamicHii |
Backed by HII variable | Boot time |
DynamicVpd |
Stored in VPD region | Manufacturing |
FeatureFlag |
Boolean feature toggle | Build time |
[Depex] Section
Dependency expression for dispatch ordering (DXE/PEI).
[Depex]
gEfiPciIoProtocolGuid AND
gEfiDevicePathProtocolGuid
[BuildOptions] Section
Module-specific compiler/linker flags.
[BuildOptions]
GCC:*_*_*_CC_FLAGS = -Wno-unused-variable
MSFT:*_*_*_CC_FLAGS = /wd4201
The format is TOOL:TARGET_TOOLCHAIN_ARCH_ATTRIBUTE = flags.
[UserExtensions] Section
Vendor-specific extensions; ignored by the base build system.
A.3 DEC File Format (Package Declaration)
The DEC file declares what a package exports to other packages.
[Defines] Section
[Defines]
DEC_SPECIFICATION = 0x00010017
PACKAGE_NAME = MyPlatformPkg
PACKAGE_GUID = AABBCCDD-1111-2222-3333-444455556666
PACKAGE_VERSION = 1.0
[Includes] Section
Public include directories available to consumers of this package.
[Includes]
Include
[Includes.X64]
Include/X64
[Includes.IA32]
Include/Ia32
[LibraryClasses] Section
Declares library classes with their header file locations.
[LibraryClasses]
MyCustomLib|Include/Library/MyCustomLib.h
PlatformHookLib|Include/Library/PlatformHookLib.h
[Guids] Section
[Guids]
gMyPkgTokenSpaceGuid = { 0x12345678, 0xABCD, 0xEF01, { 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01 }}
gMyCustomEventGuid = { 0xAABBCCDD, 0x1122, 0x3344, { 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC }}
[Protocols] Section
[Protocols]
gMyCustomProtocolGuid = { 0x11111111, 0x2222, 0x3333, { 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB }}
[Ppis] Section
[Ppis]
gMyPeiServicePpiGuid = { 0xDDDDDDDD, 0xEEEE, 0xFFFF, { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 }}
[PcdsFixedAtBuild], [PcdsPatchableInModule], [PcdsDynamic], etc.
[PcdsFixedAtBuild]
gMyPkgTokenSpaceGuid.PcdMyBufferSize|0x1000|UINT32|0x00000001
[PcdsFeatureFlag]
gMyPkgTokenSpaceGuid.PcdEnableMyFeature|TRUE|BOOLEAN|0x00000002
The format is: TokenSpaceGuid.PcdName|DefaultValue|DatumType|TokenNumber
A.4 DSC File Format (Platform Description)
The DSC is the top-level build configuration for a platform. It ties everything together.
[Defines] Section
[Defines]
PLATFORM_NAME = MyPlatformPkg
PLATFORM_GUID = 99887766-5544-3322-1100-AABBCCDDEEFF
PLATFORM_VERSION = 1.0
DSC_SPECIFICATION = 0x0001001C
OUTPUT_DIRECTORY = Build/MyPlatform
SUPPORTED_ARCHITECTURES = IA32|X64
BUILD_TARGETS = DEBUG|RELEASE|NOOPT
SKUID_IDENTIFIER = DEFAULT
[LibraryClasses] Section
Maps abstract library class names to concrete INF implementations.
[LibraryClasses]
# Base libraries -- used by all module types
BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
BaseMemoryLib|MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.inf
PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
[LibraryClasses.common.DXE_DRIVER]
# DXE-specific library mappings
UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
[LibraryClasses.common.UEFI_APPLICATION]
UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf
ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf
The format for scoped sections is [LibraryClasses.ARCH.MODULE_TYPE].
[Components] Section
Lists all modules to build.
[Components]
MdePkg/Library/BaseLib/BaseLib.inf
MyPlatformPkg/Drivers/MyDxeDriver/MyDxeDriver.inf {
<LibraryClasses>
# Per-module library override
DebugLib|MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.inf
<PcdsFixedAtBuild>
gMyPkgTokenSpaceGuid.PcdMyBufferSize|0x2000
}
[Components.X64]
MyPlatformPkg/Applications/MyApp/MyApp.inf
Per-module overrides use <LibraryClasses>, <PcdsFixedAtBuild>, <BuildOptions>, etc. inside curly braces.
[PcdsFixedAtBuild] Section
[PcdsFixedAtBuild]
gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2F
gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80400040
gEfiMdePkgTokenSpaceGuid.PcdFixedDebugPrintErrorLevel|0x80400040
[PcdsDynamicDefault] Section
[PcdsDynamicDefault]
gEfiMdeModulePkgTokenSpaceGuid.PcdConOutRow|25
gEfiMdeModulePkgTokenSpaceGuid.PcdConOutColumn|80
[BuildOptions] Section
Platform-wide compiler flags.
[BuildOptions]
GCC:*_*_*_CC_FLAGS = -Werror -Wno-address
GCC:RELEASE_*_*_CC_FLAGS = -DMDEPKG_NDEBUG
MSFT:*_*_*_CC_FLAGS = /W4 /WX
A.5 FDF File Format (Flash Description)
The FDF describes how the firmware image is laid out in flash.
[FD] Section (Flash Device)
[FD.MyPlatform]
BaseAddress = 0xFF800000 # Flash base address
Size = 0x00800000 # 8 MB
ErasePolarity = 1
BlockSize = 0x00010000 # 64 KB block
NumBlocks = 0x80 # 128 blocks
# Region layout within the flash device
0x00000000|0x00040000 # Offset | Size
gMyPkgTokenSpaceGuid.PcdFlashNvStorageVariableBase|gMyPkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
DATA = {
# NV_VARIABLE_STORE header
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
}
0x00040000|0x00010000
gMyPkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase|gMyPkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
0x00050000|0x00010000
gMyPkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase|gMyPkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
0x00100000|0x00700000
FV = FVMAIN # Firmware volume at this region
[FV] Section (Firmware Volume)
[FV.FVMAIN]
FvAlignment = 16
ERASE_POLARITY = 1
MEMORY_MAPPED = TRUE
STICKY_WRITE = TRUE
LOCK_CAP = TRUE
LOCK_STATUS = TRUE
WRITE_DISABLED_CAP = TRUE
WRITE_ENABLED_CAP = TRUE
WRITE_STATUS = TRUE
WRITE_LOCK_CAP = TRUE
WRITE_LOCK_STATUS = TRUE
READ_DISABLED_CAP = TRUE
READ_ENABLED_CAP = TRUE
READ_STATUS = TRUE
READ_LOCK_CAP = TRUE
READ_LOCK_STATUS = TRUE
#
# DXE core
#
INF MdeModulePkg/Core/Dxe/DxeMain.inf
#
# DXE drivers
#
INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
INF MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
INF MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf
INF MyPlatformPkg/Drivers/MyDxeDriver/MyDxeDriver.inf
#
# Applications (optional, for shell access)
#
INF ShellPkg/Application/Shell/Shell.inf
#
# Raw files
#
FILE RAW = AABBCCDD-1122-3344-5566-778899AABBCC {
SECTION RAW = MyPlatformPkg/Binaries/logo.bmp
}
#
# FREEFORM files (e.g., for HII resources)
#
FILE FREEFORM = 11223344-5566-7788-99AA-BBCCDDEEFF00 {
SECTION UI = "MyStrings"
SECTION RAW = MyPlatformPkg/Strings/strings.bin
}
File Types in FV
| Keyword | Description |
|---|---|
INF |
Build module from INF and include in FV |
FILE RAW |
Include a raw binary blob |
FILE FREEFORM |
Free-form file with typed sections |
FILE DRIVER |
Pre-built driver binary |
FILE APPLICATION |
Pre-built application binary |
FILE FV_IMAGE |
Nested firmware volume |
Section Types
| Section | Description |
|---|---|
SECTION PE32 |
PE32+ executable code |
SECTION RAW |
Raw binary data |
SECTION UI |
User interface name string |
SECTION DXE_DEPEX |
DXE dependency expression |
SECTION PEI_DEPEX |
PEI dependency expression |
SECTION COMPRESS |
Compressed section container |
SECTION GUIDED |
Guided encapsulation (e.g., signed) |
[Rule] Section
Defines how module types are packaged into files.
[Rule.Common.DXE_DRIVER]
FILE DRIVER = $(NAMED_GUID) {
DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
UI STRING="$(MODULE_NAME)" Optional
VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
}
[Rule.Common.UEFI_APPLICATION]
FILE APPLICATION = $(NAMED_GUID) {
PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
UI STRING="$(MODULE_NAME)" Optional
}
A.6 Build Command Reference
Traditional EDK2 Build
# Set up environment (Linux)
source edksetup.sh
# Build command
build -p MyPlatformPkg/MyPlatformPkg.dsc \
-a X64 \
-t GCC5 \
-b DEBUG \
-n 8 # Parallel jobs
| Flag | Description |
|---|---|
-p |
Platform DSC file |
-a |
Target architecture (IA32, X64, AARCH64, ARM, RISCV64) |
-t |
Tool chain tag (GCC5, VS2019, VS2022, CLANGPDB, CLANGDWARF) |
-b |
Build target (DEBUG, RELEASE, NOOPT) |
-n |
Number of parallel build threads |
-m |
Build a single module INF instead of entire platform |
-D |
Define macro (e.g., -D MY_FEATURE=TRUE) |
-y |
Build report file |
-Y |
Report types (PCD, LIBRARY, FLASH, DEPEX, BUILD_FLAGS, HASH) |
Stuart Build (Project Mu)
Stuart wraps the EDK2 build with additional features:
# One-time setup: clone dependencies
stuart_setup -c Platforms/MyPlatform/PlatformBuild.py
# Update/sync dependencies
stuart_update -c Platforms/MyPlatform/PlatformBuild.py
# Build
stuart_build -c Platforms/MyPlatform/PlatformBuild.py \
TOOL_CHAIN_TAG=GCC5 \
TARGET=DEBUG
# CI build (runs build + tests)
stuart_ci_build -c .pytool/CISettings.py -a X64
Stuart advantages over raw build:
- Automatic dependency management via
ext_depYAML files - Reproducible builds with pinned dependency versions
- Integrated CI/CD with test plugins
- Simplified command-line interface
A.7 Build Output Structure
Build/
MyPlatform/
DEBUG_GCC5/
FV/
FVMAIN.Fv # Firmware volume
MYPLATFORM.fd # Flash device image
X64/
MyDriver/
MyDriver/
OUTPUT/
MyDriver.efi # Built PE32+ binary
MyDriver.map # Linker map file
MyDriver.depex # Dependency expression
MdePkg/
Library/
BaseLib/
BaseLib/
OUTPUT/
BaseLib.lib # Library archive
A.8 Build Reports
Generate a detailed build report with:
build -p MyPlatform.dsc -a X64 -t GCC5 -b DEBUG \
-y BuildReport.txt \
-Y PCD -Y LIBRARY -Y FLASH -Y DEPEX -Y BUILD_FLAGS
The report includes:
- PCD values and their sources (DSC, DEC, command-line)
- Library class resolution chains
- Flash layout with file offsets and sizes
- Dependency expressions for each module
- Compiler flags per module
This is invaluable for debugging build configuration issues.
A.9 Common Build Errors
| Error | Cause | Fix |
|---|---|---|
No library class found for X |
Missing library mapping in DSC | Add [LibraryClasses] entry |
GUID collision |
Two modules share same FILE_GUID | Generate unique GUID |
FV overflow |
Modules exceed firmware volume size | Increase FV size or remove modules |
Undefined symbol |
Missing library dependency | Add library to INF [LibraryClasses] |
Multiple definitions |
Two libraries provide same symbol | Check DSC library resolution order |
PCD not found |
Package DEC not listed in INF | Add package to INF [Packages] |
Summary
The EDK2 build system revolves around four file types: INF (module), DEC (package), DSC (platform), and FDF (flash layout). Understanding these files and their relationships is essential for working with UEFI firmware. Project Mu’s stuart system builds on this foundation with better dependency management and CI integration.