Skip to content

Commit

Permalink
Move SSL support to own library (#80)
Browse files Browse the repository at this point in the history
* Move SSL to a separate src and headerfile

This enables us to put the SSL code in a separate library,
like its done in hiredis. A user will be able to link to the new
library when SSL is wanted, and there is no longer the need of
having `SSL_SUPPORT` defined.

* Use later version than v1.0.2 of the dependency hiredis

The tagged versions of hiredis does not include a required
packaging correction. This correction is needed to be able to
import hiredis CMake package.

* Create separate ssl library via CMake

A new target and package is created in CMake to build
the library `hiredis_cluster_ssl`

* Create separate ssl library via Make

* Update CMake configs for tests

Use the new `hiredis_library_ssl` when linking the test binaries,
but only when building with SSL/TLS enabled.

Since CMake supports transitive dependencies the `hiredis_cluster` library
will make sure `hiredis` is include when linking, thus removing the
explicit linkage in CMake.

* Update examples to use the redis_cluster_ssl library

Includes some cleanups and the use of CMAKE_PREFIX_PATH
to remove some CMake configs.

* Update README regarding the new SSL library

* Support current hiredis releases in CMake

Add the missing hiredis targets if needed. This was corrected
in hiredis via: redis/hiredis#1005
  • Loading branch information
bjosv authored Apr 6, 2022
1 parent 573c100 commit 7c39940
Show file tree
Hide file tree
Showing 19 changed files with 312 additions and 142 deletions.
63 changes: 50 additions & 13 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,6 @@ if(DOWNLOAD_HIREDIS)
if(ENABLE_SSL)
file(WRITE "${stub_dir}/hiredis_ssl-config.cmake" "")
set(hiredis_ssl_DIR ${stub_dir})
# Set variables normally got from hiredis_ssl-config.cmake
set(hiredis_ssl_LIBRARIES hiredis::hiredis_ssl)
set(hiredis_INCLUDE_DIRS "${CMAKE_CURRENT_BINARY_DIR}/_deps")
endif()

else()
Expand All @@ -116,25 +113,37 @@ endif()

find_package(hiredis REQUIRED)

if(ENABLE_SSL)
find_package(hiredis_ssl REQUIRED)
add_definitions(-DSSL_SUPPORT)
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}>)
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<INSTALL_INTERFACE:include>)

if(WIN32 OR MINGW)
target_link_libraries(hiredis_cluster ws2_32 hiredis)
target_link_libraries(hiredis_cluster PUBLIC ws2_32 hiredis::hiredis)
else()
target_link_libraries(hiredis_cluster PUBLIC hiredis::hiredis)
endif()

