Files
RedBear-OS/local/recipes/dev/libclc/source/utils/bazel/configure.bzl
T
vasilito cb424d7448 build: static patch-sanity linter (shift-left the malformed-patch class)
verify-patch-sanity.py validates every active recipe .patch has internally-
consistent hunk line counts — catching the 'malformed patch at line N' failure
at commit/CI/preflight time instead of hours into a cook. This cycle hit that
class three times (qtwaylandscanner, sddm, xwayland), each only discovered when
cookbook tried to apply the patch.

Running it across the repo found 29 latent malformed patches (validated against
GNU patch: e.g. relibc/P3-sysv-ipc reproduces 'malformed patch at line 22').
They were harmless only because they sit in vendored recipes (baked, not re-
applied) — but would fail on any version-bump re-derivation. --fix recounts the
hunk headers (body untouched) and repaired all 29.

Wired into build-preflight.sh (Phase 1.0D) and redbear-ci.yml, with a unit test
(test-patch-sanity.sh). Skips archived/legacy trees and unvalidatable formats
(empty placeholders, bare-@@ git hunks).
2026-08-01 05:13:02 +03:00

199 lines
5.8 KiB
Python

# 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
"""Helper macros to configure the LLVM overlay project."""
# Directory of overlay files relative to WORKSPACE
DEFAULT_OVERLAY_PATH = "llvm-project-overlay"
DEFAULT_TARGETS = [
"AArch64",
"AMDGPU",
"ARM",
"AVR",
"BPF",
"Hexagon",
"Lanai",
"LoongArch",
"Mips",
"MSP430",
"NVPTX",
"PowerPC",
"RISCV",
"Sparc",
"SPIRV",
"SystemZ",
"VE",
"WebAssembly",
"X86",
"XCore",
]
def _overlay_directories(repository_ctx):
src_path = repository_ctx.path(Label("@llvm-raw//:WORKSPACE")).dirname
bazel_path = src_path.get_child("utils").get_child("bazel")
overlay_path = bazel_path.get_child("llvm-project-overlay")
script_path = bazel_path.get_child("overlay_directories.py")
python_bin = repository_ctx.which("python3")
if not python_bin:
# Windows typically just defines "python" as python3. The script itself
# contains a check to ensure python3.
python_bin = repository_ctx.which("python")
if not python_bin:
fail("Failed to find python3 binary")
cmd = [
python_bin,
script_path,
"--src",
src_path,
"--overlay",
overlay_path,
"--target",
".",
]
exec_result = repository_ctx.execute(cmd, timeout = 20)
if exec_result.return_code != 0:
fail(("Failed to execute overlay script: '{cmd}'\n" +
"Exited with code {return_code}\n" +
"stdout:\n{stdout}\n" +
"stderr:\n{stderr}\n").format(
cmd = " ".join([str(arg) for arg in cmd]),
return_code = exec_result.return_code,
stdout = exec_result.stdout,
stderr = exec_result.stderr,
))
def _extract_cmake_settings(repository_ctx, llvm_cmake):
# The list to be written to vars.bzl
# `CMAKE_CXX_STANDARD` may be used from WORKSPACE for the toolchain.
c = {
"CMAKE_CXX_STANDARD": None,
"LLVM_VERSION_MAJOR": None,
"LLVM_VERSION_MINOR": None,
"LLVM_VERSION_PATCH": None,
"LLVM_VERSION_SUFFIX": None,
}
# It would be easier to use external commands like sed(1) and python.
# For portability, the parser should run on Starlark.
llvm_cmake_path = repository_ctx.path(Label("//:" + llvm_cmake))
for line in repository_ctx.read(llvm_cmake_path).splitlines():
# Extract "set ( FOO bar ... "
setfoo = line.partition("(")
if setfoo[1] != "(":
continue
if setfoo[0].strip().lower() != "set":
continue
# `kv` is assumed as \s*KEY\s+VAL\s*\).*
# Typical case is like
# LLVM_REQUIRED_CXX_STANDARD 17)
# Possible case -- It should be ignored.
# CMAKE_CXX_STANDARD ${...} CACHE STRING "...")
kv = setfoo[2].strip()
i = kv.find(" ")
if i < 0:
continue
k = kv[:i]
# Prefer LLVM_REQUIRED_CXX_STANDARD instead of CMAKE_CXX_STANDARD
if k == "LLVM_REQUIRED_CXX_STANDARD":
k = "CMAKE_CXX_STANDARD"
c[k] = None
if k not in c:
continue
# Skip if `CMAKE_CXX_STANDARD` is set with
# `LLVM_REQUIRED_CXX_STANDARD`.
# Then `v` will not be desired form, like "${...} CACHE"
if c[k] != None:
continue
# Pick up 1st word as the value.
# Note: It assumes unquoted word.
v = kv[i:].strip().partition(")")[0].partition(" ")[0]
c[k] = v
# Synthesize `LLVM_VERSION` for convenience.
c["LLVM_VERSION"] = "{}.{}.{}".format(
c["LLVM_VERSION_MAJOR"],
c["LLVM_VERSION_MINOR"],
c["LLVM_VERSION_PATCH"],
)
c["PACKAGE_VERSION"] = "{}.{}.{}{}".format(
c["LLVM_VERSION_MAJOR"],
c["LLVM_VERSION_MINOR"],
c["LLVM_VERSION_PATCH"],
c["LLVM_VERSION_SUFFIX"],
)
return c
def _write_dict_to_file(repository_ctx, filepath, header, vars):
# (fci + individual vars) + (fcd + dict items) + (fct)
fci = header
fcd = "\nllvm_vars={\n"
fct = "}\n"
for k, v in vars.items():
fci += '{} = "{}"\n'.format(k, v)
fcd += ' "{}": "{}",\n'.format(k, v)
repository_ctx.file(filepath, content = fci + fcd + fct)
def _llvm_configure_impl(repository_ctx):
_overlay_directories(repository_ctx)
llvm_cmake = "llvm/CMakeLists.txt"
vars = _extract_cmake_settings(
repository_ctx,
llvm_cmake,
)
# Grab version info and merge it with the other vars
version = _extract_cmake_settings(
repository_ctx,
"cmake/Modules/LLVMVersion.cmake",
)
version = {k: v for k, v in version.items() if v != None}
vars.update(version)
_write_dict_to_file(
repository_ctx,
filepath = "vars.bzl",
header = "# Generated from {}\n\n".format(llvm_cmake),
vars = vars,
)
# Create a starlark file with the requested LLVM targets.
llvm_targets = repository_ctx.attr.targets
repository_ctx.file(
"llvm/targets.bzl",
content = "llvm_targets = " + str(llvm_targets),
executable = False,
)
# Create a starlark file with the requested BOLT targets.
bolt_targets = ["AArch64", "X86", "RISCV"] # Supported targets.
bolt_targets = [t for t in llvm_targets if t in bolt_targets]
repository_ctx.file(
"bolt/targets.bzl",
content = "bolt_targets = " + str(bolt_targets),
executable = False,
)
llvm_configure = repository_rule(
implementation = _llvm_configure_impl,
local = True,
configure = True,
attrs = {
"targets": attr.string_list(default = DEFAULT_TARGETS),
},
)