diff mbox series

[07/10] roms: build edk2 firmware binaries and variable store templates

Message ID 20190309004826.9027-8-lersek@redhat.com
State New
Headers show
Series bundle edk2 platform firmware with QEMU | expand

Commit Message

Laszlo Ersek March 9, 2019, 12:48 a.m. UTC
Add the "efi" target to "Makefile".

Introduce "Makefile.edk2" for building and cleaning the firmware images
and varstore templates.

Collect the common bits from the recipes in the helper script
"edk2-build.sh".

Signed-off-by: Laszlo Ersek <lersek@redhat.com>
---
 roms/Makefile      |   5 +
 roms/Makefile.edk2 | 138 ++++++++++++++++++++
 roms/edk2-build.sh |  55 ++++++++
 3 files changed, 198 insertions(+)

Comments

Philippe Mathieu-Daudé March 9, 2019, 4:48 p.m. UTC | #1
Hi Laszlo,

On 3/9/19 1:48 AM, Laszlo Ersek wrote:
> Add the "efi" target to "Makefile".
> 
> Introduce "Makefile.edk2" for building and cleaning the firmware images
> and varstore templates.
> 
> Collect the common bits from the recipes in the helper script
> "edk2-build.sh".
> 
> Signed-off-by: Laszlo Ersek <lersek@redhat.com>
> ---
>  roms/Makefile      |   5 +
>  roms/Makefile.edk2 | 138 ++++++++++++++++++++
>  roms/edk2-build.sh |  55 ++++++++
>  3 files changed, 198 insertions(+)
> 
> diff --git a/roms/Makefile b/roms/Makefile
> index 2e83ececa25a..054b432834ba 100644
> --- a/roms/Makefile
> +++ b/roms/Makefile
> @@ -61,6 +61,7 @@ default:
>  	@echo "  skiboot        -- update skiboot.lid"
>  	@echo "  u-boot.e500    -- update u-boot.e500"
>  	@echo "  u-boot.sam460  -- update u-boot.sam460"
> +	@echo "  efi            -- update UEFI (edk2) platform firmware"
>  
>  bios: build-seabios-config-seabios-128k build-seabios-config-seabios-256k
>  	cp seabios/builds/seabios-128k/bios.bin ../pc-bios/bios.bin
> @@ -143,6 +144,9 @@ skiboot:
>  	$(MAKE) -C skiboot CROSS=$(powerpc64_cross_prefix)
>  	cp skiboot/skiboot.lid ../pc-bios/skiboot.lid
>  
> +efi: edk2-basetools
> +	$(MAKE) -f Makefile.edk2
> +
>  clean:
>  	rm -rf seabios/.config seabios/out seabios/builds
>  	$(MAKE) -C sgabios clean
> @@ -153,3 +157,4 @@ clean:
>  	rm -rf u-boot/build.e500
>  	$(MAKE) -C u-boot-sam460ex distclean
>  	$(MAKE) -C skiboot clean
> +	$(MAKE) -f Makefile.edk2 clean
> diff --git a/roms/Makefile.edk2 b/roms/Makefile.edk2
> new file mode 100644
> index 000000000000..ad6fff044cd6
> --- /dev/null
> +++ b/roms/Makefile.edk2
> @@ -0,0 +1,138 @@
> +# Makefile for building firmware binaries and variable store templates for a
> +# number of virtual platforms in edk2.
> +#
> +# Copyright (C) 2019, Red Hat, Inc.
> +#
> +# This program and the accompanying materials are licensed and made available
> +# under the terms and conditions of the BSD License that accompanies this
> +# distribution. The full text of the license may be found at
> +# <http://opensource.org/licenses/bsd-license.php>.
> +#
> +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
> +# WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +
> +toolchain = $(shell source ./edk2-funcs.sh && qemu_edk2_get_toolchain $(1))
> +
> +licenses := \
> +	edk2/License.txt \
> +	edk2/OvmfPkg/License.txt \
> +	edk2/CryptoPkg/Library/OpensslLib/openssl/LICENSE
> +
> +# The "edk2-arm-vars.fd" varstore template is suitable for aarch64 as well.
> +# Similarly, the "edk2-i386-vars.fd" varstore template is suitable for x86_64
> +# as well, independently of "secure" too.
> +all: \
> +	../pc-bios/edk2-aarch64-code.fd \
> +	../pc-bios/edk2-arm-code.fd \
> +	../pc-bios/edk2-i386-code.fd \
> +	../pc-bios/edk2-i386-secure-code.fd \
> +	../pc-bios/edk2-x86_64-code.fd \
> +	../pc-bios/edk2-x86_64-secure-code.fd \
> +	\
> +	../pc-bios/edk2-arm-vars.fd \
> +	../pc-bios/edk2-i386-vars.fd \
> +	\
> +	../pc-bios/edk2-licenses.txt
> +
> +submodules:
> +	cd edk2 && git submodule update --init --force
> +
> +# See notes on the ".NOTPARALLEL" target and the "+" indicator in
> +# "tests/uefi-test-tools/Makefile".
> +.NOTPARALLEL:
> +
> +../pc-bios/edk2-aarch64-code.fd: submodules
> +	+./edk2-build.sh \
> +		aarch64 \
> +		--arch=AARCH64 \
> +		--platform=ArmVirtPkg/ArmVirtQemu.dsc \
> +		-D NETWORK_IP6_ENABLE \
> +		-D HTTP_BOOT_ENABLE
> +	cp edk2/Build/ArmVirtQemu-AARCH64/DEBUG_$(call toolchain,aarch64)/FV/QEMU_EFI.fd \
> +		$@
> +	truncate --size=64M $@
[...]

Trying on Ubuntu I get:

$ make -C roms efi
[...]
Fd File Name:QEMU_EFI
(/home/phil/source/qemu/roms/edk2/Build/ArmVirtQemu-AARCH64/DEBUG_GCC5/FV/QEMU_EFI.fd)
Fd File Name:QEMU_VARS
(/home/phil/source/qemu/roms/edk2/Build/ArmVirtQemu-AARCH64/DEBUG_GCC5/FV/QEMU_VARS.fd)
GUID cross reference file can be found at
/home/phil/source/qemu/roms/edk2/Build/ArmVirtQemu-AARCH64/DEBUG_GCC5/FV/Guid.xref
- Done -
Build end time: 16:33:29, Mar.09 2019
Build total time: 00:03:35
cp edk2/Build/ArmVirtQemu-AARCH64/DEBUG_/FV/QEMU_EFI.fd \
	../pc-bios/edk2-aarch64-code.fd
cp: cannot stat 'edk2/Build/ArmVirtQemu-AARCH64/DEBUG_/FV/QEMU_EFI.fd':
No such file or directory
Makefile.edk2:45: recipe for target '../pc-bios/edk2-aarch64-code.fd' failed
make[1]: *** [../pc-bios/edk2-aarch64-code.fd] Error 1
make[1]: Leaving directory '/home/phil/source/qemu/roms'
Makefile:148: recipe for target 'efi' failed
make: *** [efi] Error 2
make: Leaving directory '/home/phil/source/qemu/roms'

The edk2-build.sh script source edksetup.sh, then you call the
'toolchain' command out of the edk2-build.sh script, but here
the edksetup.sh setup is no more effective.

Regards,

Phil.
Philippe Mathieu-Daudé March 10, 2019, 11:26 a.m. UTC | #2
Hi Laszlo,

