Building the Application

To build the application, we'll use the EDK2 docker containers provided by tianocore. In the directory that contains your src directory, create a Dockerfile:

FROM ghcr.io/tianocore/containers/ubuntu-22-build:a0dd931 ENV DEBIAN_FRONTEND=noninteractive SHELL ["/bin/bash", "-o", "pipefail", "-c"] ENV EDK2_REPO_URL "https://github.com/tianocore/edk2.git" ENV EDK2_REPO_HASH "d189de3b0a2f44f4c9b87ed120be16569ea19b51" ENV EDK2_PATH "/edk2" RUN git clone "${EDK2_REPO_URL}" "${EDK2_PATH}" && \ git -C "${EDK2_PATH}" checkout "${EDK2_REPO_HASH}" && \ python3 -m pip install --no-cache-dir -r "${EDK2_PATH}/pip-requirements.txt" && \ stuart_setup -c "${EDK2_PATH}/.pytool/CISettings.py" TOOL_CHAIN_TAG=GCC&& \ stuart_update -c "${EDK2_PATH}/.pytool/CISettings.py" TOOL_CHAIN_TAG=GCC COPY src "${EDK2_PATH}/Tutorial/" RUN stuart_setup -c "${EDK2_PATH}/Tutorial/PlatformBuild.py" TOOL_CHAIN_TAG=GCC && \ stuart_update -c "${EDK2_PATH}/Tutorial/PlatformBuild.py" TOOL_CHAIN_TAG=GCC && \ python3 "${EDK2_PATH}/BaseTools/Edk2ToolsBuild.py" -t GCC WORKDIR "${EDK2_PATH}" RUN source ${EDK2_PATH}/edksetup.sh && \ ( stuart_build -c ${EDK2_PATH}/Tutorial/PlatformBuild.py TOOL_CHAIN_TAG=GCC \ EDK_TOOLS_PATH=${EDK2_PATH}/BaseTools/ \ || ( cat ${EDK2_PATH}/Tutorial/Build/BUILDLOG.txt && exit 1 ) )

This Dockerfile will obtain the EDK2 source and compile the BaseTools, then copy our src directory into the EDK2 repository as a new package and build the package.

We will want to get our built UEFI application from the container, which we can do using the docker cp command. There are a few files we want to copy, so we'll use this script build.sh to automate the process:

#!/bin/bash SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd) IMAGE_NAME="tsffs-tutorial-edk2-uefi" CONTAINER_UID=$(echo "${RANDOM}" | sha256sum | head -c 8) CONTAINER_NAME="${IMAGE_NAME}-tmp-${CONTAINER_UID}" mkdir -p "${SCRIPT_DIR}/project/" docker build -t "${IMAGE_NAME}" -f "Dockerfile" "${SCRIPT_DIR}" docker create --name "${CONTAINER_NAME}" "${IMAGE_NAME}" docker cp \ "${CONTAINER_NAME}:/edk2/Tutorial/Build/CryptoPkg/All/DEBUG_GCC/X64/Tutorial/Tutorial/DEBUG/Tutorial.efi" \ "${SCRIPT_DIR}/project/Tutorial.efi" docker cp \ "${CONTAINER_NAME}:/edk2/Tutorial/Build/CryptoPkg/All/DEBUG_GCC/X64/Tutorial/Tutorial/DEBUG/Tutorial.map" \ "${SCRIPT_DIR}/project/Tutorial.map" docker cp \ "${CONTAINER_NAME}:/edk2/Tutorial/Build/CryptoPkg/All/DEBUG_GCC/X64/Tutorial/Tutorial/DEBUG/Tutorial.debug" \ "${SCRIPT_DIR}/project/Tutorial.debug" docker rm -f "${CONTAINER_NAME}"

The script will build the image, create a container using it, copy the relevant files to our host machine (in a project directory), then delete the container.

Mark the script executable and then we'll go ahead and run it with:

chmod +x build.sh ./build.sh