Refactored cmake scripts and test cases compile database handling

This commit is contained in:
Bartek Kryza
2023-02-05 16:35:05 +01:00
parent cdb056a52b
commit 8b70bba0c0
11 changed files with 276 additions and 198 deletions

View File

@@ -3,17 +3,27 @@ cmake_minimum_required(VERSION 3.12)
# #
# Project name # Project name
# #
project(clang-uml) project(clang-uml C CXX)
# #
# CMake standard defines # CMake standard defines
# #
set(CMAKE_DISABLE_SOURCE_CHANGES ON)
set(CMAKE_DISABLE_IN_SOURCE_BUILD ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON) set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_VERBOSE_MAKEFILE OFF) set(CMAKE_VERBOSE_MAKEFILE OFF)
set(CMAKE_FIND_DEBUG_MODE OFF) set(CMAKE_FIND_DEBUG_MODE OFF)
#
# C++ setup
#
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
if(APPLE) if(APPLE)
set(CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES ${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES}) set(CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES
${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES})
endif(APPLE) endif(APPLE)
# #
@@ -22,41 +32,21 @@ endif(APPLE)
set(CLANG_UML_INSTALL_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/include) set(CLANG_UML_INSTALL_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/include)
set(CLANG_UML_INSTALL_BIN_DIR ${PROJECT_SOURCE_DIR}/bin) set(CLANG_UML_INSTALL_BIN_DIR ${PROJECT_SOURCE_DIR}/bin)
set(UML_HEADERS_DIR ${PROJECT_SOURCE_DIR}/src/uml) set(UML_HEADERS_DIR ${PROJECT_SOURCE_DIR}/src/uml)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
# #
# CMake build options # CMake build options
# #
option(LINK_LLVM_SHARED "Should LLVM be linked using shared libraries or statically" ON) option(LINK_LLVM_SHARED "Should LLVM be linked using shared libraries" ON)
set(LLVM_VERSION CACHE STRING "Path to custom llvm-config executable") set(LLVM_VERSION CACHE STRING "Path to custom llvm-config executable")
# #
# Setup version string # Setup version string
# #
find_package(Git) include(GitVersion)
setup_git_version()
if(NOT DEFINED GIT_VERSION) message(STATUS "clang-uml version: "
if(GIT_EXECUTABLE) "${GIT_VERSION_MAJOR}.${GIT_VERSION_MINOR}.${GIT_VERSION_PATCH}")
execute_process(
COMMAND ${GIT_EXECUTABLE} describe --tags --always --abbrev=7
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
OUTPUT_VARIABLE GIT_VERSION
RESULT_VARIABLE GIT_ERROR_CODE
OUTPUT_STRIP_TRAILING_WHITESPACE
)
endif(GIT_EXECUTABLE)
endif(NOT DEFINED GIT_VERSION)
if(NOT DEFINED GIT_VERSION)
set(GIT_VERSION "0.0.0-unknown")
endif(NOT DEFINED GIT_VERSION)
string(REGEX MATCH "^([0-9]+)\\.([0-9]+)\\.(.+)"
GIT_VERSION_MATCH ${GIT_VERSION})
set(GIT_VERSION_MAJOR ${CMAKE_MATCH_1})
set(GIT_VERSION_MINOR ${CMAKE_MATCH_2})
set(GIT_VERSION_PATCH ${CMAKE_MATCH_3})
message(STATUS "clang-uml version: ${GIT_VERSION_MAJOR}.${GIT_VERSION_MINOR}.${GIT_VERSION_PATCH}")
# #
# Setup LLVM # Setup LLVM
@@ -170,32 +160,6 @@ link_directories(${LLVM_LIBRARY_DIR} ${YAML_CPP_LIBRARY_DIR})
# #
set(THIRDPARTY_HEADERS_DIR ${PROJECT_SOURCE_DIR}/thirdparty/) set(THIRDPARTY_HEADERS_DIR ${PROJECT_SOURCE_DIR}/thirdparty/)
#
# Configure clang-uml executable version
#
file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/src/version)
configure_file(src/version.h.in ${PROJECT_BINARY_DIR}/src/version/version.h)
#
# Handle various compiler quirks
#
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
execute_process(COMMAND gcc --print-file-name=include
OUTPUT_STRIP_TRAILING_WHITESPACE
OUTPUT_VARIABLE GCC_STDDEF_INCLUDE)
message(STATUS "FOUND GCC STDDEF INCLUDE ${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}")
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()
message(STATUS "Using CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}")
# #
# Setup include directories # Setup include directories
# #
@@ -207,71 +171,7 @@ 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)
# add_subdirectory(src)
# Generate source list dynamically
#
file(GLOB_RECURSE SOURCES src/*.cc include/*.h)
set(MAIN_SOURCE_FILE ${CMAKE_CURRENT_SOURCE_DIR}/src/main.cc)
list(REMOVE_ITEM SOURCES ${MAIN_SOURCE_FILE})
#
# 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})
endif(MSVC)
#
# Define the target executable clang-uml
#
add_executable(clang-uml ${MAIN_SOURCE_FILE})
target_link_libraries(clang-uml
${YAML_CPP_LIBRARIES}
${LIBTOOLING_LIBS}
${MSVC_LIBRARIES}
clang-umllib
Threads::Threads)
target_compile_features(clang-uml PRIVATE cxx_std_17)
#
# Setup install options
#
include(GNUInstallDirs)
install(TARGETS clang-uml DESTINATION ${CMAKE_INSTALL_BINDIR})
install(FILES LICENSE.md DESTINATION ${CMAKE_INSTALL_DOCDIR})
install(FILES README.md DESTINATION ${CMAKE_INSTALL_DOCDIR})
#
# Setup installer
#
set(CPACK_PACKAGE_NAME "clang-uml")
set(CPACK_PACKAGE_VENDOR "Bartek Kryza <bkryza@gmail.com>")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "clang-uml - C++ UML diagram generator based on Clang")
set(CPACK_PACKAGE_VERSION "${GIT_VERSION}")
set(CPACK_PACKAGE_VERSION_MAJOR "${GIT_VERSION_MAJOR}")
set(CPACK_PACKAGE_VERSION_MINOR "${GIT_VERSION_MINOR}")
set(CPACK_PACKAGE_VERSION_PATCH "${GIT_VERSION_PATCH}")
set(CPACK_PACKAGE_INSTALL_DIRECTORY "clang-uml")
set(CPACK_RESOURCE_FILE_LICENSE ${CMAKE_CURRENT_SOURCE_DIR}/LICENSE.md)
if(MSVC)
set(CPACK_GENERATOR "NSIS")
set(CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL ON)
set(CPACK_NSIS_DISPLAY_NAME "clang-uml")
set(CPACK_NSIS_HELP_LINK "https://github.com/bkryza/clang-uml")
set(CPACK_NSIS_URL_INFO_ABOUT "https://github.com/bkryza/clang-uml")
set(CPACK_NSIS_CONTACT "Bartek Kryza <bkryza@gmail.com>")
set(CPACK_NSIS_MODIFY_PATH ON)
set(CPACK_SOURCE_GENERATOR "ZIP")
endif(MSVC)
include(CPack)
# #
# Enable testing via CTest # Enable testing via CTest

25
cmake/GitVersion.cmake Normal file
View File

@@ -0,0 +1,25 @@
find_package(Git)
function(setup_git_version)
if(NOT DEFINED GIT_VERSION)
if(GIT_EXECUTABLE)
execute_process(
COMMAND ${GIT_EXECUTABLE} describe --tags --always --abbrev=7
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
OUTPUT_VARIABLE GIT_VERSION
RESULT_VARIABLE GIT_ERROR_CODE
OUTPUT_STRIP_TRAILING_WHITESPACE
)
endif(GIT_EXECUTABLE)
endif(NOT DEFINED GIT_VERSION)
if(NOT DEFINED GIT_VERSION)
set(GIT_VERSION "0.0.0-unknown" PARENT_SCOPE)
endif(NOT DEFINED GIT_VERSION)
string(REGEX MATCH "^([0-9]+)\\.([0-9]+)\\.(.+)"
GIT_VERSION_MATCH ${GIT_VERSION})
set(GIT_VERSION_MAJOR ${CMAKE_MATCH_1} PARENT_SCOPE)
set(GIT_VERSION_MINOR ${CMAKE_MATCH_2} PARENT_SCOPE)
set(GIT_VERSION_PATCH ${CMAKE_MATCH_3} PARENT_SCOPE)
endfunction()

83
src/CMakeLists.txt Normal file
View File

@@ -0,0 +1,83 @@
#
# Configure clang-uml executable version
#
file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/src/version)
configure_file(${CMAKE_CURRENT_LIST_DIR}/version.h.in
${PROJECT_BINARY_DIR}/src/version/version.h)
#
# Generate source list dynamically
#
file(GLOB_RECURSE SOURCES ${CMAKE_CURRENT_LIST_DIR}/*.cc)
set(MAIN_SOURCE_FILE ${CMAKE_CURRENT_LIST_DIR}/main.cc)
list(REMOVE_ITEM SOURCES ${MAIN_SOURCE_FILE})
#
# 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})
endif(MSVC)
target_compile_options(clang-umllib PUBLIC
$<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:GNU>>:
-Werror -Wall -Wextra -Wno-unused-parameter -Wno-unused-private-field>
$<$<CXX_COMPILER_ID:MSVC>:
/W1 /std:c++17 /bigobj /wd4291 /wd4624 /wd4244 /NODEFAULTLIB:MSVCRT
/NODEFAULTLIB:MSVCRTD>)
target_compile_definitions(clang-umllib PUBLIC
$<$<CXX_COMPILER_ID:MSVC>:
-DLLVM_FORCE_USE_OLD_TOOLCHAIN>)
#
# Define the target executable clang-uml
#
add_executable(clang-uml ${MAIN_SOURCE_FILE})
target_link_libraries(clang-uml
${YAML_CPP_LIBRARIES}
${LIBTOOLING_LIBS}
${MSVC_LIBRARIES}
clang-umllib
Threads::Threads)
#
# Setup install options
#
include(GNUInstallDirs)
install(TARGETS clang-uml DESTINATION ${CMAKE_INSTALL_BINDIR})
install(FILES LICENSE.md DESTINATION ${CMAKE_INSTALL_DOCDIR})
install(FILES README.md DESTINATION ${CMAKE_INSTALL_DOCDIR})
install(FILES AUTHORS.md DESTINATION ${CMAKE_INSTALL_DOCDIR})
install(FILES CHANGELOG.md DESTINATION ${CMAKE_INSTALL_DOCDIR})
#
# Setup installer
#
set(CPACK_PACKAGE_NAME "clang-uml")
set(CPACK_PACKAGE_VENDOR "Bartek Kryza <bkryza@gmail.com>")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY
"clang-uml - C++ UML diagram generator based on Clang")
set(CPACK_PACKAGE_VERSION "${GIT_VERSION}")
set(CPACK_PACKAGE_VERSION_MAJOR "${GIT_VERSION_MAJOR}")
set(CPACK_PACKAGE_VERSION_MINOR "${GIT_VERSION_MINOR}")
set(CPACK_PACKAGE_VERSION_PATCH "${GIT_VERSION_PATCH}")
set(CPACK_PACKAGE_INSTALL_DIRECTORY "clang-uml")
set(CPACK_RESOURCE_FILE_LICENSE ${PROJECT_SOURCE_DIR}/LICENSE.md)
if(MSVC)
set(CPACK_GENERATOR "NSIS")
set(CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL ON)
set(CPACK_NSIS_DISPLAY_NAME "clang-uml")
set(CPACK_NSIS_HELP_LINK "https://github.com/bkryza/clang-uml")
set(CPACK_NSIS_URL_INFO_ABOUT "https://github.com/bkryza/clang-uml")
set(CPACK_NSIS_CONTACT "Bartek Kryza <bkryza@gmail.com>")
set(CPACK_NSIS_MODIFY_PATH ON)
set(CPACK_SOURCE_GENERATOR "ZIP")
endif(MSVC)
include(CPack)

View File

@@ -1,26 +1,13 @@
cmake_minimum_required(VERSION 3.12)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
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_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_DEBUG "${CMAKE_CXX_FLAGS} ${LIBCLANG_CXXFLAGS} ${TEST_DISABLE_WARNINGS_DEBUG}")
if(APPLE) if(APPLE)
# Without this, clang-uml test cases fail with error saying that clang cannot find stdarg.h # Without this, clang-uml test cases fail with error saying that
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -I${LLVM_LIBRARY_DIR}/clang/${LLVM_PACKAGE_VERSION}/include") # clang cannot find stdarg.h
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -I${LLVM_LIBRARY_DIR}/clang/${LLVM_PACKAGE_VERSION}/include") set(CMAKE_CXX_FLAGS_RELEASE
"${CMAKE_CXX_FLAGS_RELEASE}
-I${LLVM_LIBRARY_DIR}/clang/${LLVM_PACKAGE_VERSION}/include")
set(CMAKE_CXX_FLAGS_DEBUG
"${CMAKE_CXX_FLAGS_DEBUG}
-I${LLVM_LIBRARY_DIR}/clang/${LLVM_PACKAGE_VERSION}/include")
endif(APPLE) endif(APPLE)
file(GLOB_RECURSE TEST_CASE_SOURCES t*/*.cc) file(GLOB_RECURSE TEST_CASE_SOURCES t*/*.cc)
@@ -37,55 +24,33 @@ if(MSVC)
list(APPEND CLANG_UML_TEST_LIBRARIES "Version.lib") list(APPEND CLANG_UML_TEST_LIBRARIES "Version.lib")
endif(MSVC) endif(MSVC)
set(TEST_CASES
test_util
test_model
test_cases
test_decorator_parser
test_config
test_filters
test_thread_pool_executor)
set(CLANG_UML_TEST_UTIL_SRC test_util.cc ${TEST_UTIL_SOURCES}) foreach(TEST_CASE_NAME ${TEST_CASES})
set(CLANG_UML_TEST_UTIL_HEADER catch.h) add_executable(${TEST_CASE_NAME}
${TEST_CASE_NAME}.cc catch.h)
set(CLANG_UML_TEST_MODEL_SRC test_model.cc ${TEST_MODEL_SOURCES}) target_compile_options(${TEST_CASE_NAME} PRIVATE
set(CLANG_UML_TEST_MODEL_HEADER catch.h) $<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:GNU>>:
-Wno-unused-parameter -Wno-unused-private-field -Wno-unused-variable
set(CLANG_UML_TEST_CASES_SRC test_cases.cc ${TEST_CASE_SOURCES}) -Wno-attributes -Wno-nonnull>
set(CLANG_UML_TEST_CASES_HEADER catch.h) $<$<CXX_COMPILER_ID:MSVC>:
/W1 /std:c++17 /bigobj /wd4624>)
set(CLANG_UML_TEST_DECORATOR_PARSER_SRC test_decorator_parser.cc ${TEST_UTIL_SOURCES}) target_link_libraries(${TEST_CASE_NAME} PRIVATE ${CLANG_UML_TEST_LIBRARIES})
set(CLANG_UML_TEST_DECORATOR_PARSER_HEADER catch.h) endforeach()
set(CLANG_UML_TEST_CONFIG_SRC test_config.cc ${TEST_UTIL_SOURCES})
set(CLANG_UML_TEST_CONFIG_HEADER catch.h)
set(CLANG_UML_TEST_FILTERS_SRC test_filters.cc ${TEST_FILTERS_SOURCES})
set(CLANG_UML_TEST_FILTERS_HEADER catch.h)
set(CLANG_UML_TEST_THREAD_POOL_EXECUTOR_SRC test_thread_pool_executor.cc)
set(CLANG_UML_TEST_THREAD_POOL_EXECUTOR_HEADER catch.h)
add_executable(test_util ${CLANG_UML_TEST_UTIL_SRC} ${CLANG_UML_TEST_UTIL_HEADER})
target_link_libraries(test_util PRIVATE ${CLANG_UML_TEST_LIBRARIES})
add_executable(test_model ${CLANG_UML_TEST_MODEL_SRC} ${CLANG_UML_TEST_MODEL_HEADER})
target_link_libraries(test_model PRIVATE ${CLANG_UML_TEST_LIBRARIES})
add_executable(test_decorator_parser ${CLANG_UML_TEST_DECORATOR_PARSER_SRC} ${CLANG_UML_TEST_DECORATOR_PARSER_HEADER})
target_link_libraries(test_decorator_parser PRIVATE ${CLANG_UML_TEST_LIBRARIES})
add_executable(test_config ${CLANG_UML_TEST_CONFIG_SRC} ${CLANG_UML_TEST_CONFIG_HEADER})
target_link_libraries(test_config PRIVATE ${CLANG_UML_TEST_LIBRARIES})
add_executable(test_filters ${CLANG_UML_TEST_FILTERS_SRC} ${CLANG_UML_TEST_FILTERS_HEADER})
target_link_libraries(test_filters PRIVATE ${CLANG_UML_TEST_LIBRARIES})
add_executable(test_thread_pool_executor ${CLANG_UML_TEST_THREAD_POOL_EXECUTOR_SRC} ${CLANG_UML_TEST_THREAD_POOL_EXECUTOR_HEADER})
target_link_libraries(test_thread_pool_executor PRIVATE ${CLANG_UML_TEST_LIBRARIES})
add_executable(test_cases ${CLANG_UML_TEST_CASES_SRC} ${CLANG_UML_TEST_CASES_HEADER})
target_link_libraries(test_cases PRIVATE ${CLANG_UML_TEST_LIBRARIES})
foreach(TEST_CASE_CONFIG ${TEST_CASE_CONFIGS}) foreach(TEST_CASE_CONFIG ${TEST_CASE_CONFIGS})
file(RELATIVE_PATH file(RELATIVE_PATH
TEST_CASE_CONFIG_RELATIVE TEST_CASE_CONFIG_RELATIVE
${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}
${TEST_CASE_CONFIG}) ${TEST_CASE_CONFIG})
message(${TEST_CASE_CONFIG_RELATIVE}) message(DEBUG ${TEST_CASE_CONFIG_RELATIVE})
configure_file( configure_file(
${TEST_CASE_CONFIG_RELATIVE} ${TEST_CASE_CONFIG_RELATIVE}
${TEST_CASE_CONFIG_RELATIVE} ${TEST_CASE_CONFIG_RELATIVE}
@@ -97,17 +62,13 @@ foreach(TEST_CONFIG_YML ${TEST_CONFIG_YMLS})
TEST_CONFIG_YML_RELATIVE TEST_CONFIG_YML_RELATIVE
${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}
${TEST_CONFIG_YML}) ${TEST_CONFIG_YML})
message(${TEST_CONFIG_YML_RELATIVE}) message(DEBUG ${TEST_CONFIG_YML_RELATIVE})
configure_file( configure_file(
${TEST_CONFIG_YML_RELATIVE} ${TEST_CONFIG_YML_RELATIVE}
${TEST_CONFIG_YML_RELATIVE} ${TEST_CONFIG_YML_RELATIVE}
COPYONLY) COPYONLY)
endforeach() endforeach()
add_test(NAME test_util COMMAND test_util) foreach(TEST_CASE_NAME ${TEST_CASES})
add_test(NAME test_decorator_parser COMMAND test_decorator_parser) add_test(NAME ${TEST_CASE_NAME} COMMAND ${TEST_CASE_NAME})
add_test(NAME test_config COMMAND test_config) endforeach()
add_test(NAME test_model COMMAND test_model)
add_test(NAME test_thread_pool_executor COMMAND test_thread_pool_executor)
add_test(NAME test_cases COMMAND test_cases)
add_test(NAME test_filters COMMAND test_filters)

View File

@@ -18,7 +18,7 @@
TEST_CASE("t00018", "[test-case][class]") TEST_CASE("t00018", "[test-case][class]")
{ {
auto [config, db] = load_config("t00018"); auto [config, db] = load_config("t00018", {"t00018.cc", "t00018_impl.cc"});
auto diagram = config.diagrams["t00018_class"]; auto diagram = config.diagrams["t00018_class"];

View File

@@ -18,7 +18,8 @@
TEST_CASE("t00048", "[test-case][class]") TEST_CASE("t00048", "[test-case][class]")
{ {
auto [config, db] = load_config("t00048"); auto [config, db] =
load_config("t00048", {"t00048.cc", "a_t00048.cc", "b_t00048.cc"});
auto diagram = config.diagrams["t00048_class"]; auto diagram = config.diagrams["t00048_class"];

View File

@@ -18,7 +18,8 @@
TEST_CASE("t20014", "[test-case][sequence]") TEST_CASE("t20014", "[test-case][sequence]")
{ {
auto [config, db] = load_config("t20014"); auto [config, db] = load_config(
"t20014", {"t20014.cc", "t20014_a.cc", "t20014_b.cc", "t20014_c.cc"});
auto diagram = config.diagrams["t20014_sequence"]; auto diagram = config.diagrams["t20014_sequence"];

View File

@@ -18,7 +18,7 @@
TEST_CASE("t40001", "[test-case][include]") TEST_CASE("t40001", "[test-case][include]")
{ {
auto [config, db] = load_config("t40001"); auto [config, db] = load_config("t40001", {"src/t40001.cc"});
auto diagram = config.diagrams["t40001_include"]; auto diagram = config.diagrams["t40001_include"];

View File

@@ -18,7 +18,8 @@
TEST_CASE("t40002", "[test-case][include]") TEST_CASE("t40002", "[test-case][include]")
{ {
auto [config, db] = load_config("t40002"); auto [config, db] = load_config(
"t40002", {"src/t40002.cc", "src/lib1/lib1.cc", "src/lib2/lib2.cc"});
auto diagram = config.diagrams["t40002_include"]; auto diagram = config.diagrams["t40002_include"];

View File

@@ -18,7 +18,8 @@
TEST_CASE("t40003", "[test-case][include]") TEST_CASE("t40003", "[test-case][include]")
{ {
auto [config, db] = load_config("t40003"); auto [config, db] = load_config(
"t40003", {"src/dependants/t1.cc", "src/dependencies/t2.cc"});
auto diagram = config.diagrams["t40003_include"]; auto diagram = config.diagrams["t40003_include"];

View File

@@ -18,9 +18,66 @@
#include "test_cases.h" #include "test_cases.h"
#include "common/generators/plantuml/generator.h" #include "common/generators/plantuml/generator.h"
#include "util/util.h"
#include <clang/Tooling/CompilationDatabase.h>
#include <spdlog/spdlog.h> #include <spdlog/spdlog.h>
#include <algorithm>
namespace clanguml::tests::util {
class TestCaseCompilationDatabase : public clang::tooling::CompilationDatabase {
public:
TestCaseCompilationDatabase(clang::tooling::CompileCommand &&cc)
: compile_commands_{{std::move(cc)}}
{
}
TestCaseCompilationDatabase(
std::vector<clang::tooling::CompileCommand> &&ccs)
: compile_commands_{std::move(ccs)}
{
}
virtual ~TestCaseCompilationDatabase() { }
static std::unique_ptr<CompilationDatabase> fromCompileCommand(
clang::tooling::CompileCommand &&cc)
{
return std::make_unique<TestCaseCompilationDatabase>(std::move(cc));
}
std::vector<clang::tooling::CompileCommand> getCompileCommands(
clang::StringRef FilePath) const override
{
std::vector<clang::tooling::CompileCommand> ccs;
std::copy_if(begin(compile_commands_), end(compile_commands_),
std::back_inserter(ccs), [&](const auto &cc) {
return clanguml::util::starts_with(cc.Filename, FilePath.str());
});
return ccs;
}
std::vector<std::string> getAllFiles() const override
{
std::vector<std::string> files;
std::transform(begin(compile_commands_), end(compile_commands_),
std::back_inserter(files),
[](const auto &cc) { return cc.Filename; });
return files;
}
std::vector<clang::tooling::CompileCommand>
getAllCompileCommands() const override
{
return compile_commands_;
}
private:
std::vector<clang::tooling::CompileCommand> compile_commands_;
};
}
void inject_diagram_options(std::shared_ptr<clanguml::config::diagram> diagram) void inject_diagram_options(std::shared_ptr<clanguml::config::diagram> diagram)
{ {
// Inject links config to all test cases // Inject links config to all test cases
@@ -33,8 +90,10 @@ void inject_diagram_options(std::shared_ptr<clanguml::config::diagram> diagram)
std::pair<clanguml::config::config, std::pair<clanguml::config::config,
std::unique_ptr<clang::tooling::CompilationDatabase>> std::unique_ptr<clang::tooling::CompilationDatabase>>
load_config(const std::string &test_name) load_config(const std::string &test_name, const std::vector<std::string> &tus)
{ {
using std::filesystem::path;
auto config = clanguml::config::load(test_name + "/.clang-uml", true); auto config = clanguml::config::load(test_name + "/.clang-uml", true);
std::string err{}; std::string err{};
@@ -42,12 +101,58 @@ load_config(const std::string &test_name)
clang::tooling::CompilationDatabase::autoDetectFromDirectory( clang::tooling::CompilationDatabase::autoDetectFromDirectory(
config.compilation_database_dir(), err); config.compilation_database_dir(), err);
for (const auto &cc : compilation_database->getAllCompileCommands()) {
if (clanguml::util::ends_with(
cc.Filename, std::string{"/test_cases.cc"})) {
// Create artificial CompileCommand for each source file of a
// specific test case, based on command line options for the
// test_cases.cc translation_unit, which imports specific test
// cases using #include directive
std::vector<clang::tooling::CompileCommand> compile_commands;
for (const auto &tu : tus) {
auto test_case_path =
path{cc.Filename}.parent_path() / test_name / path(tu);
auto test_case_command = cc;
auto &cline = test_case_command.CommandLine;
// We don't want to worry about all minor warnings in test
// cases during Clang parsing
cline.erase(std::remove(cline.begin(), cline.end(), "-Wall"),
cline.end());
cline.erase(std::remove(cline.begin(), cline.end(), "-Wextra"),
cline.end());
cline.erase(std::remove(cline.begin(), cline.end(), "-Werror"),
cline.end());
test_case_command.CommandLine.pop_back();
test_case_command.CommandLine.push_back(
test_case_path.string());
test_case_command.Filename = test_case_path.string();
compile_commands.push_back(std::move(test_case_command));
}
auto test_case_db = std::make_unique<
clanguml::tests::util::TestCaseCompilationDatabase>(
std::move(compile_commands));
return std::make_pair(std::move(config), std::move(test_case_db));
}
}
if (!err.empty()) if (!err.empty())
throw std::runtime_error{err}; throw std::runtime_error{err};
return std::make_pair(std::move(config), std::move(compilation_database)); return std::make_pair(std::move(config), std::move(compilation_database));
} }
std::pair<clanguml::config::config,
std::unique_ptr<clang::tooling::CompilationDatabase>>
load_config(const std::string &test_name)
{
return load_config(test_name, {fmt::format("{}.cc", test_name)});
}
std::unique_ptr<clanguml::sequence_diagram::model::diagram> std::unique_ptr<clanguml::sequence_diagram::model::diagram>
generate_sequence_diagram(clang::tooling::CompilationDatabase &db, generate_sequence_diagram(clang::tooling::CompilationDatabase &db,
std::shared_ptr<clanguml::config::diagram> diagram) std::shared_ptr<clanguml::config::diagram> diagram)