EDK2 PyTool Library
The edk2-pytool-library is a Tianocore-maintained Python library, currently at version 0.23.13, that supports UEFI EDK2 firmware development. It provides modules for tasks such as parsing EDK2-specific file types, encoding/decoding UEFI binary structures, wrapping system CLI tools (e.g., signtool), and offering general utilities like logging and path resolution. Its intent is to provide reusable python code and is typically consumed by other tools and scripts, rather than directly by end-users via command-line interfaces. It is released on an ongoing basis, with minor releases for each merged pull request.
Warnings
- gotcha It is strongly recommended to use Python virtual environments when working with `edk2-pytool-library` (and related EDK2 tools). This helps prevent dependency conflicts with other Python projects and ensures a consistent development environment. This recommendation is consistently highlighted in the official documentation for both the library and related tools.
- gotcha The EDK2 build system (which `edk2-pytool-library` supports) is sensitive to spaces in certain environment variables. `WORKSPACE`, `PACKAGES_PATH`, and `EDK_TOOLS_BIN` must not contain space characters, even if the operating system permits them.
- breaking The Project Mu Python packages for UEFI support and build tools have migrated to Tianocore and are now leveraged through `edk2-pytools`. This change implies that older build setups or documentation referencing Project Mu's tools may be outdated and require updates to align with the new `edk2-pytools` ecosystem.
- gotcha The `Edk2Path` class performs expensive package path and package validation during instantiation. If you are repeatedly using the same workspace root and packages path, it is strongly suggested to instantiate `Edk2Path` only once and pass that single instance to all consumers to avoid performance overhead.
- breaking An issue was reported (June 2023) where Capsule Update fails from the OS due to changes in `inf_generator`, specifically an integrity file's location not being updated alongside other changes, leading to a 'file not found' error.
Install
-
pip install --upgrade edk2-pytool-library
Imports
- Edk2Path
from edk2toollib.path_utilities import Edk2Path
- PrintFileData
from edk2toollib.utility_functions import PrintFileData
Quickstart
from edk2toollib.path_utilities import Edk2Path
from pathlib import Path
import tempfile
# Create a dummy workspace and package for demonstration
with tempfile.TemporaryDirectory() as tmpdir:
workspace_path = Path(tmpdir) / "edk2_workspace"
package_path = workspace_path / "MyPkg"
(package_path / "MyModule").mkdir(parents=True)
(package_path / "MyModule" / "MyModule.inf").touch()
workspace_path.mkdir()
package_path.mkdir()
# Instantiate Edk2Path - note the performance warning in warnings section
edk2_path_obj = Edk2Path(ws=workspace_path, package_path_list=[package_path])
# Example: Get an EDK2 relative path
abs_module_path = package_path / "MyModule" / "MyModule.inf"
edk2_relative_path = edk2_path_obj.GetEdk2RelativePathFromAbsolutePath(str(abs_module_path))
print(f"EDK2 Relative Path: {edk2_relative_path}")
# Example using a utility function (requires a file to print)
test_file = Path(tmpdir) / "test.txt"
test_file.write_text("Hello, EDK2!")
print("\nPrinting file data:")
# PrintFileData is often used internally, no direct output capturing shown here for simplicity
# The function itself prints to console, so we can't easily assert its output without mocking sys.stdout
# For demonstration, we simply call it.
# In a real scenario, you'd likely use a logger or capture stdout.
# from edk2toollib.utility_functions import PrintFileData
# PrintFileData(str(test_file))
print(f"Content of {test_file.name}: {test_file.read_text()}") # Simulate PrintFileData output