From e90a6fbfa19e2299e9159edb7d2ffac9bb7fe829 Mon Sep 17 00:00:00 2001 From: Nir Cohen Hershkovitz Date: Sat, 29 Mar 2025 20:09:16 +0300 Subject: [PATCH 1/2] Modernize CMake structure and convert nlohmann/json to submodule This commit introduces several improvements to the project structure: - Reorganized CMake structure with separate CMakeLists.txt in include/ and src/ directories - Converted nlohmann/json from FetchContent to git submodule for consistency with cryptopp-cmake - Added proper installation targets for headers, library, and CMake configuration files - Implemented proper exported targets for easier integration in other projects - Added datacoeconfig.cmake for find_package support - Generated version file for compatibility checking - Updated include paths for cleaner separation between interface and implementation - Added compile_commands.json generation for better IDE support - Incremented version from 0.1.1 to 0.2.0 due to significant structural improvements These changes follow modern CMake best practices and make the library easier to use as a dependency in other projects. --- .gitignore | 4 +- .gitmodules | 3 + CMakeLists.txt | 99 +++++++++++++++--------------- cmake/datacoeconfig.cmake | 5 ++ external/json | 1 + include/CMakeLists.txt | 18 ++++++ include/datacoe/data_manager.hpp | 2 - include/datacoe/game_data.hpp | 2 +- src/CMakeLists.txt | 32 ++++++++++ src/data_manager.cpp | 2 + src/data_reader_writer.cpp | 14 ++--- src/game_data.cpp | 1 - tests/CMakeLists.txt | 34 ++-------- tests/data_manager_tests.cpp | 6 +- tests/data_reader_writer_tests.cpp | 4 +- tests/error_handling_tests.cpp | 5 +- tests/game_data_tests.cpp | 5 +- tests/integration_tests.cpp | 6 +- tests/memory_tests.cpp | 5 +- tests/performance_tests.cpp | 6 +- tests/tester.cpp | 1 - 21 files changed, 143 insertions(+), 112 deletions(-) create mode 100644 cmake/datacoeconfig.cmake create mode 160000 external/json create mode 100644 include/CMakeLists.txt create mode 100644 src/CMakeLists.txt diff --git a/.gitignore b/.gitignore index 01f9cb9..91f057b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ build/ -.vscode/ \ No newline at end of file +.vscode/ +.cache/ +.clangd \ No newline at end of file diff --git a/.gitmodules b/.gitmodules index 007ff84..35f5a1f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "external/cryptopp-cmake"] path = external/cryptopp-cmake url = https://github.com/abdes/cryptopp-cmake.git +[submodule "external/json"] + path = external/json + url = https://github.com/nlohmann/json.git diff --git a/CMakeLists.txt b/CMakeLists.txt index 5a5b1b4..c9f4463 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,60 +1,63 @@ cmake_minimum_required(VERSION 3.14) -project(datacoe) - -# Debug mode, feel free to modify to your desire -set(CMAKE_BUILD_TYPE Debug) -if(MSVC) - set(CMAKE_CXX_FLAGS_DEBUG "/Zi /DEBUG") - set(CMAKE_C_FLAGS_DEBUG "/Zi /DEBUG") -else() - set(CMAKE_CXX_FLAGS_DEBUG "-g") - set(CMAKE_C_FLAGS_DEBUG "-g") -endif() +project(datacoe VERSION 0.1.1 LANGUAGES CXX) -include(FetchContent) +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) -# Currently fetching googletest v1.16.0, -# Feel free to upgrade and change the URL into the .zip file you would like to upgrade -FetchContent_Declare( - googletest - URL https://github.com/google/googletest/archive/6910c9d9165801d8827d628cb72eb7ea9dd538c5.zip - DOWNLOAD_EXTRACT_TIMESTAMP TRUE -) -if(WIN32) - set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) -endif() -FetchContent_MakeAvailable(googletest) +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +option(BUILD_TESTS "Build the test suite" ON) + +# dependencies from external/ (git submodules) add_subdirectory(external/cryptopp-cmake) +add_subdirectory(external/json) + +# project directories +add_subdirectory(include) +add_subdirectory(src) + +if(BUILD_TESTS) + include(FetchContent) + # Currently fetching googletest v1.16.0, + # Feel free to upgrade and change the URL into the .zip file you would like to upgrade + FetchContent_Declare( + googletest + URL https://github.com/google/googletest/archive/6910c9d9165801d8827d628cb72eb7ea9dd538c5.zip + DOWNLOAD_EXTRACT_TIMESTAMP TRUE + ) + if(WIN32) + set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) + endif() + FetchContent_MakeAvailable(googletest) + + add_subdirectory(tests) +endif() -# Currently fetching nlohmann/json v3.11.3, -# Feel free to upgrade to your desired version. -FetchContent_Declare( - json - GIT_REPOSITORY https://github.com/nlohmann/json.git - GIT_TAG v3.11.3 +install( + FILES "${CMAKE_SOURCE_DIR}/external/json/single_include/nlohmann/json.hpp" + DESTINATION include/nlohmann ) -FetchContent_MakeAvailable(json) -add_subdirectory(tests) - -add_library(${PROJECT_NAME} - src/game_data.cpp - src/data_reader_writer.cpp - src/data_manager.cpp +include(CMakePackageConfigHelpers) +write_basic_package_version_file( + "${CMAKE_CURRENT_BINARY_DIR}/datacoeconfigversion.cmake" + VERSION ${PROJECT_VERSION} + COMPATIBILITY SameMajorVersion ) -target_link_libraries(${PROJECT_NAME} PRIVATE cryptopp) - -target_include_directories(${PROJECT_NAME} PUBLIC - ${CMAKE_SOURCE_DIR}/include - ${json_SOURCE_DIR}/single_include/nlohmann) +if(NOT DEFINED CMAKE_INSTALL_LIBDIR) + set(CMAKE_INSTALL_LIBDIR lib) +endif() -set_target_properties(${PROJECT_NAME} PROPERTIES CXX_STANDARD 17) +install( + FILES + "${CMAKE_CURRENT_BINARY_DIR}/datacoeconfigversion.cmake" + "${CMAKE_CURRENT_SOURCE_DIR}/cmake/datacoeconfig.cmake" + DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/datacoe" +) -# "Treat warnings as errors" behavior, Feel free to remove/modify it. -if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang") - target_compile_options(${PROJECT_NAME} PRIVATE -Wall -Wextra -Werror) -elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") - target_compile_options(${PROJECT_NAME} PRIVATE /W3 /WX) -endif() \ No newline at end of file +install( + EXPORT datacoeTargets + FILE datacoeTargets.cmake + DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/datacoe" +) \ No newline at end of file diff --git a/cmake/datacoeconfig.cmake b/cmake/datacoeconfig.cmake new file mode 100644 index 0000000..af97c22 --- /dev/null +++ b/cmake/datacoeconfig.cmake @@ -0,0 +1,5 @@ +include(CMakeFindDependencyMacro) + +find_dependency(nlohmann_json REQUIRED) + +include("${CMAKE_CURRENT_LIST_DIR}/datacoeTargets.cmake") \ No newline at end of file diff --git a/external/json b/external/json new file mode 160000 index 0000000..9cca280 --- /dev/null +++ b/external/json @@ -0,0 +1 @@ +Subproject commit 9cca280a4d0ccf0c08f47a99aa71d1b0e52f8d03 diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt new file mode 100644 index 0000000..8cc0500 --- /dev/null +++ b/include/CMakeLists.txt @@ -0,0 +1,18 @@ +add_library(datacoe_headers INTERFACE) +target_include_directories(datacoe_headers + INTERFACE + $ + $ + $ +) + +install( + DIRECTORY datacoe + DESTINATION include + FILES_MATCHING PATTERN "*.hpp" +) + +install( + TARGETS datacoe_headers + EXPORT datacoeTargets +) \ No newline at end of file diff --git a/include/datacoe/data_manager.hpp b/include/datacoe/data_manager.hpp index a713951..ddbdb53 100644 --- a/include/datacoe/data_manager.hpp +++ b/include/datacoe/data_manager.hpp @@ -1,9 +1,7 @@ #pragma once #include -#include #include "game_data.hpp" -#include "data_reader_writer.hpp" namespace datacoe { diff --git a/include/datacoe/game_data.hpp b/include/datacoe/game_data.hpp index 584ba11..90259f5 100644 --- a/include/datacoe/game_data.hpp +++ b/include/datacoe/game_data.hpp @@ -1,7 +1,7 @@ #pragma once #include -#include "json.hpp" +#include using json = nlohmann::json; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..268b0fe --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,32 @@ +add_library(datacoe + data_manager.cpp + data_reader_writer.cpp + game_data.cpp +) + +target_link_libraries(datacoe + PRIVATE + cryptopp + PUBLIC + datacoe_headers +) + +target_include_directories(datacoe + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} +) + +if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + target_compile_options(datacoe PRIVATE -Wall -Wextra -Werror) +elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") + target_compile_options(datacoe PRIVATE /W3 /WX) +endif() + +install( + TARGETS datacoe + EXPORT datacoeTargets + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib + RUNTIME DESTINATION bin + INCLUDES DESTINATION include +) \ No newline at end of file diff --git a/src/data_manager.cpp b/src/data_manager.cpp index 05044d5..646f322 100644 --- a/src/data_manager.cpp +++ b/src/data_manager.cpp @@ -1,4 +1,6 @@ #include "datacoe/data_manager.hpp" +#include "datacoe/data_reader_writer.hpp" +#include namespace datacoe { diff --git a/src/data_reader_writer.cpp b/src/data_reader_writer.cpp index 173d41e..e317c0e 100644 --- a/src/data_reader_writer.cpp +++ b/src/data_reader_writer.cpp @@ -1,17 +1,13 @@ #include "datacoe/data_reader_writer.hpp" -#include #include #include -#include #include -#include -#include #include -#include "cryptopp/aes.h" -#include "cryptopp/modes.h" -#include "cryptopp/filters.h" -#include "cryptopp/osrng.h" -#include "cryptopp/base64.h" +#include +#include +#include +#include +#include namespace datacoe { diff --git a/src/game_data.cpp b/src/game_data.cpp index beda053..9b690ee 100644 --- a/src/game_data.cpp +++ b/src/game_data.cpp @@ -1,5 +1,4 @@ #include "datacoe/game_data.hpp" -#include #include namespace datacoe diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 6b87151..a86666f 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,13 +1,8 @@ -cmake_minimum_required(VERSION 3.14) - -# Enable testing enable_testing() -# Set include directories for gtest set(GTEST_INCLUDE_DIR "${googletest_SOURCE_DIR}/googletest/include/gtest") set(GMOCK_INCLUDE_DIR "${googletest_SOURCE_DIR}/googlemock/include/gmock") -# List of all test files set(TEST_FILES data_manager_tests.cpp data_reader_writer_tests.cpp @@ -18,21 +13,16 @@ set(TEST_FILES error_handling_tests.cpp ) -# Create the unified test executable using our custom main add_executable(all_tests tester.cpp ${TEST_FILES} ) -set_target_properties(all_tests PROPERTIES - CXX_STANDARD 17 -) +set_target_properties(all_tests PROPERTIES CXX_STANDARD 17) target_include_directories(all_tests PRIVATE ${GTEST_INCLUDE_DIR} ${GMOCK_INCLUDE_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/../include - ${json_SOURCE_DIR}/single_include/nlohmann ) target_link_libraries(all_tests PRIVATE @@ -41,22 +31,15 @@ target_link_libraries(all_tests PRIVATE gmock ) -# Add platform-specific settings + if(MSVC) - # MSVC-specific settings + # MSVC-specific settings treat warnings as errors target_compile_options(all_tests PRIVATE /W4 /WX) # Disable warning about truncated symbol names for MSVC (common with GTest macros) target_compile_options(all_tests PRIVATE /wd4503) else() - # GCC/Clang settings + # GCC/Clang settings treat warnings as errors target_compile_options(all_tests PRIVATE -Wall -Wextra -Werror) - - # Coverage options only for non-MSVC - option(ENABLE_COVERAGE "Enable coverage reporting for gcc/clang" FALSE) - if(ENABLE_COVERAGE) - target_compile_options(all_tests PRIVATE --coverage -O0) - target_link_options(all_tests PRIVATE --coverage) - endif() endif() # Register the unified test @@ -69,7 +52,6 @@ if(BUILD_INDIVIDUAL_TESTS) # Extract the base name without extension get_filename_component(test_name ${test_file} NAME_WE) - # Add executable target add_executable(${test_name} ${test_file}) # Set properties and include directories @@ -77,8 +59,6 @@ if(BUILD_INDIVIDUAL_TESTS) target_include_directories(${test_name} PRIVATE ${GTEST_INCLUDE_DIR} ${GMOCK_INCLUDE_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/../include - ${json_SOURCE_DIR}/single_include/nlohmann ) # Link libraries @@ -88,15 +68,11 @@ if(BUILD_INDIVIDUAL_TESTS) gmock_main ) - # Platform-specific settings + # Platform-specific settings treat warnings as errors if(MSVC) target_compile_options(${test_name} PRIVATE /W4 /WX /wd4503) else() target_compile_options(${test_name} PRIVATE -Wall -Wextra -Werror) - if(ENABLE_COVERAGE) - target_compile_options(${test_name} PRIVATE --coverage -O0) - target_link_options(${test_name} PRIVATE --coverage) - endif() endif() # Add as a test diff --git a/tests/data_manager_tests.cpp b/tests/data_manager_tests.cpp index 1918cf4..e3e5803 100644 --- a/tests/data_manager_tests.cpp +++ b/tests/data_manager_tests.cpp @@ -1,7 +1,7 @@ -#include "gtest/gtest.h" -#include "datacoe/data_manager.hpp" +#include +#include +#include #include -#include #include #include #include diff --git a/tests/data_reader_writer_tests.cpp b/tests/data_reader_writer_tests.cpp index b34bf8c..723e548 100644 --- a/tests/data_reader_writer_tests.cpp +++ b/tests/data_reader_writer_tests.cpp @@ -1,5 +1,5 @@ -#include "gtest/gtest.h" -#include "datacoe/data_reader_writer.hpp" +#include +#include #include #include #include diff --git a/tests/error_handling_tests.cpp b/tests/error_handling_tests.cpp index 9f771d3..7376bab 100644 --- a/tests/error_handling_tests.cpp +++ b/tests/error_handling_tests.cpp @@ -1,9 +1,8 @@ -#include "gtest/gtest.h" -#include "datacoe/data_manager.hpp" +#include +#include #include #include #include -#include #include #ifdef _WIN32 diff --git a/tests/game_data_tests.cpp b/tests/game_data_tests.cpp index ec5db49..8cc044c 100644 --- a/tests/game_data_tests.cpp +++ b/tests/game_data_tests.cpp @@ -1,6 +1,5 @@ -#include "gtest/gtest.h" -#include "datacoe/game_data.hpp" -#include +#include +#include namespace datacoe { diff --git a/tests/integration_tests.cpp b/tests/integration_tests.cpp index 3383287..8324cc1 100644 --- a/tests/integration_tests.cpp +++ b/tests/integration_tests.cpp @@ -1,6 +1,6 @@ -#include "gtest/gtest.h" -#include "datacoe/data_manager.hpp" -#include "datacoe/data_reader_writer.hpp" +#include +#include +#include #include #include #include diff --git a/tests/memory_tests.cpp b/tests/memory_tests.cpp index e8307bc..457416e 100644 --- a/tests/memory_tests.cpp +++ b/tests/memory_tests.cpp @@ -1,7 +1,6 @@ -#include "gtest/gtest.h" -#include "datacoe/data_manager.hpp" +#include +#include #include -#include #include #include diff --git a/tests/performance_tests.cpp b/tests/performance_tests.cpp index 470add9..dd9734d 100644 --- a/tests/performance_tests.cpp +++ b/tests/performance_tests.cpp @@ -1,7 +1,7 @@ -#include "gtest/gtest.h" -#include "datacoe/data_manager.hpp" +#include +#include +#include #include -#include #include #include #include diff --git a/tests/tester.cpp b/tests/tester.cpp index dce6526..d9d423e 100644 --- a/tests/tester.cpp +++ b/tests/tester.cpp @@ -4,7 +4,6 @@ #include #include #include -#include #include #include #include From 0dcba34c8bdc55b6e875134bc04563caeb707f46 Mon Sep 17 00:00:00 2001 From: Nir Cohen Hershkovitz Date: Sat, 29 Mar 2025 20:35:50 +0300 Subject: [PATCH 2/2] Version 0.1.0 and update README.md --- CMakeLists.txt | 2 +- README.md | 75 +++++++++++++++++++++++++++++--------------------- 2 files changed, 44 insertions(+), 33 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c9f4463..2457ab8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.14) -project(datacoe VERSION 0.1.1 LANGUAGES CXX) +project(datacoe VERSION 0.1.0 LANGUAGES CXX) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) diff --git a/README.md b/README.md index 6b11ee4..ca71277 100644 --- a/README.md +++ b/README.md @@ -101,7 +101,7 @@ cmake .. cmake --build . # Run tests (optional) -./all_tests +./tests/all_tests ``` ### Integration Steps @@ -120,13 +120,27 @@ cmake --build . 4. **Integrate into Your Project:** - Add the library to your project's CMakeLists.txt: + There are two ways to integrate datacoe into your project: + + ### 4.1. Use as Subdirectory (Recommended for development) + ```cmake add_subdirectory(path/to/datacoe) + target_link_libraries(your_game_executable PRIVATE datacoe) ``` + + ### 4.2. Install and Use with find_package (Better for distribution) - Then link your executable with the library: ```cmake + # Build and install datacoe + cd path/to/datacoe + mkdir build && cd build + cmake .. + cmake --build . + cmake --install . --prefix + + # In your project's CMakeLists.txt + find_package(datacoe REQUIRED) target_link_libraries(your_game_executable PRIVATE datacoe) ``` @@ -147,7 +161,7 @@ The library consists of three main components: #### Initialize and Save Game Data ```cpp -#include "data_manager.hpp" +#include // Initialize with a file path datacoe::DataManager manager; @@ -164,7 +178,7 @@ bool saveSuccess = manager.saveGame(); #### Load Game Data ```cpp -#include "data_manager.hpp" +#include // Initialize with the same file path datacoe::DataManager manager; @@ -182,7 +196,7 @@ int score = data.getHighscore(); #### Create New Game ```cpp -#include "data_manager.hpp" +#include datacoe::DataManager manager; manager.init("save_game.json"); @@ -221,23 +235,23 @@ To adapt this library for your game, you'll need to modify the core components t ## Dependencies -All dependencies are now automatically handled: +All dependencies are automatically handled: -- **CryptoPP:** Automatically fetched via the cryptopp-cmake Git submodule (currently points to version 8.9.0) -- **nlohmann/json:** Automatically fetched by CMake during configuration (currently version 3.11.3) -- **Google Test:** Automatically fetched by CMake during configuration (currently version 1.16.0) +- **CryptoPP:** Added as a git submodule at external/cryptopp-cmake +- **nlohmann/json:** Added as a git submodule at external/json +- **Google Test:** Automatically fetched by CMake during configuration only if BUILD_TESTS is ON (currently version 1.16.0) -You no longer need to manually download or build these dependencies. +The nlohmann/json library is now included as a submodule (like cryptopp-cmake) rather than being fetched via CMake, providing more consistent dependency management and offline build capability. ### Updating Dependencies (optional) -#### Updating the cryptopp-cmake submodule +#### Updating the cryptopp-cmake or nlohmann/json submodules -If you want to update the cryptopp-cmake submodule to a different version: +If you want to update either submodule to a different version: ```bash -# Navigate to the cryptopp-cmake directory -cd external/cryptopp-cmake +# Navigate to the submodule directory +cd external/cryptopp-cmake # or external/json # Fetch all tags git fetch --tags @@ -246,30 +260,20 @@ git fetch --tags git tag -l # Checkout the specific tag you want -git checkout # e.g., CRYPTOPP_8_9_0 +git checkout # e.g., CRYPTOPP_8_9_0 or v3.11.3 # Return to the main project directory cd ../.. # Now commit the submodule update -git add external/cryptopp-cmake -git commit -m "Update cryptopp-cmake to " +git add external/cryptopp-cmake # or external/json +git commit -m "Update submodule to " ``` -#### Updating nlohmann/json and Google Test +#### Updating Google Test -To update nlohmann/json or Google Test to newer versions, modify the FetchContent_Declare section in your CMakeLists.txt: +To update Google Test to a newer version, modify the FetchContent_Declare section in your CMakeLists.txt: -For nlohmann/json: -```cmake -FetchContent_Declare( - json - GIT_REPOSITORY https://github.com/nlohmann/json.git - GIT_TAG v3.11.3 # Change this to the desired version -) -``` - -For Google Test: ```cmake FetchContent_Declare( googletest @@ -295,7 +299,7 @@ To run all tests: ```bash cd build -./all_tests +./tests/all_tests ``` To build and run individual test executables, enable the `BUILD_INDIVIDUAL_TESTS` option: @@ -303,7 +307,7 @@ To build and run individual test executables, enable the `BUILD_INDIVIDUAL_TESTS ```bash cmake -DBUILD_INDIVIDUAL_TESTS=ON .. cmake --build . -./error_handling_tests # Run a specific test +./tests/error_handling_tests # Run a specific test ``` ### Customizing Tests @@ -410,6 +414,13 @@ Game-specific implementations will have their own tags (e.g., `worm-v1.0.0`) to ## Version History +### [v0.1.2](https://github.com/nircoe/datacoe/releases/tag/v0.1.2) (CMake Modernization) +- Reorganized CMake structure with subdirectory CMakeLists.txt files +- Converted nlohmann/json from FetchContent to git submodule +- Added proper installation targets for headers, library, and CMake config files +- Implemented exported targets for easier integration in other projects +- Added find_package support + ### [v0.1.1](https://github.com/nircoe/datacoe/releases/tag/v0.1.1) (Optional Encryption) - Added ability to disable encryption when not needed - Implemented automatic encryption detection for backwards compatibility