On 3/9/19 1:48 AM, Laszlo Ersek wrote:
> Add the "efi" target to "Makefile".
> 
> Introduce "Makefile.edk2" for building and cleaning the firmware images
> and varstore templates.
> 
> Collect the common bits from the recipes in the helper script
> "edk2-build.sh".
> 
> Signed-off-by: Laszlo Ersek <lersek@redhat.com>
> ---
>  roms/Makefile      |   5 +
>  roms/Makefile.edk2 | 138 ++++++++++++++++++++
>  roms/edk2-build.sh |  55 ++++++++
>  3 files changed, 198 insertions(+)
> 
> diff --git a/roms/Makefile b/roms/Makefile
> index 2e83ececa25a..054b432834ba 100644
> --- a/roms/Makefile
> +++ b/roms/Makefile
> @@ -61,6 +61,7 @@ default:
>  	@echo "  skiboot        -- update skiboot.lid"
>  	@echo "  u-boot.e500    -- update u-boot.e500"
>  	@echo "  u-boot.sam460  -- update u-boot.sam460"
> +	@echo "  efi            -- update UEFI (edk2) platform firmware"
>  
>  bios: build-seabios-config-seabios-128k build-seabios-config-seabios-256k
>  	cp seabios/builds/seabios-128k/bios.bin ../pc-bios/bios.bin
> @@ -143,6 +144,9 @@ skiboot:
>  	$(MAKE) -C skiboot CROSS=$(powerpc64_cross_prefix)
>  	cp skiboot/skiboot.lid ../pc-bios/skiboot.lid
>  
> +efi: edk2-basetools
> +	$(MAKE) -f Makefile.edk2
> +
>  clean:
>  	rm -rf seabios/.config seabios/out seabios/builds
>  	$(MAKE) -C sgabios clean
> @@ -153,3 +157,4 @@ clean:
>  	rm -rf u-boot/build.e500
>  	$(MAKE) -C u-boot-sam460ex distclean
>  	$(MAKE) -C skiboot clean
> +	$(MAKE) -f Makefile.edk2 clean
> diff --git a/roms/Makefile.edk2 b/roms/Makefile.edk2
> new file mode 100644
> index 000000000000..ad6fff044cd6
> --- /dev/null
> +++ b/roms/Makefile.edk2
> @@ -0,0 +1,138 @@
> +# Makefile for building firmware binaries and variable store templates for a
> +# number of virtual platforms in edk2.
> +#
> +# Copyright (C) 2019, Red Hat, Inc.
> +#
> +# This program and the accompanying materials are licensed and made available
> +# under the terms and conditions of the BSD License that accompanies this
> +# distribution. The full text of the license may be found at
> +# <http://opensource.org/licenses/bsd-license.php>.
> +#
> +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
> +# WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +
> +toolchain = $(shell source ./edk2-funcs.sh && qemu_edk2_get_toolchain $(1))
> +
> +licenses := \
> +	edk2/License.txt \
> +	edk2/OvmfPkg/License.txt \
> +	edk2/CryptoPkg/Library/OpensslLib/openssl/LICENSE
> +
> +# The "edk2-arm-vars.fd" varstore template is suitable for aarch64 as well.
> +# Similarly, the "edk2-i386-vars.fd" varstore template is suitable for x86_64
> +# as well, independently of "secure" too.
> +all: \
> +	../pc-bios/edk2-aarch64-code.fd \
> +	../pc-bios/edk2-arm-code.fd \
> +	../pc-bios/edk2-i386-code.fd \
> +	../pc-bios/edk2-i386-secure-code.fd \
> +	../pc-bios/edk2-x86_64-code.fd \
> +	../pc-bios/edk2-x86_64-secure-code.fd \
> +	\
> +	../pc-bios/edk2-arm-vars.fd \
> +	../pc-bios/edk2-i386-vars.fd \
> +	\
> +	../pc-bios/edk2-licenses.txt
> +
> +submodules:
> +	cd edk2 && git submodule update --init --force
> +
> +# See notes on the ".NOTPARALLEL" target and the "+" indicator in
> +# "tests/uefi-test-tools/Makefile".
> +.NOTPARALLEL:
> +
> +../pc-bios/edk2-aarch64-code.fd: submodules
> +	+./edk2-build.sh \
> +		aarch64 \
> +		--arch=AARCH64 \
> +		--platform=ArmVirtPkg/ArmVirtQemu.dsc \
> +		-D NETWORK_IP6_ENABLE \
> +		-D HTTP_BOOT_ENABLE
> +	cp edk2/Build/ArmVirtQemu-AARCH64/DEBUG_$(call toolchain,aarch64)/FV/QEMU_EFI.fd \
> +		$@
> +	truncate --size=64M $@
> +
> +../pc-bios/edk2-arm-code.fd: submodules
> +	+./edk2-build.sh \
> +		arm \
> +		--arch=ARM \
> +		--platform=ArmVirtPkg/ArmVirtQemu.dsc \
> +		-D NETWORK_IP6_ENABLE \
> +		-D HTTP_BOOT_ENABLE
> +	cp edk2/Build/ArmVirtQemu-ARM/DEBUG_$(call toolchain,arm)/FV/QEMU_EFI.fd \
> +		$@
> +	truncate --size=64M $@
> +
> +../pc-bios/edk2-i386-code.fd: submodules
> +	+./edk2-build.sh \
> +		i386 \
> +		--arch=IA32 \
> +		--platform=OvmfPkg/OvmfPkgIa32.dsc \
> +		-D NETWORK_IP6_ENABLE \
> +		-D HTTP_BOOT_ENABLE \
> +		-D TLS_ENABLE \
> +		-D TPM2_ENABLE \
> +		-D TPM2_CONFIG_ENABLE
> +	cp edk2/Build/OvmfIa32/DEBUG_$(call toolchain,i386)/FV/OVMF_CODE.fd $@
> +
> +../pc-bios/edk2-i386-secure-code.fd: submodules
> +	+./edk2-build.sh \
> +		i386 \
> +		--arch=IA32 \
> +		--platform=OvmfPkg/OvmfPkgIa32.dsc \
> +		-D NETWORK_IP6_ENABLE \
> +		-D HTTP_BOOT_ENABLE \
> +		-D TLS_ENABLE \
> +		-D TPM2_ENABLE \
> +		-D TPM2_CONFIG_ENABLE \
> +		-D SECURE_BOOT_ENABLE \
> +		-D SMM_REQUIRE
> +	cp edk2/Build/OvmfIa32/DEBUG_$(call toolchain,i386)/FV/OVMF_CODE.fd $@
> +
> +../pc-bios/edk2-x86_64-code.fd: submodules
> +	+./edk2-build.sh \
> +		x86_64 \
> +		--arch=X64 \
> +		--platform=OvmfPkg/OvmfPkgX64.dsc \
> +		-D NETWORK_IP6_ENABLE \
> +		-D HTTP_BOOT_ENABLE \
> +		-D TLS_ENABLE \
> +		-D TPM2_ENABLE \
> +		-D TPM2_CONFIG_ENABLE
> +	cp edk2/Build/OvmfX64/DEBUG_$(call toolchain,x86_64)/FV/OVMF_CODE.fd $@
> +
> +../pc-bios/edk2-x86_64-secure-code.fd: submodules
> +	+./edk2-build.sh \
> +		x86_64 \
> +		--arch=IA32 \
> +		--arch=X64 \
> +		--platform=OvmfPkg/OvmfPkgIa32X64.dsc \
> +		-D NETWORK_IP6_ENABLE \
> +		-D HTTP_BOOT_ENABLE \
> +		-D TLS_ENABLE \
> +		-D TPM2_ENABLE \
> +		-D TPM2_CONFIG_ENABLE \
> +		-D SECURE_BOOT_ENABLE \
> +		-D SMM_REQUIRE
> +	cp edk2/Build/Ovmf3264/DEBUG_$(call toolchain,x86_64)/FV/OVMF_CODE.fd $@

Do you mind adding a $EDK2_BUILD_OPTIONS variable to optionally add
arguments from the environment? I figured it is useful for CI
integration to quiet the build output, else the CI stdout limit is
reached quickly.

