9.1 KiB
Common diagram generation options
- Overall configuration file structure
- Diagram titles
- Translation unit glob patterns
- Custom directives
- Adding debug information in the generated diagrams
- Resolving include path and compiler flags issues
Overall configuration file structure
By default, clang-uml
will look for file .clang-uml
in the project's
directory and read all diagram definitions configuration from it. The file must
be specified in YAML and it's overall structure is as follows:
# Common options for all diagrams
# ...
# Diagram definitions
diagrams:
first_diagram_name:
type: class|sequence|package|include
# Diagram specific options
# ...
second_diagram_name:
type: class|sequence|package|include
# Diagram specific options
# ...
# More diagrams
# ...
The top level common options are inherited by specific diagrams, if the option is applicable to them and they themselves do not override this option.
For detailed reference of all configuration options see here.
Effective configuration, including default values can be printed out in YAML format using the following option:
clang-uml --dump-config
Diagram titles
Each type of diagram can have a title
property, which will be generated in the
diagram using directives specific to a given diagram generator, for instance:
diagrams:
diagram1:
type: class
title: Some explanatory diagram title
Translation unit glob patterns
One of the key options of the diagram configuration is the list of translation units, which should be parsed to get all necessary information for a diagram.
The syntax is simple and based on glob patterns, which can be added to the configuration file as follows:
glob:
- src/dir1/*.cc
- src/dir3/*.cc
- r: ".*test.*cpp$"
This is a simplified glob
definition, which assumes that are patterns are
inclusive, i.e. only matching files will be processed. It is also possible
to specify exclusive patterns, in a more elaborate glob
definition:
glob:
include:
- src/**/*.cc
exclude:
- src/main.cc
which will include all .cc
files in src
directory recursively, but will
exclude src/main.cc
. If the glob
definition includes only exclude
, than
then exclusion pattern will be matched against all files in compilation
database.
The glob patterns only need to match the translation units, which are also in
the compile_commands.json
file, i.e. any files that match the glob patterns,
but are not in compile_commands.json
will be ignored. In case the glob
pattern set does not match any translation units an error will be printed on
the standard output.
For more advanced control over the glob
pattern, instead of simple glob style
pattern, a full regular expression can be provided as an object with a single
key r
. In such case, the pattern will not be checked against file system at
all but will only filter the compile commands database entries. This can
significantly improve performance on projects with tens of thousands of
translation units.
For small projects, the glob
property can be omitted, which will result in
clang-uml
parsing all translation units from compile_commands.json
for
the diagram. However, for large projects, constraining the number of translation
units for each diagram to minimum necessary to discover all necessary diagram
elements will significantly decrease the diagram generation times.
Custom directives
In case it's necessary to add some custom PlantUML or MermaidJS declarations
before or after the generated diagram content, it can be achieved using
the plantuml
or mermaid
configuration properties, for instance for PlantUML:
plantuml:
before:
- left to right direction
after:
- note left of {{ alias("ns1::ns2::MyClass") }} This is my class.
or for MermaidJS:
mermaid:
before:
- direction LR
after:
- note for {{ alias("ns1::ns2::MyClass") }} "This is my class."
These directives are useful for instance for adding notes to elements in the diagrams or customizing diagram layout and style.
Please note that when referring to diagram elements in PlantUML or MermaidJS
directives, they must be added using Jinja templates alias
command as in the
example above.
More options can be found in the official docs for each respective generator:
Adding debug information in the generated diagrams
Sometimes it is useful for debugging issues with the diagrams to have information on the exact source location, from which given declaration or call expression was derived. By adding option:
debug_mode: true
the generated PlantUML diagram will contain comments before each line containing the source location of the specific diagram element.
Resolving include path and compiler flags issues
Due to the fact, that a project can be compiled with different compilers
and toolchains, the system paths and compilation flags detected by the Clang
version linked to your clang-uml
installation might differ from the ones
actually used to compile your project.
This is often an issue on macOS, when
clang-uml
uses Homebrew version of LLVM and a project was built using system Apple Clang.
Typically, this results in error messages on the console during diagram generation, such as:
... fatal: 'stddef.h' file not found
or
... warning: implicit conversion from 'int' to 'float' changes value from 2147483647 to 2147483648 [-Wimplicit-const-int-float-conversion]
These errors can be overcome, by ensuring that the Clang parser has the correct
include paths to analyse your code base on the given platform. clang-uml
provides several mechanisms to resolve this issue:
Use '--query-driver' command line option
This option is not available on Windows.
Providing this option on the clang-uml
command line will result in clang-uml
executing the specified compiler with the following command, e.g.:
/usr/bin/c++ -E -v -x c /dev/null 2>&1
and extracting from the output the target and system include paths, which are
then injected to each entry of the compilation database. For instance, on my
system, when generating diagrams for an embedded project and providing
arm-none-eabi-gcc
as driver:
clang-uml --query-driver arm-none-eabi-gcc
the following options are appended to each command line after argv[0]
of the
command:
--target=arm-none-eabi -isystem /usr/lib/gcc/arm-none-eabi/10.3.1/include -isystem /usr/lib/gcc/arm-none-eabi/10.3.1/include-fixed -isystem /usr/lib/gcc/arm-none-eabi/10.3.1/../../../arm-none-eabi/include
If you want to include the system headers reported by the compiler specified
already as first argument of each compile command in your
compile_commands.json
, you can simply invoke clang-uml
as:
clang-uml --query-driver .
however please make sure that the compile_commands.json
contains a command,
which is safe to execute.
Manually add and remove compile flags from the compilation database
If the system paths extracted from the compiler are not sufficient to resolve
include paths issues, it is possible to manually adjust the compilation
flags by providing add_compile_flags
and remove_compile_flags
in the
configuration file, or providing --add-compile-flag
and --remove-compile-flag
on the clang-uml
command line.
For instance:
add_compile_flags:
- -I/opt/my_toolchain/include
remove_compile_flags:
- -I/usr/include
remove_compile_flags
also accepts regular expression, so a single entry can
remove a whole set of flags, e.g.:
remove_compile_flags:
- r: "-m.*"
These options can be also passed on the command line, for instance:
clang-uml --add-compile-flag -I/opt/my_toolchain/include \
--remove-compile-flag -I/usr/include ...
Using 'CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES'
Yet another option, for CMake based projects, is to use the following CMake option:
set(CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES ${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES})
Nix wrapper
On NixOS or when using nix
, clang-uml
uses a wrapper script,
which builds and exports CPATH
and CPLUS_INCLUDE_PATH
environment variables before running clang-uml
, which contain valid
system header Clang paths for the current Nix environment.
If you want to use an unwrapped version, the clang-uml-unwrapped
binary
can be called the same way as clang-uml
.