blob: 036743e878afd70483cae6b56f7d8466db47a53d [file] [log] [blame]
# Copyright 2020 The Monogon Project Authors.
#
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
Rules for building Linux kernel images.
This currently performs the build in a fully unhermetic manner, using
make/gcc/... from the sandbox sysroot, and is only slightly better than a genrule. This
should be replaced by a hermetic build that at least uses rules_cc toolchain
information, or even better, just uses cc_library targets.
"""
load("//build/utils:detect_root.bzl", "detect_root")
load("//osbase/build:def.bzl", "ignore_unused_configuration")
def _linux_image_impl_resources(_os, _ninputs):
"""
Configures linux build resources.
See `resource_set` documentation in builtins.actions Bazel docs.
"""
# 16 threads seems about right - this fits well in both our build machines and
# development machines.
cpu = 16
# In MB. Picked based on observing build in htop.
mb_per_cpu = 256
return {
"cpu": cpu,
"memory": cpu * mb_per_cpu,
"local_test": 0,
}
def _linux_image_impl(ctx):
kernel_config = ctx.file.kernel_config
kernel_src = ctx.files.kernel_src
image_format = ctx.attr.image_format
# Tuple containing information about how to build and access the resulting
# image.
# The first element (target) is the make target to build, the second
# (image_source) is the resulting file to be copied and the last
# (image_name) is the name of the image that will be generated by this
# rule.
(target, image_source, image_name) = {
"vmlinux": ("vmlinux modules", "vmlinux", "vmlinux"),
"bzImage": ("all modules", "arch/x86/boot/bzImage", "bzImage"),
}[image_format]
# Root of the given Linux sources.
root = detect_root(ctx.attr.kernel_src)
image = ctx.actions.declare_file(image_name)
modinfo = ctx.actions.declare_file("modules.builtin.modinfo")
modules = ctx.actions.declare_directory("modules")
ctx.actions.run_shell(
outputs = [image, modinfo, modules],
inputs = [kernel_config] + kernel_src,
resource_set = _linux_image_impl_resources,
command = '''
kconfig=$1
target=$2
image_source=$3
image=$4
root=$5
modinfo=$6
modules=$7
builddir=$(mktemp -d)
mkdir ${root}/.bin
cp ${kconfig} ${builddir}/.config
(cd ${root} && KBUILD_OUTPUT="${builddir}" make -j 16 ${target} >/dev/null)
cp "${builddir}"/${image_source} ${image}
cp "${builddir}"/modules.builtin.modinfo ${modinfo}
# Not using modules_install as it tries to run depmod and friends
for f in $(find "${builddir}" -name '*.ko' -type f -printf "%P\n" ); do
install -D "${builddir}/$f" "${modules}/$f"
done
rm -Rf "$builddir"
''',
arguments = [
kernel_config.path,
target,
image_source,
image.path,
root,
modinfo.path,
modules.path,
],
use_default_shell_env = True,
)
return [
DefaultInfo(
files = depset([image]),
runfiles = ctx.runfiles(files = [image]),
),
OutputGroupInfo(
modinfo = depset([modinfo]),
modules = depset([modules]),
),
]
linux_image = rule(
doc = """
Build Linux kernel image unhermetically in a given format.
""",
implementation = _linux_image_impl,
cfg = ignore_unused_configuration,
attrs = {
"kernel_config": attr.label(
doc = """
Linux kernel configuration file to build this kernel image with.
""",
allow_single_file = True,
default = ":linux-metropolis.config",
),
"kernel_src": attr.label(
doc = """
Filegroup containing Linux kernel sources.
""",
default = "@linux//:all",
),
"image_format": attr.string(
doc = """
Format of generated Linux image, one of 'vmlinux' or 'bzImage',
""",
values = [
"vmlinux",
"bzImage",
],
default = "bzImage",
),
"_allowlist_function_transition": attr.label(
default = "@bazel_tools//tools/allowlists/function_transition_allowlist",
),
},
)