I'll suggest a patch you can amend or improve :)

> +
> +../pc-bios/edk2-arm-vars.fd: ../pc-bios/edk2-arm-code.fd
> +	cp edk2/Build/ArmVirtQemu-ARM/DEBUG_$(call toolchain,arm)/FV/QEMU_VARS.fd \
> +		$@
> +	truncate --size=64M $@
> +
> +../pc-bios/edk2-i386-vars.fd: ../pc-bios/edk2-i386-code.fd
> +	cp edk2/Build/OvmfIa32/DEBUG_$(call toolchain,i386)/FV/OVMF_VARS.fd $@
> +
> +# The license file accumulates several individual licenses from under edk2,
> +# prefixing each individual license with a header (generated by "tail") that
> +# states its pathname.
> +../pc-bios/edk2-licenses.txt: submodules
> +	tail -n $(shell cat $(licenses) | wc -l) $(licenses) > $@
> +	dos2unix $@
> +
> +clean:
> +	rm -rf edk2/Build
> +	cd edk2/Conf && \
> +		rm -rf .cache BuildEnv.sh build_rule.txt target.txt \
> +			tools_def.txt
> diff --git a/roms/edk2-build.sh b/roms/edk2-build.sh
> new file mode 100755
> index 000000000000..936d2c874a22
> --- /dev/null
> +++ b/roms/edk2-build.sh
> @@ -0,0 +1,55 @@
> +#!/bin/bash
> +
> +# Wrapper shell script for building a  virtual platform firmware in edk2.
> +#
> +# Copyright (C) 2019, Red Hat, Inc.
> +#
> +# This program and the accompanying materials are licensed and made available
> +# under the terms and conditions of the BSD License that accompanies this
> +# distribution. The full text of the license may be found at
> +# <http://opensource.org/licenses/bsd-license.php>.
> +#
> +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
> +# WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +
> +set -e -u -C
> +
> +# Save the command line arguments. We need to reset $# to 0 before sourcing
> +# "edksetup.sh", as it will inherit $@.
> +emulation_target=$1
> +shift
> +num_args=0
> +args=()
> +for arg in "$@"; do
> +  args[num_args++]="$arg"
> +done
> +shift $num_args
> +
> +cd edk2
> +
> +# Work around <https://bugzilla.tianocore.org/show_bug.cgi?id=1607>.
> +export PYTHON_COMMAND=python2
> +
> +# Source "edksetup.sh" carefully.
> +set +e +u +C
> +source ./edksetup.sh
> +ret=$?
> +set -e -u -C
> +if [ $ret -ne 0 ]; then
> +  exit $ret
> +fi
> +
> +# Fetch some option arguments, and set the cross-compilation environment (if
> +# any), for the edk2 "build" utility.
> +source ../edk2-funcs.sh
> +edk2_toolchain=$(qemu_edk2_get_toolchain "$emulation_target")
> +edk2_thread_count=$(qemu_edk2_get_thread_count "$MAKEFLAGS")
> +qemu_edk2_set_cross_env "$emulation_target"
> +
> +# Build the platform firmware.
> +build \
> +  --cmd-len=65536 \
> +  -n "$edk2_thread_count" \
> +  --buildtarget=DEBUG \
> +  --tagname="$edk2_toolchain" \
> +  "${args[@]}"
>
Philippe Mathieu-Daudé March 10, 2019, 3:10 p.m. UTC | #3
Hi Laszlo,

On 3/9/19 5:48 PM, Philippe Mathieu-Daudé wrote:
> On 3/9/19 1:48 AM, Laszlo Ersek wrote:
>> Add the "efi" target to "Makefile".
>>
>> Introduce "Makefile.edk2" for building and cleaning the firmware images
>> and varstore templates.
>>
>> Collect the common bits from the recipes in the helper script
>> "edk2-build.sh".
>>
>> Signed-off-by: Laszlo Ersek <lersek@redhat.com>
>> ---
>>  roms/Makefile      |   5 +
>>  roms/Makefile.edk2 | 138 ++++++++++++++++++++
>>  roms/edk2-build.sh |  55 ++++++++
>>  3 files changed, 198 insertions(+)
>>
>> diff --git a/roms/Makefile b/roms/Makefile
>> index 2e83ececa25a..054b432834ba 100644
>> --- a/roms/Makefile
>> +++ b/roms/Makefile
>> @@ -61,6 +61,7 @@ default:
>>  	@echo "  skiboot        -- update skiboot.lid"
>>  	@echo "  u-boot.e500    -- update u-boot.e500"
>>  	@echo "  u-boot.sam460  -- update u-boot.sam460"
>> +	@echo "  efi            -- update UEFI (edk2) platform firmware"
>>  
>>  bios: build-seabios-config-seabios-128k build-seabios-config-seabios-256k
>>  	cp seabios/builds/seabios-128k/bios.bin ../pc-bios/bios.bin
>> @@ -143,6 +144,9 @@ skiboot:
>>  	$(MAKE) -C skiboot CROSS=$(powerpc64_cross_prefix)
>>  	cp skiboot/skiboot.lid ../pc-bios/skiboot.lid
>>  
>> +efi: edk2-basetools
>> +	$(MAKE) -f Makefile.edk2
>> +
>>  clean:
>>  	rm -rf seabios/.config seabios/out seabios/builds
>>  	$(MAKE) -C sgabios clean
>> @@ -153,3 +157,4 @@ clean:
>>  	rm -rf u-boot/build.e500
>>  	$(MAKE) -C u-boot-sam460ex distclean
>>  	$(MAKE) -C skiboot clean
>> +	$(MAKE) -f Makefile.edk2 clean
>> diff --git a/roms/Makefile.edk2 b/roms/Makefile.edk2
>> new file mode 100644
>> index 000000000000..ad6fff044cd6
>> --- /dev/null
>> +++ b/roms/Makefile.edk2
>> @@ -0,0 +1,138 @@
>> +# Makefile for building firmware binaries and variable store templates for a
>> +# number of virtual platforms in edk2.
>> +#
>> +# Copyright (C) 2019, Red Hat, Inc.
>> +#
>> +# This program and the accompanying materials are licensed and made available
>> +# under the terms and conditions of the BSD License that accompanies this
>> +# distribution. The full text of the license may be found at
>> +# <http://opensource.org/licenses/bsd-license.php>.
>> +#
>> +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
>> +# WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
>> +
>> +toolchain = $(shell source ./edk2-funcs.sh && qemu_edk2_get_toolchain $(1))

Well I finally figured out why building on Ubuntu fails. It default
shell is dash, and 'source' is a bash builtin command. The portable
equivalent is '.' (dot).

The fix is:

-- >8 --
-toolchain = $(shell source ./edk2-funcs.sh && qemu_edk2_get_toolchain $(1))
+toolchain = $(shell . ./edk2-funcs.sh && qemu_edk2_get_toolchain $(1))
---

With this hunk:
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>

