| Tim Windelschmidt | 12240f9 | 2025-04-28 14:59:33 +0200 | [diff] [blame] | 1 | # Copyright The Monogon Project Authors. |
| 2 | # SPDX-License-Identifier: Apache-2.0 |
| 3 | |
| 4 | load("@rules_cc//cc:find_cc_toolchain.bzl", "find_cpp_toolchain", "use_cc_toolchain") |
| 5 | load("@rules_cc//cc/common:cc_common.bzl", "cc_common") |
| 6 | load("@rules_cc//cc/common:cc_info.bzl", "CcInfo") |
| 7 | load("//build/utils:detect_root.bzl", "detect_root", "detect_roots") |
| 8 | load("//build/utils:foreign_build.bzl", "generate_foreign_build_env", "merge_env") |
| 9 | load("//build/utils:target_info.bzl", "TargetInfo") |
| Tim Windelschmidt | 12240f9 | 2025-04-28 14:59:33 +0200 | [diff] [blame] | 10 | |
| 11 | TOOLCHAINS = [ |
| 12 | "//build/toolchain/toolchain-bundle:make_toolchain", |
| 13 | "//build/toolchain/toolchain-bundle:nasm_toolchain", |
| 14 | "//build/toolchain/toolchain-bundle:iasl_toolchain", |
| Tim Windelschmidt | 9a063ae | 2025-07-09 18:35:34 +0200 | [diff] [blame^] | 15 | "//build/toolchain/toolchain-bundle:busybox_toolchain", |
| Tim Windelschmidt | 12240f9 | 2025-04-28 14:59:33 +0200 | [diff] [blame] | 16 | ] |
| 17 | |
| 18 | def _edk2_impl(ctx): |
| 19 | _, libuuid_gen = detect_roots(ctx.attr._libuuid[CcInfo].compilation_context.direct_public_headers) |
| 20 | extra_env = { |
| 21 | "HOSTLDFLAGS": " -L ".join( |
| 22 | [ |
| 23 | "", # First element empty, for force a the join prefix |
| 24 | detect_root(ctx.attr._libuuid.files.to_list()).rsplit("/", 1)[0], |
| 25 | ], |
| 26 | ), |
| 27 | "HOSTCFLAGS": " -I ".join( |
| 28 | [ |
| 29 | "", # First element empty, for force a the join prefix |
| 30 | libuuid_gen, |
| 31 | ], |
| 32 | ), |
| 33 | "CROSS_LIB_UUID_INC": libuuid_gen.rsplit("/", 1)[0], |
| 34 | "CROSS_LIB_UUID": detect_root(ctx.attr._libuuid.files.to_list()).rsplit("/", 1)[0], |
| 35 | } |
| 36 | |
| 37 | inputs = depset( |
| 38 | ctx.files.src + |
| 39 | ctx.files._libuuid + |
| 40 | ctx.attr._libuuid[CcInfo].compilation_context.direct_public_headers, |
| 41 | ) |
| 42 | |
| 43 | # Setup the environment for the foreign build. |
| 44 | toolchain_env, toolchain_inputs, toolchain_cmd = generate_foreign_build_env( |
| 45 | ctx = ctx, |
| 46 | target_toolchain = find_cpp_toolchain(ctx), |
| 47 | exec_toolchain = ctx.attr._exec_toolchain[cc_common.CcToolchainInfo], |
| 48 | toolchain_bundle_tools = TOOLCHAINS, |
| 49 | ) |
| 50 | |
| 51 | target_arch = ctx.attr._target_arch[TargetInfo].value |
| 52 | target_path = None |
| 53 | export_script = None |
| 54 | if target_arch == "X64": |
| 55 | target_path = "OvmfPkg/OvmfPkgX64.dsc" |
| 56 | export_script = """ |
| 57 | cp {src}/Build/OvmfX64/{release_type}_"$TOOLCHAIN"/FV/OVMF_CODE.fd {code} |
| 58 | cp {src}/Build/OvmfX64/{release_type}_"$TOOLCHAIN"/FV/OVMF_VARS.fd {vars} |
| 59 | """ |
| 60 | elif target_arch == "AARCH64": |
| 61 | target_path = "ArmVirtPkg/ArmVirtQemu.dsc" |
| 62 | export_script = """ |
| 63 | dd of="{code}" if=/dev/zero bs=1M count=64 |
| 64 | dd of="{code}" if={src}/Build/ArmVirtQemu-AARCH64/{release_type}_"$TOOLCHAIN"/FV/QEMU_EFI.fd conv=notrunc |
| 65 | dd of="{vars}" if=/dev/zero bs=1M count=64 |
| 66 | dd of="{vars}" if={src}/Build/ArmVirtQemu-AARCH64/{release_type}_"$TOOLCHAIN"/FV/QEMU_VARS.fd conv=notrunc |
| 67 | """ |
| 68 | else: |
| 69 | fail("Unsupported target architecture: %s" % target_arch) |
| 70 | |
| 71 | code = ctx.actions.declare_file("CODE.fd") |
| 72 | vars = ctx.actions.declare_file("VARS.fd") |
| 73 | ctx.actions.run_shell( |
| 74 | outputs = [code, vars], |
| 75 | inputs = depset(transitive = [inputs, toolchain_inputs]), |
| 76 | env = merge_env(toolchain_env, extra_env), |
| 77 | progress_message = "Building EDK2 firmware", |
| 78 | mnemonic = "BuildEDK2Firmware", |
| 79 | command = toolchain_cmd + (""" |
| 80 | TOOLCHAIN=CLANGDWARF |
| 81 | export CLANG_BIN="$CC_PATH/" |
| 82 | |
| 83 | ( |
| 84 | cd {src} |
| 85 | . edksetup.sh |
| 86 | make \ |
| 87 | BUILD_OPTFLAGS="$HOSTCFLAGS" EXTRA_LDFLAGS="$HOSTLDFLAGS" \ |
| 88 | -C BaseTools/Source/C |
| 89 | |
| 90 | build -DTPM2_ENABLE -DSECURE_BOOT_ENABLE \ |
| 91 | -t $TOOLCHAIN -a {target_arch} -b {release_type} \ |
| 92 | -p $PWD/{target_path} |
| 93 | ) > /dev/null |
| 94 | """ + export_script).format( |
| 95 | src = detect_root(ctx.attr.src.files.to_list()), |
| 96 | code = code.path, |
| 97 | vars = vars.path, |
| 98 | target_arch = target_arch, |
| 99 | target_path = target_path, |
| 100 | release_type = ctx.attr._compilation_mode[TargetInfo].value, |
| 101 | ), |
| 102 | use_default_shell_env = True, |
| 103 | ) |
| 104 | |
| 105 | return [ |
| 106 | DefaultInfo( |
| 107 | files = depset([code, vars]), |
| 108 | runfiles = ctx.runfiles(files = [code, vars]), |
| 109 | ), |
| 110 | ] |
| 111 | |
| 112 | edk2 = rule( |
| 113 | doc = """ |
| 114 | Build EDK2 hermetically. |
| 115 | """, |
| 116 | implementation = _edk2_impl, |
| Tim Windelschmidt | 12240f9 | 2025-04-28 14:59:33 +0200 | [diff] [blame] | 117 | attrs = { |
| 118 | "src": attr.label( |
| 119 | doc = """ |
| 120 | Filegroup containing EDK2 sources. |
| 121 | """, |
| 122 | ), |
| 123 | "_libuuid": attr.label( |
| 124 | default = "@libuuid//:uuid", |
| 125 | ), |
| 126 | "_exec_toolchain": attr.label( |
| 127 | default = "@rules_cc//cc:current_cc_toolchain", |
| 128 | cfg = "exec", |
| 129 | ), |
| 130 | "_target_arch": attr.label( |
| 131 | default = "//third_party/edk2:target_arch", |
| 132 | ), |
| 133 | "_compilation_mode": attr.label( |
| 134 | default = "//third_party/edk2:compilation_mode", |
| 135 | ), |
| 136 | }, |
| 137 | fragments = ["cpp"], |
| 138 | toolchains = TOOLCHAINS + use_cc_toolchain(), |
| 139 | ) |