{"id":13418597,"url":"https://github.com/tomtom-international/cpp-dependencies","last_synced_at":"2025-04-12T22:24:30.296Z","repository":{"id":46333477,"uuid":"64384213","full_name":"tomtom-international/cpp-dependencies","owner":"tomtom-international","description":"Tool to check C++ #include dependencies (dependency graphs created in .dot format)","archived":false,"fork":false,"pushed_at":"2023-10-02T18:36:13.000Z","size":275,"stargazers_count":734,"open_issues_count":15,"forks_count":82,"subscribers_count":42,"default_branch":"master","last_synced_at":"2024-07-31T22:43:34.808Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tomtom-international.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2016-07-28T09:55:01.000Z","updated_at":"2024-07-26T14:34:54.000Z","dependencies_parsed_at":"2023-01-17T20:20:20.568Z","dependency_job_id":"898c43f1-1365-4ffc-b089-ce3fa381903d","html_url":"https://github.com/tomtom-international/cpp-dependencies","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomtom-international%2Fcpp-dependencies","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomtom-international%2Fcpp-dependencies/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomtom-international%2Fcpp-dependencies/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomtom-international%2Fcpp-dependencies/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tomtom-international","download_url":"https://codeload.github.com/tomtom-international/cpp-dependencies/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248638655,"owners_count":21137693,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-30T22:01:04.292Z","updated_at":"2025-04-12T22:24:30.276Z","avatar_url":"https://github.com/tomtom-international.png","language":"C++","readme":"# Read Me for Dependency Checker\n\n[![Codacy Badge](https://api.codacy.com/project/badge/Grade/69bd30706d964c308f78466aa138f64e)](https://www.codacy.com/app/rijnb/cpp-dependencies?utm_source=github.com\u0026amp;utm_medium=referral\u0026amp;utm_content=tomtom-international/cpp-dependencies\u0026amp;utm_campaign=Badge_Grade)\n[![Mac/Linux Build Status](https://img.shields.io/travis/tomtom-international/cpp-dependencies.svg?maxAge=3600)](https://travis-ci.org/tomtom-international/cpp-dependencies)\n[![Windows Build Status](https://img.shields.io/appveyor/ci/rijnb/cpp-dependencies.svg)](https://ci.appveyor.com/project/rijnb/cpp-dependencies)\n[![License](http://img.shields.io/badge/license-APACHE2-blue.svg)]()\n[![Release](https://img.shields.io/github/release/tomtom-international/cpp-dependencies.svg?maxAge=3600)](https://github.com/tomtom-international/cpp-dependencies/releases)\n\n[![Snap store badge](https://camo.githubusercontent.com/353bcf397acd2a7663c45bc69cd2b202417a66c24d3b38f861f9cc0fe1a25324/68747470733a2f2f736e617063726166742e696f2f7374617469632f696d616765732f6261646765732f656e2f736e61702d73746f72652d77686974652e737667)](https://snapcraft.io/cpp-dependencies)\n\nCopyright (C) 2012-2017, TomTom International BV. All rights reserved.\n----\n\nThe tool `cpp-dependencies` creates `#include` dependency information for C++ source\ncode files, which it derives from scanning a full source tree.\n\nThe dependency information is output as `.dot` files, which can be visualized\nin, for example, [GraphViz](http://www.graphviz.org).\n\nHappy coding!\n\nPeter Bindels and Rijn Buve\n\n*TomTom International BV*\n\n# License\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n   http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n\n# Build and run\n\nThe tool depends on Boost.Filesystem being available and usable. Installing this\nshould be done with your platform's package management system, such as Apt, \nPacman or Brew.\n\nThe build configuration is created with _CMake_.\nTo create the build configuration for your build system (GNU make, MSBuild/Visual Studio)\ncreate a build directory outside this source directory and run\n\n    cmake \u003cPATH_TO_THIS_SOURCE_DIR\u003e\n    \nIf you want to use Boost::Filesystem instead of std::filesystem, if your platform does \nnot have a std::filesystem implementation yet or if you prefer it, add `-DWITH_BOOST` \nto the invocation of _CMake_. \n\nTo build the tool, either execute\n\n    make\n\nfor GNU make or open the Visual Studio solution file generated in the build directory.\n\nThis creates the executable file `cpp-dependencies`.\n\nTo check if the tool was compiled correctly, execute:\n  \n    ./cpp-dependencies\n    \nThis provides help information about the tool. More information about\nits usage is presented in the next paragraph.\n    \n    \n# Using `cpp-dependencies` to analyze a component\n\nAs a first thing on a code base is to find out whether it can read the code correctly. From the root of the project, \nrun the command:\n\n    cpp-dependencies --stats .\n\nto determine the complexity of the code base and the amount of nodes that are entangled in cycles with other \ncomponents. In well set-up projects, the cycle count will be equal to zero and the amount of components will be in \nthe same order of size as the logical components you expect.\n\nTo investigate a specific component, you can use \n\n    cpp-dependencies --info \u003ccomponent\u003e .\n    \nfor all information the tool has on the component, or:    \n\n    cpp-dependencies --inout \u003ccomponent\u003e .\n    \nto find out who links to and from your component.\n\nIn case you have a dependency that you were not expecting, or find out that when rebuilding component A that a\nsupposedly-unrelated component B is built, you can use:\n\n    cpp-dependencies --shortest A B .\n\nto determine why there is a link from component A to component B. It will find one of the shortest paths it can find \nfrom A to B if there is one.\n\n\n# Using `cpp-dependencies` to make visualized graphs\n\nThe tool is also able to provide output in `.dot` format, which is a format used by [GraphViz](http://www.graphviz.org) and other tools to contain\ngraphs. It is a human-readable format and can be used by the dot tool to convert it into a graphical image. To create\na graph file, use:\n\n    cpp-dependencies --graph mygraph.dot .\n\nto create a mygraph.dot file containing the full component graph. \n\nYou can restrict the component graph to either all\ncomponents beneath a given target (`--graph-for \u003coutput\u003e \u003ctarget\u003e`) or all components part of a cycle (`--graph-cycles`). \n\nTo make this text-format graph into a viewable graph, use for example:\n\n    dot -Tpng mygraph.dot \u003emygraph.png\n\nto convert it into a PNG file. \n\nThe `dot` program will try to find a way to graphically display the graph output. Note that\nvery large graphs, in particular if many cycles are present, can take hours to render.\n\n\n# Example use of `cpp-dependencies`\n\nIn the source tree there's a folder `example` which contains an empty skeleton project, which does have some dependency information to be extracted from it. To start analyzing it, we first run the tool to extract statistics:\n\n    \u003e cpp-dependencies --dir example --stats\n    6 components with 5 public dependencies, 1 private dependencies\n    Detected 2 nodes in cycles\n\nThis informs us that there is something not quite right with the dependencies. It sees 6 components: the root folder, four libraries and an executable. The simplest way to find out what's wrong is to draw out the graph in a visual way:\n\n    \u003e cpp-dependencies --dir example --graph dependencies.dot\n    \u003e dot -Tpng dependencies.dot \u003edependencies.png\n\nThen open this PNG file in any tool that can view it, such as a web browser. This shows us the following image:\n\n![Dependency graph showing a cycle between Engine and UI](example/dependencies.png)\n\nThe light blue links are an implementation-only link, the dark blue ones expose some part of this dependency on their interface. The orange ones are the most interesting ones; they are places where a component can reach itself through some other component. Let's find out why this is there:\n\n    \u003e cpp-dependencies --dir example --shortest Engine UI\n    Engine -\u003e UI\n      ./Engine/Engine.h includes ./UI/Display.h\n    \u003e cpp-dependencies --dir example --shortest UI Engine\n    UI -\u003e Engine\n      ./UI/Display.cpp includes ./Engine/Engine.h\n      ./UI/Display.h includes ./Engine/Engine.h\n\nAt this point, it's up to the developer or architect to find out which of these two dependencies is the wrong way around and to find a way around that. In the example, the Engine component should not be talking directly to the UI component. Removing this dependency results in the following statistics:\n\n    \u003e cpp-dependencies --dir example --stats\n    6 components with 4 public dependencies, 2 private dependencies\n    Detected 0 nodes in cycles\n\nThe cycle has been removed, and there is one less dependency. We can find out what the shortest path is to the DataAccess component from the executable:\n\n    \u003e cpp-dependencies --dir example --shortest main DataAccess\n    main -\u003e UI\n      ./main/main.cpp includes ./UI/Display.h\n    UI -\u003e Engine\n      ./UI/Display.cpp includes ./Engine/Engine.h\n      ./UI/Display.h includes ./Engine/Engine.h\n    Engine -\u003e DataAccess\n      ./Engine/Engine.cpp includes ./DataAccess/DA.h\n\nThis tells us that there's no path shorter than three steps, and it informs us for each step of the way why it detects this link. In more complicated cycles, this can be a way to isolate the thinnest part of the cycle. In situations where there's an invalid dependency from one component to another - for example, from a unit test of one component to a very far away different component, this can help you identify where on the path from A to B a wrong link is present. It can also be used to explicitly verify that a link is not present, such as the one we just removed:\n\n    \u003e cpp-dependencies --dir example --shortest Engine UI\n    No path could be found from Engine to UI\n\nThe graph now also shows proper dependency ordering:\n\n    \u003e cpp-dependencies --dir example --graph newdependencies.dot\n    \u003e dot -Tpng newdependencies.dot \u003enewdependencies.png\n\n![Dependency graph showing no more cycles](example/newdependencies.png)\n\nWe can regenerate the CMakeLists.txt files as well to remove the dependency from the build inputs, so that our build system will also know that the link is no longer present:\n\n    \u003e cpp-dependencies --dir example --dryregen\n    Difference detected at \"./Engine\"\n    \u003e cpp-dependencies --dir example --regen\n\n# Customizing the outputs\n\nAs cpp-dependencies has a lot of analysis it can do on the source tree, there are also some configurable parts to it. The configuration can be found in the file config-cpp-dependencies.txt that should be in your project root. It allows you to customize the colors used in generation, the thresholds for outlier detection and some minor parameters. Please read the documentation in the example config-cpp-dependencies.txt that is in the source distribution for the tool to see all the options.\n\n# Editing the tool\n\nThe tool itself is split up into a few separate files to make it easier to find and extend its functionality. The following files are found:\n\n* `main.cpp` contains the main functions and help information, as well as the core flow.\n* `Input.cpp` contains the functions that read C++ and `CMakeLists` files into the information needed by the tool.\n* `Output.cpp` contains functions to write all output files generated, except for the `CMakeLists` generation.\n* `CmakeRegen.cpp` contains the functionality to write `CMakeLists` files.\n* `Analysis.cpp` contains all graph processing and navigation functions.\n* `Component.cpp` contains the implementation needed for the struct-like data storage classes.\n* `generated.cpp` contains the function to convert found header files into a lookup map. Also the place to add generated files\n    to the known file list, so that they will be taken into account for components.\n* `Constants.h` contains the constants used throughout the code base.\n\nIn general, the root functionality is kept in `main.cpp`, the structural classes are kept in `Component.cpp` \nand any auxiliary functions that are used to do this are split up by domain.\n\n\n# Rationale behind implementation\n\nThe tool was implemented with the goal of being able to quickly analyze dependencies between components of a \ncomplex project, including how the dependency graph changes when some changes are made to the source tree. To \naccomplish this, choices were made in the direction of more performance at the expense of strict correctness. \nSpecifically:\n\n- It does not use a proper C++ parser to read C++ files, nor a proper CMake parser to read CMake files. Properly\n  parsing these files would increase the full run time of the program by orders of magnitude and make it much less\n  useful.\n- `strstr` is used across the full code base. While profiling, we found that `std::string::find` was taking over 80% of\n  the full runtime. Replacing it with `strstr`, which is typically much more optimized, made the whole program twice \n  as fast.\n\nThis results in it running on a 1.5GB source code base in about 2.1 seconds -- fast enough for interactive checks and\nrerunning after any small modification. \n\nThe tool was set up to compile on a Ubuntu 12.04 system with the platform default compiler. This means that the sources will use C++11\nbut will not use anything not available in GCC 4.6. It has been tested and used on Linux (Ubuntu 12.04 - 16.04) and MacOS X \n(different versions).\n\n\n# Using Git and `.gitignore`\n\nIt's good practice to set up a personal global `.gitignore` file on your machine which filters a number of files\non your file systems that you do not wish to submit to the Git repository. You can set up your own global\n`~/.gitignore` file by executing:\n`git config --global core.excludesfile ~/.gitignore`\n\nIn general, add the following file types to `~/.gitignore` (each entry should be on a separate line):\n`*.com *.class *.dll *.exe *.o *.so *.log *.sql *.sqlite *.tlog *.epoch *.swp *.hprof *.hprof.index *.releaseBackup *~`\n\nThe local `.gitignore` file in the Git repository itself to reflect those file only that are produced by executing\nregular compile, build or release commands.\n\n\n# Bug reports and new feature requests\n\nIf you encounter any problems with this library, don't hesitate to use the `Issues` session to file your issues.\nNormally, one of our developers should be able to comment on them and fix.\n\n","funding_links":[],"categories":["TODO scan for Android support in followings","Static Code Analysis","Architecture and Design","排序","Tools"],"sub_categories":["静态代码分析"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftomtom-international%2Fcpp-dependencies","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftomtom-international%2Fcpp-dependencies","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftomtom-international%2Fcpp-dependencies/lists"}