blob: b31b34b0de9af11c939ea9ad12d17f65eea436e6 [file] [log] [blame]
Serge Bazanskif055a7f2021-04-13 16:22:33 +02001# Copyright 2020 The Monogon Project Authors.
2#
3# SPDX-License-Identifier: Apache-2.0
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
17"""
18Rules for building Linux kernel images.
19
20This currently performs the build in a fully unhermetic manner, using
Leopoldbc93c2b2023-01-14 13:12:23 +010021make/gcc/... from the sandbox sysroot, and is only slightly better than a genrule. This
Serge Bazanskif055a7f2021-04-13 16:22:33 +020022should be replaced by a hermetic build that at least uses rules_cc toolchain
23information, or even better, just uses cc_library targets.
24"""
25
26load("//build/utils:detect_root.bzl", "detect_root")
27
28
29def _ignore_unused_configuration_impl(settings, attr):
30 return {
31 # This list should be expanded with any configuration options that end
32 # up reaching this rule with different values across different build
33 # graph paths, but that do not actually influence the kernel build.
34 # Force-setting them to a stable value forces the build configuration
35 # to a stable hash.
36 # See the transition's comment block for more information.
37 "@io_bazel_rules_go//go/config:pure": True,
38 "@io_bazel_rules_go//go/config:static": True,
39 # Note: this toolchain is not actually used to perform the build.
Leopoldbc93c2b2023-01-14 13:12:23 +010040 "//command_line_option:platforms": "//build/platforms:linux_amd64_static",
Serge Bazanskif055a7f2021-04-13 16:22:33 +020041 }
42
43# Transition to flip all known-unimportant but varying configuration options to
44# a known, stable value.
45# This is to prevent Bazel from creating extra configurations for possible
46# combinations of options in case the linux_image rule is pulled through build
47# graph fragments that have different options set.
48#
49# Ideally, Bazel would let us mark in a list that we only care about some set
50# of options (or at least let us mark those that we explicitly don't care
51# about, instead of manually setting them to some value). However, this doesn't
52# seem to be possible, thus this transition is a bit of a hack.
53ignore_unused_configuration = transition(
54 implementation = _ignore_unused_configuration_impl,
55 inputs = [],
56 outputs = [
57 "@io_bazel_rules_go//go/config:pure",
58 "@io_bazel_rules_go//go/config:static",
Leopoldbc93c2b2023-01-14 13:12:23 +010059 "//command_line_option:platforms",
Serge Bazanskif055a7f2021-04-13 16:22:33 +020060 ],
61)
62
63
64def _linux_image_impl(ctx):
65 kernel_config = ctx.file.kernel_config
66 kernel_src = ctx.files.kernel_src
67 image_format = ctx.attr.image_format
68
69 # Tuple containing information about how to build and access the resulting
70 # image.
71 # The first element (target) is the make target to build, the second
Mateusz Zalega9a66b182021-12-22 20:33:12 +010072 # (image_source) is the resulting file to be copied and the last
73 # (image_name) is the name of the image that will be generated by this
Serge Bazanskif055a7f2021-04-13 16:22:33 +020074 # rule.
Mateusz Zalega9a66b182021-12-22 20:33:12 +010075 (target, image_source, image_name) = {
Serge Bazanskif055a7f2021-04-13 16:22:33 +020076 'vmlinux': ('vmlinux', 'vmlinux', 'vmlinux'),
77 'bzImage': ('all', 'arch/x86/boot/bzImage', 'bzImage'),
78 }[image_format]
79
80 # Root of the given Linux sources.
81 root = detect_root(ctx.attr.kernel_src)
82
Mateusz Zalega9a66b182021-12-22 20:33:12 +010083 image = ctx.actions.declare_file(image_name)
84 modinfo = ctx.actions.declare_file("modules.builtin.modinfo")
Serge Bazanskif055a7f2021-04-13 16:22:33 +020085 ctx.actions.run_shell(
Mateusz Zalega9a66b182021-12-22 20:33:12 +010086 outputs = [ image, modinfo ],
Serge Bazanskif055a7f2021-04-13 16:22:33 +020087 inputs = [ kernel_config ] + kernel_src,
88 command = '''
89 kconfig=$1
90 target=$2
Mateusz Zalega9a66b182021-12-22 20:33:12 +010091 image_source=$3
92 image=$4
Serge Bazanskif055a7f2021-04-13 16:22:33 +020093 root=$5
Mateusz Zalega9a66b182021-12-22 20:33:12 +010094 modinfo=$6
Serge Bazanskif055a7f2021-04-13 16:22:33 +020095
96 mkdir ${root}/.bin
97 cp ${kconfig} ${root}/.config
98 (cd ${root} && make -j $(nproc) ${target} >/dev/null)
Mateusz Zalega9a66b182021-12-22 20:33:12 +010099 cp ${root}/${image_source} ${image}
100 cp ${root}/modules.builtin.modinfo ${modinfo}
Serge Bazanskif055a7f2021-04-13 16:22:33 +0200101 ''',
102 arguments = [
103 kernel_config.path,
104 target,
Mateusz Zalega9a66b182021-12-22 20:33:12 +0100105 image_source,
106 image.path,
Serge Bazanskif055a7f2021-04-13 16:22:33 +0200107 root,
Mateusz Zalega9a66b182021-12-22 20:33:12 +0100108 modinfo.path
Serge Bazanskif055a7f2021-04-13 16:22:33 +0200109 ],
110 use_default_shell_env = True,
111 )
112
Mateusz Zalega9a66b182021-12-22 20:33:12 +0100113 return [
114 DefaultInfo(
115 files=depset([image]),
116 runfiles=ctx.runfiles(files=[image])
117 ),
118 OutputGroupInfo(
119 modinfo = depset([modinfo])
120 )
121 ]
Serge Bazanskif055a7f2021-04-13 16:22:33 +0200122
123linux_image = rule(
124 doc = '''
125 Build Linux kernel image unhermetically in a given format.
126 ''',
127 implementation = _linux_image_impl,
128 cfg = ignore_unused_configuration,
129 attrs = {
130 "kernel_config": attr.label(
131 doc = '''
132 Linux kernel configuration file to build this kernel image with.
133 ''',
134 allow_single_file = True,
135 default = ":linux-metropolis.config",
136 ),
137 "kernel_src": attr.label(
138 doc = '''
139 Filegroup containing Linux kernel sources.
140 ''',
141 default = "@linux//:all",
142 ),
143 "image_format": attr.string(
144 doc = '''
145 Format of generated Linux image, one of 'vmlinux' or 'bzImage',
146 ''',
147 values = [
148 'vmlinux', 'bzImage',
149 ],
150 default = 'bzImage',
151 ),
152 "_allowlist_function_transition": attr.label(
153 default = "@bazel_tools//tools/allowlists/function_transition_allowlist"
154 ),
155 },
156)