>> +
>> +licenses := \
>> +	edk2/License.txt \
>> +	edk2/OvmfPkg/License.txt \
>> +	edk2/CryptoPkg/Library/OpensslLib/openssl/LICENSE
>> +
>> +# The "edk2-arm-vars.fd" varstore template is suitable for aarch64 as well.
>> +# Similarly, the "edk2-i386-vars.fd" varstore template is suitable for x86_64
>> +# as well, independently of "secure" too.
>> +all: \
>> +	../pc-bios/edk2-aarch64-code.fd \
>> +	../pc-bios/edk2-arm-code.fd \
>> +	../pc-bios/edk2-i386-code.fd \
>> +	../pc-bios/edk2-i386-secure-code.fd \
>> +	../pc-bios/edk2-x86_64-code.fd \
>> +	../pc-bios/edk2-x86_64-secure-code.fd \
>> +	\
>> +	../pc-bios/edk2-arm-vars.fd \
>> +	../pc-bios/edk2-i386-vars.fd \
>> +	\
>> +	../pc-bios/edk2-licenses.txt
>> +
>> +submodules:
>> +	cd edk2 && git submodule update --init --force
>> +
>> +# See notes on the ".NOTPARALLEL" target and the "+" indicator in
>> +# "tests/uefi-test-tools/Makefile".
>> +.NOTPARALLEL:
>> +
>> +../pc-bios/edk2-aarch64-code.fd: submodules
>> +	+./edk2-build.sh \
>> +		aarch64 \
>> +		--arch=AARCH64 \
>> +		--platform=ArmVirtPkg/ArmVirtQemu.dsc \
>> +		-D NETWORK_IP6_ENABLE \
>> +		-D HTTP_BOOT_ENABLE
>> +	cp edk2/Build/ArmVirtQemu-AARCH64/DEBUG_$(call toolchain,aarch64)/FV/QEMU_EFI.fd \
>> +		$@
>> +	truncate --size=64M $@
> [...]
> 
> Trying on Ubuntu I get:
> 
> $ make -C roms efi
> [...]
> Fd File Name:QEMU_EFI
> (/home/phil/source/qemu/roms/edk2/Build/ArmVirtQemu-AARCH64/DEBUG_GCC5/FV/QEMU_EFI.fd)
> Fd File Name:QEMU_VARS
> (/home/phil/source/qemu/roms/edk2/Build/ArmVirtQemu-AARCH64/DEBUG_GCC5/FV/QEMU_VARS.fd)
> GUID cross reference file can be found at
> /home/phil/source/qemu/roms/edk2/Build/ArmVirtQemu-AARCH64/DEBUG_GCC5/FV/Guid.xref
> - Done -
> Build end time: 16:33:29, Mar.09 2019
> Build total time: 00:03:35
> cp edk2/Build/ArmVirtQemu-AARCH64/DEBUG_/FV/QEMU_EFI.fd \
> 	../pc-bios/edk2-aarch64-code.fd
> cp: cannot stat 'edk2/Build/ArmVirtQemu-AARCH64/DEBUG_/FV/QEMU_EFI.fd':
> No such file or directory
> Makefile.edk2:45: recipe for target '../pc-bios/edk2-aarch64-code.fd' failed
> make[1]: *** [../pc-bios/edk2-aarch64-code.fd] Error 1
> make[1]: Leaving directory '/home/phil/source/qemu/roms'
> Makefile:148: recipe for target 'efi' failed
> make: *** [efi] Error 2
> make: Leaving directory '/home/phil/source/qemu/roms'
> 
> The edk2-build.sh script source edksetup.sh, then you call the
> 'toolchain' command out of the edk2-build.sh script, but here
> the edksetup.sh setup is no more effective.

I was wrong, it is sourced. See self-reply at top of this post.

Regards,

Phil.
Eric Blake March 11, 2019, 12:09 p.m. UTC | #4
On 3/10/19 10:10 AM, Philippe Mathieu-Daudé wrote:
> Hi Laszlo,
> 
> On 3/9/19 5:48 PM, Philippe Mathieu-Daudé wrote:
>> On 3/9/19 1:48 AM, Laszlo Ersek wrote:
>>> Add the "efi" target to "Makefile".
>>>

>>> +
>>> +toolchain = $(shell source ./edk2-funcs.sh && qemu_edk2_get_toolchain $(1))
> 
> Well I finally figured out why building on Ubuntu fails. It default
> shell is dash, and 'source' is a bash builtin command. The portable
> equivalent is '.' (dot).
> 
> The fix is:
> 
> -- >8 --
> -toolchain = $(shell source ./edk2-funcs.sh && qemu_edk2_get_toolchain $(1))
> +toolchain = $(shell . ./edk2-funcs.sh && qemu_edk2_get_toolchain $(1))

Ouch - this changes my analysis in 1/10, where I argued that since the
file was only ever sourced by a bash script, its use of 'local' was
okay. Now that you are also sourcing it from /bin/sh via Makefile, you
HAVE to make edk2-funcs.sh portable to POSIX shell, by eliminating use
of 'local'.
Laszlo Ersek March 12, 2019, 3:15 p.m. UTC | #5
On 03/11/19 13:09, Eric Blake wrote:
> On 3/10/19 10:10 AM, Philippe Mathieu-Daudé wrote:
>> Hi Laszlo,
>>
>> On 3/9/19 5:48 PM, Philippe Mathieu-Daudé wrote:
>>> On 3/9/19 1:48 AM, Laszlo Ersek wrote:
>>>> Add the "efi" target to "Makefile".
>>>>
>
>>>> +
>>>> +toolchain = $(shell source ./edk2-funcs.sh && qemu_edk2_get_toolchain $(1))
>>
>> Well I finally figured out why building on Ubuntu fails. It default
>> shell is dash, and 'source' is a bash builtin command. The portable
>> equivalent is '.' (dot).

Yes, I'm aware:

  http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_18

also,

  http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_09_01_01

    If the command name matches the name of a utility listed in the
    following table, the results are unspecified [...] /source/

>> The fix is:
>>
>> -- >8 --
>> -toolchain = $(shell source ./edk2-funcs.sh && qemu_edk2_get_toolchain $(1))
>> +toolchain = $(shell . ./edk2-funcs.sh && qemu_edk2_get_toolchain $(1))
>
> Ouch - this changes my analysis in 1/10, where I argued that since the
> file was only ever sourced by a bash script, its use of 'local' was
> okay. Now that you are also sourcing it from /bin/sh via Makefile, you
> HAVE to make edk2-funcs.sh portable to POSIX shell, by eliminating use
> of 'local'.
>

I'm acutely aware of portable vs. non-portable shell scripts. While
working on the code, I specifically checked that "local" was not
specified in SUSv4. The point is, I didn't care, because I didn't target
a POSIX system, but a GNU system.

We already require GNU Make, to my knowledge. Perhaps not by decree, but
through the feature set that we use.

(

  For example, the extended description of the portable "Makefile"
  language, at

    http://pubs.opengroup.org/onlinepubs/9699919799/utilities/make.html#tag_20_76_13

  doesn't even mention $(shell), or other parametrizable macros.

)

I really want to keep "local", as it keeps the shell variable namespace
clean. Regarding the functions that I did put in the "global namespace",
I was careful to prefix them suitably.

IMO, it's perfectly fine to require the shell to be bash here, given
that this feature is meant for a subset of maintainers (and not for
end-users), and that building edk2 already requires a quite sizeable set
of packages installed (such as nasm, iasl, ...) So this feature is not
meant for any random POSIX system.

What I did miss in fact was that "GNU Make" didn't imply "/bin/bash":

  https://www.gnu.org/software/make/manual/make.html#Choosing-the-Shell

    The program used as the shell is taken from the variable SHELL. If
    this variable is not set in your makefile, the program /bin/sh is
    used as the shell.

Thus, the real fix here is to be explicit about the bash requirement. I
should add

  SHELL=/bin/bash

near the top of "Makefile.edk2".

(The GNU make documentation also provides examples with
SHELL=/usr/bin/perl, so I think SHELL=/bin/bash should be safe,
generally speaking.)


Phil: can you please test whether SHELL=/bin/bash works for you on
Ubuntu? (After you install "bash", of course.)

