From c72e072f7716ca67aafe80d1eb917e1ebb2d8a0c Mon Sep 17 00:00:00 2001 From: Tao He Date: Sun, 19 Mar 2023 11:31:57 +0800 Subject: [PATCH] Add an option `BUILD_ETCD_CORE_ONLY=ON/OFF` to select the runtime (#208) Signed-off-by: Tao He --- .github/workflows/build-test.yml | 1 + CMakeLists.txt | 59 ++++++++++++++++++++------------ README.md | 31 ++++++++--------- src/CMakeLists.txt | 54 +++++++++++++++++------------ 4 files changed, 86 insertions(+), 59 deletions(-) diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index a94ee45..e129aed 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -13,6 +13,7 @@ jobs: build: runs-on: ${{ matrix.os }} strategy: + fail-fast: false matrix: os: [ubuntu-18.04, ubuntu-20.04, ubuntu-22.04, macos-10.15, macos-11, macos-12] etcd: [v3.2.26, v3.3.11, v3.4.13, v3.5.7] diff --git a/CMakeLists.txt b/CMakeLists.txt index 4a46072..9ef84fd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,6 +27,7 @@ if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) endif() option(BUILD_SHARED_LIBS "Build etcd-cpp-apiv3 shared libraries" ON) +option(BUILD_ETCD_CORE_ONLY "Build etcd-cpp-apiv3 core library (the synchronous runtime) only" OFF) option(BUILD_ETCD_TESTS "Build etcd-cpp-apiv3 test cases" OFF) option(CMAKE_POSITION_INDEPENDENT_CODE "Build etcd-cpp-apiv3 with -fPIC" ON) option(ETCD_W_STRICT "Build etcd-cpp-apiv3 with -Werror" ON) @@ -116,14 +117,6 @@ if(Protobuf_PROTOC_EXECUTABLE) endif() endif() endif() -find_package(cpprestsdk QUIET) -if(cpprestsdk_FOUND) - set(CPPREST_INCLUDE_DIR) - set(CPPREST_LIB cpprestsdk::cpprest) -else() - find_library(CPPREST_LIB NAMES cpprest) - find_path(CPPREST_INCLUDE_DIR NAMES cpprest/http_client.h) -endif() find_package(gRPC QUIET) if(gRPC_FOUND) @@ -152,6 +145,27 @@ endif() include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/GenerateProtobuf.cmake) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/proto) +# test cases requires the async runtime +if(BUILD_ETCD_TESTS) + message(STATUS "Building etcd-cpp-apiv3 with tests requires the async runtime, " + "setting BUILD_ETCD_CORE_ONLY to ON ...") + set(BUILD_ETCD_CORE_ONLY OFF) +endif() + +if (NOT BUILD_ETCD_CORE_ONLY) + find_package(cpprestsdk QUIET) + if(cpprestsdk_FOUND) + set(CPPREST_INCLUDE_DIR) + set(CPPREST_LIB cpprestsdk::cpprest) + else() + find_library(CPPREST_LIB NAMES cpprest) + find_path(CPPREST_INCLUDE_DIR NAMES cpprest/http_client.h) + endif() +else() + set(CPPREST_INCLUDE_DIR) + set(CPPREST_LIB) +endif() + include_directories(SYSTEM ${Boost_INCLUDE_DIR} ${CPPREST_INCLUDE_DIR} ${PROTOBUF_INCLUDE_DIRS} @@ -178,16 +192,19 @@ if(BUILD_ETCD_TESTS) add_subdirectory(tst) endif() -install (FILES ${CMAKE_CURRENT_SOURCE_DIR}/etcd/Client.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/etcd/KeepAlive.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/etcd/SyncClient.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/etcd/Response.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/etcd/Value.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/etcd/Watcher.hpp - DESTINATION include/etcd) -install (FILES ${CMAKE_CURRENT_SOURCE_DIR}/etcd/v3/action_constants.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/etcd/v3/Transaction.hpp - DESTINATION include/etcd/v3) +install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/etcd/KeepAlive.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/etcd/SyncClient.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/etcd/Response.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/etcd/Value.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/etcd/Watcher.hpp + DESTINATION include/etcd) +if(NOT BUILD_ETCD_CORE_ONLY) + install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/etcd/Client.hpp + DESTINATION include/etcd) +endif() +install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/etcd/v3/action_constants.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/etcd/v3/Transaction.hpp + DESTINATION include/etcd/v3) configure_file(etcd-cpp-api-config.in.cmake "${PROJECT_BINARY_DIR}/etcd-cpp-api-config.cmake" @ONLY @@ -250,7 +267,7 @@ set(CPACK_DEBIAN_PACKAGE_DEPENDS "libcpprest-dev, libgrpc++-dev, libssl-dev") -set(CPACK_DEBIAN_PACKAGE_UPSTREAM_COPYRIGHT_YEAR 2016-2021) +set(CPACK_DEBIAN_PACKAGE_UPSTREAM_COPYRIGHT_YEAR 2016-2023) set(CPACK_DEBIAN_PACKAGE_LICENSE bsd) set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Tao He ") set(CPACK_DEBIAN_PACKAGE_HOMEPAGE "https://github.com/etcd-cpp-apiv3/etcd-cpp-apiv3/") @@ -267,8 +284,8 @@ set(CPACK_DEBIAN_PACKAGE_BUILD_NUMBER_PREFIX "") set(CPACK_DEBIAN_PACKAGE_BUILD_NUMBER 0) set(CPACK_DEBIAN_PACKAGE_DISTRIBUTION "focal") -set(DPUT_HOST "ppa:graphscope/etcd-cpp-api") -set(DPUT_SNAPSHOT_HOST "ppa:graphscope/etcd-cpp-api") +set(DPUT_HOST "ppa:etcd-cpp-apiv3/etcd-cpp-api") +set(DPUT_SNAPSHOT_HOST "ppa:etcd-cpp-apiv3/etcd-cpp-api") find_program(DEBUILD_EXECUTABLE debuild) find_program(DPUT_EXECUTABLE dput) diff --git a/README.md b/README.md index b198030..3b34ab6 100644 --- a/README.md +++ b/README.md @@ -92,28 +92,27 @@ Github when you encounter problems when working with etcd 3.x releases. There are various discussion about whether to support a user-transparent multi-thread executor in the background, or, leaving the burden of thread management to the user (e.g., see -[issue#100](https://github.com/etcd-cpp-apiv3/etcd-cpp-apiv3/issues/100) for more discussion about +[issue#100](https://github.com/etcd-cpp-apiv3/etcd-cpp-apiv3/issues/100) and +[issue#207](https://github.com/etcd-cpp-apiv3/etcd-cpp-apiv3/issues/207) for more discussion about the implementation of underlying thread model). -The _etcd-cpp-apiv3_ library supports both synchronous and asynchronous runtime, in two separate -library as follows: +The _etcd-cpp-apiv3_ library supports both synchronous and asynchronous runtime, controlled by the +cmake option `BUILD_ETCD_CORE_ONLY=ON/OFF` (defaults to `OFF`). -- **etcd-cpp-api-core**: the synchronous runtime, provides a blocking-style API and the users are responsible - for handling dispatch the request into separate thread to avoid been blocked by waiting for response. - - target found by cmake: `ETCD_CPP_CORE_LIBRARIES` - -- **etcd-cpp-api**: the asynchronous runtime backed by the `pplx` library from - [cpprestsdk](https://github.com/microsoft/cpprestsdk), where a `boost::asio::io_context` and a pool - of threads is used to run the asynchronous operations in the background. By default the number of - threads in the thread pool equals to `std::thread::hardware_concurrency()`. - - target found by cmake: `ETCD_CPP_LIBRARIES` +- When it is set as `OFF`: the library artifact name will be `libetcd-cpp-api.{a,so,dylib,lib,dll}` and a + cmake target `etcd-cpp-api` is exported and pointed to it. The library provides both synchronous runtime + (`etcd/SyncClient.hpp`) and asynchronous runtime (`etcd/Client.hpp`), and the `cpprestsdk` is a + required dependency. +- When it is set as `ON`: the library artifact name will be `libetcd-cpp-api-core.{a,so,dylib,lib,dll}` + and a cmake target `etcd-cpp-api` is exported and pointed to it. The library provides only the + synchronous runtime (`etcd/SyncClient.hpp`), and the `cpprestsdk` won't be required. We encourage the users to use the asynchronous runtime by default, as it provides more flexibility -and convenient APIs and less possibilities for errors that block the main thread. However, please note -that the asynchronous runtime will setup a thread pool in the background. +and convenient APIs and less possibilities for errors that block the main thread. Note that the +asynchronous runtime requires `cpprestsdk` and will setup a thread pool in the background. -Note that `etcd-cpp-api-core` and `etcd-cpp-api` are two separate target and don't depends on each other. -You should depends on either of them in your program. +**Warning: users cannot link both `libetcd-cpp-api.{a,so,dylib,lib,dll}` and `libetcd-cpp-api-core.{a,so,dylib,lib,dll}` +to same program.** ## Usage diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e77e92a..b7cb2ee 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -28,29 +28,39 @@ target_link_libraries(etcd-cpp-api-core-objects PUBLIC ${GRPC_LIBRARIES} ) -# add the core library, includes the sycnhronous client only -add_library(etcd-cpp-api-core $) -use_cxx(etcd-cpp-api-core) -target_link_libraries(etcd-cpp-api-core PUBLIC - ${Boost_LIBRARIES} - ${PROTOBUF_LIBRARIES} - ${OPENSSL_LIBRARIES} - ${GRPC_LIBRARIES} -) -include_generated_protobuf_files(etcd-cpp-api-core) +if(BUILD_ETCD_CORE_ONLY) + # add the core library, includes the sycnhronous client only + add_library(etcd-cpp-api-core $) + use_cxx(etcd-cpp-api-core) + target_link_libraries(etcd-cpp-api-core PUBLIC + ${Boost_LIBRARIES} + ${PROTOBUF_LIBRARIES} + ${OPENSSL_LIBRARIES} + ${GRPC_LIBRARIES} + ) + include_generated_protobuf_files(etcd-cpp-api-core) +else() + # add the client with asynchronus client + add_library(etcd-cpp-api $ + "${CMAKE_CURRENT_SOURCE_DIR}/Client.cpp") + use_cxx(etcd-cpp-api) + target_link_libraries(etcd-cpp-api PUBLIC + ${Boost_LIBRARIES} + ${CPPREST_LIB} # n.b.: the asynchronous client requires pplx in cpprestsdk + ${PROTOBUF_LIBRARIES} + ${OPENSSL_LIBRARIES} + ${GRPC_LIBRARIES} + ) + include_generated_protobuf_files(etcd-cpp-api) +endif() -# add the client with asynchronus client -add_library(etcd-cpp-api $ - "${CMAKE_CURRENT_SOURCE_DIR}/Client.cpp") -use_cxx(etcd-cpp-api) -target_link_libraries(etcd-cpp-api PUBLIC - ${Boost_LIBRARIES} - ${CPPREST_LIB} # n.b.: the asynchronous client requires pplx in cpprestsdk - ${PROTOBUF_LIBRARIES} - ${OPENSSL_LIBRARIES} - ${GRPC_LIBRARIES} -) -include_generated_protobuf_files(etcd-cpp-api) +if(BUILD_ETCD_CORE_ONLY) + add_library(etcd-cpp-api INTERFACE) + target_link_libraries(etcd-cpp-api INTERFACE etcd-cpp-api-core) +else() + add_library(etcd-cpp-api-core INTERFACE) + target_link_libraries(etcd-cpp-api-core INTERFACE etcd-cpp-api) +endif() if("${CMAKE_VERSION}" VERSION_LESS "3.14") install(TARGETS etcd-cpp-api-core etcd-cpp-api