blob: cbd4ef756087b3b33231da4a244e6d0df64c4eca [file] [log] [blame]
# Copyright 2025 The Pigweed Authors
#
# 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
#
# https://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.
def _local_patched_repository_impl(rctx):
path = rctx.attr.path
# This path is a bit ugly to get the actual path if it is relative.
if path[0] != "/":
path = rctx.workspace_root.get_child(path)
# Copy the repository
rctx.execute(["mkdir", str(rctx.path(""))])
for child in path.readdir():
copy_args = ["cp", "-fr", str(child), str(rctx.path(""))]
if rctx.attr.debug:
print(copy_args)
result = rctx.execute(copy_args)
if result.return_code != 0:
fail("Failed to copy %s (%s):\n%s" % (rctx.attr.path, result.return_code, result.stderr))
# Now patch the repository
for patch_file in rctx.attr.patches:
patch_file_path_string = str(rctx.path(patch_file).realpath)
if rctx.attr.debug:
print("Applying patch file: %s / %s" % (patch_file, patch_file_path_string))
result = rctx.execute([
"bash",
"-c",
"patch -p0 < " + patch_file_path_string,
])
if result.return_code != 0:
fail("Failed to apply patch: %s\n%s" % (patch_file, result.stderr))
local_patched_repository = repository_rule(
implementation = _local_patched_repository_impl,
attrs = {
"debug": attr.bool(default = False),
"patches": attr.label_list(allow_files = True),
"path": attr.string(mandatory = True),
},
local = True,
)
def _create_zephyr_patch_file_impl(rctx):
script_path = Label("//:generate_diff.py")
output_file = rctx.attr.filename
output_file_path = rctx.path(output_file)
rctx.file(output_file)
rctx.file("BUILD")
args = [
rctx.which("python3"),
script_path,
"--root-dir",
rctx.path(script_path).dirname,
"-o",
output_file_path,
]
if rctx.attr.debug:
print(args)
result = rctx.execute(args)
if result.return_code != 0:
fail("Failed to generate zephyr-bazel diff file (%s):\n%s" % (result.return_code, result.stderr))
if rctx.attr.debug:
print("Generated %s" % (output_file_path))
return [
DefaultInfo(
files = depset([output_file_path, rctx.path("BUILD")]),
),
]
create_zephyr_patch_file = repository_rule(
implementation = _create_zephyr_patch_file_impl,
attrs = {
"debug": attr.bool(default = False),
"filename": attr.string(
default = "patch.diff",
mandatory = True,
),
},
local = True,
)
###############################################################################
def _print_file_impl(ctx):
# Get the input file
input_file = ctx.file.file
# Create a dummy output file
output_file = ctx.actions.declare_file(ctx.label.name + ".out")
# Create a shell action to print the file
ctx.actions.run_shell(
outputs = [output_file],
inputs = [input_file],
command = "cat {} > {}".format(input_file.path, output_file.path),
)
# Return DefaultInfo to signal dependencies on the input file
return DefaultInfo(files = depset([output_file]))
# Define the rule
print_file = rule(
implementation = _print_file_impl,
attrs = {
"file": attr.label(allow_single_file = True, mandatory = True),
},
)
###############################################################################
def _version_header_impl(ctx):
version_file = ctx.attr.version_file
version_template = ctx.attr.version_template
version_content = ctx.read(version_file)
template_content = ctx.read(version_template)
# Extract version components using string manipulation
version_major = 0
version_minor = 0
patchlevel = 0
version_tweak = 0
for line in version_content.splitlines():
if line.startswith("VERSION_MAJOR"):
version_major = int(line.split("=")[1].strip())
elif line.startswith("VERSION_MINOR"):
version_minor = int(line.split("=")[1].strip())
elif line.startswith("PATCHLEVEL"):
patchlevel = int(line.split("=")[1].strip())
elif line.startswith("VERSION_TWEAK"):
version_tweak = int(line.split("=")[1].strip())
version_type = ctx.attr.VERSION_TYPE
zephyr_version_code = (version_major << 16) | (version_minor << 8) | patchlevel
kernelversion = (zephyr_version_code << 8) | version_tweak
kernelversion_hex = "0x%x" % kernelversion
kernel_version_number_hex = "0x%x" % zephyr_version_code
kernel_version_major = version_major
kernel_version_minor = version_minor
kernel_patchlevel = patchlevel
kernel_version_tweak = version_tweak
kernel_version_string = "{}.{}.{}-{}".format(version_major, version_minor, patchlevel, version_tweak)
kernel_version_extended_string = kernel_version_string + "+0"
kernel_version_tweak_string = "{}.{}.{}-0".format(version_major, version_minor, patchlevel)
build_version_name = "BUILD_VERSION"
template_dict = {
"VERSION_TYPE": version_type,
"ZEPHYR_VERSION_CODE": str(zephyr_version_code),
"KERNELVERSION": kernelversion_hex,
"KERNEL_VERSION_NUMBER": kernel_version_number_hex,
"KERNEL_VERSION_MAJOR": str(kernel_version_major),
"KERNEL_VERSION_MINOR": str(kernel_version_minor),
"KERNEL_PATCHLEVEL": str(kernel_patchlevel),
"KERNEL_VERSION_TWEAK": str(kernel_version_tweak),
"KERNEL_VERSION_STRING": kernel_version_string,
"KERNEL_VERSION_EXTENDED_STRING": kernel_version_extended_string,
"KERNEL_VERSION_TWEAK_STRING": kernel_version_tweak_string,
"KERNEL_VERSION_CUSTOMIZATION": "",
"BUILD_VERSION_NAME": build_version_name,
"BUILD_VERSION": "v" + kernel_version_string,
}
template_content = template_content.replace("#cmakedefine", "#define")
for variable, value in template_dict.items():
template_content = template_content.replace("@" + variable + "@", value)
for variable, value in template_dict.items():
template_content = template_content.replace("@" + variable + "@", value)
ctx.file("zephyr/version.h", content = template_content, executable = False)
ctx.file(
"BUILD.bazel",
content = """
cc_library(
name = "version",
hdrs = ["zephyr/version.h"],
includes = ["."],
visibility = ["//visibility:public"],
)
""",
executable = False,
)
version_header = repository_rule(
implementation = _version_header_impl,
attrs = {
"version_file": attr.label(
mandatory = True,
allow_single_file = True,
),
"version_template": attr.label(
mandatory = True,
allow_single_file = True,
),
"VERSION_TYPE": attr.string(default = "KERNEL"),
},
)