Merge pull request #71 from bkryza/add-msvc-support
Add support for building with Microsoft Visual Studio
This commit is contained in:
@@ -1,5 +1,7 @@
|
|||||||
# CHANGELOG
|
# CHANGELOG
|
||||||
|
|
||||||
|
* Added support for building with Microsoft Visual Studio
|
||||||
|
|
||||||
### 0.3.0
|
### 0.3.0
|
||||||
* Added support for sequence diagrams with template code
|
* Added support for sequence diagrams with template code
|
||||||
|
|
||||||
|
|||||||
@@ -49,6 +49,11 @@ message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
|
|||||||
message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")
|
message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")
|
||||||
message(STATUS "LLVM library dir: ${LLVM_LIBRARY_DIR}")
|
message(STATUS "LLVM library dir: ${LLVM_LIBRARY_DIR}")
|
||||||
|
|
||||||
|
if(MSVC)
|
||||||
|
# LLVM_BUILD_LLVM_DYLIB is not available on Windows
|
||||||
|
set(LINK_LLVM_SHARED NO)
|
||||||
|
endif(MSVC)
|
||||||
|
|
||||||
if(LINK_LLVM_SHARED)
|
if(LINK_LLVM_SHARED)
|
||||||
set(LIBTOOLING_LIBS clang-cpp LLVM)
|
set(LIBTOOLING_LIBS clang-cpp LLVM)
|
||||||
else(LINK_LLVM_SHARED)
|
else(LINK_LLVM_SHARED)
|
||||||
@@ -59,6 +64,7 @@ else(LINK_LLVM_SHARED)
|
|||||||
clangDriver
|
clangDriver
|
||||||
clangParse
|
clangParse
|
||||||
clangSema
|
clangSema
|
||||||
|
clangSupport
|
||||||
clangAnalysis
|
clangAnalysis
|
||||||
clangAST
|
clangAST
|
||||||
clangBasic
|
clangBasic
|
||||||
@@ -78,8 +84,19 @@ else(LINK_LLVM_SHARED)
|
|||||||
LLVMBitReader
|
LLVMBitReader
|
||||||
LLVMCore
|
LLVMCore
|
||||||
LLVMSupport)
|
LLVMSupport)
|
||||||
|
if(MSVC)
|
||||||
|
list(APPEND LIBTOOLING_LIBS
|
||||||
|
LLVMWindowsDriver
|
||||||
|
LLVMWindowsManifest)
|
||||||
|
endif(MSVC)
|
||||||
endif(LINK_LLVM_SHARED)
|
endif(LINK_LLVM_SHARED)
|
||||||
|
|
||||||
|
if("${LIBTOOLING_LIBS}" STREQUAL "")
|
||||||
|
message(FATAL_ERROR "Failed to find LibTooling libraries!")
|
||||||
|
else()
|
||||||
|
message(STATUS "Found LibTooling libraries: ${LIBTOOLING_LIBS}")
|
||||||
|
endif()
|
||||||
|
|
||||||
#
|
#
|
||||||
# Setup threads library
|
# Setup threads library
|
||||||
#
|
#
|
||||||
@@ -100,12 +117,18 @@ if(PKG_CONFIG_FOUND)
|
|||||||
NAMES yaml-cpp
|
NAMES yaml-cpp
|
||||||
PATHS ${YAML_CPP_LIBRARIES} /usr/local/lib)
|
PATHS ${YAML_CPP_LIBRARIES} /usr/local/lib)
|
||||||
set(YAML_CPP_LIBRARY_DIR /usr/local/lib)
|
set(YAML_CPP_LIBRARY_DIR /usr/local/lib)
|
||||||
endif()
|
endif(PKG_CONFIG_FOUND)
|
||||||
else(APPLE)
|
elseif(MSVC)
|
||||||
|
set(YAML_CPP_LIBRARIES "yaml-cpp")
|
||||||
|
else()
|
||||||
find_package(yaml-cpp REQUIRED)
|
find_package(yaml-cpp REQUIRED)
|
||||||
endif(APPLE)
|
endif()
|
||||||
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -Wall -Wextra -std=c++17 -Wno-unused-parameter -Wno-unused-private-field")
|
if("${YAML_CPP_LIBRARIES}" STREQUAL "")
|
||||||
|
message(FATAL_ERROR "Failed to find yaml-cpp library!")
|
||||||
|
else()
|
||||||
|
message(STATUS "Found yaml-cpp libraries: ${YAML_CPP_LIBRARIES}")
|
||||||
|
endif()
|
||||||
|
|
||||||
link_directories(${LLVM_LIBRARY_DIR} ${YAML_CPP_LIBRARY_DIR})
|
link_directories(${LLVM_LIBRARY_DIR} ${YAML_CPP_LIBRARY_DIR})
|
||||||
|
|
||||||
@@ -129,7 +152,13 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
|||||||
OUTPUT_VARIABLE GCC_STDDEF_INCLUDE)
|
OUTPUT_VARIABLE GCC_STDDEF_INCLUDE)
|
||||||
message(STATUS "FOUND GCC STDDEF INCLUDE ${GCC_STDDEF_INCLUDE}")
|
message(STATUS "FOUND GCC STDDEF INCLUDE ${GCC_STDDEF_INCLUDE}")
|
||||||
include_directories(${GCC_STDDEF_INCLUDE})
|
include_directories(${GCC_STDDEF_INCLUDE})
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -Wall -Wextra -std=c++17 -Wno-unused-parameter -Wno-unused-private-field")
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I${GCC_STDDEF_INCLUDE}")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I${GCC_STDDEF_INCLUDE}")
|
||||||
|
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -Wall -Wextra -std=c++17 -Wno-unused-parameter -Wno-unused-private-field")
|
||||||
|
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DLLVM_FORCE_USE_OLD_TOOLCHAIN /W1 /std:c++17 /bigobj /wd4291 /wd4624 /wd4244")
|
||||||
|
set(LINK_OPTIONS "${LINK_OPTIONS} /NODEFAULTLIB:MSVCRT /NODEFAULTLIB:MSVCRTD")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
message(STATUS "Using CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}")
|
message(STATUS "Using CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}")
|
||||||
@@ -145,7 +174,6 @@ include_directories(${THIRDPARTY_HEADERS_DIR})
|
|||||||
include_directories(${PROJECT_SOURCE_DIR}/src/)
|
include_directories(${PROJECT_SOURCE_DIR}/src/)
|
||||||
include_directories(${PROJECT_BINARY_DIR}/src/version)
|
include_directories(${PROJECT_BINARY_DIR}/src/version)
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Generate source list dynamically
|
# Generate source list dynamically
|
||||||
#
|
#
|
||||||
@@ -153,19 +181,25 @@ file(GLOB_RECURSE SOURCES src/*.cc include/*.h)
|
|||||||
set(MAIN_SOURCE_FILE ${CMAKE_CURRENT_SOURCE_DIR}/src/main.cc)
|
set(MAIN_SOURCE_FILE ${CMAKE_CURRENT_SOURCE_DIR}/src/main.cc)
|
||||||
list(REMOVE_ITEM SOURCES ${MAIN_SOURCE_FILE})
|
list(REMOVE_ITEM SOURCES ${MAIN_SOURCE_FILE})
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Define library target for linking with test cases and output executable
|
# Define library target for linking with test cases and output executable
|
||||||
#
|
#
|
||||||
|
if(MSVC)
|
||||||
|
add_library(clang-umllib STATIC ${SOURCES})
|
||||||
|
set(MSVC_LIBRARIES "version")
|
||||||
|
else(MSVC)
|
||||||
add_library(clang-umllib OBJECT ${SOURCES})
|
add_library(clang-umllib OBJECT ${SOURCES})
|
||||||
|
endif(MSVC)
|
||||||
|
|
||||||
#
|
#
|
||||||
# Define the target executable clang-uml
|
# Define the target executable clang-uml
|
||||||
#
|
#
|
||||||
add_executable(clang-uml ${MAIN_SOURCE_FILE})
|
add_executable(clang-uml ${MAIN_SOURCE_FILE})
|
||||||
|
|
||||||
target_link_libraries(clang-uml
|
target_link_libraries(clang-uml
|
||||||
${YAML_CPP_LIBRARIES}
|
${YAML_CPP_LIBRARIES}
|
||||||
${LIBTOOLING_LIBS}
|
${LIBTOOLING_LIBS}
|
||||||
|
${MSVC_LIBRARIES}
|
||||||
clang-umllib
|
clang-umllib
|
||||||
Threads::Threads)
|
Threads::Threads)
|
||||||
|
|
||||||
|
|||||||
8
Makefile
8
Makefile
@@ -20,7 +20,15 @@
|
|||||||
|
|
||||||
.DEFAULT_GOAL := debug
|
.DEFAULT_GOAL := debug
|
||||||
|
|
||||||
|
OS_UNAME := $(shell uname -s)
|
||||||
|
|
||||||
|
ifeq ($(OS_UNAME),Linux)
|
||||||
NUMPROC ?= $(shell nproc)
|
NUMPROC ?= $(shell nproc)
|
||||||
|
else ifeq ($(OS_UNAME),Darwin)
|
||||||
|
NUMPROC ?= $(shell sysctl -n hw.logicalcpu)
|
||||||
|
else
|
||||||
|
NUMPROC ?= 1
|
||||||
|
endif
|
||||||
|
|
||||||
LLVM_VERSION ?=
|
LLVM_VERSION ?=
|
||||||
CMAKE_CXX_FLAGS ?=
|
CMAKE_CXX_FLAGS ?=
|
||||||
|
|||||||
71
README.md
71
README.md
@@ -9,7 +9,7 @@ YAML configuration files. The main idea behind the
|
|||||||
project is to easily maintain up-to-date diagrams within a code-base or document
|
project is to easily maintain up-to-date diagrams within a code-base or document
|
||||||
legacy code. The configuration file or files for `clang-uml` define the
|
legacy code. The configuration file or files for `clang-uml` define the
|
||||||
type and contents of each generated diagram.
|
type and contents of each generated diagram.
|
||||||
Currently the diagrams are generated in [PlantUML](https://plantuml.com) format.
|
Currently, the diagrams are generated in [PlantUML](https://plantuml.com) format.
|
||||||
|
|
||||||
`clang-uml` currently supports C++ up to version 17.
|
`clang-uml` currently supports C++ up to version 17.
|
||||||
|
|
||||||
@@ -46,71 +46,7 @@ More comprehensive documentation can be found [here](./docs/README.md).
|
|||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
### Distribution packages
|
Installation instructions for `Linux`, `macos` and `Windows` can be found [here](./docs/installation.md).
|
||||||
|
|
||||||
#### Ubuntu
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Currently supported Ubuntu versions are Focal, Jammy and Kinetic
|
|
||||||
sudo add-apt-repository ppa:bkryza/clang-uml
|
|
||||||
sudo apt update
|
|
||||||
sudo apt install clang-uml
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Fedora
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Fedora 36
|
|
||||||
wget https://github.com/bkryza/clang-uml/releases/download/0.3.0/clang-uml-0.3.0-1.fc36.x86_64.rpm
|
|
||||||
sudo dnf install ./clang-uml-0.3.0-1.fc36.x86_64.rpm
|
|
||||||
|
|
||||||
# Fedora 37
|
|
||||||
wget https://github.com/bkryza/clang-uml/releases/download/0.3.0/clang-uml-0.3.0-1.fc37.x86_64.rpm
|
|
||||||
sudo dnf install ./clang-uml-0.3.0-1.fc37.x86_64.rpm
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Conda
|
|
||||||
|
|
||||||
```bash
|
|
||||||
conda config --add channels conda-forge
|
|
||||||
conda config --set channel_priority strict
|
|
||||||
conda install -c bkryza/label/clang-uml clang-uml
|
|
||||||
```
|
|
||||||
|
|
||||||
### Building from source
|
|
||||||
|
|
||||||
First make sure that you have the following dependencies installed:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Ubuntu (clang version will vary depending on Ubuntu version)
|
|
||||||
apt install ccache cmake libyaml-cpp-dev clang-12 libclang-12-dev libclang-cpp12-dev
|
|
||||||
|
|
||||||
# macos
|
|
||||||
brew install ccache cmake llvm yaml-cpp
|
|
||||||
```
|
|
||||||
|
|
||||||
Then proceed with building the sources:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git clone https://github.com/bkryza/clang-uml
|
|
||||||
cd clang-uml
|
|
||||||
# Please note that top level Makefile is just a convenience wrapper for CMake
|
|
||||||
make release
|
|
||||||
release/clang-uml --help
|
|
||||||
|
|
||||||
# To build using a specific installed version of LLVM use:
|
|
||||||
LLVM_VERSION=14 make release
|
|
||||||
|
|
||||||
# Optionally
|
|
||||||
make install
|
|
||||||
# or
|
|
||||||
export PATH=$PATH:$PWD/release
|
|
||||||
|
|
||||||
# On macos, it is necessary to build clang-uml using the same llvm against which it is linked, e.g.
|
|
||||||
export CC=/usr/local/opt/llvm/bin/clang
|
|
||||||
export CCX=/usr/local/opt/llvm/bin/clang++
|
|
||||||
LLVM_VERSION=14 make release
|
|
||||||
```
|
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
@@ -128,6 +64,7 @@ Nowadays, this file can be generated rather easily using multiple methods:
|
|||||||
* For Boost-based projects
|
* For Boost-based projects
|
||||||
try [commands_to_compilation_database](https://github.com/tee3/commands_to_compilation_database)
|
try [commands_to_compilation_database](https://github.com/tee3/commands_to_compilation_database)
|
||||||
* For SCons, invoke `compilation_db` tool (requires SCons > 4.0.0)
|
* For SCons, invoke `compilation_db` tool (requires SCons > 4.0.0)
|
||||||
|
* For Microsoft Visual Studio projects try [Clang Power Tools](https://www.clangpowertools.com)
|
||||||
|
|
||||||
### Invocation
|
### Invocation
|
||||||
|
|
||||||
@@ -466,6 +403,8 @@ exclude:
|
|||||||
- clanguml::common::ClassF
|
- clanguml::common::ClassF
|
||||||
```
|
```
|
||||||
|
|
||||||
|
More details on this can be found in the [diagram filters](./docs/diagram_filters.md) documentation section.
|
||||||
|
|
||||||
### Test cases
|
### Test cases
|
||||||
|
|
||||||
The build-in test cases used for unit testing of the `clang-uml`, can be browsed [here](./docs/test_cases.md).
|
The build-in test cases used for unit testing of the `clang-uml`, can be browsed [here](./docs/test_cases.md).
|
||||||
|
|||||||
148
docs/installation.md
Normal file
148
docs/installation.md
Normal file
@@ -0,0 +1,148 @@
|
|||||||
|
# Installation
|
||||||
|
|
||||||
|
### Distribution packages
|
||||||
|
|
||||||
|
#### Ubuntu
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Currently supported Ubuntu versions are Focal, Jammy and Kinetic
|
||||||
|
sudo add-apt-repository ppa:bkryza/clang-uml
|
||||||
|
sudo apt update
|
||||||
|
sudo apt install clang-uml
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Fedora
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Fedora 36
|
||||||
|
wget https://github.com/bkryza/clang-uml/releases/download/0.3.0/clang-uml-0.3.0-1.fc36.x86_64.rpm
|
||||||
|
sudo dnf install ./clang-uml-0.3.0-1.fc36.x86_64.rpm
|
||||||
|
|
||||||
|
# Fedora 37
|
||||||
|
wget https://github.com/bkryza/clang-uml/releases/download/0.3.0/clang-uml-0.3.0-1.fc37.x86_64.rpm
|
||||||
|
sudo dnf install ./clang-uml-0.3.0-1.fc37.x86_64.rpm
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Conda
|
||||||
|
|
||||||
|
```bash
|
||||||
|
conda config --add channels conda-forge
|
||||||
|
conda config --set channel_priority strict
|
||||||
|
conda install -c bkryza/label/clang-uml clang-uml
|
||||||
|
```
|
||||||
|
|
||||||
|
### Building from source
|
||||||
|
|
||||||
|
#### Linux
|
||||||
|
First make sure that you have the following dependencies installed:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Ubuntu (clang version will vary depending on Ubuntu version)
|
||||||
|
apt install ccache cmake libyaml-cpp-dev clang-12 libclang-12-dev libclang-cpp12-dev
|
||||||
|
```
|
||||||
|
|
||||||
|
Then proceed with building the sources:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/bkryza/clang-uml
|
||||||
|
cd clang-uml
|
||||||
|
# Please note that top level Makefile is just a convenience wrapper for CMake
|
||||||
|
make release
|
||||||
|
release/clang-uml --help
|
||||||
|
|
||||||
|
# To build using a specific installed version of LLVM use:
|
||||||
|
LLVM_VERSION=14 make release
|
||||||
|
|
||||||
|
# Optionally
|
||||||
|
make install
|
||||||
|
# or
|
||||||
|
export PATH=$PATH:$PWD/release
|
||||||
|
```
|
||||||
|
|
||||||
|
#### macos
|
||||||
|
|
||||||
|
```bash
|
||||||
|
brew install ccache cmake llvm yaml-cpp
|
||||||
|
|
||||||
|
export CC=/usr/local/opt/llvm/bin/clang
|
||||||
|
export CCX=/usr/local/opt/llvm/bin/clang++
|
||||||
|
LLVM_VERSION=14 make release
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Windows
|
||||||
|
|
||||||
|
##### Visual Studio native build
|
||||||
|
|
||||||
|
These steps present how to build and use `clang-uml` natively using Visual Studio only.
|
||||||
|
|
||||||
|
First, install the following dependencies manually:
|
||||||
|
|
||||||
|
* [Python 3](https://www.python.org/downloads/windows/)
|
||||||
|
* [Git](https://git-scm.com/download/win)
|
||||||
|
* [CMake](https://cmake.org/download/)
|
||||||
|
* [Visual Studio](https://visualstudio.microsoft.com/vs/community/)
|
||||||
|
|
||||||
|
> All the following steps should be invoked in `Developer PowerShell for VS`.
|
||||||
|
|
||||||
|
Create installation directory for `clang-uml` and its dependencies:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# This is where clang-uml binary and its dependencies will be installed after build
|
||||||
|
# If you change this path, adapt all consecutive steps
|
||||||
|
mkdir C:\clang-uml
|
||||||
|
# This directory will be removed after build
|
||||||
|
mkdir C:\clang-uml-tmp
|
||||||
|
cd C:\clang-uml-tmp
|
||||||
|
```
|
||||||
|
|
||||||
|
Build and install `yaml-cpp`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/jbeder/yaml-cpp
|
||||||
|
cd yaml-cpp
|
||||||
|
git checkout yaml-cpp-0.7.0
|
||||||
|
cd ..
|
||||||
|
cmake -S .\yaml-cpp\ -B .\yaml-cpp-build\ -DCMAKE_INSTALL_PREFIX="C:\clang-uml" -Thost=x64
|
||||||
|
cd yaml-cpp-build
|
||||||
|
msbuild .\INSTALL.sln -maxcpucount /p:Configuration=Release
|
||||||
|
```
|
||||||
|
|
||||||
|
Build and install `LLVM`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pip install psutil
|
||||||
|
# Update the LLVM branch if necessary
|
||||||
|
git clone --branch llvmorg-15.0.6 --depth 1 https://github.com/llvm/llvm-project.git llvm
|
||||||
|
cmake -S .\llvm\llvm -B llvm-build -DLLVM_ENABLE_PROJECTS=clang -DCMAKE_INSTALL_PREFIX="C:\clang-uml" -DCMAKE_BUILD_TYPE=Release -DLLVM_TARGETS_TO_BUILD=X86 -Thost=x64
|
||||||
|
cd llvm-build
|
||||||
|
msbuild .\INSTALL.sln -maxcpucount /p:Configuration=Release
|
||||||
|
```
|
||||||
|
|
||||||
|
Build and install `clang-uml`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/bkryza/clang-uml
|
||||||
|
cmake -S .\clang-uml\ -B .\clang-uml-build\ -DCMAKE_INSTALL_PREFIX="C:\clang-uml" -DCMAKE_PREFIX_PATH="C:\clang-uml" -DBUILD_TESTS=OFF -Thost=x64
|
||||||
|
cd clang-uml-build
|
||||||
|
msbuild .\INSTALL.sln -maxcpucount /p:Configuration=Release
|
||||||
|
```
|
||||||
|
|
||||||
|
Check if `clang-uml` works:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd C:\clang-uml
|
||||||
|
bin\clang-uml.exe --version
|
||||||
|
```
|
||||||
|
It should produce something like:
|
||||||
|
```bash
|
||||||
|
clang-uml 0.3.0
|
||||||
|
Copyright (C) 2021-2023 Bartek Kryza <bkryza@gmail.com>
|
||||||
|
Built against LLVM/Clang libraries version: 15.0.6
|
||||||
|
Using LLVM/Clang libraries version: clang version 15.0.6 (https://github.com/llvm/llvm-project.git 088f33605d8a61ff519c580a71b1dd57d16a03f8)
|
||||||
|
```
|
||||||
|
|
||||||
|
Finally, remove the temporary build directory:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
rm -r C:\clang-uml-tmp
|
||||||
|
```
|
||||||
@@ -32,8 +32,6 @@ public:
|
|||||||
clanguml::common::id_t id() const noexcept { return id_; }
|
clanguml::common::id_t id() const noexcept { return id_; }
|
||||||
void set_id(clanguml::common::id_t id) { id_ = id; }
|
void set_id(clanguml::common::id_t id) { id_ = id; }
|
||||||
|
|
||||||
void set_id(id_t id);
|
|
||||||
|
|
||||||
void is_virtual(bool is_virtual);
|
void is_virtual(bool is_virtual);
|
||||||
bool is_virtual() const;
|
bool is_virtual() const;
|
||||||
|
|
||||||
|
|||||||
@@ -763,6 +763,7 @@ void translation_unit_visitor::process_class_children(
|
|||||||
|
|
||||||
// Static fields have to be processed by iterating over variable
|
// Static fields have to be processed by iterating over variable
|
||||||
// declarations
|
// declarations
|
||||||
|
#ifndef _MSC_VER
|
||||||
for (const auto *decl : cls->decls()) {
|
for (const auto *decl : cls->decls()) {
|
||||||
if (decl->getKind() == clang::Decl::Var) {
|
if (decl->getKind() == clang::Decl::Var) {
|
||||||
const clang::VarDecl *variable_declaration{
|
const clang::VarDecl *variable_declaration{
|
||||||
@@ -788,7 +789,7 @@ void translation_unit_visitor::process_class_children(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
if (cls->isCompleteDefinition())
|
if (cls->isCompleteDefinition())
|
||||||
for (const auto *friend_declaration : cls->friends()) {
|
for (const auto *friend_declaration : cls->friends()) {
|
||||||
if (friend_declaration != nullptr)
|
if (friend_declaration != nullptr)
|
||||||
@@ -1429,7 +1430,7 @@ std::unique_ptr<class_> translation_unit_visitor::
|
|||||||
template_instantiation.set_name(template_decl->getNameAsString());
|
template_instantiation.set_name(template_decl->getNameAsString());
|
||||||
template_instantiation.set_namespace(ns);
|
template_instantiation.set_namespace(ns);
|
||||||
template_instantiation.set_id(template_decl->getID() +
|
template_instantiation.set_id(template_decl->getID() +
|
||||||
static_cast<id_t>(
|
static_cast<common::id_t>(
|
||||||
std::hash<std::string>{}(full_template_specialization_name) >> 4U));
|
std::hash<std::string>{}(full_template_specialization_name) >> 4U));
|
||||||
|
|
||||||
build_template_instantiation_process_template_arguments(parent,
|
build_template_instantiation_process_template_arguments(parent,
|
||||||
|
|||||||
@@ -191,14 +191,18 @@ inja::json generator<C, D>::element_context(const E &e) const
|
|||||||
if (!e.file().empty()) {
|
if (!e.file().empty()) {
|
||||||
std::filesystem::path file{e.file()};
|
std::filesystem::path file{e.file()};
|
||||||
std::string relative_path = file.string();
|
std::string relative_path = file.string();
|
||||||
|
#if _MSC_VER
|
||||||
|
if (file.is_absolute() && ctx.contains("git"))
|
||||||
|
#else
|
||||||
if (file.is_absolute() && ctx.template contains("git"))
|
if (file.is_absolute() && ctx.template contains("git"))
|
||||||
|
#endif
|
||||||
relative_path =
|
relative_path =
|
||||||
std::filesystem::relative(file, ctx["git"]["toplevel"]);
|
std::filesystem::relative(file, ctx["git"]["toplevel"])
|
||||||
|
.string();
|
||||||
|
|
||||||
ctx["element"]["source"]["path"] = relative_path;
|
ctx["element"]["source"]["path"] = relative_path;
|
||||||
ctx["element"]["source"]["full_path"] = file.string();
|
ctx["element"]["source"]["full_path"] = file.string();
|
||||||
ctx["element"]["source"]["name"] = file.filename();
|
ctx["element"]["source"]["name"] = file.filename().string();
|
||||||
ctx["element"]["source"]["line"] = e.line();
|
ctx["element"]["source"]["line"] = e.line();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -184,12 +184,12 @@ tvl::value_t namespace_filter::match(
|
|||||||
auto namespace_starts_with_element_qualified_name =
|
auto namespace_starts_with_element_qualified_name =
|
||||||
nsit.starts_with(e.get_namespace());
|
nsit.starts_with(e.get_namespace());
|
||||||
|
|
||||||
auto result = element_full_name_starts_with_namespace |
|
auto result = element_full_name_starts_with_namespace ||
|
||||||
element_full_name_equals_pattern;
|
element_full_name_equals_pattern;
|
||||||
|
|
||||||
if (is_inclusive)
|
if (is_inclusive)
|
||||||
result =
|
result =
|
||||||
result | namespace_starts_with_element_qualified_name;
|
result || namespace_starts_with_element_qualified_name;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
});
|
});
|
||||||
@@ -391,9 +391,11 @@ tvl::value_t paths_filter::match(
|
|||||||
|
|
||||||
auto pp = p.fs_path(root_);
|
auto pp = p.fs_path(root_);
|
||||||
for (const auto &path : paths_) {
|
for (const auto &path : paths_) {
|
||||||
if (util::starts_with(pp, path))
|
if (pp.root_name().string() == path.root_name().string() &&
|
||||||
|
util::starts_with(pp, path)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,11 @@ namespace clanguml::common::model {
|
|||||||
enum class source_file_t { kDirectory, kHeader, kImplementation };
|
enum class source_file_t { kDirectory, kHeader, kImplementation };
|
||||||
|
|
||||||
struct fs_path_sep {
|
struct fs_path_sep {
|
||||||
|
#ifdef _WIN32
|
||||||
|
static constexpr std::string_view value = "\\";
|
||||||
|
#else
|
||||||
static constexpr std::string_view value = "/";
|
static constexpr std::string_view value = "/";
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
using filesystem_path = common::model::path<fs_path_sep>;
|
using filesystem_path = common::model::path<fs_path_sep>;
|
||||||
@@ -53,7 +57,7 @@ public:
|
|||||||
explicit source_file(const std::filesystem::path &p)
|
explicit source_file(const std::filesystem::path &p)
|
||||||
{
|
{
|
||||||
set_path({p.parent_path().string()});
|
set_path({p.parent_path().string()});
|
||||||
set_name(p.filename());
|
set_name(p.filename().string());
|
||||||
is_absolute_ = p.is_absolute();
|
is_absolute_ = p.is_absolute();
|
||||||
set_id(common::to_id(p));
|
set_id(common::to_id(p));
|
||||||
}
|
}
|
||||||
@@ -107,7 +111,7 @@ public:
|
|||||||
res /= name();
|
res /= name();
|
||||||
|
|
||||||
if (is_absolute_)
|
if (is_absolute_)
|
||||||
res = "/" / res;
|
res = fs_path_sep::value / res;
|
||||||
else
|
else
|
||||||
res = base / res;
|
res = base / res;
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ namespace clanguml::common::visitor {
|
|||||||
translation_unit_visitor::translation_unit_visitor(
|
translation_unit_visitor::translation_unit_visitor(
|
||||||
clang::SourceManager &sm, const clanguml::config::diagram &config)
|
clang::SourceManager &sm, const clanguml::config::diagram &config)
|
||||||
: source_manager_{sm}
|
: source_manager_{sm}
|
||||||
, config_{config}
|
|
||||||
{
|
{
|
||||||
if (config.comment_parser() == config::comment_parser_t::plain) {
|
if (config.comment_parser() == config::comment_parser_t::plain) {
|
||||||
comment_visitor_ =
|
comment_visitor_ =
|
||||||
|
|||||||
@@ -103,8 +103,6 @@ protected:
|
|||||||
private:
|
private:
|
||||||
clang::SourceManager &source_manager_;
|
clang::SourceManager &source_manager_;
|
||||||
|
|
||||||
const clanguml::config::diagram &config_;
|
|
||||||
|
|
||||||
std::unique_ptr<comment::comment_visitor> comment_visitor_;
|
std::unique_ptr<comment::comment_visitor> comment_visitor_;
|
||||||
};
|
};
|
||||||
} // namespace clanguml::common::visitor
|
} // namespace clanguml::common::visitor
|
||||||
|
|||||||
@@ -599,7 +599,8 @@ template <> struct convert<sequence_diagram> {
|
|||||||
|
|
||||||
// Ensure relative_to has a value
|
// Ensure relative_to has a value
|
||||||
if (!rhs.relative_to.has_value)
|
if (!rhs.relative_to.has_value)
|
||||||
rhs.relative_to.set(std::filesystem::current_path());
|
rhs.relative_to.set(
|
||||||
|
std::filesystem::current_path().lexically_normal());
|
||||||
|
|
||||||
rhs.initialize_type_aliases();
|
rhs.initialize_type_aliases();
|
||||||
|
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ decorator_toks decorator::tokenize(const std::string &label, std::string_view c)
|
|||||||
decorator_toks res;
|
decorator_toks res;
|
||||||
res.label = label;
|
res.label = label;
|
||||||
size_t pos{};
|
size_t pos{};
|
||||||
const auto *it = c.begin();
|
auto it = c.begin();
|
||||||
std::advance(it, label.size());
|
std::advance(it, label.size());
|
||||||
|
|
||||||
if (*it == ':') {
|
if (*it == ':') {
|
||||||
|
|||||||
@@ -24,11 +24,11 @@
|
|||||||
|
|
||||||
namespace clanguml::include_diagram::visitor {
|
namespace clanguml::include_diagram::visitor {
|
||||||
|
|
||||||
translation_unit_visitor::translation_unit_visitor(clang::SourceManager &sm,
|
translation_unit_visitor::translation_unit_visitor(
|
||||||
|
clang::SourceManager & /*sm*/,
|
||||||
clanguml::include_diagram::model::diagram &diagram,
|
clanguml::include_diagram::model::diagram &diagram,
|
||||||
const clanguml::config::include_diagram &config)
|
const clanguml::config::include_diagram &config)
|
||||||
: source_manager_{sm}
|
: diagram_{diagram}
|
||||||
, diagram_{diagram}
|
|
||||||
, config_{config}
|
, config_{config}
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -104,8 +104,6 @@ public:
|
|||||||
void finalize() { }
|
void finalize() { }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
clang::SourceManager &source_manager_;
|
|
||||||
|
|
||||||
// Reference to the output diagram model
|
// Reference to the output diagram model
|
||||||
clanguml::include_diagram::model::diagram &diagram_;
|
clanguml::include_diagram::model::diagram &diagram_;
|
||||||
|
|
||||||
|
|||||||
@@ -151,7 +151,7 @@ int main(int argc, const char *argv[])
|
|||||||
CLI::App app{"Clang-based PlantUML diagram generator for C++"};
|
CLI::App app{"Clang-based PlantUML diagram generator for C++"};
|
||||||
|
|
||||||
std::string config_path{".clang-uml"};
|
std::string config_path{".clang-uml"};
|
||||||
std::string compilation_database_dir{'.'};
|
std::string compilation_database_dir{};
|
||||||
std::vector<std::string> diagram_names{};
|
std::vector<std::string> diagram_names{};
|
||||||
std::optional<std::string> output_directory;
|
std::optional<std::string> output_directory;
|
||||||
unsigned int thread_count{0};
|
unsigned int thread_count{0};
|
||||||
@@ -245,6 +245,10 @@ int main(int argc, const char *argv[])
|
|||||||
|
|
||||||
LOG_INFO("Loaded clang-uml config from {}", config_path);
|
LOG_INFO("Loaded clang-uml config from {}", config_path);
|
||||||
|
|
||||||
|
if (!compilation_database_dir.empty()) {
|
||||||
|
config.compilation_database_dir.set(compilation_database_dir);
|
||||||
|
}
|
||||||
|
|
||||||
LOG_INFO("Loading compilation database from {} directory",
|
LOG_INFO("Loading compilation database from {} directory",
|
||||||
config.compilation_database_dir());
|
config.compilation_database_dir());
|
||||||
|
|
||||||
@@ -551,7 +555,7 @@ int add_config_diagram(clanguml::common::model::diagram_t type,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
YAML::Node doc = YAML::LoadFile(config_file);
|
YAML::Node doc = YAML::LoadFile(config_file.string());
|
||||||
|
|
||||||
for (YAML::const_iterator it = doc["diagrams"].begin();
|
for (YAML::const_iterator it = doc["diagrams"].begin();
|
||||||
it != doc["diagrams"].end(); ++it) {
|
it != doc["diagrams"].end(); ++it) {
|
||||||
|
|||||||
@@ -220,6 +220,7 @@ void translation_unit_visitor::process_class_children(
|
|||||||
|
|
||||||
// Static fields have to be processed by iterating over variable
|
// Static fields have to be processed by iterating over variable
|
||||||
// declarations
|
// declarations
|
||||||
|
#ifndef _MSC_VER
|
||||||
for (const auto *decl : cls.decls()) {
|
for (const auto *decl : cls.decls()) {
|
||||||
if (decl->getKind() == clang::Decl::Var) {
|
if (decl->getKind() == clang::Decl::Var) {
|
||||||
const clang::VarDecl *variable_declaration{
|
const clang::VarDecl *variable_declaration{
|
||||||
@@ -230,6 +231,7 @@ void translation_unit_visitor::process_class_children(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (cls.isCompleteDefinition())
|
if (cls.isCompleteDefinition())
|
||||||
for (const auto *friend_declaration : cls.friends()) {
|
for (const auto *friend_declaration : cls.friends()) {
|
||||||
|
|||||||
@@ -49,11 +49,16 @@ void setup_logging(int verbose)
|
|||||||
std::string get_process_output(const std::string &command)
|
std::string get_process_output(const std::string &command)
|
||||||
{
|
{
|
||||||
constexpr size_t kBufferSize{1024};
|
constexpr size_t kBufferSize{1024};
|
||||||
|
|
||||||
std::array<char, kBufferSize> buffer{};
|
std::array<char, kBufferSize> buffer{};
|
||||||
std::string result;
|
std::string result;
|
||||||
|
|
||||||
|
#if defined(__linux) || defined(__unix) || defined(__APPLE__)
|
||||||
std::unique_ptr<FILE, decltype(&pclose)> pipe(
|
std::unique_ptr<FILE, decltype(&pclose)> pipe(
|
||||||
popen(command.c_str(), "r"), pclose);
|
popen(command.c_str(), "r"), pclose);
|
||||||
|
#elif defined(_WIN32)
|
||||||
|
std::unique_ptr<FILE, decltype(&_pclose)> pipe(
|
||||||
|
_popen(command.c_str(), "r"), _pclose);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!pipe) {
|
if (!pipe) {
|
||||||
throw std::runtime_error("popen() failed!");
|
throw std::runtime_error("popen() failed!");
|
||||||
@@ -68,12 +73,25 @@ std::string get_process_output(const std::string &command)
|
|||||||
|
|
||||||
std::string get_env(const std::string &name)
|
std::string get_env(const std::string &name)
|
||||||
{
|
{
|
||||||
|
#if defined(__linux) || defined(__unix)
|
||||||
const char *value = std::getenv(name.c_str()); // NOLINT
|
const char *value = std::getenv(name.c_str()); // NOLINT
|
||||||
|
|
||||||
if (value == nullptr)
|
if (value == nullptr)
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
return std::string{value};
|
return std::string{value};
|
||||||
|
#elif defined(WINDOWS) || defined(_WIN32) || defined(WIN32)
|
||||||
|
static constexpr auto kMaxEnvLength = 2096U;
|
||||||
|
static char value[kMaxEnvLength];
|
||||||
|
const DWORD ret =
|
||||||
|
GetEnvironmentVariableA(name.c_str(), value, kMaxEnvLength);
|
||||||
|
if (ret == 0 || ret > kMaxEnvLength)
|
||||||
|
return {};
|
||||||
|
else
|
||||||
|
return value;
|
||||||
|
#else
|
||||||
|
return {};
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_git_repository()
|
bool is_git_repository()
|
||||||
@@ -83,13 +101,8 @@ bool is_git_repository()
|
|||||||
if (!env.empty())
|
if (!env.empty())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
#if defined(_WIN32) || defined(_WIN64)
|
|
||||||
return false;
|
|
||||||
#else
|
|
||||||
return contains(
|
return contains(
|
||||||
trim(get_process_output("git rev-parse --git-dir 2> /dev/null")),
|
trim(get_process_output("git rev-parse --git-dir")), ".git");
|
||||||
".git");
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string get_git_branch()
|
std::string get_git_branch()
|
||||||
|
|||||||
@@ -4,9 +4,15 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
|||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 17)
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
|
|
||||||
|
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||||
set(TEST_DISABLE_WARNINGS_DEBUG "-Wno-unused-parameter -Wno-unused-private-field -Wno-unused-variable -Wno-attributes -Wno-nonnull")
|
set(TEST_DISABLE_WARNINGS_DEBUG "-Wno-unused-parameter -Wno-unused-private-field -Wno-unused-variable -Wno-attributes -Wno-nonnull")
|
||||||
set(TEST_DISABLE_WARNINGS_RELEASE "${TEST_DISABLE_WARNINGS} -Wno-aggressive-loop-optimizations")
|
set(TEST_DISABLE_WARNINGS_RELEASE "${TEST_DISABLE_WARNINGS} -Wno-aggressive-loop-optimizations")
|
||||||
|
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||||
|
set(TEST_DISABLE_WARNINGS_DEBUG "-Wno-unused-parameter -Wno-unused-private-field -Wno-unused-variable -Wno-attributes -Wno-nonnull")
|
||||||
|
set(TEST_DISABLE_WARNINGS_RELEASE "${TEST_DISABLE_WARNINGS} -Wno-aggressive-loop-optimizations")
|
||||||
|
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W1 /std:c++17 /bigobj /wd4624")
|
||||||
|
endif()
|
||||||
|
|
||||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS} ${LIBCLANG_CXXFLAGS} ${TEST_DISABLE_WARNINGS_RELEASE}")
|
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS} ${LIBCLANG_CXXFLAGS} ${TEST_DISABLE_WARNINGS_RELEASE}")
|
||||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS} ${LIBCLANG_CXXFLAGS} ${TEST_DISABLE_WARNINGS_DEBUG}")
|
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS} ${LIBCLANG_CXXFLAGS} ${TEST_DISABLE_WARNINGS_DEBUG}")
|
||||||
@@ -28,6 +34,10 @@ set(CLANG_UML_TEST_LIBRARIES
|
|||||||
${LIBTOOLING_LIBS}
|
${LIBTOOLING_LIBS}
|
||||||
Threads::Threads)
|
Threads::Threads)
|
||||||
|
|
||||||
|
if(MSVC)
|
||||||
|
list(APPEND CLANG_UML_TEST_LIBRARIES "Version.lib")
|
||||||
|
endif(MSVC)
|
||||||
|
|
||||||
|
|
||||||
set(CLANG_UML_TEST_UTIL_SRC test_util.cc ${TEST_UTIL_SOURCES})
|
set(CLANG_UML_TEST_UTIL_SRC test_util.cc ${TEST_UTIL_SOURCES})
|
||||||
set(CLANG_UML_TEST_UTIL_HEADER catch.h)
|
set(CLANG_UML_TEST_UTIL_HEADER catch.h)
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef _MSC_VER
|
||||||
#include <experimental/propagate_const>
|
#include <experimental/propagate_const>
|
||||||
|
#endif
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include <array>
|
#include <array>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace clanguml {
|
namespace clanguml {
|
||||||
|
|||||||
2
thirdparty/glob/glob.hpp
vendored
2
thirdparty/glob/glob.hpp
vendored
@@ -177,7 +177,7 @@ static inline fs::path expand_tilde(fs::path path)
|
|||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
char *home;
|
char *home;
|
||||||
size_t sz;
|
size_t sz;
|
||||||
errno_t err = _dupenv_s(&home, &sz, "USERPROFILE");
|
[[maybe_unused]] errno_t err = _dupenv_s(&home, &sz, "USERPROFILE");
|
||||||
#else
|
#else
|
||||||
const char *home = std::getenv("HOME");
|
const char *home = std::getenv("HOME");
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user