| Tim Windelschmidt | 6cca932 | 2025-04-15 21:13:32 +0200 | [diff] [blame^] | 1 | # Copyright The Monogon Project Authors. |
| 2 | # SPDX-License-Identifier: Apache-2.0 |
| Serge Bazanski | f055a7f | 2021-04-13 16:22:33 +0200 | [diff] [blame] | 3 | |
| 4 | """ |
| 5 | Rules for building Linux kernel images. |
| 6 | |
| Tim Windelschmidt | 6cca932 | 2025-04-15 21:13:32 +0200 | [diff] [blame^] | 7 | This currently performs the build in a fully hermetic manner, using |
| 8 | make/gcc/... from the toolchain bundle, and is only slightly better than a genrule. This |
| 9 | should be replaced by a hermetic build that just uses cc_library targets. |
| Serge Bazanski | f055a7f | 2021-04-13 16:22:33 +0200 | [diff] [blame] | 10 | """ |
| 11 | |
| Lorenz Brun | 6df40aa | 2025-05-22 15:35:44 +0200 | [diff] [blame] | 12 | load("@rules_cc//cc:find_cc_toolchain.bzl", "CC_TOOLCHAIN_ATTRS", "find_cpp_toolchain", "use_cc_toolchain") |
| Tim Windelschmidt | d481749 | 2025-06-16 15:03:12 +0200 | [diff] [blame] | 13 | load("@rules_cc//cc/common:cc_common.bzl", "cc_common") |
| Tim Windelschmidt | 6cca932 | 2025-04-15 21:13:32 +0200 | [diff] [blame^] | 14 | load("@rules_cc//cc/common:cc_info.bzl", "CcInfo") |
| 15 | load("//build/utils:detect_root.bzl", "detect_root", "detect_roots") |
| 16 | load("//build/utils:foreign_build.bzl", "generate_foreign_build_env", "merge_env") |
| 17 | load("//build/utils:target_info.bzl", "TargetInfo") |
| Tim Windelschmidt | 08054ca | 2025-04-04 01:11:56 +0200 | [diff] [blame] | 18 | load("//osbase/build:def.bzl", "ignore_unused_configuration") |
| Serge Bazanski | f055a7f | 2021-04-13 16:22:33 +0200 | [diff] [blame] | 19 | |
| Serge Bazanski | f9c8249 | 2024-09-16 16:50:39 +0200 | [diff] [blame] | 20 | def _linux_image_impl_resources(_os, _ninputs): |
| 21 | """ |
| 22 | Configures linux build resources. |
| 23 | |
| 24 | See `resource_set` documentation in builtins.actions Bazel docs. |
| 25 | """ |
| Tim Windelschmidt | 156248b | 2025-01-10 00:27:45 +0100 | [diff] [blame] | 26 | |
| Serge Bazanski | f9c8249 | 2024-09-16 16:50:39 +0200 | [diff] [blame] | 27 | # 16 threads seems about right - this fits well in both our build machines and |
| 28 | # development machines. |
| 29 | cpu = 16 |
| Tim Windelschmidt | 156248b | 2025-01-10 00:27:45 +0100 | [diff] [blame] | 30 | |
| Serge Bazanski | f9c8249 | 2024-09-16 16:50:39 +0200 | [diff] [blame] | 31 | # In MB. Picked based on observing build in htop. |
| 32 | mb_per_cpu = 256 |
| 33 | return { |
| Tim Windelschmidt | 156248b | 2025-01-10 00:27:45 +0100 | [diff] [blame] | 34 | "cpu": cpu, |
| 35 | "memory": cpu * mb_per_cpu, |
| 36 | "local_test": 0, |
| Serge Bazanski | f9c8249 | 2024-09-16 16:50:39 +0200 | [diff] [blame] | 37 | } |
| Serge Bazanski | f055a7f | 2021-04-13 16:22:33 +0200 | [diff] [blame] | 38 | |
| Tim Windelschmidt | 6cca932 | 2025-04-15 21:13:32 +0200 | [diff] [blame^] | 39 | TOOLCHAINS = [ |
| 40 | "//build/toolchain/toolchain-bundle:make_toolchain", |
| 41 | "//build/toolchain/toolchain-bundle:flex_toolchain", |
| 42 | "//build/toolchain/toolchain-bundle:bison_toolchain", |
| 43 | "//build/toolchain/toolchain-bundle:m4_toolchain", |
| 44 | "//build/toolchain/toolchain-bundle:busybox_toolchain", |
| 45 | "//build/toolchain/toolchain-bundle:bc_toolchain", |
| 46 | "//build/toolchain/toolchain-bundle:diff_toolchain", |
| 47 | "//build/toolchain/toolchain-bundle:perl_toolchain", |
| 48 | "//build/toolchain/toolchain-bundle:lz4_toolchain", |
| 49 | ] |
| Lorenz Brun | 6df40aa | 2025-05-22 15:35:44 +0200 | [diff] [blame] | 50 | |
| Serge Bazanski | f055a7f | 2021-04-13 16:22:33 +0200 | [diff] [blame] | 51 | def _linux_image_impl(ctx): |
| Serge Bazanski | f055a7f | 2021-04-13 16:22:33 +0200 | [diff] [blame] | 52 | # Tuple containing information about how to build and access the resulting |
| 53 | # image. |
| 54 | # The first element (target) is the make target to build, the second |
| Mateusz Zalega | 9a66b18 | 2021-12-22 20:33:12 +0100 | [diff] [blame] | 55 | # (image_source) is the resulting file to be copied and the last |
| 56 | # (image_name) is the name of the image that will be generated by this |
| Serge Bazanski | f055a7f | 2021-04-13 16:22:33 +0200 | [diff] [blame] | 57 | # rule. |
| Mateusz Zalega | 9a66b18 | 2021-12-22 20:33:12 +0100 | [diff] [blame] | 58 | (target, image_source, image_name) = { |
| Tim Windelschmidt | 156248b | 2025-01-10 00:27:45 +0100 | [diff] [blame] | 59 | "vmlinux": ("vmlinux modules", "vmlinux", "vmlinux"), |
| Tim Windelschmidt | 6cca932 | 2025-04-15 21:13:32 +0200 | [diff] [blame^] | 60 | "Image": ("all modules", "arch/" + ctx.attr._target_arch[TargetInfo].value + "/boot/" + ctx.attr._image_name[TargetInfo].value, "Image"), |
| 61 | }[ctx.attr.image_format] |
| 62 | |
| 63 | ssl_src, ssl_gen = detect_roots(ctx.attr._ssl[CcInfo].compilation_context.direct_public_headers) |
| 64 | crypto_src, crypto_gen = detect_roots(ctx.attr._crypto[CcInfo].compilation_context.direct_public_headers) |
| 65 | extra_env = { |
| 66 | "HOSTLDFLAGS": " -L ".join( |
| 67 | [ |
| 68 | "", # First element empty, for force a the join prefix |
| 69 | detect_root(ctx.attr._zstd.files.to_list()).rsplit("/", 1)[0], |
| 70 | detect_root(ctx.attr._zlib.files.to_list()).rsplit("/", 1)[0], |
| 71 | detect_root(ctx.attr._libelf.files.to_list()).rsplit("/", 1)[0], |
| 72 | detect_root(ctx.attr._ssl.files.to_list()).rsplit("/", 1)[0], |
| 73 | detect_root(ctx.attr._crypto.files.to_list()).rsplit("/", 1)[0], |
| 74 | ], |
| 75 | ), |
| 76 | "HOSTCFLAGS": " -I ".join( |
| 77 | [ |
| 78 | "", # First element empty, for force a the join prefix |
| 79 | detect_root(ctx.attr._libelf[CcInfo].compilation_context.direct_public_headers), |
| 80 | ssl_src + "/../", |
| 81 | ssl_gen + "/../include/", |
| 82 | crypto_src + "/../", |
| 83 | crypto_gen + "/../include/", |
| 84 | ], |
| 85 | ), |
| 86 | } |
| 87 | |
| 88 | inputs = depset( |
| 89 | ctx.files.kernel_config + |
| 90 | ctx.files.kernel_src + |
| 91 | ctx.files._libelf + |
| 92 | ctx.attr._libelf[CcInfo].compilation_context.direct_public_headers + |
| 93 | ctx.files._zlib + |
| 94 | ctx.files._ssl + |
| 95 | ctx.attr._ssl[CcInfo].compilation_context.direct_public_headers + |
| 96 | ctx.files._crypto + |
| 97 | ctx.attr._crypto[CcInfo].compilation_context.direct_public_headers, |
| 98 | ) |
| 99 | |
| 100 | # Setup the environment for the foreign build. |
| 101 | toolchain_env, toolchain_inputs, toolchain_cmd = generate_foreign_build_env( |
| 102 | ctx = ctx, |
| 103 | target_toolchain = find_cpp_toolchain(ctx), |
| 104 | exec_toolchain = ctx.attr._exec_toolchain[cc_common.CcToolchainInfo], |
| 105 | toolchain_bundle_tools = TOOLCHAINS, |
| 106 | ) |
| Serge Bazanski | f055a7f | 2021-04-13 16:22:33 +0200 | [diff] [blame] | 107 | |
| Mateusz Zalega | 9a66b18 | 2021-12-22 20:33:12 +0100 | [diff] [blame] | 108 | image = ctx.actions.declare_file(image_name) |
| 109 | modinfo = ctx.actions.declare_file("modules.builtin.modinfo") |
| Lorenz Brun | 6c45434 | 2023-06-01 12:23:38 +0200 | [diff] [blame] | 110 | modules = ctx.actions.declare_directory("modules") |
| Serge Bazanski | f055a7f | 2021-04-13 16:22:33 +0200 | [diff] [blame] | 111 | ctx.actions.run_shell( |
| Tim Windelschmidt | 156248b | 2025-01-10 00:27:45 +0100 | [diff] [blame] | 112 | outputs = [image, modinfo, modules], |
| Tim Windelschmidt | 6cca932 | 2025-04-15 21:13:32 +0200 | [diff] [blame^] | 113 | inputs = depset(transitive = [inputs, toolchain_inputs]), |
| Serge Bazanski | f9c8249 | 2024-09-16 16:50:39 +0200 | [diff] [blame] | 114 | resource_set = _linux_image_impl_resources, |
| Tim Windelschmidt | 6cca932 | 2025-04-15 21:13:32 +0200 | [diff] [blame^] | 115 | env = merge_env(toolchain_env, extra_env), |
| 116 | progress_message = "Building Linux Kernel: {}".format(ctx.label.name), |
| 117 | mnemonic = "BuildLinux", |
| 118 | command = toolchain_cmd + """ |
| 119 | export BISON_PKGDATADIR=$(realpath $(dirname $BISON))/../share/bison |
| Lorenz Brun | 6c45434 | 2023-06-01 12:23:38 +0200 | [diff] [blame] | 120 | builddir=$(mktemp -d) |
| Serge Bazanski | f055a7f | 2021-04-13 16:22:33 +0200 | [diff] [blame] | 121 | |
| Tim Windelschmidt | 6cca932 | 2025-04-15 21:13:32 +0200 | [diff] [blame^] | 122 | mkdir {kernel_src}/.bin |
| 123 | cp {kconfig} $builddir/.config |
| 124 | ( |
| 125 | cd {kernel_src} && |
| 126 | make -j 16 \ |
| 127 | \ |
| 128 | CC="$CC" CXX="$CXX" LD="$LD" AR="$AR" NM="$NM" STRIP="$STRIP" \ |
| 129 | OBJCOPY="$OBJCOPY" OBJDUMP="$OBJDUMP" READELF="$READELF" \ |
| 130 | CFLAGS="$CFLAGS" LDFLAGS="$LDFLAGS" \ |
| 131 | \ |
| 132 | HOSTCC="$HOSTCC" HOSTCXX="$HOSTCXX" HOSTLD="$HOSTLD" \ |
| 133 | HOSTAR="$HOSTAR" HOSTNM="$HOSTNM" HOSTSTRIP="$HOSTSTRIP" \ |
| 134 | HOSTOBJCOPY="$HOSTOBJCOPY" HOSTOBJDUMP="$HOSTOBJDUMP" \ |
| 135 | HOSTREADELF="$HOSTREADELF" HOSTCFLAGS="$HOSTCFLAGS" \ |
| 136 | HOSTLDFLAGS="$HOSTLDFLAGS" \ |
| 137 | \ |
| 138 | KBUILD_OUTPUT="$builddir" \ |
| 139 | ARCH="{target_arch}" \ |
| 140 | olddefconfig {target} |
| 141 | ) > /dev/null |
| 142 | |
| 143 | cp "$builddir"/{image_source} {image} |
| 144 | cp "$builddir"/modules.builtin.modinfo {modinfo} |
| Lorenz Brun | 6c45434 | 2023-06-01 12:23:38 +0200 | [diff] [blame] | 145 | # Not using modules_install as it tries to run depmod and friends |
| Tim Windelschmidt | 6cca932 | 2025-04-15 21:13:32 +0200 | [diff] [blame^] | 146 | for f in $(find "$builddir" -name '*.ko' -type f -printf "%P\n" ); do |
| 147 | install -D "$builddir/$f" "{modules}/$f" |
| Lorenz Brun | 6c45434 | 2023-06-01 12:23:38 +0200 | [diff] [blame] | 148 | done |
| 149 | rm -Rf "$builddir" |
| Tim Windelschmidt | 6cca932 | 2025-04-15 21:13:32 +0200 | [diff] [blame^] | 150 | """.format( |
| 151 | kconfig = ctx.file.kernel_config.path, |
| 152 | target = target, |
| 153 | image_source = image_source, |
| 154 | kernel_src = detect_root(ctx.attr.kernel_src.files.to_list()), |
| 155 | image = image.path, |
| 156 | modinfo = modinfo.path, |
| 157 | modules = modules.path, |
| 158 | target_arch = ctx.attr._target_arch[TargetInfo].value, |
| 159 | ), |
| Serge Bazanski | f055a7f | 2021-04-13 16:22:33 +0200 | [diff] [blame] | 160 | use_default_shell_env = True, |
| 161 | ) |
| 162 | |
| Mateusz Zalega | 9a66b18 | 2021-12-22 20:33:12 +0100 | [diff] [blame] | 163 | return [ |
| Tim Windelschmidt | 156248b | 2025-01-10 00:27:45 +0100 | [diff] [blame] | 164 | DefaultInfo( |
| 165 | files = depset([image]), |
| 166 | runfiles = ctx.runfiles(files = [image]), |
| 167 | ), |
| 168 | OutputGroupInfo( |
| 169 | modinfo = depset([modinfo]), |
| 170 | modules = depset([modules]), |
| 171 | ), |
| Mateusz Zalega | 9a66b18 | 2021-12-22 20:33:12 +0100 | [diff] [blame] | 172 | ] |
| Serge Bazanski | f055a7f | 2021-04-13 16:22:33 +0200 | [diff] [blame] | 173 | |
| 174 | linux_image = rule( |
| Tim Windelschmidt | 156248b | 2025-01-10 00:27:45 +0100 | [diff] [blame] | 175 | doc = """ |
| Tim Windelschmidt | 6cca932 | 2025-04-15 21:13:32 +0200 | [diff] [blame^] | 176 | Build Linux kernel image hermetically in a given format. |
| Tim Windelschmidt | 156248b | 2025-01-10 00:27:45 +0100 | [diff] [blame] | 177 | """, |
| Serge Bazanski | f055a7f | 2021-04-13 16:22:33 +0200 | [diff] [blame] | 178 | implementation = _linux_image_impl, |
| 179 | cfg = ignore_unused_configuration, |
| 180 | attrs = { |
| 181 | "kernel_config": attr.label( |
| Tim Windelschmidt | 156248b | 2025-01-10 00:27:45 +0100 | [diff] [blame] | 182 | doc = """ |
| Serge Bazanski | f055a7f | 2021-04-13 16:22:33 +0200 | [diff] [blame] | 183 | Linux kernel configuration file to build this kernel image with. |
| Tim Windelschmidt | 156248b | 2025-01-10 00:27:45 +0100 | [diff] [blame] | 184 | """, |
| Serge Bazanski | f055a7f | 2021-04-13 16:22:33 +0200 | [diff] [blame] | 185 | allow_single_file = True, |
| Serge Bazanski | f055a7f | 2021-04-13 16:22:33 +0200 | [diff] [blame] | 186 | ), |
| 187 | "kernel_src": attr.label( |
| Tim Windelschmidt | 156248b | 2025-01-10 00:27:45 +0100 | [diff] [blame] | 188 | doc = """ |
| Serge Bazanski | f055a7f | 2021-04-13 16:22:33 +0200 | [diff] [blame] | 189 | Filegroup containing Linux kernel sources. |
| Tim Windelschmidt | 156248b | 2025-01-10 00:27:45 +0100 | [diff] [blame] | 190 | """, |
| Serge Bazanski | f055a7f | 2021-04-13 16:22:33 +0200 | [diff] [blame] | 191 | ), |
| 192 | "image_format": attr.string( |
| Tim Windelschmidt | 156248b | 2025-01-10 00:27:45 +0100 | [diff] [blame] | 193 | doc = """ |
| Lorenz Brun | 6df40aa | 2025-05-22 15:35:44 +0200 | [diff] [blame] | 194 | Format of generated Linux image, one of 'vmlinux' or 'Image', |
| Tim Windelschmidt | 156248b | 2025-01-10 00:27:45 +0100 | [diff] [blame] | 195 | """, |
| Serge Bazanski | f055a7f | 2021-04-13 16:22:33 +0200 | [diff] [blame] | 196 | values = [ |
| Tim Windelschmidt | 156248b | 2025-01-10 00:27:45 +0100 | [diff] [blame] | 197 | "vmlinux", |
| Lorenz Brun | 6df40aa | 2025-05-22 15:35:44 +0200 | [diff] [blame] | 198 | "Image", |
| Serge Bazanski | f055a7f | 2021-04-13 16:22:33 +0200 | [diff] [blame] | 199 | ], |
| Lorenz Brun | 6df40aa | 2025-05-22 15:35:44 +0200 | [diff] [blame] | 200 | default = "Image", |
| Serge Bazanski | f055a7f | 2021-04-13 16:22:33 +0200 | [diff] [blame] | 201 | ), |
| Tim Windelschmidt | 6cca932 | 2025-04-15 21:13:32 +0200 | [diff] [blame^] | 202 | "_libelf": attr.label( |
| 203 | default = "//third_party:libelf_elf", |
| 204 | cfg = "exec", |
| 205 | ), |
| 206 | "_zstd": attr.label( |
| 207 | default = "//third_party:zstd_zstd", |
| 208 | cfg = "exec", |
| 209 | ), |
| 210 | "_zlib": attr.label( |
| 211 | default = "//third_party:zlib_z", |
| 212 | cfg = "exec", |
| 213 | ), |
| 214 | "_ssl": attr.label( |
| 215 | default = "//third_party:openssl_ssl", |
| 216 | cfg = "exec", |
| 217 | ), |
| 218 | "_crypto": attr.label( |
| 219 | default = "//third_party:openssl_crypto", |
| 220 | cfg = "exec", |
| 221 | ), |
| Serge Bazanski | f055a7f | 2021-04-13 16:22:33 +0200 | [diff] [blame] | 222 | "_allowlist_function_transition": attr.label( |
| Tim Windelschmidt | 156248b | 2025-01-10 00:27:45 +0100 | [diff] [blame] | 223 | default = "@bazel_tools//tools/allowlists/function_transition_allowlist", |
| Serge Bazanski | f055a7f | 2021-04-13 16:22:33 +0200 | [diff] [blame] | 224 | ), |
| Tim Windelschmidt | 6cca932 | 2025-04-15 21:13:32 +0200 | [diff] [blame^] | 225 | "_exec_toolchain": attr.label( |
| 226 | default = "@rules_cc//cc:current_cc_toolchain", |
| 227 | cfg = "exec", |
| Lorenz Brun | 6df40aa | 2025-05-22 15:35:44 +0200 | [diff] [blame] | 228 | ), |
| Tim Windelschmidt | 6cca932 | 2025-04-15 21:13:32 +0200 | [diff] [blame^] | 229 | "_image_name": attr.label( |
| 230 | default = "//third_party/linux:image_name", |
| Lorenz Brun | 6df40aa | 2025-05-22 15:35:44 +0200 | [diff] [blame] | 231 | ), |
| Tim Windelschmidt | 6cca932 | 2025-04-15 21:13:32 +0200 | [diff] [blame^] | 232 | "_target_arch": attr.label( |
| 233 | default = "//third_party/linux:target_arch", |
| Lorenz Brun | 6df40aa | 2025-05-22 15:35:44 +0200 | [diff] [blame] | 234 | ), |
| 235 | } | CC_TOOLCHAIN_ATTRS, |
| Lorenz Brun | 6df40aa | 2025-05-22 15:35:44 +0200 | [diff] [blame] | 236 | fragments = ["cpp"], |
| Tim Windelschmidt | 6cca932 | 2025-04-15 21:13:32 +0200 | [diff] [blame^] | 237 | toolchains = TOOLCHAINS + use_cc_toolchain(), |
| Serge Bazanski | f055a7f | 2021-04-13 16:22:33 +0200 | [diff] [blame] | 238 | ) |