diff --git a/.github/workflows/build_dependencies.yml b/.github/workflows/build_dependencies.yml index 0008ad8..83fd5e3 100644 --- a/.github/workflows/build_dependencies.yml +++ b/.github/workflows/build_dependencies.yml @@ -140,8 +140,8 @@ jobs: conan install \ -o sisl:prerelease=${{ inputs.prerelease }} \ -o sisl:malloc_impl=${{ inputs.malloc-impl }} \ - -o testing=False \ -s build_type=${{ inputs.build-type }} \ + -c tools.build:skip_test=True \ --build missing \ . if: ${{ steps.restore-cache.outputs.cache-hit != 'true' }} diff --git a/.gitignore b/.gitignore index 1f8d128..80af3a4 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ compile_commands* .clangd/ .vscode/ .cache/ +CMakeUserPresets.json diff --git a/3rd_party/nuraft/conanfile.py b/3rd_party/nuraft/conanfile.py index 8ddf6b6..28437f4 100644 --- a/3rd_party/nuraft/conanfile.py +++ b/3rd_party/nuraft/conanfile.py @@ -40,9 +40,9 @@ def layout(self): cmake_layout(self, src_folder="src") def requirements(self): - self.requires("openssl/1.1.1q") + self.requires("openssl/[>=1.1 <4]") if self.options.asio == "boost": - self.requires("boost/1.79.0") + self.requires("boost/[>=1.80]") else: self.requires("asio/1.27.0") diff --git a/CMakeLists.txt b/CMakeLists.txt index 0475955..8497e77 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,29 +1,30 @@ -cmake_minimum_required(VERSION 3.10) -project(nuraft_mesg) +cmake_minimum_required(VERSION 3.15) +project(nuraft_mesg CXX) enable_testing() include (cmake/Flags.cmake) set(CMAKE_CXX_STANDARD 20) -if(EXISTS ${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) - include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) - conan_basic_setup(TARGETS) -else() - message(WARNING "Conan Build file does not exist, trying to build without!") +if (NOT BUILD_TESTING STREQUAL OFF) + set(ENABLE_TESTING ON) + enable_testing() + find_package(GTest QUIET REQUIRED) endif() -if (DEFINED CONAN_BUILD_COVERAGE) - if (${CONAN_BUILD_COVERAGE}) +if (DEFINED BUILD_COVERAGE) + if (${BUILD_COVERAGE}) include (cmake/CodeCoverage.cmake) APPEND_COVERAGE_COMPILER_FLAGS() SETUP_TARGET_FOR_COVERAGE_GCOVR_XML(NAME coverage EXECUTABLE ctest DEPENDENCIES ) endif () endif () -if (${MEMORY_SANITIZER_ON}) - include (cmake/mem_sanitizer.cmake) -endif () +if (DEFINED MEMORY_SANITIZER_ON) + if (${MEMORY_SANITIZER_ON}) + include (cmake/mem_sanitizer.cmake) + endif () +endif() find_program(CCACHE_FOUND ccache) if (CCACHE_FOUND) diff --git a/README.md b/README.md index e2f8c8f..e081f2e 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,8 @@ This project depends on the [Symbiosis Library](https://github.com/eBay/sisl) wh in conan-center. If using conan-center one must first export this recipe to their local conan cache, example: ``` $ git clone https://github.com/eBay/sisl sisl +$ pip install --user conan +$ conan profile detect --name default $ conan export sisl/ oss/master ``` @@ -51,7 +53,6 @@ $ conan export sisl/ oss/master This project is typically built from a combination of conan.io and CMake (which must be installed on the host). ``` -$ pip install -U conan $ conan create --build missing . / ``` diff --git a/conanfile.py b/conanfile.py index 9e029c1..ab6e0ce 100644 --- a/conanfile.py +++ b/conanfile.py @@ -1,14 +1,16 @@ -from os.path import join from conan import ConanFile -from conan.tools.files import copy +from conan.errors import ConanInvalidConfiguration from conan.tools.build import check_min_cppstd -from conans import CMake +from conan.tools.cmake import CMakeToolchain, CMakeDeps, CMake, cmake_layout +from conan.tools.files import copy +from conan.tools.files import copy +from os.path import join -required_conan_version = ">=1.50.0" +required_conan_version = ">=1.60.0" class NuRaftMesgConan(ConanFile): name = "nuraft_mesg" - version = "2.3.3" + version = "2.4.1" homepage = "https://github.com/eBay/nuraft_mesg" description = "A gRPC service for NuRAFT" @@ -23,70 +25,77 @@ class NuRaftMesgConan(ConanFile): "fPIC": ['True', 'False'], "coverage": ['True', 'False'], "sanitize": ['True', 'False'], - "testing": ['True', 'False'], } default_options = { 'shared': False, 'fPIC': True, 'coverage': False, 'sanitize': False, - 'testing': True, } - generators = "cmake", "cmake_find_package" - exports = ["LICENSE"] exports_sources = ( + "LICENSE", "CMakeLists.txt", "cmake/*", "include/*", "src/*", ) + def _min_cppstd(self): + return 20 + + def validate(self): + if self.settings.compiler.get_safe("cppstd"): + check_min_cppstd(self, self._min_cppstd()) + def configure(self): if self.options.shared: - del self.options.fPIC + self.options.rm_safe("fPIC") if self.settings.build_type == "Debug": if self.options.coverage and self.options.sanitize: raise ConanInvalidConfiguration("Sanitizer does not work with Code Coverage!") - if not self.options.testing: + if self.conf.get("tools.build:skip_test", default=False): if self.options.coverage or self.options.sanitize: raise ConanInvalidConfiguration("Coverage/Sanitizer requires Testing!") def build_requirements(self): - self.build_requires("gtest/1.14.0") - if (self.options.testing): - self.build_requires("jungle/cci.20221201") + if not self.conf.get("tools.build:skip_test", default=False): + self.test_requires("lz4/[>=1.9]") + self.test_requires("gtest/1.14.0") + self.test_requires("jungle/cci.20221201") def requirements(self): - self.requires("sisl/[~=11, include_prerelease=True]@oss/master") - self.requires("nuraft/2.3.0") - - self.requires("boost/[>=1.80]") - self.requires("flatbuffers/23.5.26") - self.requires("openssl/3.1.3") + self.requires("boost/1.83.0", transitive_headers=True) + self.requires("sisl/[>=11.1, include_prerelease=True]@oss/master", transitive_headers=True) + self.requires("nuraft/2.3.0", transitive_headers=True) + + def layout(self): + cmake_layout(self) + + def generate(self): + # This generates "conan_toolchain.cmake" in self.generators_folder + tc = CMakeToolchain(self) + tc.variables["CMAKE_EXPORT_COMPILE_COMMANDS"] = "ON" + tc.variables["CONAN_CMAKE_SILENT_OUTPUT"] = "ON" + tc.variables["CTEST_OUTPUT_ON_FAILURE"] = "ON" + tc.variables["PACKAGE_VERSION"] = self.version + if self.settings.build_type == "Debug": + if self.options.get_safe("coverage"): + tc.variables['BUILD_COVERAGE'] = 'ON' + elif self.options.get_safe("sanitize"): + tc.variables['MEMORY_SANITIZER_ON'] = 'ON' + tc.generate() - def validate(self): - if self.info.settings.compiler.cppstd: - check_min_cppstd(self, 17) + # This generates "boost-config.cmake" and "grpc-config.cmake" etc in self.generators_folder + deps = CMakeDeps(self) + deps.generate() def build(self): cmake = CMake(self) - - definitions = {'CONAN_BUILD_COVERAGE': 'OFF', - 'CMAKE_EXPORT_COMPILE_COMMANDS': 'ON', - 'CONAN_CMAKE_SILENT_OUTPUT': 'ON', - 'MEMORY_SANITIZER_ON': 'OFF'} - - if self.settings.build_type == "Debug": - if self.options.sanitize: - definitions['MEMORY_SANITIZER_ON'] = 'ON' - elif self.options.coverage: - definitions['CONAN_BUILD_COVERAGE'] = 'ON' - - cmake.configure(defs=definitions) + cmake.configure() cmake.build() - if (self.options.testing): - cmake.test(output_on_failure=True) + if not self.conf.get("tools.build:skip_test", default=False): + cmake.test() def package(self): lib_dir = join(self.package_folder, "lib") @@ -100,13 +109,22 @@ def package(self): copy(self, "*.so*", self.build_folder, lib_dir, keep_path=False) def package_info(self): + self.cpp_info.components["proto"].libs = ["nuraft_mesg", "nuraft_mesg_proto"] + self.cpp_info.components["proto"].set_property("pkg_config_name", "libnuraft_mesg_proto") + self.cpp_info.components["proto"].requires.extend([ + "nuraft::nuraft", + "boost::boost", + "sisl::sisl" + ]) + + for component in self.cpp_info.components.values(): + if self.options.get_safe("sanitize"): + component.sharedlinkflags.append("-fsanitize=address") + component.exelinkflags.append("-fsanitize=address") + component.sharedlinkflags.append("-fsanitize=undefined") + component.exelinkflags.append("-fsanitize=undefined") + + self.cpp_info.set_property("cmake_file_name", "NuraftMesg") + self.cpp_info.set_property("cmake_target_name", "NuraftMesg::NuraftMesg") self.cpp_info.names["cmake_find_package"] = "NuraftMesg" self.cpp_info.names["cmake_find_package_multi"] = "NuraftMesg" - self.cpp_info.components["proto"].libs = ["nuraft_mesg", "nuraft_mesg_proto"] - self.cpp_info.components["proto"].requires = ["nuraft::nuraft", "sisl::sisl"] - - if self.settings.build_type == "Debug" and self.options.sanitize: - self.cpp_info.components["proto"].sharedlinkflags.append("-fsanitize=address") - self.cpp_info.components["proto"].exelinkflags.append("-fsanitize=address") - self.cpp_info.components["proto"].sharedlinkflags.append("-fsanitize=undefined") - self.cpp_info.components["proto"].exelinkflags.append("-fsanitize=undefined") diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9a3f79b..0501efa 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -12,4 +12,8 @@ add_subdirectory (proto) add_subdirectory (flatb) add_subdirectory (lib) -add_subdirectory(tests) +if(DEFINED ENABLE_TESTING) + if(${ENABLE_TESTING}) + add_subdirectory(tests) + endif() +endif() diff --git a/src/flatb/CMakeLists.txt b/src/flatb/CMakeLists.txt index f588812..0265088 100644 --- a/src/flatb/CMakeLists.txt +++ b/src/flatb/CMakeLists.txt @@ -13,7 +13,7 @@ flatbuffers_generate_headers( FLAGS "--grpc" ${SCHEMA_FLAGS} ) -add_library(${PROJECT_NAME}_flatb OBJECT) +add_library(${PROJECT_NAME}_flatb) target_sources(${PROJECT_NAME}_flatb PRIVATE flatb_client.cpp $ diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index de31f20..e000d2b 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -1,48 +1,45 @@ cmake_minimum_required (VERSION 3.11) -find_package(jungle QUIET) +find_package(jungle QUIET REQUIRED) -if (jungle_FOUND) - find_package(GTest REQUIRED) - add_subdirectory(jungle_logstore) +add_subdirectory(jungle_logstore) - add_library(test_fixture OBJECT) - target_sources(test_fixture PRIVATE - test_state_manager.cpp - ) - target_link_libraries(test_fixture - ${PROJECT_NAME} - jungle::jungle - GTest::gmock - ) +add_library(test_fixture OBJECT) +target_sources(test_fixture PRIVATE + test_state_manager.cpp +) +target_link_libraries(test_fixture + ${PROJECT_NAME} + jungle::jungle + GTest::gmock +) - add_executable(raft_service_test) - target_sources(raft_service_test PRIVATE - raft_service_tests.cpp - $ - $ - ) - target_link_libraries (raft_service_test - ${PROJECT_NAME} - ${PROJECT_NAME}_proto - jungle::jungle - GTest::gmock - ) - add_test(NAME RaftServiceTest COMMAND raft_service_test -cv 2) - set_property(TEST RaftServiceTest PROPERTY RUN_SERIAL 1) +add_executable(raft_service_test) +target_sources(raft_service_test PRIVATE + raft_service_tests.cpp + $ + $ +) +target_link_libraries (raft_service_test + ${PROJECT_NAME} + ${PROJECT_NAME}_proto + jungle::jungle + GTest::gmock +) +add_test(NAME RaftServiceTest COMMAND raft_service_test -cv 2) +set_property(TEST RaftServiceTest PROPERTY RUN_SERIAL 1) - add_executable(data_service_test) - target_sources(data_service_test PRIVATE - data_service_tests.cpp - $ - $ - ) - target_link_libraries (data_service_test - ${PROJECT_NAME} - ${PROJECT_NAME}_proto - jungle::jungle - GTest::gmock - ) - add_test(NAME DataServiceTest COMMAND data_service_test -cv 1) - set_property(TEST DataServiceTest PROPERTY RUN_SERIAL 1) -endif () +add_executable(data_service_test) +target_sources(data_service_test PRIVATE + data_service_tests.cpp + $ + $ +) +target_link_libraries (data_service_test + ${PROJECT_NAME} + ${PROJECT_NAME}_proto + jungle::jungle + GTest::gmock +) +add_test(NAME DataServiceTest COMMAND data_service_test -cv 1) +set_property(TEST DataServiceTest PROPERTY RUN_SERIAL 1) diff --git a/src/tests/jungle_logstore/CMakeLists.txt b/src/tests/jungle_logstore/CMakeLists.txt index dc959d4..ff5d0d7 100644 --- a/src/tests/jungle_logstore/CMakeLists.txt +++ b/src/tests/jungle_logstore/CMakeLists.txt @@ -1,5 +1,7 @@ cmake_minimum_required (VERSION 3.11) +find_package(lz4) + file (GLOB LIBRARY_SOURCES *.cc) add_flags("-w") diff --git a/test_package/CMakeLists.txt b/test_package/CMakeLists.txt index 3bad86e..9c9353f 100644 --- a/test_package/CMakeLists.txt +++ b/test_package/CMakeLists.txt @@ -1,16 +1,12 @@ cmake_minimum_required(VERSION 3.11) project(test_package) -include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) -conan_basic_setup(TARGETS) - find_package(NuraftMesg QUIET REQUIRED) -set(CMAKE_CXX_STANDARD 20) -set(CPP_WARNINGS "-Wall -Wextra -Werror") - add_executable(example_server example_server.cpp example_state_manager.cpp in_memory_log_store.cpp) -target_link_libraries(example_server NuraftMesg::proto) +target_compile_features(example_server PUBLIC cxx_std_20) +target_link_libraries(example_server nuraft_mesg::proto) add_executable(example_client example_client.cpp) -target_link_libraries(example_client NuraftMesg::proto) +target_compile_features(example_client PUBLIC cxx_std_20) +target_link_libraries(example_client nuraft_mesg::proto) diff --git a/test_package/conanfile.py b/test_package/conanfile.py index ce34dc6..c3ff1dc 100644 --- a/test_package/conanfile.py +++ b/test_package/conanfile.py @@ -1,20 +1,28 @@ -from conans import ConanFile -from conan.tools.build import cross_building -from conans import CMake +from conan import ConanFile +from conan.tools.build import can_run +from conan.tools.cmake import cmake_layout, CMake import os + class TestPackageConan(ConanFile): settings = "os", "compiler", "build_type", "arch" - generators = "cmake", "cmake_find_package" + generators = "CMakeDeps", "CMakeToolchain", "VirtualRunEnv" + test_type = "explicit" + + def requirements(self): + self.requires(self.tested_reference_str) + + def layout(self): + cmake_layout(self) def build(self): cmake = CMake(self) - cmake.configure(defs={'CONAN_CMAKE_SILENT_OUTPUT': 'ON'}) + cmake.configure() cmake.build() def test(self): - if not cross_building(self): - sbin_path = os.path.join("bin", "example_server") - cbin_path = os.path.join("bin", "example_client") - self.run(sbin_path, run_environment=True) - self.run(cbin_path, run_environment=True) + if can_run(self): + sbin_path = os.path.join(self.cpp.build.bindir, "example_server") + cbin_path = os.path.join(self.cpp.build.bindir, "example_client") + self.run(sbin_path, env="conanrun") + self.run(cbin_path, env="conanrun")