Thanks!
Laszlo
Laszlo Ersek March 12, 2019, 3:25 p.m. UTC | #6
On 03/10/19 12:26, Philippe Mathieu-Daudé wrote:
> Hi Laszlo,
> 
> On 3/9/19 1:48 AM, Laszlo Ersek wrote:
>> Add the "efi" target to "Makefile".
>>
>> Introduce "Makefile.edk2" for building and cleaning the firmware images
>> and varstore templates.
>>
>> Collect the common bits from the recipes in the helper script
>> "edk2-build.sh".
>>
>> Signed-off-by: Laszlo Ersek <lersek@redhat.com>
>> ---
>>  roms/Makefile      |   5 +
>>  roms/Makefile.edk2 | 138 ++++++++++++++++++++
>>  roms/edk2-build.sh |  55 ++++++++
>>  3 files changed, 198 insertions(+)
>>
>> diff --git a/roms/Makefile b/roms/Makefile
>> index 2e83ececa25a..054b432834ba 100644
>> --- a/roms/Makefile
>> +++ b/roms/Makefile
>> @@ -61,6 +61,7 @@ default:
>>  	@echo "  skiboot        -- update skiboot.lid"
>>  	@echo "  u-boot.e500    -- update u-boot.e500"
>>  	@echo "  u-boot.sam460  -- update u-boot.sam460"
>> +	@echo "  efi            -- update UEFI (edk2) platform firmware"
>>  
>>  bios: build-seabios-config-seabios-128k build-seabios-config-seabios-256k
>>  	cp seabios/builds/seabios-128k/bios.bin ../pc-bios/bios.bin
>> @@ -143,6 +144,9 @@ skiboot:
>>  	$(MAKE) -C skiboot CROSS=$(powerpc64_cross_prefix)
>>  	cp skiboot/skiboot.lid ../pc-bios/skiboot.lid
>>  
>> +efi: edk2-basetools
>> +	$(MAKE) -f Makefile.edk2
>> +
>>  clean:
>>  	rm -rf seabios/.config seabios/out seabios/builds
>>  	$(MAKE) -C sgabios clean
>> @@ -153,3 +157,4 @@ clean:
>>  	rm -rf u-boot/build.e500
>>  	$(MAKE) -C u-boot-sam460ex distclean
>>  	$(MAKE) -C skiboot clean
>> +	$(MAKE) -f Makefile.edk2 clean
>> diff --git a/roms/Makefile.edk2 b/roms/Makefile.edk2
>> new file mode 100644
>> index 000000000000..ad6fff044cd6
>> --- /dev/null
>> +++ b/roms/Makefile.edk2
>> @@ -0,0 +1,138 @@
>> +# Makefile for building firmware binaries and variable store templates for a
>> +# number of virtual platforms in edk2.
>> +#
>> +# Copyright (C) 2019, Red Hat, Inc.
>> +#
>> +# This program and the accompanying materials are licensed and made available
>> +# under the terms and conditions of the BSD License that accompanies this
>> +# distribution. The full text of the license may be found at
>> +# <http://opensource.org/licenses/bsd-license.php>.
>> +#
>> +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
>> +# WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
>> +
>> +toolchain = $(shell source ./edk2-funcs.sh && qemu_edk2_get_toolchain $(1))
>> +
>> +licenses := \
>> +	edk2/License.txt \
>> +	edk2/OvmfPkg/License.txt \
>> +	edk2/CryptoPkg/Library/OpensslLib/openssl/LICENSE
>> +
>> +# The "edk2-arm-vars.fd" varstore template is suitable for aarch64 as well.
>> +# Similarly, the "edk2-i386-vars.fd" varstore template is suitable for x86_64
>> +# as well, independently of "secure" too.
>> +all: \
>> +	../pc-bios/edk2-aarch64-code.fd \
>> +	../pc-bios/edk2-arm-code.fd \
>> +	../pc-bios/edk2-i386-code.fd \
>> +	../pc-bios/edk2-i386-secure-code.fd \
>> +	../pc-bios/edk2-x86_64-code.fd \
>> +	../pc-bios/edk2-x86_64-secure-code.fd \
>> +	\
>> +	../pc-bios/edk2-arm-vars.fd \
>> +	../pc-bios/edk2-i386-vars.fd \
>> +	\
>> +	../pc-bios/edk2-licenses.txt
>> +
>> +submodules:
>> +	cd edk2 && git submodule update --init --force
>> +
>> +# See notes on the ".NOTPARALLEL" target and the "+" indicator in
>> +# "tests/uefi-test-tools/Makefile".
>> +.NOTPARALLEL:
>> +
>> +../pc-bios/edk2-aarch64-code.fd: submodules
>> +	+./edk2-build.sh \
>> +		aarch64 \
>> +		--arch=AARCH64 \
>> +		--platform=ArmVirtPkg/ArmVirtQemu.dsc \
>> +		-D NETWORK_IP6_ENABLE \
>> +		-D HTTP_BOOT_ENABLE
>> +	cp edk2/Build/ArmVirtQemu-AARCH64/DEBUG_$(call toolchain,aarch64)/FV/QEMU_EFI.fd \
>> +		$@
>> +	truncate --size=64M $@
>> +
>> +../pc-bios/edk2-arm-code.fd: submodules
>> +	+./edk2-build.sh \
>> +		arm \
>> +		--arch=ARM \
>> +		--platform=ArmVirtPkg/ArmVirtQemu.dsc \
>> +		-D NETWORK_IP6_ENABLE \
>> +		-D HTTP_BOOT_ENABLE
>> +	cp edk2/Build/ArmVirtQemu-ARM/DEBUG_$(call toolchain,arm)/FV/QEMU_EFI.fd \
>> +		$@
>> +	truncate --size=64M $@
>> +
>> +../pc-bios/edk2-i386-code.fd: submodules
>> +	+./edk2-build.sh \
>> +		i386 \
>> +		--arch=IA32 \
>> +		--platform=OvmfPkg/OvmfPkgIa32.dsc \
>> +		-D NETWORK_IP6_ENABLE \
>> +		-D HTTP_BOOT_ENABLE \
>> +		-D TLS_ENABLE \
>> +		-D TPM2_ENABLE \
>> +		-D TPM2_CONFIG_ENABLE
>> +	cp edk2/Build/OvmfIa32/DEBUG_$(call toolchain,i386)/FV/OVMF_CODE.fd $@
>> +
>> +../pc-bios/edk2-i386-secure-code.fd: submodules
>> +	+./edk2-build.sh \
>> +		i386 \
>> +		--arch=IA32 \
>> +		--platform=OvmfPkg/OvmfPkgIa32.dsc \
>> +		-D NETWORK_IP6_ENABLE \
>> +		-D HTTP_BOOT_ENABLE \
>> +		-D TLS_ENABLE \
>> +		-D TPM2_ENABLE \
>> +		-D TPM2_CONFIG_ENABLE \
>> +		-D SECURE_BOOT_ENABLE \
>> +		-D SMM_REQUIRE
>> +	cp edk2/Build/OvmfIa32/DEBUG_$(call toolchain,i386)/FV/OVMF_CODE.fd $@
>> +
>> +../pc-bios/edk2-x86_64-code.fd: submodules
>> +	+./edk2-build.sh \
>> +		x86_64 \
>> +		--arch=X64 \
>> +		--platform=OvmfPkg/OvmfPkgX64.dsc \
>> +		-D NETWORK_IP6_ENABLE \
>> +		-D HTTP_BOOT_ENABLE \
>> +		-D TLS_ENABLE \
>> +		-D TPM2_ENABLE \
>> +		-D TPM2_CONFIG_ENABLE
>> +	cp edk2/Build/OvmfX64/DEBUG_$(call toolchain,x86_64)/FV/OVMF_CODE.fd $@
>> +
>> +../pc-bios/edk2-x86_64-secure-code.fd: submodules
>> +	+./edk2-build.sh \
>> +		x86_64 \
>> +		--arch=IA32 \
>> +		--arch=X64 \
>> +		--platform=OvmfPkg/OvmfPkgIa32X64.dsc \
>> +		-D NETWORK_IP6_ENABLE \
>> +		-D HTTP_BOOT_ENABLE \
>> +		-D TLS_ENABLE \
>> +		-D TPM2_ENABLE \
>> +		-D TPM2_CONFIG_ENABLE \
>> +		-D SECURE_BOOT_ENABLE \
>> +		-D SMM_REQUIRE
>> +	cp edk2/Build/Ovmf3264/DEBUG_$(call toolchain,x86_64)/FV/OVMF_CODE.fd $@
> 
> Do you mind adding a $EDK2_BUILD_OPTIONS variable to optionally add
> arguments from the environment?

