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