blob: 4d09c158beb62ac68a02fb07f6dd0b48c84a7222 [file] [log] [blame]
"""Rules for defining a native cc_library based on a kernel's UAPI headers."""
load("@rules_cc//cc:defs.bzl", "cc_library")
load("//build/kernel/kleaf/impl:common_providers.bzl", "KernelBuildUapiInfo")
load(":hermetic_toolchain.bzl", "hermetic_toolchain")
visibility("//build/kernel/kleaf/...")
def _kernel_unarchived_uapi_headers_impl(ctx):
hermetic_tools = hermetic_toolchain.get(ctx)
uapi_headers = ctx.attr.kernel_build[KernelBuildUapiInfo].kernel_uapi_headers.to_list()
if not uapi_headers:
fail("ERROR: no UAPI headers found in kernel_build")
# If using a mixed build, the main tree's UAPI header's will be last in the list. If
# not a mixed build, there will be only one element. Take the last one either way.
input_tar = uapi_headers[-1]
out_dir = ctx.actions.declare_directory(ctx.label.name)
command = ""
command += hermetic_tools.setup
command += """
# Create output dir
mkdir -p "{out_dir}"
# Unpack headers (stripping /usr/include)
tar --strip-components=2 -C "{out_dir}" -xzf "{tar_file}"
""".format(
tar_file = input_tar.path,
out_dir = out_dir.path,
)
ctx.actions.run_shell(
mnemonic = "KernelUnarchivedUapiHeaders",
inputs = [input_tar],
outputs = [out_dir],
tools = hermetic_tools.deps,
progress_message = "Unpacking UAPI headers %{label}",
command = command,
)
return [
DefaultInfo(files = depset([out_dir])),
]
_kernel_unarchived_uapi_headers = rule(
implementation = _kernel_unarchived_uapi_headers_impl,
doc = """Unpack `kernel_build`'s `kernel-uapi-headers.tar.gz` (stripping usr/include)""",
attrs = {
"kernel_build": attr.label(
providers = [KernelBuildUapiInfo],
mandatory = True,
doc = "the `kernel_build` whose UAPI headers to unarchive",
),
},
toolchains = [hermetic_toolchain.type],
)
def kernel_uapi_headers_cc_library(name, kernel_build):
"""Defines a native cc_library based on a kernel's UAPI headers.
Example:
```
kernel_uapi_headers_cc_library(
name = "uapi_header_lib",
kernel_build = "//common:kernel_aarch64",
)
cc_binary(
name = "foo",
srcs = ["foo.c"],
deps = [":uapi_header_lib"],
)
```
Internally, the `kernel_build`'s UAPI header output tarball is unpacked. Then, a header-only
[`cc_library`](https://bazel.build/reference/be/c-cpp#cc_library) is generated. This allows
other native Bazel C/C++ rules to add the kernel's UAPI headers as a dependency.
The library will automatically include the header directory in the dependent build, so source
files are free to simply include the UAPI headers they need.
Note: the `kernel_build`'s output UAPI header tarball includes the `usr/include` prefix. The
prefix is stripped while creating this library. To include the file `usr/include/linux/time.h`
from the tarball, a source file would `#include <linux/time.h>`.
Args:
name: Name of target.
kernel_build: [`kernel_build`](#kernel_build)
"""
unarchived_headers_rule = name + "_unarchived_uapi_headers"
_kernel_unarchived_uapi_headers(
name = unarchived_headers_rule,
kernel_build = kernel_build,
)
# Header-only library build will not invoke any toolchain
cc_library(
name = name,
hdrs = [":" + unarchived_headers_rule],
includes = [unarchived_headers_rule],
)