clang-uml
是一个自动 C++ 到 UML 类、序列、包和包含图生成器,由 YAML 配置文件驱动。该项目背后的主要思想是在代码库或文档遗留代码中轻松维护最新的图表。 clang-uml
的一个或多个配置文件定义了每个生成的图表的类型和内容。图表可以以 PlantUML、MermaidJS 和 JSON 格式生成。
clang-uml
目前支持 C++ 最高版本 20,以及 C 和 Objective-C。
完整文档可以在 clang-uml.github.io 找到。
要了解clang-uml
可以做什么,请查看此处为单元测试用例生成的图表或 clang-uml-examples 存储库中的示例。
目前支持的主要功能包括:
更全面的文档可以在 clang-uml.github.io 上找到。
可在此处找到Linux
、 macos
和Windows
的安装说明。
clang-uml
需要最新的compile_commands.json 文件,其中包含用于编译源代码的命令列表。
有关如何使用某些现有 C++ 构建系统生成compile_commands.json
的说明,请参阅此处。
默认情况下, clang-uml
会假设配置文件.clang-uml
和编译数据库compile_commands.json
文件位于当前目录中,因此如果它们位于项目的顶级目录中,只需运行:
clang-uml
图表的输出路径以及编译数据库的替代位置可以在.clang-uml
配置文件中或通过命令行参数指定。
对于其他选项,请参阅帮助:
clang-uml --help
配置文件用 YAML 编写,并提供应由clang-uml
生成的图表的定义。基本示例如下:
compilation_database_dir : .
output_directory : diagrams
diagrams :
myproject_class :
type : class
glob :
- src/*.cc
using_namespace : myproject
include :
namespaces :
- myproject
exclude :
namespaces :
- myproject::detail
plantuml :
after :
- ' note left of {{ alias("MyProjectMain") }}: Main class of myproject library. '
请参阅此处了解详细的配置文件参考指南。
要了解clang-uml
功能,请浏览此处的测试用例文档。
为了查看clang-uml
本身的图表,请根据其自己的配置运行以下命令:
make clanguml_diagrams
并打开docs/diagrams
文件夹中的 SVG 图表。
以下C++代码:
template < typename T, typename P> struct A {
T t;
P p;
};
struct B {
std::string value;
};
template < typename T> using AString = A<T, std::string>;
template < typename T> using AStringPtr = A<T, std::unique_ptr<std::string>>;
template < typename T>
using PairPairBA = std::pair<std::pair<B, A< long , T>>, long >;
template < class T > using VectorPtr = std::unique_ptr<std::vector<T>>;
template < class T > using APtr = std::unique_ptr<A< double , T>>;
template < class T > using ASharedPtr = std::shared_ptr<A< double , T>>;
template < class T , class U >
using AAPtr = std::unique_ptr<std::pair<A< double , T>, A< long , U>>>;
template < typename T> using SimpleCallback = std::function< void (T, int )>;
template < typename ... T> using GenericCallback = std::function< void (T..., int )>;
using VoidCallback = GenericCallback< void *>;
using BVector = std::vector<B>;
using BVector2 = BVector;
using AIntString = AString< int >;
using ACharString = AString< char >;
using AStringString = AString<std::string>;
using BStringString = AStringString;
template < typename T> class R {
using AWCharString = AString< wchar_t >;
PairPairBA< bool > bapair;
APtr< bool > abool;
AAPtr< bool , float > aboolfloat;
ASharedPtr< float > afloat;
A< bool , std::string> boolstring;
AStringPtr< float > floatstring;
AIntString intstring;
AStringString stringstring;
BStringString bstringstring;
AAPtr<T, float > atfloat;
protected:
BVector bs;
public:
BVector2 bs2;
SimpleCallback<ACharString> cb;
GenericCallback<AWCharString> gcb;
VoidCallback vcb;
VectorPtr<B> vps;
};
结果如下图所示(通过 PlantUML):
在此处打开原始图像,然后查看悬停工具提示以及类和方法的超链接。
以下C++代码:
# include < atomic >
# include < functional >
# include < iostream >
# include < memory >
# include < string >
namespace clanguml {
namespace t20029 {
std::string encode_b64 (std::string &&content) { return std::move (content); }
template < typename T> class Encoder : public T {
public:
bool send (std::string &&msg)
{
return T::send ( std::move (
// Encode the message using Base64 encoding and pass it to the next
// layer
encode ( std::move (msg))));
}
protected:
std::string encode (std::string &&msg) { return encode_b64 ( std::move (msg)); }
};
template < typename T> class Retrier : public T {
public:
bool send (std::string &&msg)
{
std::string buffer{ std::move (msg)};
int retryCount = 5 ;
// Repeat until send() succeeds or retry count is exceeded
while (retryCount--) {
if ( T::send (buffer))
return true ;
}
return false ;
}
};
class ConnectionPool {
public:
void connect ()
{
if (!is_connected_. load ())
connect_impl ();
}
bool send ( const std::string &msg) { return true ; }
private:
void connect_impl () { is_connected_ = true ; }
std::atomic< bool > is_connected_;
};
int tmain ()
{
auto pool = std::make_shared<Encoder<Retrier<ConnectionPool>>>();
// Establish connection to the remote server synchronously
pool-> connect ();
// Repeat for each line in the input stream
for (std::string line; std::getline (std::cin, line);) {
if (!pool-> send ( std::move (line)))
break ;
}
return 0 ;
}
}
}
结果如下图所示(通过 PlantUML):
以下C++代码:
namespace clanguml {
namespace t30003 {
namespace ns1 {
namespace ns2_v1_0_0 {
class A {
};
}
namespace [ [deprecated]] ns2_v0_9_0 {
class A {
};
}
namespace {
class Anon final {
};
}
}
namespace [ [deprecated]] ns3 {
namespace ns1 ::ns2 {
class Anon : public t30003 ::ns1::ns2_v1_0_0::A {
};
}
class B : public ns1 ::ns2::Anon {
};
}
}
}
结果如下图所示(通过 PlantUML):
如果您正在寻找一个更简单的工具来可视化和分析包含图,请查看我的其他工具 - clang-include-graph
C++代码结构如下:
tests/t40001
├── include
│ ├── lib1
│ │ └── lib1.h
│ └── t40001_include1.h
└── src
└── t40001.cc
基于代码中的 include 指令,结果如下图(通过 PlantUML):
统一建模语言 | 植物UML | 美人鱼JS |
---|---|---|
遗产 | ||
协会 | ||
依赖性 | ||
聚合 | ||
作品 | ||
模板专业化/实例化 | ||
嵌套(内部类/枚举) | ||
包括(本地) | ||
包括(系统) |
对于典型的代码库,从整个代码甚至单个命名空间生成的单个图表可能太大而无法使用,例如作为文档的一部分。 clang-uml
允许使用简单的 YAML 配置指定要包含在每个图中和从每个图中排除的内容:
include :
# Include only elements from these namespaces
namespaces :
- clanguml::common
- clanguml::config
# Include all subclasses of ClassA (including ClassA)
subclasses :
- clanguml::common::ClassA
# and specializations of template Class<T> (including Class<T>)
specializations :
- clanguml::common::ClassT<T>
# and all classes depending on Class D
dependants :
- clanguml::common::ClassD
# and all dependencies of ClassE
dependencies :
- clanguml::common::ClassE
# and classes in direct relation to ClassB (including ClassB)
context :
- clanguml::common::ClassB
# Include only inheritance relationships
relationships :
- inheritance
exclude :
# Exclude all elements from detail namespace
namespaces :
- clanguml::common::detail
# and also exclude ClassF
elements :
- clanguml::common::ClassF
有关此内容的更多详细信息,请参阅图表过滤器文档部分。
用于clang-uml
单元测试的内置测试用例可以在此处浏览。
该项目依赖于以下强大的工具:
如果您想为该项目做出贡献,请查看贡献指南。
Copyright 2021-present Bartek Kryza <[email protected]>
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.