blob: aa0a764d2e1e470b01f66bc45010e75427d0bd9b [file]
# This file is licensed under the Apache License v2.0 with LLVM Exceptions.
# See https://llvm.org/LICENSE.txt for license information.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
"""bzlmod extension for making Linux kernel UAPI headers available in Bazel."""
_SYSTEM_HEADERS_PATH_ENV_VAR = "LINUX_UAPI_INCLUDE_DIR"
_ERROR_MESSAGE_BZL = """\
def _error_message_impl(ctx):
fail(ctx.attr.message)
error_message = rule(
implementation = _error_message_impl,
attrs = {"message": attr.string()},
)
"""
_ERROR_BUILD = """\
load(":error_message.bzl", "error_message")
error_message(
name = "linux_uapi_headers",
message = \"""System linux UAPI headers not found.
Pass --repo_env={var_name}=/path/to/your/linux/include to bazel build.
\"""
)
""".format(var_name = _SYSTEM_HEADERS_PATH_ENV_VAR)
_SYSTEM_BUILD = """\
load("@rules_cc//cc:defs.bzl", "cc_library")
cc_library(
name = "linux_uapi_headers",
# Builds using /usr/include may have a lot of junk that does not cleanly
# compile, so use `textual_hdrs` instead of `hdrs`.
textual_hdrs = glob(["include/**"]),
includes = ["include"],
visibility = ["//visibility:public"],
)
"""
def _default_include_dir(repository_ctx):
"""Returns a default include dir if it looks to have Linux UAPI headers."""
include_dir = "/usr/include"
if not repository_ctx.path(include_dir + "/linux").exists:
return None
return include_dir
def _linux_uapi_setup_impl(repository_ctx):
"""Sets up a repository of UAPI headers from a system directory."""
include_dir = repository_ctx.getenv(_SYSTEM_HEADERS_PATH_ENV_VAR, "")
if not include_dir:
include_dir = _default_include_dir(repository_ctx)
# If the directory doesn't exist, then set up a dummy rule that just errors.
# This defers the error message until an actual build,
# rather than failing during repository setup.
if not include_dir:
repository_ctx.file("error_message.bzl", _ERROR_MESSAGE_BZL)
repository_ctx.file("BUILD.bazel", _ERROR_BUILD)
return
if not include_dir.startswith("/"):
fail("{} must be absolute, was {}".format(
_SYSTEM_HEADERS_PATH_ENV_VAR,
include_dir,
))
repository_ctx.symlink(include_dir, "include")
repository_ctx.file("BUILD.bazel", _SYSTEM_BUILD)
linux_uapi_setup = repository_rule(implementation = _linux_uapi_setup_impl)