Hm. Not really a fan of easily hooking random stuff into these command
lines.

> I figured it is useful for CI
> integration to quiet the build output, else the CI stdout limit is
> reached quickly.

That sounds really bad. "CI stdout limit" is something that should not
exist, or should be flexibly configurable. Where else do they want us to
read the build log, for example?

Anyway, the "build" utility can take a "--log" option. IMO it does not
belong in "Makefile.edk2", but in the "edk2-build.sh" script.

> I'll suggest a patch you can amend or improve :)

I'm extremely starved for cycles on this. Please let's stick to the
minimum acceptable content here, and work with incremental patches on
top (maybe in the next development cycle).

Thanks,
Laszlo

> 
>> +
>> +../pc-bios/edk2-arm-vars.fd: ../pc-bios/edk2-arm-code.fd
>> +	cp edk2/Build/ArmVirtQemu-ARM/DEBUG_$(call toolchain,arm)/FV/QEMU_VARS.fd \
>> +		$@
>> +	truncate --size=64M $@
>> +
>> +../pc-bios/edk2-i386-vars.fd: ../pc-bios/edk2-i386-code.fd
>> +	cp edk2/Build/OvmfIa32/DEBUG_$(call toolchain,i386)/FV/OVMF_VARS.fd $@
>> +
>> +# The license file accumulates several individual licenses from under edk2,
>> +# prefixing each individual license with a header (generated by "tail") that
>> +# states its pathname.
>> +../pc-bios/edk2-licenses.txt: submodules
>> +	tail -n $(shell cat $(licenses) | wc -l) $(licenses) > $@
>> +	dos2unix $@
>> +
>> +clean:
>> +	rm -rf edk2/Build
>> +	cd edk2/Conf && \
>> +		rm -rf .cache BuildEnv.sh build_rule.txt target.txt \
>> +			tools_def.txt
>> diff --git a/roms/edk2-build.sh b/roms/edk2-build.sh
>> new file mode 100755
>> index 000000000000..936d2c874a22
>> --- /dev/null
>> +++ b/roms/edk2-build.sh
>> @@ -0,0 +1,55 @@
>> +#!/bin/bash
>> +
>> +# Wrapper shell script for building a  virtual platform firmware in edk2.
>> +#
>> +# Copyright (C) 2019, Red Hat, Inc.
>> +#
>> +# This program and the accompanying materials are licensed and made available
>> +# under the terms and conditions of the BSD License that accompanies this
>> +# distribution. The full text of the license may be found at
>> +# <http://opensource.org/licenses/bsd-license.php>.
>> +#
>> +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
>> +# WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
>> +
>> +set -e -u -C
>> +
>> +# Save the command line arguments. We need to reset $# to 0 before sourcing
>> +# "edksetup.sh", as it will inherit $@.
>> +emulation_target=$1
>> +shift
>> +num_args=0
>> +args=()
>> +for arg in "$@"; do
>> +  args[num_args++]="$arg"
>> +done
>> +shift $num_args
>> +
>> +cd edk2
>> +
>> +# Work around <https://bugzilla.tianocore.org/show_bug.cgi?id=1607>.
>> +export PYTHON_COMMAND=python2
>> +
>> +# Source "edksetup.sh" carefully.
>> +set +e +u +C
>> +source ./edksetup.sh
>> +ret=$?
>> +set -e -u -C
>> +if [ $ret -ne 0 ]; then
>> +  exit $ret
>> +fi
>> +
>> +# Fetch some option arguments, and set the cross-compilation environment (if
>> +# any), for the edk2 "build" utility.
>> +source ../edk2-funcs.sh
>> +edk2_toolchain=$(qemu_edk2_get_toolchain "$emulation_target")
>> +edk2_thread_count=$(qemu_edk2_get_thread_count "$MAKEFLAGS")
>> +qemu_edk2_set_cross_env "$emulation_target"
>> +
>> +# Build the platform firmware.
>> +build \
>> +  --cmd-len=65536 \
>> +  -n "$edk2_thread_count" \
>> +  --buildtarget=DEBUG \
>> +  --tagname="$edk2_toolchain" \
>> +  "${args[@]}"
>>
Eric Blake March 12, 2019, 4:07 p.m. UTC | #7
On 3/12/19 10:15 AM, Laszlo Ersek wrote:

> I'm acutely aware of portable vs. non-portable shell scripts. While
> working on the code, I specifically checked that "local" was not
> specified in SUSv4. The point is, I didn't care, because I didn't target
> a POSIX system, but a GNU system.
> 
> We already require GNU Make, to my knowledge. Perhaps not by decree, but
> through the feature set that we use.

Indeed, qemu fails to build under BSD make.

> I really want to keep "local", as it keeps the shell variable namespace
> clean. Regarding the functions that I did put in the "global namespace",
> I was careful to prefix them suitably.

Yes, using local makes bash functions easier to write. (And I've been
trying to argue that POSIX should adopt local, but there is a
fundamental difference between ksh local (static scoping) and bash local
(dynamic scoping) that neither shell is willing to switch their existing
practice to meet at common ground - which is why POSIX hasn't
standardized anything yet)

> 
> IMO, it's perfectly fine to require the shell to be bash here, given
> that this feature is meant for a subset of maintainers (and not for
> end-users), and that building edk2 already requires a quite sizeable set
> of packages installed (such as nasm, iasl, ...) So this feature is not
> meant for any random POSIX system.
> 
> What I did miss in fact was that "GNU Make" didn't imply "/bin/bash":

Yep, I can see how that was not obvious, and I also agree that:

> Thus, the real fix here is to be explicit about the bash requirement. I
> should add
> 
>   SHELL=/bin/bash
> 
> near the top of "Makefile.edk2".

this should indeed force the use of bash for all shell snippets and
$(shell) invocations in that makefile (and let you get away with
'source' instead of '.', as well as the use of 'local' within the
sourced functions).
Laszlo Ersek March 12, 2019, 7:33 p.m. UTC | #8
On 03/12/19 17:07, Eric Blake wrote:
> On 3/12/19 10:15 AM, Laszlo Ersek wrote:
> 
>> I'm acutely aware of portable vs. non-portable shell scripts. While
>> working on the code, I specifically checked that "local" was not
>> specified in SUSv4. The point is, I didn't care, because I didn't target
>> a POSIX system, but a GNU system.
>>
>> We already require GNU Make, to my knowledge. Perhaps not by decree, but
>> through the feature set that we use.
> 
> Indeed, qemu fails to build under BSD make.
> 
>> I really want to keep "local", as it keeps the shell variable namespace
>> clean. Regarding the functions that I did put in the "global namespace",
>> I was careful to prefix them suitably.
> 
> Yes, using local makes bash functions easier to write. (And I've been
> trying to argue that POSIX should adopt local, but there is a
> fundamental difference between ksh local (static scoping) and bash local
> (dynamic scoping) that neither shell is willing to switch their existing
> practice to meet at common ground - which is why POSIX hasn't
> standardized anything yet)

Interesting! I didn't know about this. "local" has always seemed like a
"no brainer" to me (for POSIX to incorporate), but given the actual
conflict between bash and ksh, I guess it might never happen. (Also, it
should be quite obvious at this point that the only "ksh" command I have
ever typed has been "exit" :) )

