#!/usr/bin/make -f

SHELL=/bin/bash

include /usr/share/dpkg/architecture.mk

# Bumping this up to >= GCC5 will require the replacing the pre-compiled
# liblto*.a binaries that we strip from our orig.tar.xz.
EDK2_TOOLCHAIN = GCC5
export $(EDK2_TOOLCHAIN)_AARCH64_PREFIX=aarch64-linux-gnu-
export $(EDK2_TOOLCHAIN)_ARM_PREFIX=arm-linux-gnueabihf-

export PYTHON3_ENABLE=TRUE

ifeq ($(DEB_BUILD_ARCH),amd64)
	EDK2_BUILD_ARCH=X64
endif
ifeq ($(DEB_BUILD_ARCH),i386)
	EDK2_BUILD_ARCH=IA32
endif
ifeq ($(DEB_BUILD_ARCH),arm64)
	EDK2_BUILD_ARCH=AARCH64
endif

ifeq ($(DEB_HOST_ARCH),amd64)
	EDK2_HOST_ARCH=X64
endif
ifeq ($(DEB_HOST_ARCH),i386)
	EDK2_HOST_ARCH=IA32
endif

COMMON_FLAGS = -DNETWORK_HTTP_BOOT_ENABLE=TRUE -DNETWORK_TLS_ENABLE -DSECURE_BOOT_ENABLE=TRUE
OVMF_COMMON_FLAGS = $(COMMON_FLAGS) -DTPM2_ENABLE=TRUE
OVMF_2M_FLAGS = $(OVMF_COMMON_FLAGS) -DFD_SIZE_2MB
OVMF_4M_FLAGS = $(OVMF_COMMON_FLAGS) -DFD_SIZE_4MB
OVMF_2M_SMM_FLAGS = $(OVMF_2M_FLAGS) -DSMM_REQUIRE=TRUE
OVMF_4M_SMM_FLAGS = $(OVMF_4M_FLAGS) -DSMM_REQUIRE=TRUE
AAVMF_FLAGS  = $(COMMON_FLAGS)

OVMF_VARS_GENERATOR = ./qemu-ovmf-secureboot-1-1-3/ovmf-vars-generator

# Clear variables used internally by the edk2 build system
undefine WORKSPACE
undefine ECP_SOURCE
undefine EDK_SOURCE
undefine EFI_SOURCE
undefine EDK_TOOLS_PATH
undefine CONF_PATH

ver := $(shell dpkg-parsechangelog | sed -n -e's/^Version: \(.*\)-[^-]\+/\1/p')

%:
	dh $@

override_dh_auto_build: build-qemu-efi-aarch64 build-qemu-efi-arm build-ovmf

debian/setup-build-stamp:
	set -e; . ./edksetup.sh; \
	make -C BaseTools ARCH=$(EDK2_BUILD_ARCH)
	touch $@

OVMF_BUILD_DIR = Build/OvmfX64/RELEASE_$(EDK2_TOOLCHAIN)
OVMF_ENROLL = $(OVMF_BUILD_DIR)/X64/EnrollDefaultKeys.efi
OVMF_SHELL =  $(OVMF_BUILD_DIR)/X64/Shell.efi
OVMF_IMAGES := OVMF_CODE.fd OVMF_CODE_4M.fd OVMF_CODE.secboot.fd OVMF_CODE_4M.secboot.fd OVMF_VARS.fd OVMF_VARS_4M.fd
OVMF_BINARIES = $(OVMF_ENROLL) $(OVMF_SHELL)
OVMF_BINARIES += $(prefix debian/ovmf-install/,$(OVMF_IMAGES))

build-ovmf: $(OVMF_BINARIES) debian/ovmf-install/OVMF_VARS.ms.fd debian/ovmf-install/OVMF_VARS_4M.ms.fd debian/ovmf-install/OVMF_VARS_4M.snakeoil.fd

