summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlises Mendez Martinez <umendez@google.com>2024-06-07 14:31:16 +0000
committerMatthias Männich <maennich@google.com>2024-06-11 11:52:50 +0000
commit35c2f67f6a4aa2d0b918028ef20727dd77bce97b (patch)
treea872d254f202c9ab75616d0eb5e24912c03b97a4
parent9fabd0c074d62c1c6cd1c5a9c6d3c04464799b41 (diff)
downloadbuild-main.tar.gz
Kleaf: Add macro to bundle dependency graph targetsHEADmastermain
Bug: 341655806 Change-Id: Ifc492f4a14d6eeed86d5465a59d1fa31f1bbea09 Signed-off-by: Ulises Mendez Martinez <umendez@google.com>
-rw-r--r--abi/dependency_graph_drawer.py4
-rw-r--r--kleaf/README.md2
-rw-r--r--kleaf/docs/api_reference/kernel.md29
-rw-r--r--kleaf/docs/dependencies.md51
-rw-r--r--kleaf/impl/abi/dependency_graph.bzl49
-rw-r--r--kleaf/kernel.bzl2
6 files changed, 134 insertions, 3 deletions
diff --git a/abi/dependency_graph_drawer.py b/abi/dependency_graph_drawer.py
index 1d924dc2..5e11ad7e 100644
--- a/abi/dependency_graph_drawer.py
+++ b/abi/dependency_graph_drawer.py
@@ -35,13 +35,14 @@ def _create_graphviz(
"\tnode [color=steelblue, shape=plaintext];",
"\tedge [arrowhead=odot, color=olive];",
])
+ leaves = []
for node in adjacency_list.values():
# vmlinux is dependency for most of the nodes so skip it.
if node["name"] == "vmlinux":
continue
# Skip nodes without dependents.
if not node["dependents"]:
- logging.info("Skipping leaf module %s", node["name"])
+ leaves.append(node["name"])
continue
edges = []
for neighbor in node["dependents"]:
@@ -53,6 +54,7 @@ def _create_graphviz(
h = hashlib.shake_256(edge_str.encode())
edge_color = f' [color=" # {h.hexdigest(3)}"]'
content.append(f'\t"{node["name"]}" -> {edge_str}{edge_color};')
+ logging.warning("Leaf nodes: [%s]", leaves)
content.append("}")
output.write_text("\n".join(content), encoding="utf-8")
diff --git a/kleaf/README.md b/kleaf/README.md
index e7e7c3ad..8332ea41 100644
--- a/kleaf/README.md
+++ b/kleaf/README.md
@@ -34,6 +34,8 @@
[Debugging Kleaf](docs/debugging.md)
+[Visualizing dependencies](docs/dependencies.md)
+
### Advanced topics
[Handling SCM version](docs/scmversion.md)
diff --git a/kleaf/docs/api_reference/kernel.md b/kleaf/docs/api_reference/kernel.md
index 7315eebc..a3703582 100644
--- a/kleaf/docs/api_reference/kernel.md
+++ b/kleaf/docs/api_reference/kernel.md
@@ -150,7 +150,7 @@ ddk_uapi_headers(
## dependency_graph_drawer
<pre>
-dependency_graph_drawer(<a href="#dependency_graph_drawer-name">name</a>, <a href="#dependency_graph_drawer-adjacency_list">adjacency_list</a>)
+dependency_graph_drawer(<a href="#dependency_graph_drawer-name">name</a>, <a href="#dependency_graph_drawer-adjacency_list">adjacency_list</a>, <a href="#dependency_graph_drawer-colorful">colorful</a>)
</pre>
A rule that creates a [Graphviz](https://graphviz.org/) diagram file.
@@ -183,6 +183,7 @@ A rule that creates a [Graphviz](https://graphviz.org/) diagram file.
| :------------- | :------------- | :------------- | :------------- | :------------- |
| <a id="dependency_graph_drawer-name"></a>name | A unique name for this target. | <a href="https://bazel.build/concepts/labels#target-names">Name</a> | required | |
| <a id="dependency_graph_drawer-adjacency_list"></a>adjacency_list | - | <a href="https://bazel.build/concepts/labels">Label</a> | required | |
+| <a id="dependency_graph_drawer-colorful"></a>colorful | Whether outgoing edges from every node are colored. | Boolean | optional | `False` |
<a id="dependency_graph_extractor"></a>
@@ -910,6 +911,32 @@ dependencies are stable, it is recommended to:
| <a id="ddk_submodule-kwargs"></a>kwargs | Additional attributes to the internal rule, e.g. [`visibility`](https://docs.bazel.build/versions/main/visibility.html). See complete list [here](https://docs.bazel.build/versions/main/be/common-definitions.html#common-attributes). | none |
+<a id="dependency_graph"></a>
+
+## dependency_graph
+
+<pre>
+dependency_graph(<a href="#dependency_graph-name">name</a>, <a href="#dependency_graph-kernel_build">kernel_build</a>, <a href="#dependency_graph-kernel_modules">kernel_modules</a>, <a href="#dependency_graph-colorful">colorful</a>, <a href="#dependency_graph-kwargs">kwargs</a>)
+</pre>
+
+Declare targets for dependency graph visualization.
+
+Output:
+ File with a diagram representing a graph in DOT language.
+
+
+**PARAMETERS**
+
+
+| Name | Description | Default Value |
+| :------------- | :------------- | :------------- |
+| <a id="dependency_graph-name"></a>name | Name of this target. | none |
+| <a id="dependency_graph-kernel_build"></a>kernel_build | The [`kernel_build`](#kernel_build). | none |
+| <a id="dependency_graph-kernel_modules"></a>kernel_modules | A list of external [`kernel_module()`](#kernel_module)s. | none |
+| <a id="dependency_graph-colorful"></a>colorful | When set to True, outgoing edges from every node are colored differently. | `None` |
+| <a id="dependency_graph-kwargs"></a>kwargs | Additional attributes to the internal rule, e.g. [`visibility`](https://docs.bazel.build/versions/main/visibility.html). See complete list [here](https://docs.bazel.build/versions/main/be/common-definitions.html#common-attributes). | none |
+
+
<a id="initramfs_modules_lists_test"></a>
## initramfs_modules_lists_test
diff --git a/kleaf/docs/dependencies.md b/kleaf/docs/dependencies.md
new file mode 100644
index 00000000..8cab51a4
--- /dev/null
+++ b/kleaf/docs/dependencies.md
@@ -0,0 +1,51 @@
+# Visualizing dependencies
+
+This is a non exhaustive list of options to help understanding dependencies.
+
+## Understanding kernel modules dependencies
+
+Use the `dependency_graph` macro to create a diagram of dependencies between
+ kernel modules. The dependencies are calculated via the exported symbols from
+ each modules and are represented in DOT language so they can be rendered
+ using a [Graphviz Server](https://graphviz.org/about/#viewers) or using the
+[CLI](https://graphviz.org/doc/info/command.html) as follows.
+
+<!-- TODO: After the change adding these targets land, reference the code here. -->
+Provide the `kernel_build` and a list of `kernel_module`'s to analyze:
+
+For example:
+```python
+dependency_graph(
+ name = "virtual_device_x86_64_dependency_graph",
+ colorful = True,
+ kernel_build = ":virtual_device_x86_64",
+ kernel_modules = [
+ ":virtual_device_x86_64_external_modules",
+ ],
+)
+```
+
+Build the diagram by running:
+```shell
+$ tools/bazel build //common-modules/virtual-device:virtual_device_x86_64_dependency_graph
+```
+
+The generated file can be found at:
+```
+bazel-bin/common-modules/virtual-device/virtual_device_x86_64_dependency_graph_drawer/dependency_graph.dot
+```
+
+You can use this file to render the graph in `.png` or `.svg` format.
+
+For example:
+```shell
+$ dot -Tsvg bazel-bin/common-modules/virtual-device/virtual_device_x86_64_dependency_graph_drawer/dependency_graph.dot
+```
+
+Optionally to reduce the graph density by eliminating transitive dependencies use the [tred]() utility:
+```shell
+$ tred bazel-bin/common-modules/virtual-device/virtual_device_x86_64_dependency_graph_drawer/dependency_graph.dot > reduced_graph.dot
+```
+
+
+<!-- TODO: Add section for Bazel dependencies. --> \ No newline at end of file
diff --git a/kleaf/impl/abi/dependency_graph.bzl b/kleaf/impl/abi/dependency_graph.bzl
index bc2ba844..f8962581 100644
--- a/kleaf/impl/abi/dependency_graph.bzl
+++ b/kleaf/impl/abi/dependency_graph.bzl
@@ -136,11 +136,16 @@ def _dependency_graph_drawer_impl(ctx):
out = ctx.actions.declare_file("{}/dependency_graph.dot".format(ctx.attr.name))
input = ctx.file.adjacency_list
tool = ctx.executable._dependency_graph_drawer
+ flags = []
+ if ctx.attr.colorful:
+ flags.append("--colors")
+
command = """
- {dependency_graph_drawer} {input} {output}
+ {dependency_graph_drawer} {input} {output} {flags}
""".format(
input = input.path,
dependency_graph_drawer = tool.path,
+ flags = " ".join(flags),
output = out.path,
)
debug.print_scripts(ctx, command)
@@ -182,6 +187,9 @@ dependency_graph_drawer = rule(
""",
attrs = {
"adjacency_list": attr.label(allow_single_file = True, mandatory = True),
+ "colorful": attr.bool(
+ doc = "Whether outgoing edges from every node are colored.",
+ ),
"_dependency_graph_drawer": attr.label(
default = "//build/kernel:dependency_graph_drawer",
cfg = "exec",
@@ -190,3 +198,42 @@ dependency_graph_drawer = rule(
"_debug_print_scripts": attr.label(default = "//build/kernel/kleaf:debug_print_scripts"),
},
)
+
+def dependency_graph(name, kernel_build, kernel_modules, colorful = None, **kwargs):
+ """Declare targets for dependency graph visualization.
+
+ Output:
+ File with a diagram representing a graph in DOT language.
+
+ Args:
+ name: Name of this target.
+ kernel_build: The [`kernel_build`](#kernel_build).
+ kernel_modules: A list of external [`kernel_module()`](#kernel_module)s.
+ colorful: When set to True, outgoing edges from every node are colored differently.
+ **kwargs: Additional attributes to the internal rule, e.g.
+ [`visibility`](https://docs.bazel.build/versions/main/visibility.html).
+ See complete list
+ [here](https://docs.bazel.build/versions/main/be/common-definitions.html#common-attributes).
+
+ """
+
+ dependency_graph_extractor(
+ name = name + "_extractor",
+ kernel_build = kernel_build,
+ kernel_modules = kernel_modules,
+ **kwargs
+ )
+
+ dependency_graph_drawer(
+ name = name + "_drawer",
+ adjacency_list = name + "_extractor",
+ colorful = colorful,
+ )
+
+ native.filegroup(
+ name = name,
+ srcs = [
+ name + "_drawer",
+ ],
+ **kwargs
+ )
diff --git a/kleaf/kernel.bzl b/kleaf/kernel.bzl
index 3ce24459..6fd03e74 100644
--- a/kleaf/kernel.bzl
+++ b/kleaf/kernel.bzl
@@ -25,6 +25,7 @@ load(
)
load(
"//build/kernel/kleaf/impl:abi/dependency_graph.bzl",
+ _dependency_graph = "dependency_graph",
_dependency_graph_drawer = "dependency_graph_drawer",
_dependency_graph_extractor = "dependency_graph_extractor",
)
@@ -62,6 +63,7 @@ ddk_headers_archive = _ddk_headers_archive
ddk_module = _ddk_module
ddk_submodule = _ddk_submodule
ddk_uapi_headers = _ddk_uapi_headers
+dependency_graph = _dependency_graph
dependency_graph_drawer = _dependency_graph_drawer
dependency_graph_extractor = _dependency_graph_extractor
extract_symbols = _extract_symbols