cmake_minimum_required(VERSION 3.11)
project(hiredis-cluster)
include(GNUInstallDirs)
# Options
option(DOWNLOAD_HIREDIS "Download the dependency hiredis from GitHub" ON)
option(ENABLE_SSL "Enable SSL/TLS support" OFF)
option(DISABLE_TESTS "Disable compilation of test" OFF)
option(ENABLE_IPV6_TESTS "Enable IPv6 tests requiring special prerequisites" OFF)
option(ENABLE_COVERAGE "Enable test coverage reporting" OFF)
macro(getVersionBit name)
set(VERSION_REGEX "^#define ${name} (.+)$")
file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/hircluster.h"
VERSION_BIT REGEX ${VERSION_REGEX})
string(REGEX REPLACE ${VERSION_REGEX} "\\1" ${name} "${VERSION_BIT}")
endmacro(getVersionBit)
# Get version information from src
getVersionBit(HIREDIS_CLUSTER_MAJOR)
getVersionBit(HIREDIS_CLUSTER_MINOR)
getVersionBit(HIREDIS_CLUSTER_PATCH)
getVersionBit(HIREDIS_CLUSTER_SONAME)
set(VERSION "${HIREDIS_CLUSTER_MAJOR}.${HIREDIS_CLUSTER_MINOR}.${HIREDIS_CLUSTER_PATCH}")
message("Detected version: ${VERSION}")
project(hiredis-cluster
VERSION "${VERSION}"
LANGUAGES C)
# Use plain C99 (-std=c99) without extensions like GNU C (-std=gnu99)
set(CMAKE_C_STANDARD 99)
set(CMAKE_C_EXTENSIONS OFF)
# Build using a sanitizer
if(USE_SANITIZER)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-omit-frame-pointer -fsanitize=${USE_SANITIZER}")
endif()
if(ENABLE_COVERAGE)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --coverage -O0" )
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --coverage" )
endif()
SET(hiredis_cluster_sources
adlist.c
command.c
crc16.c
dict.c
hiarray.c
hircluster.c
hiutil.c)
if(WIN32 OR MINGW)
add_compile_definitions(_CRT_SECURE_NO_WARNINGS WIN32_LEAN_AND_MEAN)
set(hiredis_cluster_sources
${hiredis_cluster_sources}
hiredis_cluster.def)
endif()
add_library(hiredis_cluster
SHARED
${hiredis_cluster_sources})
if(NOT MSVC)
target_compile_options(hiredis_cluster PRIVATE -Wall -Wextra -pedantic -Werror
-Wstrict-prototypes -Wwrite-strings -Wno-missing-field-initializers)
# Add extra defines when CMAKE_BUILD_TYPE is set to Debug
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DHI_ASSERT_PANIC -DHI_HAVE_BACKTRACE")
# Alternative: -DHI_ASSERT_LOG)
endif()
set_target_properties(hiredis_cluster
PROPERTIES
VERSION "${HIREDIS_CLUSTER_SONAME}")
if(DOWNLOAD_HIREDIS)
if(${CMAKE_VERSION} VERSION_LESS "3.20")
message(FATAL_ERROR
"Downloading of the dependency 'hiredis' requires CMake >= v3.20.\n"
"Upgrade CMake or manually install 'hiredis' and use -DDOWNLOAD_HIREDIS=OFF")
endif()
set(HIREDIS_VERSION "1.2.0")
message("Downloading dependency: hiredis v${HIREDIS_VERSION}")
include(FetchContent)
FetchContent_Declare(hiredis
GIT_REPOSITORY https://github.com/redis/hiredis
GIT_TAG "v${HIREDIS_VERSION}"
SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/_deps/hiredis"
)
# Disable tests in hiredis
set(DISABLE_TESTS_OLD ${DISABLE_TESTS})
set(DISABLE_TESTS ON CACHE INTERNAL "")
FetchContent_GetProperties(hiredis)
if(NOT hiredis_POPULATED)
FetchContent_Populate(hiredis)
add_subdirectory(${hiredis_SOURCE_DIR} ${hiredis_BINARY_DIR})
endif()
set(DISABLE_TESTS ${DISABLE_TESTS_OLD} CACHE INTERNAL "")
# Create an empty *-config.cmake for find_package
# See: https://github.com/abandonware-pjz37/cmake-find-package-include/blob/master/hooks/fetch.cmake
set(stub_dir "${CMAKE_CURRENT_BINARY_DIR}/generated/pkg")
file(WRITE "${stub_dir}/hiredis-config.cmake" "")
file(WRITE "${stub_dir}/hiredis-config-version.cmake" "set(PACKAGE_VERSION ${HIREDIS_VERSION})")
set(hiredis_DIR ${stub_dir})
# Set variables normally got from hiredis-config.cmake
set(hiredis_LIBRARIES hiredis::hiredis)
set(hiredis_INCLUDE_DIRS "${CMAKE_CURRENT_BINARY_DIR}/_deps")
if(ENABLE_SSL)
file(WRITE "${stub_dir}/hiredis_ssl-config.cmake" "")
set(hiredis_ssl_DIR ${stub_dir})
endif()
else()
message("Expecting to find dependencies in path..")
endif()
find_package(hiredis QUIET)
if(NOT hiredis_FOUND)
message("CMake package for 'hiredis' not found, searching for the library..")
find_library(HIREDIS_LIB hiredis REQUIRED)
find_path(HIREDIS_INCLUDES hiredis/hiredis.h)
add_library(hiredis::hiredis UNKNOWN IMPORTED GLOBAL)
set_target_properties(hiredis::hiredis PROPERTIES IMPORTED_LOCATION ${HIREDIS_LIB})
set_target_properties(hiredis::hiredis PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ${HIREDIS_INCLUDES})
endif()
if(NOT TARGET hiredis::hiredis)
# Add target to support older hiredis releases
add_library(hiredis::hiredis ALIAS hiredis)
endif()
target_include_directories(hiredis_cluster PUBLIC
$<BUILD_INTERFACE:${hiredis_INCLUDE_DIRS}>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<INSTALL_INTERFACE:include>)
if(WIN32 OR MINGW)
target_link_libraries(hiredis_cluster PUBLIC ws2_32 hiredis::hiredis)
else()
target_link_libraries(hiredis_cluster PUBLIC hiredis::hiredis)
endif()
if(ENABLE_SSL)
find_package(hiredis_ssl QUIET)
if(NOT hiredis_ssl_FOUND)
message("CMake package for 'hiredis_ssl' not found, searching for the library..")
find_library(HIREDIS_SSL_LIB hiredis_ssl REQUIRED)
find_path(HIREDIS_SSL_INCLUDES hiredis/hiredis_ssl.h)
add_library(hiredis::hiredis_ssl UNKNOWN IMPORTED GLOBAL)
set_target_properties(hiredis::hiredis_ssl PROPERTIES IMPORTED_LOCATION ${HIREDIS_SSL_LIB})
set_target_properties(hiredis::hiredis_ssl PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ${HIREDIS_SSL_INCLUDES})
endif()
if(NOT TARGET hiredis::hiredis_ssl)
# Add target to support older hiredis releases
add_library(hiredis::hiredis_ssl ALIAS hiredis_ssl)
endif()
add_library(hiredis_cluster_ssl
SHARED hircluster_ssl.c)
set_target_properties(hiredis_cluster_ssl
PROPERTIES VERSION "${HIREDIS_CLUSTER_SONAME}")
target_link_libraries(hiredis_cluster_ssl
PRIVATE hiredis_cluster
PUBLIC hiredis::hiredis_ssl)
endif()
if(NOT DISABLE_TESTS)
include(CTest)
add_subdirectory(tests)
endif()
# Code formatting target
find_program(CLANG_FORMAT "clang-format")
file(GLOB_RECURSE FILES_TO_FORMAT
${PROJECT_SOURCE_DIR}/*.[ch]
)
add_custom_target(format
COMMAND ${CLANG_FORMAT} -i ${FILES_TO_FORMAT}
)
# Code coverage target
if(ENABLE_COVERAGE)
find_program(GCOVR "gcovr")
add_custom_command(OUTPUT _run_gcovr
POST_BUILD
COMMAND ${GCOVR} -r ${CMAKE_SOURCE_DIR} --object-dir=${CMAKE_BINARY_DIR} --html-details coverage.html
COMMAND echo "Coverage report generated: ${CMAKE_BINARY_DIR}/coverage.html"
WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
add_custom_target (coverage DEPENDS _run_gcovr)
endif()
configure_file(hiredis_cluster.pc.in hiredis_cluster.pc @ONLY)
install(TARGETS hiredis_cluster
EXPORT hiredis_cluster-targets
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
install(FILES hircluster.h adlist.h hiarray.h dict.h
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/hiredis_cluster)
install(DIRECTORY adapters
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/hiredis_cluster)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/hiredis_cluster.pc
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
export(EXPORT hiredis_cluster-targets
FILE ${CMAKE_CURRENT_BINARY_DIR}/hiredis_cluster-targets.cmake
NAMESPACE hiredis_cluster::)
set(CMAKE_CONF_INSTALL_DIR share/hiredis_cluster)
set(INCLUDE_INSTALL_DIR include)
include(CMakePackageConfigHelpers)
configure_package_config_file(hiredis_cluster-config.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/hiredis_cluster-config.cmake
INSTALL_DESTINATION ${CMAKE_CONF_INSTALL_DIR}
PATH_VARS INCLUDE_INSTALL_DIR)
write_basic_package_version_file(${CMAKE_CURRENT_BINARY_DIR}/hiredis_cluster-config-version.cmake
COMPATIBILITY SameMinorVersion)
install(EXPORT hiredis_cluster-targets
FILE hiredis_cluster-targets.cmake
NAMESPACE hiredis_cluster::
DESTINATION ${CMAKE_CONF_INSTALL_DIR})
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/hiredis_cluster-config.cmake
${CMAKE_CURRENT_BINARY_DIR}/hiredis_cluster-config-version.cmake
DESTINATION ${CMAKE_CONF_INSTALL_DIR})
# Install target for hiredis_cluster_ssl
if(ENABLE_SSL)
configure_file(hiredis_cluster_ssl.pc.in hiredis_cluster_ssl.pc @ONLY)
install(TARGETS hiredis_cluster_ssl
EXPORT hiredis_cluster_ssl-targets
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
install(FILES hircluster_ssl.h
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/hiredis_cluster)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/hiredis_cluster_ssl.pc
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
export(EXPORT hiredis_cluster_ssl-targets
FILE ${CMAKE_CURRENT_BINARY_DIR}/hiredis_cluster_ssl-targets.cmake
NAMESPACE hiredis_cluster::)
set(CMAKE_CONF_INSTALL_DIR share/hiredis_cluster_ssl)
configure_package_config_file(hiredis_cluster_ssl-config.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/hiredis_cluster_ssl-config.cmake
INSTALL_DESTINATION ${CMAKE_CONF_INSTALL_DIR}
PATH_VARS INCLUDE_INSTALL_DIR)
install(EXPORT hiredis_cluster_ssl-targets
FILE hiredis_cluster_ssl-targets.cmake
NAMESPACE hiredis_cluster::
DESTINATION ${CMAKE_CONF_INSTALL_DIR})
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/hiredis_cluster_ssl-config.cmake
DESTINATION ${CMAKE_CONF_INSTALL_DIR})
endif()