$(OVMF_BINARIES): EDK2_ARCH_DIR=X64
$(OVMF_BINARIES): EDK2_HOST_ARCH=X64
$(OVMF_BINARIES): debian/setup-build-stamp
	cd UefiCpuPkg/ResetVector/Vtf0 && python3 Build.py
	rm -rf debian/ovmf-install
	mkdir debian/ovmf-install
	set -e; . ./edksetup.sh; \
		build -a $(EDK2_HOST_ARCH) \
			-t $(EDK2_TOOLCHAIN) \
			-p OvmfPkg/OvmfPkgX64.dsc \
			$(OVMF_2M_FLAGS) -b RELEASE; \
		cp $(OVMF_BUILD_DIR)/FV/OVMF_CODE.fd \
			$(OVMF_BUILD_DIR)/FV/OVMF.fd \
			debian/ovmf-install/; \
		cp $(OVMF_BUILD_DIR)/FV/OVMF_VARS.fd \
			debian/ovmf-install/; \
		rm -rf Build/Ovmf$(EDK2_HOST_ARCH); \
		build -a $(EDK2_HOST_ARCH) \
			-t $(EDK2_TOOLCHAIN) \
			-p OvmfPkg/OvmfPkgX64.dsc \
			$(OVMF_4M_FLAGS) -b RELEASE; \
		cp $(OVMF_BUILD_DIR)/FV/OVMF_CODE.fd \
			debian/ovmf-install/OVMF_CODE_4M.fd; \
		cp $(OVMF_BUILD_DIR)/FV/OVMF_VARS.fd \
			debian/ovmf-install/OVMF_VARS_4M.fd; \
		rm -rf Build/Ovmf$(EDK2_HOST_ARCH); \
		build -a $(EDK2_HOST_ARCH) \
			-t $(EDK2_TOOLCHAIN) \
			-p OvmfPkg/OvmfPkgX64.dsc \
			$(OVMF_2M_SMM_FLAGS) -b RELEASE; \
		cp $(OVMF_BUILD_DIR)/FV/OVMF_CODE.fd \
			debian/ovmf-install/OVMF_CODE.secboot.fd; \
		rm -rf Build/Ovmf$(EDK2_HOST_ARCH); \
		build -a $(EDK2_HOST_ARCH) \
			-t $(EDK2_TOOLCHAIN) \
			-p OvmfPkg/OvmfPkgX64.dsc \
			$(OVMF_4M_SMM_FLAGS) -b RELEASE; \
		cp $(OVMF_BUILD_DIR)/FV/OVMF_CODE.fd \
			debian/ovmf-install/OVMF_CODE_4M.secboot.fd; \

dpkg_vendor = $(shell dpkg-vendor --query vendor)
debian/oem-string-vendor: debian/PkKek-1-$(dpkg_vendor).pem
	tr -d '\n' < $< | \
		sed -e 's/.*-----BEGIN CERTIFICATE-----/4e32566d-8e9e-4f52-81d3-5bb9715f9727:/' -e 's/-----END CERTIFICATE-----//' > $@

debian/oem-string-snakeoil: debian/PkKek-1-snakeoil.pem
	tr -d '\n' < $< | \
		sed -e 's/.*-----BEGIN CERTIFICATE-----/4e32566d-8e9e-4f52-81d3-5bb9715f9727:/' -e 's/-----END CERTIFICATE-----//' > $@

debian/iso-root/shell.img: VFAT_ROOT=debian/vfat-root
debian/iso-root/shell.img: $(OVMF_SHELL) $(OVMF_ENROLL)
	rm -rf debian/iso-root
	mkdir debian/iso-root
	rm -rf $(VFAT_ROOT)
	mkdir -p $(VFAT_ROOT)/efi/boot
	cp $(OVMF_SHELL) $(VFAT_ROOT)/efi/boot/bootx64.efi
	cp $(OVMF_ENROLL) $(VFAT_ROOT)
	qemu-img convert --image-opts \
		driver=vvfat,floppy=on,fat-type=12,label=UEFI_SHELL,dir=$(VFAT_ROOT) $@

debian/UefiShell.iso: debian/iso-root/shell.img
	xorriso --as mkisofs -input-charset ASCII -J -rational-rock \
		-e `basename $<` -no-emul-boot -o $@ `dirname $<`

%.ms.fd: %.fd debian/UefiShell.iso debian/oem-string-vendor
	python3 $(OVMF_VARS_GENERATOR) --qemu-binary /usr/bin/qemu-system-x86_64 \
		--print-output \
		--disable-smm \
		--skip-testing \
		--oem-string `< debian/oem-string-vendor` \
		--ovmf-binary $(subst VARS,CODE,$<) \
		--ovmf-template-vars $< \
		--uefi-shell-iso debian/UefiShell.iso $@

