I'm in the process of rewriting a legacy CMake setup to use modern features like automatic dependency propagation. (i.e. using things like target_include_directories(<target> PUBLIC <dir>)
instead of include_directories(<dir>)
.) Currently, we manually handle all project dependency information by setting a bunch of global directory properties.
In my testing, I've found a few examples where a target in the new build will link to a library that the old build would not. I'm not linking to it explicitly, so I know this is coming from the target's dependencies, but in order to find which one(s) I have to recursively look through all of the project's CMakeLists.txt
s, following up the dependency hierarchy until I find one that pulls in the library in question. We have dozens of libraries so this is not a trivial process.
Does CMake provide any way to see, for each target, which of its dependencies were added explicitly, and which ones were propagated through transitive dependencies?
It looks like the --graphviz
output does show this distinction, so clearly CMake knows the context internally. However, I'd like to write a tree
-like script to show dependency information on the command line, and parsing Graphviz files sounds like both a nightmare and a hack.
As far as I can tell, cmake-file-api
does not include this information. I thought the codemodel/target/dependencies
field might work, but it lists both local and transitive dependencies mixed together. And the backtrace
field of each dependency only ties back to the add_executable
/add_library
call for the current target.
Once you identify your package to be fixed using any of the above methods, to fix the transitive dependency, you must add a dependency to the updated version of the vulnerable package by adding it to the . csproj file. i.e such a vulnerable package needs to be made a direct dependency of your main project.
Transitive dependencyA dependency that your package indirectly uses because one of its dependencies requires it. If your package depends on A, which in turn depends on B which depends on C, then A is an immediate dependency and B and C are transitive ones.
In a computer program a direct dependency is functionality exported by a library, or API, or any software component that is referenced directly by the program itself. A transitive dependency is any dependency that is induced by the components that the program references directly.
CMake provides a number of ways to incorporate such things into the build. Projects and users have the flexibility to choose between methods that best suit their needs. The primary methods of bringing dependencies into the build are the find_package () command and the FetchContent module.
This prints the dependency tree. It’s a text report which shows all of the dependencies in your project, both the direct and transitive dependencies. If you’re not sure what the terms ‘direct’ and ‘transitive’ mean, then scroll further down for a quick guide to dependencies and how they work in Maven!
It is common for users to set the CMAKE_MODULE_PATH when running CMake, and it is common for CMake projects to append to CMAKE_MODULE_PATH to allow use of local Find module files. CMake ships Find<PackageName>.cmake files for some third party packages.
One of Maven’s main jobs is to handle your Java project’s dependencies. So when Maven runs, it builds a “tree” of all dependencies in your project. If you tell Maven to print a dependency tree, you will be able to see all of the dependencies in your project. Drop to a terminal.
You can parse dot
file generated by graphviz
and extract details which you want. Below is sample python script to do that.
import pydot
import sys
graph = pydot.graph_from_dot_file(sys.argv[1])
result = {}
for g in graph:
# print(g)
for node in g.get_node_list():
if node.get("label") != None:
result[node.get("label")] = []
for edge in g.get_edges():
result[g.get_node(edge.get_source())[0].get("label")].append(g.get_node(edge.get_destination())[0].get("label"))
for r in result:
print(r+":"+",".join(result[r]))
You can also add this script to run from cmake as custom target, so you can call it from you build system. You can find sample cmake project here
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With