kleaf: abi: Add rule to invoke stgdiff directly.
* This is so `*_abi_diff_stg` can be invoked.
* Cleanup of previous XML support will be done as
follow ups.
* This is not integrated to kernel_abi_dist yet.
Bug: 261722616
Change-Id: Ib27299efa2ae597d3bb225ea5624825e5c318780
Signed-off-by: Ulises Mendez Martinez <umendez@google.com>
diff --git a/kleaf/common_kernels.bzl b/kleaf/common_kernels.bzl
index ca1f778..7ba5313c 100644
--- a/kleaf/common_kernels.bzl
+++ b/kleaf/common_kernels.bzl
@@ -101,6 +101,7 @@
# Subset of _TARGET_CONFIG_VALID_KEYS for kernel_abi.
_KERNEL_ABI_VALID_KEYS = [
"abi_definition",
+ "abi_definition_stg",
"kmi_enforced",
]
@@ -131,6 +132,8 @@
aarch64_trim_and_check = bool(aarch64_kmi_symbol_list) or len(aarch64_additional_kmi_symbol_lists) > 0
aarch64_abi_definition = native.glob(["android/abi_gki_aarch64.xml"])
aarch64_abi_definition = aarch64_abi_definition[0] if aarch64_abi_definition else None
+ aarch64_abi_definition_stg = native.glob(["android/abi_gki_aarch64.stg"])
+ aarch64_abi_definition_stg = aarch64_abi_definition_stg[0] if aarch64_abi_definition_stg else None
# Common configs for aarch64 and aarch64_debug
aarch64_common = {
@@ -139,6 +142,7 @@
"kmi_symbol_list": aarch64_kmi_symbol_list,
"additional_kmi_symbol_lists": aarch64_additional_kmi_symbol_lists,
"abi_definition": aarch64_abi_definition,
+ "abi_definition_stg": aarch64_abi_definition_stg,
"kmi_enforced": bool(aarch64_abi_definition),
# Assume BUILD_GKI_ARTIFACTS=1
"build_gki_artifacts": True,
diff --git a/kleaf/impl/BUILD.bazel b/kleaf/impl/BUILD.bazel
index 7f2a7ac..aa4699d 100644
--- a/kleaf/impl/BUILD.bazel
+++ b/kleaf/impl/BUILD.bazel
@@ -24,6 +24,7 @@
"abi/abi_diff.bzl",
"abi/abi_dump.bzl",
"abi/abi_prop.bzl",
+ "abi/abi_stgdiff.bzl",
"abi/abi_transitions.bzl",
"abi/base_kernel_utils.bzl",
"abi/extracted_symbols.bzl",
diff --git a/kleaf/impl/abi/abi_dump.bzl b/kleaf/impl/abi/abi_dump.bzl
index 8369cd5..c382a73 100644
--- a/kleaf/impl/abi/abi_dump.bzl
+++ b/kleaf/impl/abi/abi_dump.bzl
@@ -48,7 +48,7 @@
])),
OutputGroupInfo(
abi_out_file = depset([abi_out_file]),
- stg_abi_out_file = depset([abi_out_file_stg]),
+ abi_out_file_stg = depset([abi_out_file_stg]),
),
]
diff --git a/kleaf/impl/abi/abi_stgdiff.bzl b/kleaf/impl/abi/abi_stgdiff.bzl
new file mode 100644
index 0000000..c80a5d4
--- /dev/null
+++ b/kleaf/impl/abi/abi_stgdiff.bzl
@@ -0,0 +1,148 @@
+# Copyright (C) 2023 The Android Open Source Project
+#
+# 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.
+
+"""
+Run `stgdiff` tool.
+"""
+
+load("//build/kernel/kleaf:hermetic_tools.bzl", "HermeticToolsInfo")
+load(":debug.bzl", "debug")
+
+STGDIFF_FORMATS = ["plain", "flat", "small", "short", "viz"]
+STGDIFF_CHANGE_CODE = 4
+
+def _stgdiff_impl(ctx):
+ inputs = [
+ ctx.file._stgdiff,
+ ctx.file.baseline,
+ ctx.file.new,
+ ]
+ inputs += ctx.attr._hermetic_tools[HermeticToolsInfo].deps
+
+ output_dir = ctx.actions.declare_directory("{}/abi_stgdiff".format(ctx.attr.name))
+ error_msg_file = ctx.actions.declare_file("{}/error_msg_file.txt".format(ctx.attr.name))
+ exit_code_file = ctx.actions.declare_file("{}/exit_code_file.txt".format(ctx.attr.name))
+
+ default_outputs = [output_dir]
+ command_outputs = default_outputs + [
+ error_msg_file,
+ exit_code_file,
+ ]
+ basename = "{output_dir}/abi.stg_report".format(output_dir = output_dir.path)
+ short_report = basename + ".short"
+ outputs = " ".join(["--format {ext} --output {basename}.{ext}".format(
+ basename = basename,
+ ext = ext,
+ ) for ext in STGDIFF_FORMATS])
+
+ command = ctx.attr._hermetic_tools[HermeticToolsInfo].setup + """
+ set +e
+ {stgdiff} --stg {new} {baseline} {outputs} > {error_msg_file}
+ rc=$?
+ set -e
+ echo $rc > {exit_code_file}
+ if [[ $rc == 0 ]]; then
+ echo "INFO: $(cat {error_msg_file})"
+ elif [[ $rc == {change_code} ]]; then
+ echo "INFO: ABI DIFFERENCES HAVE BEEN DETECTED!"
+ echo "INFO: $(cat {short_report})"
+ else
+ echo "ERROR: $(cat {error_msg_file})" >&2
+ echo "INFO: exit code is not checked. 'tools/bazel run {label}' to check the exit code." >&2
+ fi
+ """.format(
+ stgdiff = ctx.file._stgdiff.path,
+ baseline = ctx.file.baseline.path,
+ new = ctx.file.new.path,
+ output_dir = output_dir.path,
+ exit_code_file = exit_code_file.path,
+ error_msg_file = error_msg_file.path,
+ short_report = short_report,
+ outputs = outputs,
+ label = ctx.label,
+ change_code = STGDIFF_CHANGE_CODE,
+ )
+
+ debug.print_scripts(ctx, command)
+ ctx.actions.run_shell(
+ inputs = inputs,
+ outputs = command_outputs,
+ command = command,
+ mnemonic = "KernelDiffAbiStg",
+ progress_message = "[stg] Comparing Kernel ABI {}".format(ctx.label),
+ )
+
+ script = ctx.actions.declare_file("{}/print_results.sh".format(ctx.attr.name))
+
+ # TODO(b/265020068) Remove duplicate code here.
+ short_report = "{output_dir}/abi.stg_report.short".format(output_dir = output_dir.short_path)
+ script_content = """#!/bin/bash -e
+ rc=$(cat {exit_code_file})
+ if [[ $rc == 0 ]]; then
+ echo "INFO: $(cat {error_msg_file})"
+ elif [[ $rc == 4 ]]; then
+ echo "INFO: ABI DIFFERENCES HAVE BEEN DETECTED!"
+ echo "INFO: $(cat {short_report})"
+ else
+ echo "ERROR: $(cat {error_msg_file})" >&2
+ fi
+""".format(
+ exit_code_file = exit_code_file.short_path,
+ error_msg_file = error_msg_file.short_path,
+ short_report = short_report,
+ )
+ if ctx.attr.kmi_enforced:
+ script_content += """
+ exit $rc
+ """
+ else:
+ script_content += """
+ if [[ $rc != 0 ]]; then
+ echo "WARN: KMI is not enforced, return code of stgdiff is not checked" >&2
+ fi
+ """
+ ctx.actions.write(script, script_content, is_executable = True)
+
+ return [
+ DefaultInfo(
+ files = depset(default_outputs),
+ executable = script,
+ runfiles = ctx.runfiles(files = command_outputs),
+ ),
+ OutputGroupInfo(
+ executable = depset([script]),
+ ),
+ ]
+
+stgdiff = rule(
+ implementation = _stgdiff_impl,
+ doc = "Run `stgdiff`",
+ attrs = {
+ "baseline": attr.label(allow_single_file = True),
+ "new": attr.label(allow_single_file = True),
+ "kmi_enforced": attr.bool(),
+ "_hermetic_tools": attr.label(
+ default = "//build/kernel:hermetic-tools",
+ providers = [HermeticToolsInfo],
+ ),
+ "_stgdiff": attr.label(
+ default = "//prebuilts/kernel-build-tools:linux-x86/bin/stgdiff",
+ allow_single_file = True,
+ cfg = "exec",
+ executable = True,
+ ),
+ "_debug_print_scripts": attr.label(default = "//build/kernel/kleaf:debug_print_scripts"),
+ },
+ executable = True,
+)
diff --git a/kleaf/impl/abi/kernel_build_abi.bzl b/kleaf/impl/abi/kernel_build_abi.bzl
index e66e4ea..b6baf1e 100644
--- a/kleaf/impl/abi/kernel_build_abi.bzl
+++ b/kleaf/impl/abi/kernel_build_abi.bzl
@@ -17,6 +17,7 @@
load("//build/bazel_common_rules/exec:exec.bzl", "exec")
load("//build/kernel/kleaf:update_source_file.bzl", "update_source_file")
load(":abi/abi_diff.bzl", "abi_diff")
+load(":abi/abi_stgdiff.bzl", "stgdiff")
load(":abi/abi_dump.bzl", "abi_dump")
load(":abi/abi_prop.bzl", "abi_prop")
load(":abi/extracted_symbols.bzl", "extracted_symbols")
@@ -32,6 +33,7 @@
kernel_modules = None,
module_grouping = None,
abi_definition = None,
+ abi_definition_stg = None,
kmi_enforced = None,
unstripped_modules_archive = None,
kmi_symbol_list_add_only = None,
@@ -75,6 +77,7 @@
kernel_modules: See [`kernel_abi.kernel_modules`](#kernel_abi-kernel_modules)
module_grouping: See [`kernel_abi.module_grouping`](#kernel_abi-module_grouping)
abi_definition: See [`kernel_abi.abi_definition`](#kernel_abi-abi_definition)
+ abi_definition_stg: See [`kernel_abi.abi_definition_stg`](#kernel_abi-abi_definition_stg)
kmi_enforced: See [`kernel_abi.kmi_enforced`](#kernel_abi-kmi_enforced)
unstripped_modules_archive: See [`kernel_abi.unstripped_modules_archive`](#kernel_abi-unstripped_modules_archive)
kmi_symbol_list_add_only: See [`kernel_abi.kmi_symbol_list_add_only`](#kernel_abi-kmi_symbol_list_add_only)
@@ -122,6 +125,7 @@
kernel_modules = kernel_modules,
module_grouping = module_grouping,
abi_definition = abi_definition,
+ abi_definition_stg = abi_definition_stg,
kmi_enforced = kmi_enforced,
unstripped_modules_archive = unstripped_modules_archive,
kmi_symbol_list_add_only = kmi_symbol_list_add_only,
@@ -140,6 +144,7 @@
module_grouping = module_grouping,
kmi_symbol_list_add_only = kmi_symbol_list_add_only,
abi_definition = abi_definition,
+ abi_definition_stg = abi_definition_stg,
kmi_enforced = kmi_enforced,
unstripped_modules_archive = unstripped_modules_archive,
# common attributes
@@ -166,6 +171,7 @@
kernel_modules = None,
module_grouping = None,
abi_definition = None,
+ abi_definition_stg = None,
kmi_enforced = None,
unstripped_modules_archive = None,
kmi_symbol_list_add_only = None,
@@ -239,6 +245,7 @@
list will simply be a sorted list of symbols used by all the kernel
modules.
abi_definition: Location of the ABI definition.
+ abi_definition_stg: Location of the ABI definition in STG format.
kmi_enforced: This is an indicative option to signal that KMI is enforced.
If set to `True`, KMI checking tools respects it and
reacts to it by failing if KMI differences are detected.
@@ -286,6 +293,7 @@
module_grouping = module_grouping,
kmi_symbol_list_add_only = kmi_symbol_list_add_only,
abi_definition = abi_definition,
+ abi_definition_stg = abi_definition_stg,
kmi_enforced = kmi_enforced,
unstripped_modules_archive = unstripped_modules_archive,
abi_dump_target = name + "_dump",
@@ -322,6 +330,11 @@
script = "",
**private_kwargs
)
+ exec(
+ name = name + "_diff_executable_stg",
+ script = "",
+ **private_kwargs
+ )
def _define_abi_targets(
name,
@@ -330,6 +343,7 @@
module_grouping,
kmi_symbol_list_add_only,
abi_definition,
+ abi_definition_stg,
kmi_enforced,
unstripped_modules_archive,
abi_dump_target,
@@ -371,10 +385,10 @@
dst = name + "_src_kmi_symbol_list",
**private_kwargs
)
-
default_outputs += _define_abi_definition_targets(
name = name,
abi_definition = abi_definition,
+ abi_definition_stg = abi_definition_stg,
kmi_enforced = kmi_enforced,
kmi_symbol_list = name + "_src_kmi_symbol_list",
**private_kwargs
@@ -399,6 +413,7 @@
def _define_abi_definition_targets(
name,
abi_definition,
+ abi_definition_stg,
kmi_enforced,
kmi_symbol_list,
**kwargs):
@@ -408,6 +423,9 @@
Defines `{name}_diff_executable`.
"""
+
+ default_outputs = []
+
if not abi_definition:
# For kernel_abi_dist to use when abi_definition is empty.
exec(
@@ -415,111 +433,132 @@
script = "",
**kwargs
)
- return []
+ default_outputs.append(name + "_diff_executable")
+ else:
+ native.filegroup(
+ name = name + "_out_file",
+ srcs = [name + "_dump"],
+ output_group = "abi_out_file",
+ **kwargs
+ )
- default_outputs = []
+ abi_diff(
+ name = name + "_diff",
+ baseline = abi_definition,
+ new = name + "_out_file",
+ kmi_enforced = kmi_enforced,
+ **kwargs
+ )
+ default_outputs.append(name + "_diff")
- native.filegroup(
- name = name + "_out_file",
- srcs = [name + "_dump"],
- output_group = "abi_out_file",
- **kwargs
- )
+ # The default outputs of _diff does not contain the executable,
+ # but the reports. Use this filegroup to select the executable
+ # so rootpath in _update works.
+ native.filegroup(
+ name = name + "_diff_executable",
+ srcs = [name + "_diff"],
+ output_group = "executable",
+ **kwargs
+ )
- abi_diff(
- name = name + "_diff",
- baseline = abi_definition,
- new = name + "_out_file",
- kmi_enforced = kmi_enforced,
- **kwargs
- )
- default_outputs.append(name + "_diff")
+ native.filegroup(
+ name = name + "_diff_git_message",
+ srcs = [name + "_diff"],
+ output_group = "git_message",
+ **kwargs
+ )
- # The default outputs of _diff does not contain the executable,
- # but the reports. Use this filegroup to select the executable
- # so rootpath in _update works.
- native.filegroup(
- name = name + "_diff_executable",
- srcs = [name + "_diff"],
- output_group = "executable",
- **kwargs
- )
+ update_source_file(
+ name = name + "_update_definition",
+ src = name + "_out_file",
+ dst = abi_definition,
+ **kwargs
+ )
- native.filegroup(
- name = name + "_diff_git_message",
- srcs = [name + "_diff"],
- output_group = "git_message",
- **kwargs
- )
+ exec(
+ name = name + "_nodiff_update",
+ data = [
+ name + "_extracted_symbols",
+ name + "_update_definition",
+ kmi_symbol_list,
+ ],
+ script = """
+ # Ensure that symbol list is updated
+ if ! diff -q $(rootpath {src_symbol_list}) $(rootpath {dst_symbol_list}); then
+ echo "ERROR: symbol list must be updated before updating ABI definition. To update, execute 'tools/bazel run //{package}:{update_symbol_list_label}'." >&2
+ exit 1
+ fi
+ # Update abi_definition
+ $(rootpath {update_definition})
+ """.format(
+ src_symbol_list = name + "_extracted_symbols",
+ dst_symbol_list = kmi_symbol_list,
+ package = native.package_name(),
+ update_symbol_list_label = name + "_update_symbol_list",
+ update_definition = name + "_update_definition",
+ ),
+ **kwargs
+ )
- update_source_file(
- name = name + "_update_definition",
- src = name + "_out_file",
- dst = abi_definition,
- **kwargs
- )
+ exec(
+ name = name + "_update",
+ data = [
+ abi_definition,
+ name + "_diff_git_message",
+ name + "_diff_executable",
+ name + "_nodiff_update",
+ ],
+ script = """
+ # Update abi_definition
+ $(rootpath {nodiff_update})
+ # Create git commit if requested
+ if [[ $1 == "--commit" ]]; then
+ real_abi_def="$(realpath $(rootpath {abi_definition}))"
+ git -C $(dirname ${{real_abi_def}}) add $(basename ${{real_abi_def}})
+ git -C $(dirname ${{real_abi_def}}) commit -F $(realpath $(rootpath {git_message}))
+ fi
+ # Check return code of diff_abi and kmi_enforced
+ set +e
+ $(rootpath {diff})
+ rc=$?
+ set -e
+ # Prompt for editing the commit message
+ if [[ $1 == "--commit" ]]; then
+ echo
+ echo "INFO: git commit created. Execute the following to edit the commit message:"
+ echo " git -C $(dirname $(rootpath {abi_definition})) commit --amend"
+ fi
+ exit $rc
+ """.format(
+ diff = name + "_diff_executable",
+ nodiff_update = name + "_nodiff_update",
+ abi_definition = abi_definition,
+ git_message = name + "_diff_git_message",
+ ),
+ **kwargs
+ )
- exec(
- name = name + "_nodiff_update",
- data = [
- name + "_extracted_symbols",
- name + "_update_definition",
- kmi_symbol_list,
- ],
- script = """
- # Ensure that symbol list is updated
- if ! diff -q $(rootpath {src_symbol_list}) $(rootpath {dst_symbol_list}); then
- echo "ERROR: symbol list must be updated before updating ABI definition. To update, execute 'tools/bazel run //{package}:{update_symbol_list_label}'." >&2
- exit 1
- fi
- # Update abi_definition
- $(rootpath {update_definition})
- """.format(
- src_symbol_list = name + "_extracted_symbols",
- dst_symbol_list = kmi_symbol_list,
- package = native.package_name(),
- update_symbol_list_label = name + "_update_symbol_list",
- update_definition = name + "_update_definition",
- ),
- **kwargs
- )
-
- exec(
- name = name + "_update",
- data = [
- abi_definition,
- name + "_diff_git_message",
- name + "_diff_executable",
- name + "_nodiff_update",
- ],
- script = """
- # Update abi_definition
- $(rootpath {nodiff_update})
- # Create git commit if requested
- if [[ $1 == "--commit" ]]; then
- real_abi_def="$(realpath $(rootpath {abi_definition}))"
- git -C $(dirname ${{real_abi_def}}) add $(basename ${{real_abi_def}})
- git -C $(dirname ${{real_abi_def}}) commit -F $(realpath $(rootpath {git_message}))
- fi
- # Check return code of diff_abi and kmi_enforced
- set +e
- $(rootpath {diff})
- rc=$?
- set -e
- # Prompt for editing the commit message
- if [[ $1 == "--commit" ]]; then
- echo
- echo "INFO: git commit created. Execute the following to edit the commit message:"
- echo " git -C $(dirname $(rootpath {abi_definition})) commit --amend"
- fi
- exit $rc
- """.format(
- diff = name + "_diff_executable",
- nodiff_update = name + "_nodiff_update",
- abi_definition = abi_definition,
- git_message = name + "_diff_git_message",
- ),
- **kwargs
- )
+ if not abi_definition_stg:
+ # For kernel_abi_dist to use when abi_definition is empty.
+ exec(
+ name = name + "_diff_executable_stg",
+ script = "",
+ **kwargs
+ )
+ default_outputs.append(name + "_diff_executable_stg")
+ else:
+ native.filegroup(
+ name = name + "_out_file_stg",
+ srcs = [name + "_dump"],
+ output_group = "abi_out_file_stg",
+ **kwargs
+ )
+ stgdiff(
+ name = name + "_diff_stg",
+ baseline = abi_definition_stg,
+ new = name + "_out_file_stg",
+ kmi_enforced = kmi_enforced,
+ )
+ default_outputs.append(name + "_diff_stg")
return default_outputs