| 1 | # Makefile for the test helper UEFI applications that run in guests. |
| 2 | # |
| 3 | # Copyright (C) 2019, Red Hat, Inc. |
| 4 | # |
| 5 | # This program and the accompanying materials are licensed and made available |
| 6 | # under the terms and conditions of the BSD License that accompanies this |
| 7 | # distribution. The full text of the license may be found at |
| 8 | # <http://opensource.org/licenses/bsd-license.php>. |
| 9 | # |
| 10 | # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT |
| 11 | # WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. |
| 12 | |
| 13 | edk2_dir := ../../roms/edk2 |
| 14 | images_dir := ../data/uefi-boot-images |
| 15 | emulation_targets := arm aarch64 i386 x86_64 riscv64 loongarch64 |
| 16 | uefi_binaries := bios-tables-test |
| 17 | intermediate_suffixes := .efi .fat .iso.raw |
| 18 | |
| 19 | images: $(foreach binary,$(uefi_binaries), \ |
| 20 | $(foreach target,$(emulation_targets), \ |
| 21 | $(images_dir)/$(binary).$(target).iso.qcow2)) |
| 22 | |
| 23 | # Preserve all intermediate targets if the build succeeds. |
| 24 | # - Intermediate targets help with development & debugging. |
| 25 | # - Preserving intermediate targets also keeps spurious changes out of the |
| 26 | # final build products, in case the user re-runs "make" without any changes |
| 27 | # to the UEFI source code. Normally, the intermediate files would have been |
| 28 | # removed by the last "make" invocation, hence the re-run would rebuild them |
| 29 | # from the unchanged UEFI sources. Unfortunately, the "mkdosfs" and |
| 30 | # "genisoimage" utilities embed timestamp-based information in their outputs, |
| 31 | # which causes git to report differences for the tracked qcow2 ISO images. |
| 32 | .SECONDARY: $(foreach binary,$(uefi_binaries), \ |
| 33 | $(foreach target,$(emulation_targets), \ |
| 34 | $(foreach suffix,$(intermediate_suffixes), \ |
| 35 | Build/$(binary).$(target)$(suffix)))) |
| 36 | |
| 37 | # In the pattern rules below, the stem (%, $*) stands for |
| 38 | # "$(binary).$(target)". |
| 39 | |
| 40 | # Convert the raw ISO image to a qcow2 one, enabling compression, and using a |
| 41 | # small cluster size. This allows for small binary files under git control, |
| 42 | # hence for small binary patches. |
| 43 | $(images_dir)/%.iso.qcow2: Build/%.iso.raw |
| 44 | mkdir -p -- $(images_dir) |
| 45 | $${QTEST_QEMU_IMG:-qemu-img} convert -f raw -O qcow2 -c \ |
| 46 | -o cluster_size=512 -- $< $@ |
| 47 | |
| 48 | # Embed the "UEFI system partition" into an ISO9660 file system as an ElTorito |
| 49 | # boot image. |
| 50 | Build/%.iso.raw: Build/%.fat |
| 51 | genisoimage -input-charset ASCII -efi-boot $(notdir $<) -no-emul-boot \ |
| 52 | -quiet -o $@ -- $< |
| 53 | |
| 54 | # Define chained macros in order to map QEMU system emulation targets to |
| 55 | # *short* UEFI architecture identifiers. Periods are allowed in, and ultimately |
| 56 | # stripped from, the argument. |
| 57 | map_arm_to_uefi = $(subst arm,ARM,$(1)) |
| 58 | map_aarch64_to_uefi = $(subst aarch64,AA64,$(call map_arm_to_uefi,$(1))) |
| 59 | map_loongarch64_to_uefi = $(subst loongarch64,LOONGARCH64,$(call map_aarch64_to_uefi,$(1))) |
| 60 | map_riscv64_to_uefi = $(subst riscv64,RISCV64,$(call map_loongarch64_to_uefi,$(1))) |
| 61 | map_i386_to_uefi = $(subst i386,IA32,$(call map_riscv64_to_uefi,$(1))) |
| 62 | map_x86_64_to_uefi = $(subst x86_64,X64,$(call map_i386_to_uefi,$(1))) |
| 63 | map_to_uefi = $(subst .,,$(call map_x86_64_to_uefi,$(1))) |
| 64 | |
| 65 | # Format a "UEFI system partition", using the UEFI binary as the default boot |
| 66 | # loader. Add 10% size for filesystem metadata, round up to the next KB, and |
| 67 | # make sure the size is large enough for a FAT filesystem. Name the filesystem |
| 68 | # after the UEFI binary. (Excess characters are automatically dropped from the |
| 69 | # filesystem label.) |
| 70 | Build/%.fat: Build/%.efi |
| 71 | rm -f -- $@ |
| 72 | uefi_bin_b=$$(stat --format=%s -- $<) && \ |
| 73 | uefi_fat_kb=$$(( (uefi_bin_b * 11 / 10 + 1023) / 1024 )) && \ |
| 74 | uefi_fat_kb=$$(( uefi_fat_kb >= 64 ? uefi_fat_kb : 64 )) && \ |
| 75 | mkdosfs -C $@ -n "bios-test" -- $$uefi_fat_kb |
| 76 | MTOOLS_SKIP_CHECK=1 mmd -i $@ ::EFI |
| 77 | MTOOLS_SKIP_CHECK=1 mmd -i $@ ::EFI/BOOT |
| 78 | MTOOLS_SKIP_CHECK=1 mcopy -i $@ -- $< \ |
| 79 | ::EFI/BOOT/BOOT$(call map_to_uefi,$(suffix $*)).EFI |
| 80 | |
| 81 | # In the pattern rules below, the stem (%, $*) stands for "$(target)" only. The |
| 82 | # association between the UEFI binary (such as "bios-tables-test") and the |
| 83 | # component name from the edk2 platform DSC file (such as "BiosTablesTest") is |
| 84 | # explicit in each rule. |
| 85 | |
| 86 | # "build.sh" invokes the "build" utility of edk2 BaseTools. In any given edk2 |
| 87 | # workspace, at most one "build" instance may be operating at a time. Therefore |
| 88 | # we must serialize the rebuilding of targets in this Makefile. |
| 89 | .NOTPARALLEL: |
| 90 | |
| 91 | # In turn, the "build" utility of edk2 BaseTools invokes another "make". |
| 92 | # Although the outer "make" process advertises its job server to all child |
| 93 | # processes via MAKEFLAGS in the environment, the outer "make" closes the job |
| 94 | # server file descriptors (exposed in MAKEFLAGS) before executing a recipe -- |
| 95 | # unless the recipe is recognized as a recursive "make" recipe. Recipes that |
| 96 | # call $(MAKE) are classified automatically as recursive; for "build.sh" below, |
| 97 | # we must mark the recipe manually as recursive, by using the "+" indicator. |
| 98 | # This way, when the inner "make" starts a parallel build of the target edk2 |
| 99 | # module, it can communicate with the outer "make"'s job server. |
| 100 | Build/bios-tables-test.%.efi: |
| 101 | $(PYTHON) ../../roms/edk2-build.py --config uefi-test-build.config \ |
| 102 | --match $* |
| 103 | |
| 104 | clean: |
| 105 | rm -rf Build Conf log |
| 106 | $(MAKE) -C $(edk2_dir)/BaseTools clean |