From 8b70bba0c07f8ecf5e042e4ce2d887599b08aa2c Mon Sep 17 00:00:00 2001 From: Bartek Kryza Date: Sun, 5 Feb 2023 16:35:05 +0100 Subject: [PATCH] Refactored cmake scripts and test cases compile database handling --- CMakeLists.txt | 140 ++++++--------------------------------- cmake/GitVersion.cmake | 25 +++++++ src/CMakeLists.txt | 83 +++++++++++++++++++++++ tests/CMakeLists.txt | 103 +++++++++------------------- tests/t00018/test_case.h | 2 +- tests/t00048/test_case.h | 3 +- tests/t20014/test_case.h | 3 +- tests/t40001/test_case.h | 2 +- tests/t40002/test_case.h | 3 +- tests/t40003/test_case.h | 3 +- tests/test_cases.cc | 107 +++++++++++++++++++++++++++++- 11 files changed, 276 insertions(+), 198 deletions(-) create mode 100644 cmake/GitVersion.cmake create mode 100644 src/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index ce5e66e5..15bf1602 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,17 +3,27 @@ cmake_minimum_required(VERSION 3.12) # # Project name # -project(clang-uml) +project(clang-uml C CXX) # # CMake standard defines # +set(CMAKE_DISABLE_SOURCE_CHANGES ON) +set(CMAKE_DISABLE_IN_SOURCE_BUILD ON) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) -set(CMAKE_CXX_STANDARD 17) set(CMAKE_VERBOSE_MAKEFILE 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) - set(CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES ${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES}) + set(CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES + ${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES}) endif(APPLE) # @@ -22,41 +32,21 @@ endif(APPLE) set(CLANG_UML_INSTALL_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/include) set(CLANG_UML_INSTALL_BIN_DIR ${PROJECT_SOURCE_DIR}/bin) set(UML_HEADERS_DIR ${PROJECT_SOURCE_DIR}/src/uml) +list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") # # 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") # # Setup version string # -find_package(Git) - -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") -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}") +include(GitVersion) +setup_git_version() +message(STATUS "clang-uml version: " + "${GIT_VERSION_MAJOR}.${GIT_VERSION_MINOR}.${GIT_VERSION_PATCH}") # # Setup LLVM @@ -170,32 +160,6 @@ link_directories(${LLVM_LIBRARY_DIR} ${YAML_CPP_LIBRARY_DIR}) # 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 # @@ -207,71 +171,7 @@ include_directories(${THIRDPARTY_HEADERS_DIR}) include_directories(${PROJECT_SOURCE_DIR}/src/) include_directories(${PROJECT_BINARY_DIR}/src/version) -# -# 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 ") -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 ") - set(CPACK_NSIS_MODIFY_PATH ON) - set(CPACK_SOURCE_GENERATOR "ZIP") -endif(MSVC) - -include(CPack) +add_subdirectory(src) # # Enable testing via CTest diff --git a/cmake/GitVersion.cmake b/cmake/GitVersion.cmake new file mode 100644 index 00000000..690c695b --- /dev/null +++ b/cmake/GitVersion.cmake @@ -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() \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 00000000..99f08aae --- /dev/null +++ b/src/CMakeLists.txt @@ -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 + $<$,$>: + -Werror -Wall -Wextra -Wno-unused-parameter -Wno-unused-private-field> + $<$: + /W1 /std:c++17 /bigobj /wd4291 /wd4624 /wd4244 /NODEFAULTLIB:MSVCRT + /NODEFAULTLIB:MSVCRTD>) +target_compile_definitions(clang-umllib PUBLIC + $<$: + -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 ") +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 ") + set(CPACK_NSIS_MODIFY_PATH ON) + set(CPACK_SOURCE_GENERATOR "ZIP") +endif(MSVC) + +include(CPack) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 6edf1c76..f8a7e95c 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -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) - # Without this, clang-uml test cases fail with error saying that clang cannot find stdarg.h - 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") + # Without this, clang-uml test cases fail with error saying that + # clang cannot find stdarg.h + 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) file(GLOB_RECURSE TEST_CASE_SOURCES t*/*.cc) @@ -37,55 +24,33 @@ if(MSVC) list(APPEND CLANG_UML_TEST_LIBRARIES "Version.lib") 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}) -set(CLANG_UML_TEST_UTIL_HEADER catch.h) - -set(CLANG_UML_TEST_MODEL_SRC test_model.cc ${TEST_MODEL_SOURCES}) -set(CLANG_UML_TEST_MODEL_HEADER catch.h) - -set(CLANG_UML_TEST_CASES_SRC test_cases.cc ${TEST_CASE_SOURCES}) -set(CLANG_UML_TEST_CASES_HEADER catch.h) - -set(CLANG_UML_TEST_DECORATOR_PARSER_SRC test_decorator_parser.cc ${TEST_UTIL_SOURCES}) -set(CLANG_UML_TEST_DECORATOR_PARSER_HEADER catch.h) - -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_NAME ${TEST_CASES}) + add_executable(${TEST_CASE_NAME} + ${TEST_CASE_NAME}.cc catch.h) + target_compile_options(${TEST_CASE_NAME} PRIVATE + $<$,$>: + -Wno-unused-parameter -Wno-unused-private-field -Wno-unused-variable + -Wno-attributes -Wno-nonnull> + $<$: + /W1 /std:c++17 /bigobj /wd4624>) + target_link_libraries(${TEST_CASE_NAME} PRIVATE ${CLANG_UML_TEST_LIBRARIES}) +endforeach() foreach(TEST_CASE_CONFIG ${TEST_CASE_CONFIGS}) file(RELATIVE_PATH TEST_CASE_CONFIG_RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${TEST_CASE_CONFIG}) - message(${TEST_CASE_CONFIG_RELATIVE}) + message(DEBUG ${TEST_CASE_CONFIG_RELATIVE}) configure_file( ${TEST_CASE_CONFIG_RELATIVE} ${TEST_CASE_CONFIG_RELATIVE} @@ -97,17 +62,13 @@ foreach(TEST_CONFIG_YML ${TEST_CONFIG_YMLS}) TEST_CONFIG_YML_RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${TEST_CONFIG_YML}) - message(${TEST_CONFIG_YML_RELATIVE}) + message(DEBUG ${TEST_CONFIG_YML_RELATIVE}) configure_file( ${TEST_CONFIG_YML_RELATIVE} ${TEST_CONFIG_YML_RELATIVE} COPYONLY) endforeach() -add_test(NAME test_util COMMAND test_util) -add_test(NAME test_decorator_parser COMMAND test_decorator_parser) -add_test(NAME test_config COMMAND test_config) -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) +foreach(TEST_CASE_NAME ${TEST_CASES}) + add_test(NAME ${TEST_CASE_NAME} COMMAND ${TEST_CASE_NAME}) +endforeach() diff --git a/tests/t00018/test_case.h b/tests/t00018/test_case.h index cea7544b..6da1c833 100644 --- a/tests/t00018/test_case.h +++ b/tests/t00018/test_case.h @@ -18,7 +18,7 @@ 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"]; diff --git a/tests/t00048/test_case.h b/tests/t00048/test_case.h index 9bf75981..4376c20e 100644 --- a/tests/t00048/test_case.h +++ b/tests/t00048/test_case.h @@ -18,7 +18,8 @@ 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"]; diff --git a/tests/t20014/test_case.h b/tests/t20014/test_case.h index f7d7aeb9..a54452f1 100644 --- a/tests/t20014/test_case.h +++ b/tests/t20014/test_case.h @@ -18,7 +18,8 @@ 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"]; diff --git a/tests/t40001/test_case.h b/tests/t40001/test_case.h index 2ed7621f..8aae49c4 100644 --- a/tests/t40001/test_case.h +++ b/tests/t40001/test_case.h @@ -18,7 +18,7 @@ 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"]; diff --git a/tests/t40002/test_case.h b/tests/t40002/test_case.h index 0f6451b4..c217af96 100644 --- a/tests/t40002/test_case.h +++ b/tests/t40002/test_case.h @@ -18,7 +18,8 @@ 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"]; diff --git a/tests/t40003/test_case.h b/tests/t40003/test_case.h index e45cbea9..160537b2 100644 --- a/tests/t40003/test_case.h +++ b/tests/t40003/test_case.h @@ -18,7 +18,8 @@ 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"]; diff --git a/tests/test_cases.cc b/tests/test_cases.cc index 42448016..dca7d479 100644 --- a/tests/test_cases.cc +++ b/tests/test_cases.cc @@ -18,9 +18,66 @@ #include "test_cases.h" #include "common/generators/plantuml/generator.h" +#include "util/util.h" +#include #include +#include + +namespace clanguml::tests::util { +class TestCaseCompilationDatabase : public clang::tooling::CompilationDatabase { +public: + TestCaseCompilationDatabase(clang::tooling::CompileCommand &&cc) + : compile_commands_{{std::move(cc)}} + { + } + + TestCaseCompilationDatabase( + std::vector &&ccs) + : compile_commands_{std::move(ccs)} + { + } + + virtual ~TestCaseCompilationDatabase() { } + + static std::unique_ptr fromCompileCommand( + clang::tooling::CompileCommand &&cc) + { + return std::make_unique(std::move(cc)); + } + + std::vector getCompileCommands( + clang::StringRef FilePath) const override + { + std::vector 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 getAllFiles() const override + { + std::vector files; + std::transform(begin(compile_commands_), end(compile_commands_), + std::back_inserter(files), + [](const auto &cc) { return cc.Filename; }); + return files; + } + + std::vector + getAllCompileCommands() const override + { + return compile_commands_; + } + +private: + std::vector compile_commands_; +}; +} + void inject_diagram_options(std::shared_ptr diagram) { // Inject links config to all test cases @@ -33,8 +90,10 @@ void inject_diagram_options(std::shared_ptr diagram) std::pair> -load_config(const std::string &test_name) +load_config(const std::string &test_name, const std::vector &tus) { + using std::filesystem::path; + auto config = clanguml::config::load(test_name + "/.clang-uml", true); std::string err{}; @@ -42,12 +101,58 @@ load_config(const std::string &test_name) clang::tooling::CompilationDatabase::autoDetectFromDirectory( 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 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()) throw std::runtime_error{err}; return std::make_pair(std::move(config), std::move(compilation_database)); } +std::pair> +load_config(const std::string &test_name) +{ + return load_config(test_name, {fmt::format("{}.cc", test_name)}); +} + std::unique_ptr generate_sequence_diagram(clang::tooling::CompilationDatabase &db, std::shared_ptr diagram)