blob: 62a0fbeb84b090897a2f3ab35e9cc88b6101a096 [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")
10load("//osbase/build:def.bzl", "ignore_unused_configuration")
11
12TOOLCHAINS = [
13 "//build/toolchain/toolchain-bundle:make_toolchain",
14 "//build/toolchain/toolchain-bundle:nasm_toolchain",
15 "//build/toolchain/toolchain-bundle:iasl_toolchain",
16 "//build/toolchain/toolchain-bundle:strace_toolchain",
17]
18
19def _edk2_impl(ctx):
20 _, 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],
36 }
37
38 inputs = depset(
39 ctx.files.src +
40 ctx.files._libuuid +
41 ctx.attr._libuuid[CcInfo].compilation_context.direct_public_headers,
42 )
43
44 # Setup the environment for the foreign build.
45 toolchain_env, toolchain_inputs, toolchain_cmd = generate_foreign_build_env(
46 ctx = ctx,
47 target_toolchain = find_cpp_toolchain(ctx),
48 exec_toolchain = ctx.attr._exec_toolchain[cc_common.CcToolchainInfo],
49 toolchain_bundle_tools = TOOLCHAINS,
50 )
51
52 target_arch = ctx.attr._target_arch[TargetInfo].value
53 target_path = None
54 export_script = None
55 if target_arch == "X64":
56 target_path = "OvmfPkg/OvmfPkgX64.dsc"
57 export_script = """
58 cp {src}/Build/OvmfX64/{release_type}_"$TOOLCHAIN"/FV/OVMF_CODE.fd {code}
59 cp {src}/Build/OvmfX64/{release_type}_"$TOOLCHAIN"/FV/OVMF_VARS.fd {vars}
60 """
61 elif target_arch == "AARCH64":
62 target_path = "ArmVirtPkg/ArmVirtQemu.dsc"
63 export_script = """
64 dd of="{code}" if=/dev/zero bs=1M count=64
65 dd of="{code}" if={src}/Build/ArmVirtQemu-AARCH64/{release_type}_"$TOOLCHAIN"/FV/QEMU_EFI.fd conv=notrunc
66 dd of="{vars}" if=/dev/zero bs=1M count=64
67 dd of="{vars}" if={src}/Build/ArmVirtQemu-AARCH64/{release_type}_"$TOOLCHAIN"/FV/QEMU_VARS.fd conv=notrunc
68 """
69 else:
70 fail("Unsupported target architecture: %s" % target_arch)
71
72 code = ctx.actions.declare_file("CODE.fd")
73 vars = ctx.actions.declare_file("VARS.fd")
74 ctx.actions.run_shell(
75 outputs = [code, vars],
76 inputs = depset(transitive = [inputs, toolchain_inputs]),
77 env = merge_env(toolchain_env, extra_env),
78 progress_message = "Building EDK2 firmware",
79 mnemonic = "BuildEDK2Firmware",
80 command = toolchain_cmd + ("""
81 TOOLCHAIN=CLANGDWARF
82 export CLANG_BIN="$CC_PATH/"
83
84 (
85 cd {src}
86 . edksetup.sh
87 make \
88 BUILD_OPTFLAGS="$HOSTCFLAGS" EXTRA_LDFLAGS="$HOSTLDFLAGS" \
89 -C BaseTools/Source/C
90
91 build -DTPM2_ENABLE -DSECURE_BOOT_ENABLE \
92 -t $TOOLCHAIN -a {target_arch} -b {release_type} \
93 -p $PWD/{target_path}
94 ) > /dev/null
95 """ + export_script).format(
96 src = detect_root(ctx.attr.src.files.to_list()),
97 code = code.path,
98 vars = vars.path,
99 target_arch = target_arch,
100 target_path = target_path,
101 release_type = ctx.attr._compilation_mode[TargetInfo].value,
102 ),
103 use_default_shell_env = True,
104 )
105
106 return [
107 DefaultInfo(
108 files = depset([code, vars]),
109 runfiles = ctx.runfiles(files = [code, vars]),
110 ),
111 ]
112
113edk2 = rule(
114 doc = """
115 Build EDK2 hermetically.
116 """,
117 implementation = _edk2_impl,
118 cfg = ignore_unused_configuration,
119 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"],
140 toolchains = TOOLCHAINS + use_cc_toolchain(),
141)