# Custom build graph walking plugins

**URL:** https://discourse.cmake.org/t/custom-build-graph-walking-plugins/15321
**Category:** Development
**Created:** [November 18, 2025, 8:43am UTC](https://discourse.cmake.org/t/custom-build-graph-walking-plugins/15321 "2025-11-18T08:43:20Z")
**Posts on this page:** 12
**Page:** 1

<div class="post-metadata">

### Author: ![tom](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/t/3d9bf3/32.png) [@tom](https://discourse.cmake.org/u/tom)
#### Post date: [November 18, 2025, 8:43am UTC](https://discourse.cmake.org/t/custom-build-graph-walking-plugins/15321/1 "2025-11-18T08:43:20Z")

</div>

CMake has code to walk the build graph and generate dot files.

We have a large and complex codebase, and it would be extremely useful for us to be able to walk the build graph and execute arbitrary code that has access to CMake-level information. For example, we could:

1. Interrogate custom target properties to write a Bill of Materials
2. Ensure that there’s nothing in the build graph that isn’t cleared by our legal team
3. Automatically generate install rules for a target and its dependencies
4. Detect unnecessary links
5. Detect include directories that break the dependencies implied by target links
6. Etc, etc…

Some of that code could potentially be upstreamed, for example the BoM generation or detection of odd-looking include patterns. However, some of it will always be specific to our codebase.

We could implement a plugin loading mechanism, similar to how clang-tidy handles custom checks. In clang-tidy, developers build against a specific version of LLVM and override a specific class. They compile their code into a shared library. There are very few guarantees about ABI stability and you are expected to build against the version your want to run. At run-time, there is a `--load /path/to/your/plugin.so` flag which you pass, and clang-tidy will execute your custom code as part of its normal workflow.

I wonder if something similar could be implemented for CMake.

So, questions:

1. Has this been discussed before? I couldn’t find anything
2. In principle, and without getting into technical details, might this plugin approach to build graph walking be accepted upstream?

Thanks!

---

<div class="post-metadata">

### Author: ![benthevining](https://discourse.cmake.org/user_avatar/discourse.cmake.org/benthevining/32/1924_2.png) [@benthevining](https://discourse.cmake.org/u/benthevining)
#### Post date: [November 18, 2025, 1:39pm UTC](https://discourse.cmake.org/t/custom-build-graph-walking-plugins/15321/2 "2025-11-18T13:39:15Z")

</div>

It sounds like you want the file API. Basically you write a request, then after CMake generation, it writes some JSON files providing all the build graph information that you can then crawl in the manner you describe.

---

<div class="post-metadata">

### Author: ![tom](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/t/3d9bf3/32.png) [@tom](https://discourse.cmake.org/u/tom)
#### Post date: [November 18, 2025, 2:17pm UTC](https://discourse.cmake.org/t/custom-build-graph-walking-plugins/15321/3 "2025-11-18T14:17:01Z")

</div>

So the build graph traversal code that’s used for the dot file generation is a bit of a dead end? If dot file generation was being added today, it would be a stand-alone piece of code that uses the file api?

---

<div class="post-metadata">

### Author: ![benthevining](https://discourse.cmake.org/user_avatar/discourse.cmake.org/benthevining/32/1924_2.png) [@benthevining](https://discourse.cmake.org/u/benthevining)
#### Post date: [November 18, 2025, 2:34pm UTC](https://discourse.cmake.org/t/custom-build-graph-walking-plugins/15321/4 "2025-11-18T14:34:35Z")

</div>

Probably? I can’t speak for the CMake developers, perhaps one of them will chime in. But the file API is the recommended way for IDEs and other tools to get build graph information from CMake.

---

<div class="post-metadata">

### Author: ![tom](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/t/3d9bf3/32.png) [@tom](https://discourse.cmake.org/u/tom)
#### Post date: [November 18, 2025, 2:54pm UTC](https://discourse.cmake.org/t/custom-build-graph-walking-plugins/15321/5 "2025-11-18T14:54:49Z")

</div>

Actually, I’m not sure the file api quite gives us the information we need. It seems a layer too close to the build system.

Let’s take dot file generation as an example. It needs to know the type of each link between targets (public, private, or interface), because graphviz wants to represent those links differently. It seems that the file API exposes “dependencies” for each target, but that’s effectively a flat list of target names. If you want to know what kind of links they are it seems you’d have to go through the backtrace and re-parse the CMake code to find the public/private/interface specifier. Have I misunderstood something here?

The dot file generator (and the build graph traversal C++ code) allows you to query CMake target properties directly, which is the level at which the dot file generator wants to work.

---

<div class="post-metadata">

### Author: ![brad.king](https://discourse.cmake.org/user_avatar/discourse.cmake.org/brad.king/32/11_2.png) [@brad.king](https://discourse.cmake.org/u/brad.king)
#### Post date: [November 18, 2025, 2:59pm UTC](https://discourse.cmake.org/t/custom-build-graph-walking-plugins/15321/6 "2025-11-18T14:59:28Z")

</div>

CMake 4.2 updates the file-api’s codemodel reply to include much more information about the target dependency graph. See [CMake Issue 25213](https://gitlab.kitware.com/cmake/cmake/-/issues/25213).

---

<div class="post-metadata">

### Author: ![tom](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/t/3d9bf3/32.png) [@tom](https://discourse.cmake.org/u/tom)
#### Post date: [November 18, 2025, 3:13pm UTC](https://discourse.cmake.org/t/custom-build-graph-walking-plugins/15321/7 "2025-11-18T15:13:27Z")

</div>

Okay good, so that helps with the dot file generation example.

I think in general we need access to any arbitrary property of any target of the build graph. For example, we might want to compare `LINK_LIBRARIES` to `INCLUDE_DIRECTORIES`, or write `MY_CUSTOM_TARGET_PROPERTY` to the bill of materials.

It seems information from more target properties is being written to the file API. Are there plans to write _all_ target properties to the file API? What about custom target properties?

It seems the file API is taking target properties, parsing them, and outputting some derived quantities. In theory we could take these target properties and work our way back to their declaration in the CMakeLists, but that does seem like we’re going a long way around. Is the file API _really_ the right approach here?

---

<div class="post-metadata">

### Author: ![brad.king](https://discourse.cmake.org/user_avatar/discourse.cmake.org/brad.king/32/11_2.png) [@brad.king](https://discourse.cmake.org/u/brad.king)
#### Post date: [November 18, 2025, 3:24pm UTC](https://discourse.cmake.org/t/custom-build-graph-walking-plugins/15321/8 "2025-11-18T15:24:10Z")

</div>

> [@tom](#):
>
> might this plugin approach to build graph walking be accepted upstream?

No. We have no intention or desire to add or maintain support for dynamically loaded plugins. We just finally ripped out the old `load_command` support in CMake 4.0, and do not want to add anything like that again.

---

<div class="post-metadata">

### Author: ![brad.king](https://discourse.cmake.org/user_avatar/discourse.cmake.org/brad.king/32/11_2.png) [@brad.king](https://discourse.cmake.org/u/brad.king)
#### Post date: [November 18, 2025, 3:27pm UTC](https://discourse.cmake.org/t/custom-build-graph-walking-plugins/15321/9 "2025-11-18T15:27:36Z")

</div>

Almost all of the example use cases above have been proposed as first-class features of CMake itself and have associated issue tracker entries. SBOM support is in active progress (and Qt has actually implemented it based on existing CMake features).

---

<div class="post-metadata">

### Author: ![tom](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/t/3d9bf3/32.png) [@tom](https://discourse.cmake.org/u/tom)
#### Post date: [November 18, 2025, 3:58pm UTC](https://discourse.cmake.org/t/custom-build-graph-walking-plugins/15321/10 "2025-11-18T15:58:41Z")

</div>

> > might this plugin approach to build graph walking be accepted upstream?
> 
> No. We have no intention or desire to add or maintain support for dynamically loaded plugins. […]

Fair enough! If we have some obscure project-specific use-case that requires interacting with target properties in this way, we’ll fork. If we come up with anything more general we’ll try and upstream a self-contained utility rather than a plugin interface.

Thanks for the quick response.

> Almost all of the example use cases above have been proposed as first-class features of CMake itself and have associated issue tracker entries.

Even better.

I already know about this: [https://gitlab.kitware.com/cmake/cmake/-/issues/26719](https://gitlab.kitware.com/cmake/cmake/-/issues/26719)

Is there a ticket for installing a branch of the tree without having to manually specify all dependencies? If so, I couldn’t find it - would you mind please linking it here?

---

<div class="post-metadata">

### Author: ![brad.king](https://discourse.cmake.org/user_avatar/discourse.cmake.org/brad.king/32/11_2.png) [@brad.king](https://discourse.cmake.org/u/brad.king)
#### Post date: [November 18, 2025, 4:31pm UTC](https://discourse.cmake.org/t/custom-build-graph-walking-plugins/15321/11 "2025-11-18T16:31:53Z")

</div>

> [@tom](#):
>
> ticket for installing a branch of the tree without having to manually specify all dependencies?

Please open one with a more complete description of the use case and an example.

---

<div class="post-metadata">

### Author: ![tom](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/t/3d9bf3/32.png) [@tom](https://discourse.cmake.org/u/tom)
#### Post date: [November 27, 2025, 9:14am UTC](https://discourse.cmake.org/t/custom-build-graph-walking-plugins/15321/12 "2025-11-27T09:14:18Z")

</div>

@brad.king , I’ve raised [Dynamic package generation](https://discourse.cmake.org/t/dynamic-package-generation/15348)
