diff --git a/.github/actions/setup/action.yml b/.github/actions/setup/action.yml index df748bb94e..be17bc167e 100644 --- a/.github/actions/setup/action.yml +++ b/.github/actions/setup/action.yml @@ -11,6 +11,16 @@ inputs: APPLE_IDENTITY: description: Apple identity to use for signing required: false + skip-codesign-import: + description: > + When 'true', skip importing the Apple Developer ID into the keychain. + Useful for recipes whose binaries require adhoc signing (eg. those + carrying com.apple.security.virtualization / .hypervisor entitlements, + which need either adhoc or a matching provisioning profile to be + accepted by macOS at runtime). Defense-in-depth on top of brewkit's + fix-machos.rb policy. See pkgxdev/pantry#7853. + required: false + default: 'false' runs: using: composite @@ -38,11 +48,11 @@ runs: # delete it if it does. - name: Delete keychain shell: sh - if: runner.os == 'macOS' && inputs.p12-password && inputs.p12-file-base64 + if: runner.os == 'macOS' && inputs.p12-password && inputs.p12-file-base64 && inputs.skip-codesign-import != 'true' run: security delete-keychain signing_temp.keychain || true - uses: apple-actions/import-codesign-certs@v6 - if: runner.os == 'macOS' && inputs.p12-password && inputs.p12-file-base64 + if: runner.os == 'macOS' && inputs.p12-password && inputs.p12-file-base64 && inputs.skip-codesign-import != 'true' with: p12-file-base64: ${{ inputs.p12-file-base64 }} p12-password: ${{ inputs.p12-password }} diff --git a/.github/workflows/pkg-platform.yml b/.github/workflows/pkg-platform.yml index c6693dc2c4..bcde347981 100644 --- a/.github/workflows/pkg-platform.yml +++ b/.github/workflows/pkg-platform.yml @@ -40,6 +40,13 @@ on: invalidate-cloudfront: type: boolean default: true + skip-codesign-import: + description: > + Skip importing the Apple Developer ID into the keychain. + For recipes whose binaries need adhoc signing (virtualization / + hypervisor entitlements). See pkgxdev/pantry#7853. + type: boolean + default: false secrets: APPLE_CERTIFICATE_P12: { required: false } APPLE_CERTIFICATE_P12_PASSWORD: { required: false } @@ -80,6 +87,7 @@ jobs: p12-file-base64: ${{ secrets.APPLE_CERTIFICATE_P12 }} p12-password: ${{ secrets.APPLE_CERTIFICATE_P12_PASSWORD }} APPLE_IDENTITY: ${{ secrets.APPLE_IDENTITY }} + skip-codesign-import: ${{ inputs.skip-codesign-import }} - uses: pkgxdev/setup@v5 with: diff --git a/.github/workflows/pkg.yml b/.github/workflows/pkg.yml index 5e88f4adce..c77341f136 100644 --- a/.github/workflows/pkg.yml +++ b/.github/workflows/pkg.yml @@ -16,6 +16,13 @@ on: invalidate-cloudfront: type: boolean default: true + skip-codesign-import: + description: > + Skip importing the Apple Developer ID into the keychain. + For recipes whose binaries need adhoc signing (virtualization / + hypervisor entitlements). See pkgxdev/pantry#7853. + type: boolean + default: false jobs: plan: @@ -54,4 +61,5 @@ jobs: tinyname: ${{ matrix.platform.tinyname }} complain: ${{ inputs.complain }} invalidate-cloudfront: ${{ inputs.invalidate-cloudfront }} + skip-codesign-import: ${{ inputs.skip-codesign-import }} secrets: inherit diff --git a/projects/tianocore.org/edk2/package.yml b/projects/tianocore.org/edk2/package.yml new file mode 100644 index 0000000000..336e9b8315 --- /dev/null +++ b/projects/tianocore.org/edk2/package.yml @@ -0,0 +1,232 @@ +# EDK II — TianoCore reference UEFI implementation. +# +# Ships OVMF / ArmVirtPkg firmware blobs for qemu, matching qemu's +# `share/qemu/` bundle layout so existing runners can pick them up +# via env-var overrides (QEMU_EFI_BIOS, etc.) without code changes. +# +# Primary target: X64 (amd64) → edk2-x86_64-code.fd / edk2-i386-vars.fd +# Secondary: AARCH64 (arm64) → edk2-aarch64-code.fd / edk2-arm-vars.fd +# +# RISCV64 and LOONGARCH64 are tracked as follow-ups: ArmVirtPkg/OvmfPkg +# DSCs exist for them, but bottle layout + cross-toolchain wiring need +# additional shake-out. +# +# Tag scheme is `edk2-stableYYYYMM[.N]`; pkgx strips the prefix so +# `versions: github` exposes a YYYYMM[.N] series that orders correctly. +# +# Platform notes: +# * Linux (GCC5) — fully self-contained on pantry deps. +# * Darwin (CLANGPDB) — uses pantry's llvm.org (clang + lld-link) to +# emit PE/COFF directly, sidestepping macOS-only `mtoc`. Slightly +# slower than XCODE5 but reproducible across hosts. + +distributable: + url: git+https://github.com/tianocore/edk2 + ref: edk2-stable{{version.raw}} + +versions: + github: tianocore/edk2/tags + match: /^edk2-stable\d+(\.\d+)?$/ + strip: /^edk2-stable/ + +build: + dependencies: + git-scm.org: '*' + python.org: ~3.11 + nasm.us: '*' + freedesktop.org/pkg-config: '*' + # iasl (ACPI compiler) — EDK II compiles `.asl` ACPI tables to `.aml` + # for several modules (RamDiskDxe's NFIT, etc.). It is not in qemu's + # toolchain, so without this the X64 build dies with + # `iasl: command not found` (exit 127) on every platform. + acpica.org: '*' + linux: + gnu.org/gcc: '*' + darwin: + # CLANGPDB toolchain emits PE/COFF directly via lld-link, avoiding + # the macOS-only `mtoc` that XCODE5 requires. + llvm.org: '*' + script: + - run: | + set -e + + # Brewkit checks out git+ sources to ${PKGX_PANTRY_PATH}/srcs/... + # and rsyncs once into ${SRCROOT}. After a manual `rm -rf builds` + # the re-stage may skip the copy (only rsyncs `props/`), leaving + # cwd empty. Repopulate from srcs/ if needed. + SRC_DIR="${PKGX_PANTRY_PATH}/srcs/$(basename "$SRCROOT")" + if [ ! -d ./BaseTools ] && [ -d "$SRC_DIR/BaseTools" ]; then + echo "edk2: repopulating build dir from $SRC_DIR" + cp -a "$SRC_DIR/." ./ + fi + + # EDK II pulls a pinned OpenSSL via submodule (CryptoPkg) and a + # handful of others (BrotliCustomDecompressLib, MipiSysTLib, …). + # We need them for SecureBoot-capable OVMF builds. + git submodule update --init --recursive --depth 1 + + # BaseTools — the C helpers (GenFv, GenFw, …) used by the build. + # + # Built SERIALLY on purpose. The VfrCompile sub-makefile has a + # missing dependency between the `dlg`-generated VfrLexer.cpp and + # its own compile step; under `make -j` the compiler races the + # generator and reads a half-written file, failing with + # `VfrLexer.cpp: error: expected expression`. With many cores + # (CI runners) the race is near-deterministic, which is why every + # platform's build was red. Serial BaseTools is quick (~1-2 min) + # and the EDK II `build` below is still fully parallel via `-n`. + make -C BaseTools + + # edksetup.sh is bash-only and expects to be sourced from $PWD. + export WORKSPACE="$PWD" + export EDK_TOOLS_PATH="$PWD/BaseTools" + export CONF_PATH="$PWD/Conf" + . ./edksetup.sh BaseTools + + # EDK II's toolchain tag is platform-specific: + # GCC5 → Linux gcc/clang, ld.bfd or ld.lld + # CLANGPDB → cross-platform clang + lld-link → PE/COFF directly + # (used on Darwin to skip the macOS-only mtoc hop) + case "$(uname -s)" in + Darwin) TC=CLANGPDB ;; + *) TC=GCC5 ;; + esac + echo "edk2: using toolchain tag $TC" + + # Recent clang (>=20) tightens -Wcast-function-type-mismatch, which + # trips OpenSSL's pem_password_cb casts in CryptoPkg/BaseCryptLib. + # EDK II compiles with -Werror, so soften that one warning. We + # also relax a couple of other newer-clang diagnostics that + # surface in third-party submodules (OpenSSL, MipiSysT). + if [ -f Conf/tools_def.txt ]; then + EXTRA="-Wno-error=cast-function-type-mismatch -Wno-error=incompatible-function-pointer-types -Wno-error=unused-but-set-variable -Wno-error=deprecated-declarations" + # Append EXTRA to every CC_FLAGS line for the active toolchain. + sed -i.bak -E \ + "s@^([[:space:]]*(DEBUG|RELEASE|NOOPT)_${TC}_[A-Z0-9]+_CC_FLAGS[[:space:]]*=.*)\$@\\1 ${EXTRA}@" \ + Conf/tools_def.txt + echo "edk2: patched $(grep -cE \"^[[:space:]]*(DEBUG|RELEASE|NOOPT)_${TC}_[A-Z0-9]+_CC_FLAGS.*cast-function-type-mismatch\" Conf/tools_def.txt) ${TC} CC_FLAGS lines" + + # CryptoPkg overrides CC_FLAGS in its DSC, so the tools_def + # patch isn't enough — patch the source file directly to + # silence the two pem_password_cb casts that newer clang + # rejects with -Wcast-function-type-mismatch. + CRYPT_PEM="CryptoPkg/Library/BaseCryptLib/Pem/CryptPem.c" + if [ -f "$CRYPT_PEM" ] && ! grep -q "clang diagnostic.*cast-function-type-mismatch" "$CRYPT_PEM"; then + { + printf '%s\n' '#if defined(__clang__)' + printf '%s\n' '#pragma clang diagnostic push' + printf '%s\n' '#pragma clang diagnostic ignored "-Wcast-function-type-mismatch"' + printf '%s\n' '#endif' + cat "$CRYPT_PEM" + printf '%s\n' '#if defined(__clang__)' + printf '%s\n' '#pragma clang diagnostic pop' + printf '%s\n' '#endif' + } > "$CRYPT_PEM.new" + mv "$CRYPT_PEM.new" "$CRYPT_PEM" + echo "edk2: patched $CRYPT_PEM for -Wcast-function-type-mismatch" + fi + fi + + mkdir -p "{{prefix}}/share/qemu" + + # ── X64 (amd64) ───────────────────────────────────────────── + build -a X64 -t "$TC" -b RELEASE \ + -p OvmfPkg/OvmfPkgX64.dsc \ + -D SECURE_BOOT_ENABLE=TRUE \ + -D TPM2_ENABLE=TRUE \ + -D NETWORK_IP6_ENABLE=TRUE \ + -D NETWORK_HTTP_BOOT_ENABLE=TRUE \ + -n {{ hw.concurrency }} + + OUT_X64="Build/OvmfX64/RELEASE_${TC}/FV" + install -m 0644 "$OUT_X64/OVMF_CODE.fd" \ + "{{prefix}}/share/qemu/edk2-x86_64-code.fd" + install -m 0644 "$OUT_X64/OVMF_VARS.fd" \ + "{{prefix}}/share/qemu/edk2-i386-vars.fd" + + # Combined CODE+VARS image (qemu `-bios` style, easier to test). + if [ -f "$OUT_X64/OVMF.fd" ]; then + install -m 0644 "$OUT_X64/OVMF.fd" \ + "{{prefix}}/share/qemu/edk2-x86_64.fd" + fi + + # ── AARCH64 (arm64) ───────────────────────────────────────── + # ArmVirtQemu emits QEMU_EFI.fd + QEMU_VARS.fd. GCC5 + CLANGPDB + # can both target AARCH64 PE/COFF as long as the host toolchain + # ships a cross-compiler. + build -a AARCH64 -t "$TC" -b RELEASE \ + -p ArmVirtPkg/ArmVirtQemu.dsc \ + -D NETWORK_HTTP_BOOT_ENABLE=TRUE \ + -n {{ hw.concurrency }} \ + || echo "edk2: aarch64 build failed; continuing (non-fatal)" + + OUT_AARCH64="Build/ArmVirtQemu-AARCH64/RELEASE_${TC}/FV" + if [ -f "$OUT_AARCH64/QEMU_EFI.fd" ]; then + install -m 0644 "$OUT_AARCH64/QEMU_EFI.fd" \ + "{{prefix}}/share/qemu/edk2-aarch64-code.fd" + install -m 0644 "$OUT_AARCH64/QEMU_VARS.fd" \ + "{{prefix}}/share/qemu/edk2-arm-vars.fd" + fi + + # Thin shim so pkgx has at least one `bin/*` entry to advertise + # and so downstream tooling can discover the blob directory + # without sourcing env vars. + mkdir -p "{{prefix}}/bin" + shim="{{prefix}}/bin/edk2-firmware-path" + { + printf '%s\n' '#!/bin/sh' + printf '%s\n' '# Print the absolute path to an EDK II firmware blob.' + printf '%s\n' '# Usage: edk2-firmware-path [x86_64-code|i386-vars|aarch64-code|arm-vars|dir]' + printf '%s\n' 'dir="$(cd "$(dirname "$0")/../share/qemu" && pwd)"' + printf '%s\n' 'case "${1:-dir}" in' + printf '%s\n' ' dir) echo "$dir" ;;' + printf '%s\n' ' x86_64-code|amd64-code) echo "$dir/edk2-x86_64-code.fd" ;;' + printf '%s\n' ' i386-vars|amd64-vars) echo "$dir/edk2-i386-vars.fd" ;;' + printf '%s\n' ' aarch64-code|arm64-code) echo "$dir/edk2-aarch64-code.fd" ;;' + printf '%s\n' ' arm-vars|arm64-vars) echo "$dir/edk2-arm-vars.fd" ;;' + printf '%s\n' ' *) echo "unknown firmware key: $1" >&2; exit 2 ;;' + printf '%s\n' 'esac' + } > "$shim" + chmod +x "$shim" + +provides: + - bin/edk2-firmware-path + +runtime: + env: + EDK2_FIRMWARE_DIR: "{{prefix}}/share/qemu" + # Backwards-compat names used by some libvirt / qemu wrappers. + OVMF_CODE: "{{prefix}}/share/qemu/edk2-x86_64-code.fd" + OVMF_VARS: "{{prefix}}/share/qemu/edk2-i386-vars.fd" + AAVMF_CODE: "{{prefix}}/share/qemu/edk2-aarch64-code.fd" + AAVMF_VARS: "{{prefix}}/share/qemu/edk2-arm-vars.fd" + +test: + dependencies: + qemu.org: '*' + # `timeout` is GNU coreutils — present on Linux runners but NOT on + # macOS, where the test would otherwise die with `timeout: command + # not found`. + gnu.org/coreutils: '*' + script: + # The firmware blobs exist and are non-empty. + - test -s "{{prefix}}/share/qemu/edk2-x86_64-code.fd" + - test -s "{{prefix}}/share/qemu/edk2-i386-vars.fd" + + # Boot qemu-system-x86_64 with the firmware and a writable vars + # copy. `-display none` keeps it headless while `-serial stdio` + # routes the firmware's console to our pipe. (Do NOT add + # `-nographic`: it also grabs stdio for the monitor and qemu aborts + # with "cannot use stdio by multiple character devices".) UEFI + # starts, finds no boot device, and waits at the Boot Manager — we + # just confirm it reached BdsDxe without faulting. + - cp "{{prefix}}/share/qemu/edk2-i386-vars.fd" ./vars.fd + - timeout 20 qemu-system-x86_64 + -machine q35,accel=tcg + -m 256 + -drive if=pflash,format=raw,readonly=on,file={{prefix}}/share/qemu/edk2-x86_64-code.fd + -drive if=pflash,format=raw,file=./vars.fd + -display none + -no-reboot + -serial stdio > boot.log 2>&1 || true + - grep -q -E "(TianoCore|EDK II|UEFI Interactive Shell|BdsDxe)" boot.log