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