>> IMO, it's perfectly fine to require the shell to be bash here, given
>> that this feature is meant for a subset of maintainers (and not for
>> end-users), and that building edk2 already requires a quite sizeable set
>> of packages installed (such as nasm, iasl, ...) So this feature is not
>> meant for any random POSIX system.
>>
>> What I did miss in fact was that "GNU Make" didn't imply "/bin/bash":
> 
> Yep, I can see how that was not obvious, and I also agree that:
> 
>> Thus, the real fix here is to be explicit about the bash requirement. I
>> should add
>>
>>   SHELL=/bin/bash
>>
>> near the top of "Makefile.edk2".
> 
> this should indeed force the use of bash for all shell snippets and
> $(shell) invocations in that makefile (and let you get away with
> 'source' instead of '.', as well as the use of 'local' within the
> sourced functions).
> 

Awesome, thank you.
Laszlo
Philippe Mathieu-Daudé March 12, 2019, 9:11 p.m. UTC | #9
On 3/12/19 4:15 PM, Laszlo Ersek wrote:
> On 03/11/19 13:09, Eric Blake wrote:
>> On 3/10/19 10:10 AM, Philippe Mathieu-Daudé wrote:
>>> Hi Laszlo,
>>>
>>> On 3/9/19 5:48 PM, Philippe Mathieu-Daudé wrote:
>>>> On 3/9/19 1:48 AM, Laszlo Ersek wrote:
>>>>> Add the "efi" target to "Makefile".
>>>>>
>>
>>>>> +
>>>>> +toolchain = $(shell source ./edk2-funcs.sh && qemu_edk2_get_toolchain $(1))
>>>
>>> Well I finally figured out why building on Ubuntu fails. It default
>>> shell is dash, and 'source' is a bash builtin command. The portable
>>> equivalent is '.' (dot).
> 
> Yes, I'm aware:
> 
>   http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_18
> 
> also,
> 
>   http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_09_01_01
> 
>     If the command name matches the name of a utility listed in the
>     following table, the results are unspecified [...] /source/
> 
>>> The fix is:
>>>
>>> -- >8 --
>>> -toolchain = $(shell source ./edk2-funcs.sh && qemu_edk2_get_toolchain $(1))
>>> +toolchain = $(shell . ./edk2-funcs.sh && qemu_edk2_get_toolchain $(1))
>>
>> Ouch - this changes my analysis in 1/10, where I argued that since the
>> file was only ever sourced by a bash script, its use of 'local' was
>> okay. Now that you are also sourcing it from /bin/sh via Makefile, you
>> HAVE to make edk2-funcs.sh portable to POSIX shell, by eliminating use
>> of 'local'.
>>
> 
> I'm acutely aware of portable vs. non-portable shell scripts. While
> working on the code, I specifically checked that "local" was not
> specified in SUSv4. The point is, I didn't care, because I didn't target
> a POSIX system, but a GNU system.
> 
> We already require GNU Make, to my knowledge. Perhaps not by decree, but
> through the feature set that we use.
> 
> (
> 
>   For example, the extended description of the portable "Makefile"
>   language, at
> 
>     http://pubs.opengroup.org/onlinepubs/9699919799/utilities/make.html#tag_20_76_13
> 
>   doesn't even mention $(shell), or other parametrizable macros.
> 
> )
> 
> I really want to keep "local", as it keeps the shell variable namespace
> clean. Regarding the functions that I did put in the "global namespace",
> I was careful to prefix them suitably.
> 
> IMO, it's perfectly fine to require the shell to be bash here, given
> that this feature is meant for a subset of maintainers (and not for
> end-users), and that building edk2 already requires a quite sizeable set
> of packages installed (such as nasm, iasl, ...) So this feature is not
> meant for any random POSIX system.
> 
> What I did miss in fact was that "GNU Make" didn't imply "/bin/bash":
> 
>   https://www.gnu.org/software/make/manual/make.html#Choosing-the-Shell
> 
>     The program used as the shell is taken from the variable SHELL. If
>     this variable is not set in your makefile, the program /bin/sh is
>     used as the shell.
> 
> Thus, the real fix here is to be explicit about the bash requirement. I
> should add
> 
>   SHELL=/bin/bash
> 
> near the top of "Makefile.edk2".
> 
> (The GNU make documentation also provides examples with
> SHELL=/usr/bin/perl, so I think SHELL=/bin/bash should be safe,
> generally speaking.)
> 
> 
> Phil: can you please test whether SHELL=/bin/bash works for you on
> Ubuntu? (After you install "bash", of course.)

It indeed worked using:
-- >8 --
@@ -11,6 +11,8 @@
 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT
 # WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+SHELL = /bin/bash
+
 toolchain = $(shell source ./edk2-funcs.sh && qemu_edk2_get_toolchain $(1))
---

With this fixup:
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>

Regards,

Phil.
Laszlo Ersek March 13, 2019, 10:45 a.m. UTC | #10
On 03/12/19 22:11, Philippe Mathieu-Daudé wrote:
> On 3/12/19 4:15 PM, Laszlo Ersek wrote:

>> Phil: can you please test whether SHELL=/bin/bash works for you on
>> Ubuntu? (After you install "bash", of course.)
> 
> It indeed worked using:
> -- >8 --
> @@ -11,6 +11,8 @@
>  # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> WITHOUT
>  # WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> 
> +SHELL = /bin/bash
> +
>  toolchain = $(shell source ./edk2-funcs.sh && qemu_edk2_get_toolchain $(1))
> ---
> 
> With this fixup:
> Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
> Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
> 
> Regards,
> 
> Phil.
> 

Thank you very much!
Laszlo
diff mbox series

Patch

diff --git a/roms/Makefile b/roms/Makefile
index 2e83ececa25a..054b432834ba 100644
--- a/roms/Makefile
+++ b/roms/Makefile
@@ -61,6 +61,7 @@  default:
 	@echo "  skiboot        -- update skiboot.lid"
 	@echo "  u-boot.e500    -- update u-boot.e500"
 	@echo "  u-boot.sam460  -- update u-boot.sam460"
+	@echo "  efi            -- update UEFI (edk2) platform firmware"
 
 bios: build-seabios-config-seabios-128k build-seabios-config-seabios-256k
 	cp seabios/builds/seabios-128k/bios.bin ../pc-bios/bios.bin
@@ -143,6 +144,9 @@  skiboot:
 	$(MAKE) -C skiboot CROSS=$(powerpc64_cross_prefix)
 	cp skiboot/skiboot.lid ../pc-bios/skiboot.lid
 
+efi: edk2-basetools
+	$(MAKE) -f Makefile.edk2
+
 clean:
 	rm -rf seabios/.config seabios/out seabios/builds
 	$(MAKE) -C sgabios clean
@@ -153,3 +157,4 @@  clean:
 	rm -rf u-boot/build.e500
 	$(MAKE) -C u-boot-sam460ex distclean
 	$(MAKE) -C skiboot clean