if(APPLE)
if(ENABLE_SSL)
target_link_libraries(hiredis_cluster hiredis hiredis_ssl)
else()
target_link_libraries(hiredis_cluster hiredis)
if(ENABLE_SSL)
find_package(hiredis_ssl REQUIRED)

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)
Expand Down Expand Up @@ -198,3 +207,31 @@ install(EXPORT hiredis_cluster-targets

install(FILES ${CMAKE_CURRENT_BINARY_DIR}/hiredis_cluster-config.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()
64 changes: 56 additions & 8 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
# This file is released under the BSD license, see the COPYING file

OBJ=adlist.o command.o crc16.o dict.o hiarray.o hircluster.o hiutil.o
EXAMPLES=hiredis-cluster-example hiredis-cluster-example-tls
EXAMPLES=hiredis-cluster-example
LIBNAME=libhiredis_cluster
PKGCONFNAME=hiredis_cluster.pc

Expand Down Expand Up @@ -42,38 +42,63 @@ DYLIB_MAKE_CMD=$(CC) -shared -Wl,-soname,$(DYLIB_MINOR_NAME)
STLIBNAME=$(LIBNAME).$(STLIBSUFFIX)
STLIB_MAKE_CMD=$(AR) rcs

SSL_OBJ=hircluster_ssl.o
SSL_LIBNAME=libhiredis_cluster_ssl
SSL_PKGCONFNAME=hiredis_cluster_ssl.pc
SSL_INSTALLNAME=install-ssl
SSL_DYLIB_MINOR_NAME=$(SSL_LIBNAME).$(DYLIBSUFFIX).$(HIREDIS_SONAME)
SSL_DYLIB_MAJOR_NAME=$(SSL_LIBNAME).$(DYLIBSUFFIX).$(HIREDIS_MAJOR)
SSL_DYLIBNAME=$(SSL_LIBNAME).$(DYLIBSUFFIX)
SSL_STLIBNAME=$(SSL_LIBNAME).$(STLIBSUFFIX)
SSL_DYLIB_MAKE_CMD=$(CC) -shared -Wl,-soname,$(SSL_DYLIB_MINOR_NAME)

USE_SSL?=0
ifeq ($(USE_SSL),1)
SSL_STLIB=$(SSL_STLIBNAME)
SSL_DYLIB=$(SSL_DYLIBNAME)
SSL_PKGCONF=$(SSL_PKGCONFNAME)
SSL_INSTALL=$(SSL_INSTALLNAME)
EXAMPLES+=hiredis-cluster-example-tls
endif

# Platform-specific overrides
uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not')

ifeq ($(USE_SSL),1)
ifeq ($(uname_S),Linux)
REAL_CFLAGS+=-DSSL_SUPPORT
REAL_LDFLAGS+=-lssl -lcrypto
endif
endif

all: $(DYLIBNAME) $(STLIBNAME) $(PKGCONFNAME)
all: $(DYLIBNAME) $(SSL_DYLIBNAME) $(STLIBNAME) $(SSL_STLIBNAME) $(PKGCONFNAME) $(SSL_PKGCONFNAME)

# Deps (use make dep to generate this)
adlist.o: adlist.c adlist.h hiutil.h
command.o: command.c command.h adlist.h hiarray.h hiutil.h
command.o: command.c command.h adlist.h hiarray.h hiutil.h win32.h
crc16.o: crc16.c hiutil.h
dict.o: dict.c dict.h
hiarray.o: hiarray.c hiarray.h hiutil.h
hircluster.o: hircluster.c adlist.h command.h dict.h hiarray.h \
hircluster.h hiutil.h win32.h
hiutil.o: hiutil.c hiutil.h win32.h
hircluster_ssl.o: hircluster_ssl.c hircluster_ssl.h hircluster.h dict.h

$(DYLIBNAME): $(OBJ)
$(DYLIB_MAKE_CMD) -o $(DYLIBNAME) $(OBJ) $(REAL_LDFLAGS)

$(STLIBNAME): $(OBJ)
$(STLIB_MAKE_CMD) $(STLIBNAME) $(OBJ)

dynamic: $(DYLIBNAME)
static: $(STLIBNAME)
$(SSL_DYLIBNAME): $(SSL_OBJ)
$(SSL_DYLIB_MAKE_CMD) $(DYLIB_PLUGIN) -o $(SSL_DYLIBNAME) $(SSL_OBJ) $(REAL_LDFLAGS) $(SSL_LDFLAGS)

$(SSL_STLIBNAME): $(SSL_OBJ)
$(STLIB_MAKE_CMD) $(SSL_STLIBNAME) $(SSL_OBJ)

$(SSL_OBJ): hircluster_ssl.c

dynamic: $(DYLIBNAME) $(SSL_DYLIB)
static: $(STLIBNAME) $(SSL_STLIB)

# Binaries:
hiredis-cluster-example: examples/src/example.c
Expand All @@ -87,7 +112,7 @@ examples: $(EXAMPLES)
$(CC) -std=c99 -pedantic -c $(REAL_CFLAGS) $<

clean:
rm -rf $(DYLIBNAME) $(STLIBNAME) $(SSL_DYLIBNAME) $(PKGCONFNAME) examples/hiredis-cluster-example* *.o *.gcda *.gcno *.gcov
rm -rf $(DYLIBNAME) $(STLIBNAME) $(SSL_DYLIBNAME) $(SSL_STLIBNAME) $(PKGCONFNAME) $(SSL_PKGCONFNAME) examples/hiredis-cluster-example* *.o *.gcda *.gcno *.gcov

dep:
$(CC) $(CPPFLAGS) $(CFLAGS) -MM *.c
Expand All @@ -107,7 +132,21 @@ $(PKGCONFNAME): hircluster.h
@echo Libs: -L\$${libdir} -lhiredis_cluster >> $@
@echo Cflags: -I\$${includedir} -D_FILE_OFFSET_BITS=64 >> $@

install: $(DYLIBNAME) $(STLIBNAME) $(PKGCONFNAME)
$(SSL_PKGCONFNAME): hircluster_ssl.h
@echo "Generating $@ for pkgconfig..."
@echo prefix=$(PREFIX) > $@
@echo exec_prefix=\$${prefix} >> $@
@echo libdir=$(PREFIX)/$(LIBRARY_PATH) >> $@
@echo includedir=$(PREFIX)/$(INCLUDE_PATH) >> $@
@echo >> $@
@echo Name: hiredis-cluster-ssl >> $@
@echo Description: SSL support for hiredis-cluster. >> $@
@echo Version: $(HIREDIS_CLUSTER_MAJOR).$(HIREDIS_CLUSTER_MINOR).$(HIREDIS_CLUSTER_PATCH) >> $@
@echo Requires: hiredis >> $@
@echo Libs: -L\$${libdir} -lhiredis_cluster_ssl >> $@
@echo Libs.private: -lhiredis_ssl -lssl -lcrypto >> $@

install: $(DYLIBNAME) $(STLIBNAME) $(PKGCONFNAME) $(SSL_INSTALL)
mkdir -p $(INSTALL_INCLUDE_PATH) $(INSTALL_INCLUDE_PATH)/adapters $(INSTALL_LIBRARY_PATH)
$(INSTALL) adlist.h dict.h hiarray.h hircluster.h hiutil.h win32.h $(INSTALL_INCLUDE_PATH)
$(INSTALL) adapters/*.h $(INSTALL_INCLUDE_PATH)/adapters
Expand All @@ -117,6 +156,15 @@ install: $(DYLIBNAME) $(STLIBNAME) $(PKGCONFNAME)
mkdir -p $(INSTALL_PKGCONF_PATH)
$(INSTALL) $(PKGCONFNAME) $(INSTALL_PKGCONF_PATH)

install-ssl: $(SSL_DYLIBNAME) $(SSL_STLIBNAME) $(SSL_PKGCONFNAME)
mkdir -p $(INSTALL_INCLUDE_PATH) $(INSTALL_LIBRARY_PATH)
$(INSTALL) hircluster_ssl.h $(INSTALL_INCLUDE_PATH)
$(INSTALL) $(SSL_DYLIBNAME) $(INSTALL_LIBRARY_PATH)/$(SSL_DYLIB_MINOR_NAME)
cd $(INSTALL_LIBRARY_PATH) && ln -sf $(SSL_DYLIB_MINOR_NAME) $(SSL_DYLIBNAME)
$(INSTALL) $(SSL_STLIBNAME) $(INSTALL_LIBRARY_PATH)
mkdir -p $(INSTALL_PKGCONF_PATH)
$(INSTALL) $(SSL_PKGCONFNAME) $(INSTALL_PKGCONF_PATH)

32bit:
@echo ""
@echo "WARNING: if this fails under Linux you probably need to install libc6-dev-i386"
Expand Down
22 changes: 15 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,14 @@ Prerequisites:
if building without tests (DISABLE_TESTS=ON)
* OpenSSL (`libssl-dev` in Debian) if building with TLS support

Hiredis-cluster will be built as a shared library and the test suites will
additionally depend on the shared library libhiredis.so, and libhiredis_ssl.so
when SSL is enabled.
Hiredis-cluster will be built as a shared library `libhiredis_cluster.so` and
it depends on the hiredis shared library `libhiredis.so`.

When SSL/TLS support is enabled an extra library `libhiredis_cluster_ssl.so`
is built, which depends on the hiredis SSL support library `libhiredis_ssl.a`.

A user project that needs SSL/TLS support should link to both `libhiredis_cluster.so`
and `libhiredis_cluster_ssl.so` to enable the SSL/TLS configuration API.

```sh
$ mkdir build; cd build
Expand Down Expand Up @@ -110,12 +115,15 @@ Options needs to be set with the `-D` flag when generating makefiles, e.g.
### Build details

The build uses CMake's [find_package](https://cmake.org/cmake/help/latest/command/find_package.html#search-procedure)
to search for a `hiredis` installation. When building and installing `hiredis` a
file called `hiredis-config.cmake` will be installed and this contains relevant information for users.

As described in the CMake docs a specific path can be set using a flag like:
to search for a `hiredis` installation. CMake will search for a `hiredis`
installation in the default paths, searching for a file called `hiredis-config.cmake`.
The default search path can be altered via `CMAKE_PREFIX_PATH` or
as described in the CMake docs; a specific path can be set using a flag like:
`-Dhiredis_DIR:PATH=${MY_DIR}/hiredis/share/hiredis`

See `examples/using_cmake_separate/build.sh` or
`examples/using_cmake_externalproject/build.sh` for alternative CMake builds.

### Alternative build using Makefile directly

When a simpler build setup is preferred a provided Makefile can be used directly
Expand Down
30 changes: 12 additions & 18 deletions examples/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,27 @@ project(examples LANGUAGES C)
# Handle libevent and hiredis
find_library(EVENT_LIBRARY event HINTS /usr/lib/x86_64-linux-gnu)
find_package(hiredis REQUIRED)
find_package(hiredis_ssl REQUIRED)
find_package(hiredis_cluster REQUIRED)

add_definitions(-DSSL_SUPPORT)

include_directories("${hiredis_INCLUDE_DIRS}")
include_directories("${hiredis_cluster_INCLUDE_DIRS}")

# Executable: IPv4
add_executable(example_ipv4 example.c)
target_link_libraries(example_ipv4
${hiredis_LIBRARIES}
${hiredis_cluster_LIBRARIES}
${hiredis_ssl_LIBRARIES})
hiredis_cluster::hiredis_cluster)

# Executable: async
add_executable(example_async example_async.c)
target_link_libraries(example_async
${hiredis_LIBRARIES}
${hiredis_cluster_LIBRARIES}
${hiredis_ssl_LIBRARIES}
hiredis_cluster::hiredis_cluster
${EVENT_LIBRARY})

# Executable: tls
add_executable(example_tls example_tls.c)
target_link_libraries(example_tls
${hiredis_LIBRARIES}
${hiredis_cluster_LIBRARIES}
${hiredis_ssl_LIBRARIES}
${EVENT_LIBRARY})
if(ENABLE_SSL)
find_package(hiredis_ssl REQUIRED)
find_package(hiredis_cluster_ssl REQUIRED)

add_executable(example_tls example_tls.c)
target_link_libraries(example_tls
hiredis_cluster::hiredis_cluster
hiredis_cluster::hiredis_cluster_ssl
${EVENT_LIBRARY})
endif()
2 changes: 1 addition & 1 deletion examples/src/example.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#include "hiredis_cluster/hircluster.h"
#include <hiredis_cluster/hircluster.h>
#include <stdio.h>
#include <stdlib.h>

Expand Down
4 changes: 2 additions & 2 deletions examples/src/example_async.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#include "hiredis_cluster/adapters/libevent.h"
#include "hiredis_cluster/hircluster.h"
#include <hiredis_cluster/adapters/libevent.h>
#include <hiredis_cluster/hircluster.h>
#include <stdio.h>
#include <stdlib.h>

Expand Down
7 changes: 4 additions & 3 deletions examples/src/example_tls.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "hiredis_cluster/hircluster.h"

#include "hiredis/hiredis_ssl.h"
#include <hiredis/hiredis.h>
#include <hiredis/hiredis_ssl.h>
#include <hiredis_cluster/hircluster.h>
#include <hiredis_cluster/hircluster_ssl.h>
#include <stdio.h>
#include <stdlib.h>

Expand Down
15 changes: 7 additions & 8 deletions examples/using_cmake_externalproject/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ ExternalProject_Add(hiredis
CMAKE_ARGS
"-DCMAKE_C_FLAGS:STRING=-std=c99"
"-DENABLE_SSL:BOOL=ON"
"-DDISABLE_TESTS:BOOL=ON"
"-DCMAKE_BUILD_TYPE:STRING=Debug"
"-DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_CURRENT_BINARY_DIR}/hiredis"
"-DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_CURRENT_BINARY_DIR}/install"
)

ExternalProject_Add(hiredis_cluster
Expand All @@ -21,9 +22,8 @@ ExternalProject_Add(hiredis_cluster
"-DDISABLE_TESTS:BOOL=ON"
"-DDOWNLOAD_HIREDIS:BOOL=OFF"
"-DCMAKE_BUILD_TYPE:STRING=Debug"
"-DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_CURRENT_BINARY_DIR}/hiredis_cluster"
"-Dhiredis_DIR:PATH=${CMAKE_CURRENT_BINARY_DIR}/hiredis/share/hiredis"
"-Dhiredis_ssl_DIR:PATH=${CMAKE_CURRENT_BINARY_DIR}/hiredis/share/hiredis_ssl"
"-DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_CURRENT_BINARY_DIR}/install"
"-DCMAKE_PREFIX_PATH:PATH=${CMAKE_CURRENT_BINARY_DIR}/install/usr/local"
DEPENDS hiredis
)

Expand All @@ -32,10 +32,9 @@ ExternalProject_Add(examples
SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../src"
INSTALL_COMMAND ""
CMAKE_ARGS
"-DENABLE_SSL:BOOL=ON"
"-DCMAKE_BUILD_TYPE:STRING=Debug"
"-DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_CURRENT_BINARY_DIR}/examples"
"-Dhiredis_DIR:PATH=${CMAKE_CURRENT_BINARY_DIR}/hiredis/share/hiredis"
"-Dhiredis_ssl_DIR:PATH=${CMAKE_CURRENT_BINARY_DIR}/hiredis/share/hiredis_ssl"
"-Dhiredis_cluster_DIR:PATH=${CMAKE_CURRENT_BINARY_DIR}/hiredis_cluster/share/hiredis_cluster"
"-DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_CURRENT_BINARY_DIR}/install"
"-DCMAKE_PREFIX_PATH:PATH=${CMAKE_CURRENT_BINARY_DIR}/install/usr/local"
DEPENDS hiredis_cluster
)
14 changes: 4 additions & 10 deletions examples/using_cmake_separate/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,11 @@ cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DDISABLE_TESTS=ON -DENABLE_SSL=ON \
make DESTDIR=${script_dir}/install install


# Build and install hiredis-cluster from the repo using CMake
# Uses '-Dxxxx_DIR' defines that points to hiredis-config.cmake and hiredis_ssl-config.cmake installed
# above. These files defines paths and variables needed by CMake.
# Build and install hiredis-cluster from the repo using CMake.
mkdir -p ${script_dir}/hiredis_cluster_build
cd ${script_dir}/hiredis_cluster_build
cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DDISABLE_TESTS=ON -DENABLE_SSL=ON -DDOWNLOAD_HIREDIS=OFF \
-DCMAKE_C_FLAGS="-std=c99 -D_XOPEN_SOURCE=600" \
-Dhiredis_DIR=${script_dir}/install/usr/local/share/hiredis \
-Dhiredis_ssl_DIR=${script_dir}/install/usr/local/share/hiredis_ssl \
-DCMAKE_PREFIX_PATH=${script_dir}/install/usr/local \
${repo_dir}
make DESTDIR=${script_dir}/install clean install

Expand All @@ -38,9 +34,7 @@ make DESTDIR=${script_dir}/install clean install
mkdir -p ${script_dir}/example_build
cd ${script_dir}/example_build
cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo \
-DCMAKE_C_FLAGS="-std=c99" \
-Dhiredis_DIR=${script_dir}/install/usr/local/share/hiredis \
-Dhiredis_ssl_DIR=${script_dir}/install/usr/local/share/hiredis_ssl \
-Dhiredis_cluster_DIR=${script_dir}/install/usr/local/share/hiredis_cluster \
-DENABLE_SSL=ON \
-DCMAKE_PREFIX_PATH=${script_dir}/install/usr/local \
${script_dir}/../src
make
Loading

0 comments on commit 7c39940

Please sign in to comment.