%.snakeoil.fd: %.fd debian/UefiShell.iso debian/oem-string-snakeoil
	python3 $(OVMF_VARS_GENERATOR) --qemu-binary /usr/bin/qemu-system-x86_64 \
		--print-output \
		--disable-smm \
		--skip-testing \
		--no-default \
		--oem-string `< debian/oem-string-snakeoil` \
		--ovmf-binary $(subst VARS,CODE,$<) \
		--ovmf-template-vars $< \
		--uefi-shell-iso debian/UefiShell.iso $@

ArmPkg/Library/GccLto/liblto-aarch64.a:	ArmPkg/Library/GccLto/liblto-aarch64.s
	$($(EDK2_TOOLCHAIN)_AARCH64_PREFIX)gcc -c -fpic $< -o $@

ArmPkg/Library/GccLto/liblto-arm.a: ArmPkg/Library/GccLto/liblto-arm.s
	$($(EDK2_TOOLCHAIN)_ARM_PREFIX)gcc -c -fpic $< -o $@

build-qemu-efi: debian/setup-build-stamp
	set -e; . ./edksetup.sh; \
		build -a $(EDK2_HOST_ARCH) \
			-t $(EDK2_TOOLCHAIN) \
			-p ArmVirtPkg/ArmVirtQemu.dsc \
			$(AAVMF_FLAGS) -b RELEASE
	dd if=/dev/zero of=Build/ArmVirtQemu-$(EDK2_HOST_ARCH)/RELEASE_$(EDK2_TOOLCHAIN)/FV/$(FW_NAME)_CODE.fd bs=1M seek=64 count=0
	dd if=Build/ArmVirtQemu-$(EDK2_HOST_ARCH)/RELEASE_$(EDK2_TOOLCHAIN)/FV/QEMU_EFI.fd of=Build/ArmVirtQemu-$(EDK2_HOST_ARCH)/RELEASE_$(EDK2_TOOLCHAIN)/FV/$(FW_NAME)_CODE.fd conv=notrunc
	dd if=/dev/zero of=Build/ArmVirtQemu-$(EDK2_HOST_ARCH)/RELEASE_$(EDK2_TOOLCHAIN)/FV/$(FW_NAME)_VARS.fd bs=1M seek=64 count=0

build-qemu-efi-aarch64: ArmPkg/Library/GccLto/liblto-aarch64.a
	$(MAKE) -f debian/rules build-qemu-efi EDK2_ARCH_DIR=AArch64 EDK2_HOST_ARCH=AARCH64 FW_NAME=AAVMF

build-qemu-efi-arm: ArmPkg/Library/GccLto/liblto-arm.a
	$(MAKE) -f debian/rules build-qemu-efi EDK2_ARCH_DIR=Arm EDK2_HOST_ARCH=ARM FW_NAME=AAVMF32

override_dh_auto_clean:
	set -e; \
	if [ -d BaseTools/Source/C/bin ]; then \
		. ./edksetup.sh; build clean; \
		make -C BaseTools clean; \
	fi
	rm -rf Conf/.cache Build .pc-post
	rm -rf debian/ovmf-install debian/iso-root debian/vfat-root
	rm -f debian/oem-string debian/oem-string-snakeoil
	rm -f debian/shell.img debian/UefiShell.iso
	rm -f ArmPkg/Library/GccLto/liblto-*.a
	rm -f debian/setup-build-stamp

get-orig-source:
	# Should be executed on a checkout of the upstream master branch,
	# with the debian/ directory manually copied in.
	rm -rf edk2.tmp && git clone . edk2.tmp
	# Don't recurse, openssl will bring in MBs of stuff we don't need
	cd edk2.tmp && git submodule update --init
	rm -rf edk2-$(ver) && mkdir edk2-$(ver)
	cd edk2.tmp && git archive HEAD | tar xv -C ../edk2-$(ver)
	cd edk2.tmp && git submodule foreach \
		'git archive HEAD | tar xv -C $$toplevel/../edk2-$(ver)/$$sm_path'
	ln -s ../debian edk2-$(ver)
	# Remove unused embedded source, requested by Ubuntu security team
	rm -r edk2-$(ver)/BaseTools/Source/C/BrotliCompress
	# Remove known-binary files
	cd edk2-$(ver) && python3 ./debian/remove-binaries.py
	# Look for possible unknown binary files
	cd edk2-$(ver) && python3 ./debian/find-binaries.py
	rm edk2-$(ver)/debian
	tar Jcvf ../edk2_$(ver).orig.tar.xz edk2-$(ver)
	rm -rf edk2.tmp edk2-$(ver)

.PHONY: build-ovmf build-qemu-efi
