Fixes for windows (vcpkg environment) compatibility.
Signed-off-by: Tao He <sighingnow@gmail.com>
This commit is contained in:
parent
eee2ea2d14
commit
e286c36926
|
|
@ -8,9 +8,6 @@ set(etcd-cpp-api_VERSION_MINOR 1)
|
|||
|
||||
option(BUILD_ETCD_TESTS "Build test cases" OFF)
|
||||
|
||||
find_library(CPPREST_LIB NAMES cpprest)
|
||||
find_path(CPPREST_INCLUDE_DIR NAMES cpprest/http_client.h)
|
||||
|
||||
find_package(Boost REQUIRED COMPONENTS system thread locale random)
|
||||
if (APPLE)
|
||||
# If we're on OS X check for Homebrew's copy of OpenSSL instead of Apple's
|
||||
|
|
@ -28,22 +25,31 @@ if (APPLE)
|
|||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
find_package(OpenSSL REQUIRED)
|
||||
find_package(Protobuf REQUIRED)
|
||||
find_package(cpprestsdk REQUIRED)
|
||||
|
||||
find_package(gRPC)
|
||||
if(gRPC_FOUND)
|
||||
set(GRPC_LIBRARIES gRPC::gpr gRPC::grpc gRPC::grpc++)
|
||||
else()
|
||||
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/FindGRPC.cmake)
|
||||
set(GRPC_LIBRARIES ${GPR_LIBRARY} ${GRPC_LIBRARY} ${GRPC_GRPC++_LIBRARY})
|
||||
endif()
|
||||
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/GenerateProtobufGRPC.cmake)
|
||||
|
||||
# will set `PROTOBUF_GENERATES`, indicates all generated .cc files, and a target `protobuf_generates`.
|
||||
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/GenerateProtobuf.cmake)
|
||||
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/proto)
|
||||
|
||||
include_directories(SYSTEM ${CPPREST_INCLUDE_DIR}
|
||||
${Boost_INCLUDE_DIR}
|
||||
include_directories(SYSTEM ${Boost_INCLUDE_DIR}
|
||||
${PROTOBUF_INCLUDE_DIRS}
|
||||
${OPENSSL_INCLUDE_DIR})
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
||||
if(NOT CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wpedantic -Werror -Wno-string-compare -std=c++11")
|
||||
endif()
|
||||
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib)
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib)
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@
|
|||
#
|
||||
# The original repository is open-sourced with the MIT license.
|
||||
#
|
||||
#
|
||||
# Locate and configure the gRPC library
|
||||
#
|
||||
# Adds the following targets:
|
||||
|
|
@ -16,76 +15,6 @@
|
|||
# gRPC::grpc_cpp_plugin - C++ generator plugin for Protocol Buffers
|
||||
#
|
||||
|
||||
#
|
||||
# Generates C++ sources from the .proto files
|
||||
#
|
||||
# grpc_generate_cpp (<SRCS> <HDRS> <DEST> [<ARGN>...])
|
||||
#
|
||||
# SRCS - variable to define with autogenerated source files
|
||||
# HDRS - variable to define with autogenerated header files
|
||||
# DEST - directory where the source files will be created
|
||||
# ARGN - .proto files
|
||||
#
|
||||
function(GRPC_GENERATE_CPP SRCS HDRS DEST)
|
||||
if(NOT ARGN)
|
||||
message(SEND_ERROR "Error: GRPC_GENERATE_CPP() called without any proto files")
|
||||
return()
|
||||
endif()
|
||||
|
||||
if(GRPC_GENERATE_CPP_APPEND_PATH)
|
||||
# Create an include path for each file specified
|
||||
foreach(FIL ${ARGN})
|
||||
get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
|
||||
get_filename_component(ABS_PATH ${ABS_FIL} PATH)
|
||||
list(FIND _protobuf_include_path ${ABS_PATH} _contains_already)
|
||||
if(${_contains_already} EQUAL -1)
|
||||
list(APPEND _protobuf_include_path -I ${ABS_PATH})
|
||||
endif()
|
||||
endforeach()
|
||||
else()
|
||||
set(_protobuf_include_path -I ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
endif()
|
||||
|
||||
if(DEFINED PROTOBUF_IMPORT_DIRS)
|
||||
foreach(DIR ${PROTOBUF_IMPORT_DIRS})
|
||||
get_filename_component(ABS_PATH ${DIR} ABSOLUTE)
|
||||
list(FIND _protobuf_include_path ${ABS_PATH} _contains_already)
|
||||
if(${_contains_already} EQUAL -1)
|
||||
list(APPEND _protobuf_include_path -I ${ABS_PATH})
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
set(${SRCS})
|
||||
set(${HDRS})
|
||||
foreach(FIL ${ARGN})
|
||||
get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
|
||||
get_filename_component(FIL_WE ${FIL} NAME_WE)
|
||||
|
||||
list(APPEND ${SRCS} "${DEST}/${FIL_WE}.grpc.pb.cc")
|
||||
list(APPEND ${HDRS} "${DEST}/${FIL_WE}.grpc.pb.h")
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT "${DEST}/${FIL_WE}.grpc.pb.cc"
|
||||
"${DEST}/${FIL_WE}.grpc.pb.h"
|
||||
COMMAND protobuf::protoc
|
||||
ARGS --grpc_out ${DEST} ${_protobuf_include_path} --plugin=protoc-gen-grpc=${GRPC_CPP_PLUGIN} ${ABS_FIL}
|
||||
DEPENDS ${ABS_FIL} protobuf::protoc gRPC::grpc_cpp_plugin
|
||||
COMMENT "Running C++ gRPC compiler on ${FIL}"
|
||||
VERBATIM )
|
||||
endforeach()
|
||||
|
||||
set_source_files_properties(${${SRCS}} ${${HDRS}} PROPERTIES GENERATED TRUE)
|
||||
set(${SRCS} ${${SRCS}} PARENT_SCOPE)
|
||||
set(${HDRS} ${${HDRS}} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# By default have GRPC_GENERATE_CPP macro pass -I to protoc
|
||||
# for each directory where a proto file is referenced.
|
||||
if(NOT DEFINED GRPC_GENERATE_CPP_APPEND_PATH)
|
||||
set(GRPC_GENERATE_CPP_APPEND_PATH TRUE)
|
||||
endif()
|
||||
|
||||
# Find gRPC include directory
|
||||
find_path(GRPC_INCLUDE_DIR grpc/grpc.h)
|
||||
mark_as_advanced(GRPC_INCLUDE_DIR)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,74 @@
|
|||
# This file is taken from
|
||||
#
|
||||
# https://github.com/IvanSafonov/grpc-cmake-example
|
||||
#
|
||||
# The original repository is open-sourced with the MIT license.
|
||||
#
|
||||
# Generates C++ sources from the .proto files
|
||||
#
|
||||
# grpc_generate_cpp (<SRCS> <HDRS> <DEST> [<ARGN>...])
|
||||
#
|
||||
# SRCS - variable to define with autogenerated source files
|
||||
# HDRS - variable to define with autogenerated header files
|
||||
# DEST - directory where the source files will be created
|
||||
# ARGN - .proto files
|
||||
#
|
||||
function(GRPC_GENERATE_CPP SRCS HDRS DEST)
|
||||
if(NOT ARGN)
|
||||
message(SEND_ERROR "Error: GRPC_GENERATE_CPP() called without any proto files")
|
||||
return()
|
||||
endif()
|
||||
|
||||
if(GRPC_GENERATE_CPP_APPEND_PATH)
|
||||
# Create an include path for each file specified
|
||||
foreach(FIL ${ARGN})
|
||||
get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
|
||||
get_filename_component(ABS_PATH ${ABS_FIL} PATH)
|
||||
list(FIND _protobuf_include_path ${ABS_PATH} _contains_already)
|
||||
if(${_contains_already} EQUAL -1)
|
||||
list(APPEND _protobuf_include_path -I ${ABS_PATH})
|
||||
endif()
|
||||
endforeach()
|
||||
else()
|
||||
set(_protobuf_include_path -I ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
endif()
|
||||
|
||||
if(DEFINED PROTOBUF_IMPORT_DIRS)
|
||||
foreach(DIR ${PROTOBUF_IMPORT_DIRS})
|
||||
get_filename_component(ABS_PATH ${DIR} ABSOLUTE)
|
||||
list(FIND _protobuf_include_path ${ABS_PATH} _contains_already)
|
||||
if(${_contains_already} EQUAL -1)
|
||||
list(APPEND _protobuf_include_path -I ${ABS_PATH})
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
set(${SRCS})
|
||||
set(${HDRS})
|
||||
foreach(FIL ${ARGN})
|
||||
get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
|
||||
get_filename_component(FIL_WE ${FIL} NAME_WE)
|
||||
|
||||
list(APPEND ${SRCS} "${DEST}/${FIL_WE}.grpc.pb.cc")
|
||||
list(APPEND ${HDRS} "${DEST}/${FIL_WE}.grpc.pb.h")
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT "${DEST}/${FIL_WE}.grpc.pb.cc"
|
||||
"${DEST}/${FIL_WE}.grpc.pb.h"
|
||||
COMMAND protobuf::protoc
|
||||
ARGS --grpc_out ${DEST} ${_protobuf_include_path} --plugin=protoc-gen-grpc=${GRPC_CPP_PLUGIN} ${ABS_FIL}
|
||||
DEPENDS ${ABS_FIL} protobuf::protoc gRPC::grpc_cpp_plugin
|
||||
COMMENT "Running C++ gRPC compiler on ${FIL}"
|
||||
VERBATIM )
|
||||
endforeach()
|
||||
|
||||
set_source_files_properties(${${SRCS}} ${${HDRS}} PROPERTIES GENERATED TRUE)
|
||||
set(${SRCS} ${${SRCS}} PARENT_SCOPE)
|
||||
set(${HDRS} ${${HDRS}} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# By default have GRPC_GENERATE_CPP macro pass -I to protoc
|
||||
# for each directory where a proto file is referenced.
|
||||
if(NOT DEFINED GRPC_GENERATE_CPP_APPEND_PATH)
|
||||
set(GRPC_GENERATE_CPP_APPEND_PATH TRUE)
|
||||
endif()
|
||||
|
|
@ -31,7 +31,7 @@ message KeyValue {
|
|||
message Event {
|
||||
enum EventType {
|
||||
PUT = 0;
|
||||
DELETE = 1;
|
||||
DELETE_ = 1;
|
||||
}
|
||||
// type is the kind of event. If type is a PUT, it indicates
|
||||
// new data has been stored to the key. If type is a DELETE,
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ add_dependencies(etcd-cpp-api protobuf_generates)
|
|||
set_property(TARGET etcd-cpp-api PROPERTY CXX_STANDARD 11)
|
||||
|
||||
target_link_libraries(etcd-cpp-api PUBLIC
|
||||
${CPPREST_LIB}
|
||||
cpprestsdk::cpprest
|
||||
${Boost_LIBRARIES}
|
||||
${PROTOBUF_LIBRARIES}
|
||||
${OPENSSL_LIBRARIES}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,14 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#if defined(_WIN32)
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#else
|
||||
#include <netdb.h>
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
|
|
@ -47,8 +53,26 @@ static bool dns_resolve(std::string const &target, std::vector<std::string> &end
|
|||
std::cerr << "warn: invalid URL: " << target << std::endl;
|
||||
return false;
|
||||
}
|
||||
if (getaddrinfo(target_parts[0].c_str(), target_parts[1].c_str(), &hints, &addrs) != 0) {
|
||||
std::cerr << "warn: getaddrinfo() failed for endpoint " << target << std::endl;
|
||||
|
||||
#if defined(_WIN32)
|
||||
{
|
||||
// Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h.
|
||||
WORD wVersionRequested = MAKEWORD(2, 2);
|
||||
WSADATA wsaData;
|
||||
|
||||
int err = WSAStartup(wVersionRequested, &wsaData);
|
||||
if (err != 0) {
|
||||
// Tell the user that we could not find a usable Winsock DLL. */
|
||||
std::cerr << "WSAStartup failed with error: %d" << err << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int r = getaddrinfo(target_parts[0].c_str(), target_parts[1].c_str(), &hints, &addrs);
|
||||
if (r != 0) {
|
||||
std::cerr << "warn: getaddrinfo() failed for endpoint " << target
|
||||
<< " with error: " << r << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ void etcdv3::AsyncWatchResponse::ParseResponse(WatchResponse& reply)
|
|||
value.kvs = event.kv();
|
||||
|
||||
}
|
||||
else if(mvccpb::Event::EventType::Event_EventType_DELETE == event.type())
|
||||
else if(mvccpb::Event::EventType::Event_EventType_DELETE_ == event.type())
|
||||
{
|
||||
action = etcdv3::DELETE_ACTION;
|
||||
value.kvs = event.kv();
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#define CATCH_CONFIG_MAIN
|
||||
#include <catch.hpp>
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
|
||||
#include "etcd/SyncClient.hpp"
|
||||
|
|
@ -11,6 +12,7 @@ TEST_CASE("sync operations")
|
|||
etcd::SyncClient etcd(etcd_uri);
|
||||
etcd.rmdir("/test", true);
|
||||
|
||||
|
||||
// add
|
||||
CHECK(0 == etcd.add("/test/key1", "42").error_code());
|
||||
CHECK(105 == etcd.add("/test/key1", "42").error_code()); // Key already exists
|
||||
|
|
@ -119,7 +121,7 @@ TEST_CASE("wait for a value change")
|
|||
CHECK("43" == res.value().as_string());
|
||||
});
|
||||
|
||||
sleep(1);
|
||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
etcd.set("/test/key1", "43");
|
||||
watch_thrd.join();
|
||||
|
||||
|
|
@ -136,7 +138,7 @@ TEST_CASE("wait for a directory change")
|
|||
CHECK("44" == res.value().as_string());
|
||||
});
|
||||
|
||||
sleep(1);
|
||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
etcd.add("/test/key4", "44");
|
||||
watch_thrd1.join();
|
||||
|
||||
|
|
@ -146,7 +148,7 @@ TEST_CASE("wait for a directory change")
|
|||
CHECK("45" == res2.value().as_string());
|
||||
});
|
||||
|
||||
sleep(1);
|
||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
etcd.set("/test/key4", "45");
|
||||
watch_thrd2.join();
|
||||
|
||||
|
|
@ -188,7 +190,7 @@ TEST_CASE("watch changes in the past")
|
|||
|
||||
// etcd.cancel_operations();
|
||||
|
||||
// sleep(1);
|
||||
// std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
// REQUIRE(res.is_done());
|
||||
// try {
|
||||
// res.wait();
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
#define CATCH_CONFIG_MAIN
|
||||
#include <catch.hpp>
|
||||
|
||||
#include <chrono>
|
||||
#include <iostream>
|
||||
#include <thread>
|
||||
|
||||
#include "etcd/Client.hpp"
|
||||
|
||||
|
|
@ -258,11 +260,11 @@ TEST_CASE("wait for a value change")
|
|||
|
||||
pplx::task<etcd::Response> res = etcd.watch("/test/key1");
|
||||
CHECK(!res.is_done());
|
||||
sleep(1);
|
||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
CHECK(!res.is_done());
|
||||
|
||||
etcd.set("/test/key1", "43").get();
|
||||
sleep(1);
|
||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
REQUIRE(res.is_done());
|
||||
REQUIRE("set" == res.get().action());
|
||||
CHECK("43" == res.get().value().as_string());
|
||||
|
|
@ -275,22 +277,22 @@ TEST_CASE("wait for a directory change")
|
|||
|
||||
pplx::task<etcd::Response> res = etcd.watch("/test", true);
|
||||
CHECK(!res.is_done());
|
||||
sleep(1);
|
||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
CHECK(!res.is_done());
|
||||
|
||||
etcd.add("/test/key4", "44").wait();
|
||||
sleep(1);
|
||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
REQUIRE(res.is_done());
|
||||
CHECK("create" == res.get().action());
|
||||
CHECK("44" == res.get().value().as_string());
|
||||
|
||||
pplx::task<etcd::Response> res2 = etcd.watch("/test", true);
|
||||
CHECK(!res2.is_done());
|
||||
sleep(1);
|
||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
CHECK(!res2.is_done());
|
||||
|
||||
etcd.set("/test/key4", "45").wait();
|
||||
sleep(1);
|
||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
REQUIRE(res2.is_done());
|
||||
CHECK("set" == res2.get().action());
|
||||
CHECK("45" == res2.get().value().as_string());
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
#include <catch.hpp>
|
||||
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
#include <iostream>
|
||||
#include <thread>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#define CATCH_CONFIG_MAIN
|
||||
#include <catch.hpp>
|
||||
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
|
||||
#include "etcd/Watcher.hpp"
|
||||
|
|
@ -31,17 +32,17 @@ TEST_CASE("create watcher with cancel")
|
|||
|
||||
watcher_called = 0;
|
||||
etcd::Watcher watcher(etcd_uri, "/test", printResponse, true);
|
||||
sleep(1);
|
||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
etcd.set("/test/key", "42");
|
||||
etcd.set("/test/key", "43");
|
||||
etcd.rm("/test/key");
|
||||
etcd.set("/test/key", "44");
|
||||
sleep(1);
|
||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
CHECK(4 == watcher_called);
|
||||
watcher.Cancel();
|
||||
etcd.set("/test/key", "50");
|
||||
etcd.set("/test/key", "51");
|
||||
sleep(1);
|
||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
CHECK(4 == watcher_called);
|
||||
|
||||
etcd.rmdir("/test", true);
|
||||
|
|
@ -56,7 +57,7 @@ TEST_CASE("create watcher")
|
|||
watcher_called = 0;
|
||||
{
|
||||
etcd::Watcher watcher(etcd_uri, "/test", printResponse, true);
|
||||
sleep(1);
|
||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
etcd.set("/test/key", "42");
|
||||
etcd.set("/test/key", "43");
|
||||
}
|
||||
|
|
@ -97,7 +98,7 @@ TEST_CASE("watch should can be cancelled repeatedly")
|
|||
|
||||
// etcd.cancel_operations();
|
||||
|
||||
// sleep(1);
|
||||
// std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
// REQUIRE(res.is_done());
|
||||
// try {
|
||||
// res.wait();
|
||||
|
|
|
|||
Loading…
Reference in New Issue