+	$(MAKE) -f Makefile.edk2 clean
diff --git a/roms/Makefile.edk2 b/roms/Makefile.edk2
new file mode 100644
index 000000000000..ad6fff044cd6
--- /dev/null
+++ b/roms/Makefile.edk2
@@ -0,0 +1,138 @@ 
+# Makefile for building firmware binaries and variable store templates for a
+# number of virtual platforms in edk2.
+#
+# Copyright (C) 2019, Red Hat, Inc.
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License that accompanies this
+# distribution. The full text of the license may be found at
+# <http://opensource.org/licenses/bsd-license.php>.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
+# WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+toolchain = $(shell source ./edk2-funcs.sh && qemu_edk2_get_toolchain $(1))
+
+licenses := \
+	edk2/License.txt \
+	edk2/OvmfPkg/License.txt \
+	edk2/CryptoPkg/Library/OpensslLib/openssl/LICENSE
+
+# The "edk2-arm-vars.fd" varstore template is suitable for aarch64 as well.
+# Similarly, the "edk2-i386-vars.fd" varstore template is suitable for x86_64
+# as well, independently of "secure" too.
+all: \
+	../pc-bios/edk2-aarch64-code.fd \
+	../pc-bios/edk2-arm-code.fd \
+	../pc-bios/edk2-i386-code.fd \
+	../pc-bios/edk2-i386-secure-code.fd \
+	../pc-bios/edk2-x86_64-code.fd \
+	../pc-bios/edk2-x86_64-secure-code.fd \
+	\
+	../pc-bios/edk2-arm-vars.fd \
+	../pc-bios/edk2-i386-vars.fd \
+	\
+	../pc-bios/edk2-licenses.txt
+
+submodules:
+	cd edk2 && git submodule update --init --force
+
+# See notes on the ".NOTPARALLEL" target and the "+" indicator in
+# "tests/uefi-test-tools/Makefile".
+.NOTPARALLEL:
+
+../pc-bios/edk2-aarch64-code.fd: submodules
+	+./edk2-build.sh \
+		aarch64 \
+		--arch=AARCH64 \
+		--platform=ArmVirtPkg/ArmVirtQemu.dsc \
+		-D NETWORK_IP6_ENABLE \
+		-D HTTP_BOOT_ENABLE
+	cp edk2/Build/ArmVirtQemu-AARCH64/DEBUG_$(call toolchain,aarch64)/FV/QEMU_EFI.fd \
+		$@
+	truncate --size=64M $@
+
+../pc-bios/edk2-arm-code.fd: submodules
+	+./edk2-build.sh \
+		arm \
+		--arch=ARM \
+		--platform=ArmVirtPkg/ArmVirtQemu.dsc \
+		-D NETWORK_IP6_ENABLE \
+		-D HTTP_BOOT_ENABLE
+	cp edk2/Build/ArmVirtQemu-ARM/DEBUG_$(call toolchain,arm)/FV/QEMU_EFI.fd \
+		$@
+	truncate --size=64M $@
+
+../pc-bios/edk2-i386-code.fd: submodules
+	+./edk2-build.sh \
+		i386 \
+		--arch=IA32 \
+		--platform=OvmfPkg/OvmfPkgIa32.dsc \
+		-D NETWORK_IP6_ENABLE \
+		-D HTTP_BOOT_ENABLE \
+		-D TLS_ENABLE \
+		-D TPM2_ENABLE \
+		-D TPM2_CONFIG_ENABLE
+	cp edk2/Build/OvmfIa32/DEBUG_$(call toolchain,i386)/FV/OVMF_CODE.fd $@
+
+../pc-bios/edk2-i386-secure-code.fd: submodules
+	+./edk2-build.sh \
+		i386 \
+		--arch=IA32 \
+		--platform=OvmfPkg/OvmfPkgIa32.dsc \
+		-D NETWORK_IP6_ENABLE \
+		-D HTTP_BOOT_ENABLE \
+		-D TLS_ENABLE \
+		-D TPM2_ENABLE \
+		-D TPM2_CONFIG_ENABLE \
+		-D SECURE_BOOT_ENABLE \
+		-D SMM_REQUIRE
+	cp edk2/Build/OvmfIa32/DEBUG_$(call toolchain,i386)/FV/OVMF_CODE.fd $@
+
+../pc-bios/edk2-x86_64-code.fd: submodules
+	+./edk2-build.sh \
+		x86_64 \
+		--arch=X64 \
+		--platform=OvmfPkg/OvmfPkgX64.dsc \
+		-D NETWORK_IP6_ENABLE \
+		-D HTTP_BOOT_ENABLE \
+		-D TLS_ENABLE \
+		-D TPM2_ENABLE \
+		-D TPM2_CONFIG_ENABLE
+	cp edk2/Build/OvmfX64/DEBUG_$(call toolchain,x86_64)/FV/OVMF_CODE.fd $@
+
+../pc-bios/edk2-x86_64-secure-code.fd: submodules
+	+./edk2-build.sh \
+		x86_64 \
+		--arch=IA32 \
+		--arch=X64 \
+		--platform=OvmfPkg/OvmfPkgIa32X64.dsc \
+		-D NETWORK_IP6_ENABLE \
+		-D HTTP_BOOT_ENABLE \
+		-D TLS_ENABLE \
+		-D TPM2_ENABLE \
+		-D TPM2_CONFIG_ENABLE \
+		-D SECURE_BOOT_ENABLE \
+		-D SMM_REQUIRE
+	cp edk2/Build/Ovmf3264/DEBUG_$(call toolchain,x86_64)/FV/OVMF_CODE.fd $@
+
+../pc-bios/edk2-arm-vars.fd: ../pc-bios/edk2-arm-code.fd
+	cp edk2/Build/ArmVirtQemu-ARM/DEBUG_$(call toolchain,arm)/FV/QEMU_VARS.fd \
+		$@
+	truncate --size=64M $@
+
+../pc-bios/edk2-i386-vars.fd: ../pc-bios/edk2-i386-code.fd
+	cp edk2/Build/OvmfIa32/DEBUG_$(call toolchain,i386)/FV/OVMF_VARS.fd $@
+
+# The license file accumulates several individual licenses from under edk2,
+# prefixing each individual license with a header (generated by "tail") that
+# states its pathname.
+../pc-bios/edk2-licenses.txt: submodules
+	tail -n $(shell cat $(licenses) | wc -l) $(licenses) > $@
+	dos2unix $@
+
+clean:
+	rm -rf edk2/Build
+	cd edk2/Conf && \
+		rm -rf .cache BuildEnv.sh build_rule.txt target.txt \
+			tools_def.txt
diff --git a/roms/edk2-build.sh b/roms/edk2-build.sh
new file mode 100755
index 000000000000..936d2c874a22
--- /dev/null
+++ b/roms/edk2-build.sh
@@ -0,0 +1,55 @@ 
+#!/bin/bash
+
+# Wrapper shell script for building a  virtual platform firmware in edk2.
+#
+# Copyright (C) 2019, Red Hat, Inc.
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License that accompanies this
+# distribution. The full text of the license may be found at
+# <http://opensource.org/licenses/bsd-license.php>.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
+# WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+set -e -u -C
+
+# Save the command line arguments. We need to reset $# to 0 before sourcing
+# "edksetup.sh", as it will inherit $@.
+emulation_target=$1
+shift
+num_args=0
+args=()
+for arg in "$@"; do
+  args[num_args++]="$arg"
+done
+shift $num_args
+
+cd edk2
+
+# Work around <https://bugzilla.tianocore.org/show_bug.cgi?id=1607>.
+export PYTHON_COMMAND=python2
+
+# Source "edksetup.sh" carefully.
+set +e +u +C
+source ./edksetup.sh
+ret=$?
+set -e -u -C
+if [ $ret -ne 0 ]; then
+  exit $ret
+fi
+
+# Fetch some option arguments, and set the cross-compilation environment (if
+# any), for the edk2 "build" utility.
+source ../edk2-funcs.sh
+edk2_toolchain=$(qemu_edk2_get_toolchain "$emulation_target")
+edk2_thread_count=$(qemu_edk2_get_thread_count "$MAKEFLAGS")
+qemu_edk2_set_cross_env "$emulation_target"
+
+# Build the platform firmware.
+build \
+  --cmd-len=65536 \
+  -n "$edk2_thread_count" \
+  --buildtarget=DEBUG \
+  --tagname="$edk2_toolchain" \
+  "${args[@]}"