cmake_minimum_required(VERSION 3.15) project(ruby_client LANGUAGES CXX C) set(CMAKE_CXX_STANDARD 17) find_program(CCACHE ccache) if(CCACHE) set(CMAKE_CXX_COMPILER_LAUNCHER ${CCACHE}) endif() include(CMakePushCheckState) include(CheckSymbolExists) cmake_push_check_state(RESET) find_library(EXECINFO_LIBRARY NAMES execinfo) if(EXECINFO_LIBRARY) set(CMAKE_REQUIRED_LIBRARIES "${EXECINFO_LIBRARY}") list(APPEND PLATFORM_LIBRARIES "${EXECINFO_LIBRARY}") endif(EXECINFO_LIBRARY) check_symbol_exists(backtrace execinfo.h HAVE_BACKTRACE) cmake_pop_check_state() cmake_push_check_state(RESET) set(CMAKE_REQUIRED_DEFINITIONS "-D_GNU_SOURCE") find_library(DL_LIBRARY NAMES dl) if(DL_LIBRARY) set(CMAKE_REQUIRED_LIBRARIES "${DL_LIBRARY}") list(APPEND PLATFORM_LIBRARIES "${DL_LIBRARY}") endif(DL_LIBRARY) check_symbol_exists(dladdr dlfcn.h HAVE_DLADDR) cmake_pop_check_state() if(HAVE_BACKTRACE) add_definitions(-DHAVE_BACKTRACE=1) endif() if(HAVE_DLADDR) add_definitions(-DHAVE_DLADDR=1) endif() add_subdirectory(third_party/gsl) add_subdirectory(third_party/json) add_subdirectory(third_party/spdlog) add_subdirectory(third_party/snappy) include_directories(BEFORE SYSTEM third_party/gsl/include) include_directories(BEFORE SYSTEM third_party/asio/asio/include) include_directories(BEFORE SYSTEM third_party/json/include) include_directories(BEFORE SYSTEM third_party/spdlog/include) include_directories(BEFORE SYSTEM third_party/http_parser) add_library(project_warnings INTERFACE) add_library(project_options INTERFACE) target_compile_features(project_options INTERFACE cxx_std_17) target_include_directories(project_options INTERFACE include) if(MSVC) target_compile_options(project_warnings INTERFACE /W4 /WX "/permissive-") else() option(ONLY_COVERAGE "Build only tests necessary for coverage" FALSE) option(STATIC_STDLIB "Statically link C++ standard library" FALSE) option(ENABLE_COVERAGE "Enable coverage reporting for gcc/clang" FALSE) option(ENABLE_FUZZERS "Enable fuzz testing tools" FALSE) if(ONLY_COVERAGE OR ENABLE_COVERAGE) target_compile_options(project_options INTERFACE --coverage -O0 -g) target_link_libraries(project_options INTERFACE --coverage) endif() option(ENABLE_ASAN "Enable address sanitizer" FALSE) if(ENABLE_ASAN) target_compile_options(project_options INTERFACE -fsanitize=address) target_link_libraries(project_options INTERFACE -fsanitize=address) endif() option(ENABLE_TSAN "Enable thread sanitizer" FALSE) if(ENABLE_TSAN) target_compile_options(project_options INTERFACE -fsanitize=thread) target_link_libraries(project_options INTERFACE -fsanitize=thread) endif() if(STATIC_STDLIB) target_compile_options(project_options INTERFACE -static-libgcc -static-libstdc++) target_link_options(project_options INTERFACE -static-libgcc -static-libstdc++) endif() target_compile_options( project_warnings INTERFACE -Wall -Werror # treat all warnings as errors -Wextra # reasonable and standard -Wshadow # warn the user if a variable declaration shadows one from a parent # context -Wnon-virtual-dtor # warn the user if a class with virtual functions has a non- # virtual destructor. This helps catch hard to track down memory errors -Wcast-align # warn for potential performance problem casts -Wunused # warn on anything being unused -Woverloaded-virtual # warn if you overload (not override) a virtual function -Wpedantic # warn if non-standard C++ is used -Wold-style-cast # warn for c-style casts -Wconversion # warn on type conversions that may lose data -Wsign-conversion # warn on sign conversions -Wnull-dereference # warn if a null dereference is detected -Wformat=2 # warn on security issues around functions that format output (ie # printf) ) if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") target_compile_options( project_warnings INTERFACE -Wmisleading-indentation # warn if indentation implies blocks where blocks do # not exist -Wduplicated-cond # warn if if / else chain has duplicated conditions -Wduplicated-branches # warn if if / else branches have duplicated code -Wlogical-op # warn about logical operations being used where bitwise were # probably wanted -Wuseless-cast # warn if you perform a cast to the same type ) endif() if(HAVE_BACKTRACE OR HAVE_DLADDR) target_compile_options(project_options INTERFACE -ggdb3) target_link_libraries(project_options INTERFACE -rdynamic) add_definitions(-D_GNU_SOURCE=1) endif() endif() # Read more at https://wiki.wireshark.org/TLS option(TLS_KEY_LOG_FILE "Path to file to write per-session secrets (Useful for Wireshark SSL/TLS dissection)") include(FindOpenSSL) message(STATUS "OPENSSL_VERSION: ${OPENSSL_VERSION}") message(STATUS "OPENSSL_INCLUDEDIRS: ${OPENSSL_INCLUDE_DIR}") message(STATUS "OPENSSL_LIBRARIES: ${OPENSSL_LIBRARIES}") include_directories(${CMAKE_SOURCE_DIR}/couchbase) add_library( platform OBJECT couchbase/platform/string_hex.cc couchbase/platform/uuid.cc couchbase/platform/random.cc couchbase/platform/base64.cc couchbase/platform/backtrace.c couchbase/platform/terminate_handler.cc) target_include_directories(platform PRIVATE ${PROJECT_BINARY_DIR}/generated) add_library(cbcrypto OBJECT couchbase/cbcrypto/cbcrypto.cc) add_library(http_parser OBJECT third_party/http_parser/http_parser.c) set_target_properties(http_parser PROPERTIES C_VISIBILITY_PRESET hidden POSITION_INDEPENDENT_CODE TRUE) add_library( cbsasl OBJECT couchbase/cbsasl/client.cc couchbase/cbsasl/context.cc couchbase/cbsasl/mechanism.cc couchbase/cbsasl/plain/plain.cc couchbase/cbsasl/scram-sha/scram-sha.cc couchbase/cbsasl/scram-sha/stringutils.cc) if(RUBY_HDR_DIR) set(RUBY_INCLUDE_DIR ${RUBY_HDR_DIR} ${RUBY_ARCH_HDR_DIR}) else() find_package(Ruby REQUIRED) message(STATUS "RUBY_VERSION: ${RUBY_VERSION}") message(STATUS "RUBY_EXECUTABLE: ${RUBY_EXECUTABLE}") endif() message(STATUS "RUBY_INCLUDE_DIR: ${RUBY_INCLUDE_DIR}") message(STATUS "RUBY_LIBRARY: ${RUBY_LIBRARY}") include_directories(BEFORE SYSTEM "${RUBY_INCLUDE_DIR}") find_program(GIT git) if(GIT) execute_process( COMMAND git rev-parse HEAD WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE BACKEND_GIT_REVISION) endif() string(TIMESTAMP BACKEND_BUILD_TIMESTAMP "%Y-%m-%d %H:%M:%S" UTC) configure_file(${PROJECT_SOURCE_DIR}/build_version.hxx.in ${PROJECT_BINARY_DIR}/generated/build_version.hxx @ONLY) configure_file(${PROJECT_SOURCE_DIR}/build_config.hxx.in ${PROJECT_BINARY_DIR}/generated/build_config.hxx @ONLY) add_library(couchbase SHARED couchbase/couchbase.cxx) target_include_directories(couchbase PRIVATE ${PROJECT_BINARY_DIR}/generated) target_link_libraries( couchbase PRIVATE project_options project_warnings OpenSSL::SSL OpenSSL::Crypto platform cbcrypto cbsasl http_parser snappy spdlog::spdlog_header_only) set_target_properties(cbcrypto cbsasl platform snappy PROPERTIES POSITION_INDEPENDENT_CODE TRUE) if(APPLE) target_link_options(couchbase PRIVATE -Wl,-undefined,dynamic_lookup) else() set_target_properties(cbcrypto cbsasl platform PROPERTIES CXX_VISIBILITY_PRESET hidden) endif() if(BUILD_EXAMPLES) file( GENERATE OUTPUT ${PROJECT_BINARY_DIR}/generated/generated_config.hxx CONTENT "#pragma once\n#define LIBCOUCHBASE_EXT_PATH \"$<TARGET_FILE:couchbase>\"") add_executable(main test/main.cxx) target_include_directories(main PRIVATE ${PROJECT_BINARY_DIR}/generated) target_link_libraries(main PRIVATE project_options project_warnings ${RUBY_LIBRARY} spdlog::spdlog_header_only) add_dependencies(main couchbase) endif()