c++windowsredishiredis

Develop with hiredis on Windows


Trying to use hiredis on Windows, building a normal c++ application to read from and write to redis. The problem is that hiredis does not officially support building on Windows. How can one build an application utilizing hiredis with c++?


Solution

  • After lots of searches and tries I propose this method using CMake, although the information can be used to build with other build systems too.

    Grab Microsoft's open source redis project and open project file msvs\RedisServer.sln

    Build the project in desired configuration (debug, release, ...)

    Create an environmental variable named hiredis_ROOT (Control Panel->System->Advanced System Settings->Environmental Variables) and set its value to the extracted redis folder

    Create a cmake find module with the content below and put in project root under cmake folder with the name Findhiredis.cmake

    # set search hint directories
    set(
         hiredis_POSSIBLE_ROOT_PATHS
         $ENV{hiredis_ROOT}
         /usr/local
         /usr
    )
    
    
    # find hiredis include directory
    # =================================================================================
    
    find_path(
      hiredis_INCLUDE_DIR
      NAME          hiredis/hiredis.h
      HINTS         ${hiredis_POSSIBLE_ROOT_PATHS}
      PATH_SUFFIXES "include" "deps"
    )
    
    if(NOT hiredis_INCLUDE_DIR)
      message(STATUS "Checking for hiredis... no")
      message(STATUS "Could not find include path for hiredis, try setting hiredis_ROOT")
      return()
    endif()
    
    
    # find hiredis library
    # =================================================================================
    
    # library for debug builds
    find_library(
      hiredis_LIBRARY_DEBUG
      NAMES          hiredis
      HINTS          ${hiredis_POSSIBLE_ROOT_PATHS}
      PATH_SUFFIXES  "msvs/x64/Debug"
      DOC            "hiredis library for debug builds"
    )
    
    # library for release builds
    find_library(
      hiredis_LIBRARY_RELEASE
      NAMES          hiredis
      HINTS          ${hiredis_POSSIBLE_ROOT_PATHS}
      PATH_SUFFIXES  "msvs/x64/Release"
      DOC            "hiredis library for release builds"
    )
    
    # create library name for linking
    set(hiredis_LIBRARY "")
    if(hiredis_LIBRARY_DEBUG AND hiredis_LIBRARY_RELEASE)
      set(hiredis_LIBRARY "optimized;${hiredis_LIBRARY_RELEASE};debug;${hiredis_LIBRARY_DEBUG}")
    elseif(hiredis_LIBRARY_DEBUG)
      set(hiredis_LIBRARY "${hiredis_LIBRARY_DEBUG}")
    elseif(hiredis_LIBRARY_RELEASE)
      set(hiredis_LIBRARY "${hiredis_LIBRARY_RELEASE}")
    endif()
    
    # check the result
    if(NOT hiredis_LIBRARY)
      message(STATUS "Checking for hiredis... no")
      message(STATUS "hiredis include directory: ${hiredis_INCLUDE_DIR}")
      message(STATUS "Could not find hiredis library")
      return()
    endif()
    
    
    # find hiredis' interop library
    # =================================================================================
    
    find_library(
      hiredis_interop_LIBRARY_DEBUG
      NAMES          Win32_Interop
      HINTS          ${hiredis_POSSIBLE_ROOT_PATHS}
      PATH_SUFFIXES  "msvs/x64/Debug"
      DOC            "Windows modified interop library for debug builds"
    )
    
    find_library(
      hiredis_interop_LIBRARY_RELEASE
      NAMES          Win32_Interop
      HINTS          ${hiredis_POSSIBLE_ROOT_PATHS}
      PATH_SUFFIXES  "msvs/x64/Release"
      DOC            "Windows modified interop library for release builds"
    )
    
    set(hiredis_interop_LIBRARY "")
    if(hiredis_interop_LIBRARY_DEBUG AND hiredis_interop_LIBRARY_RELEASE)
      set(hiredis_interop_LIBRARY "optimized;${hiredis_interop_LIBRARY_RELEASE};debug;${hiredis_interop_LIBRARY_DEBUG}")
    elseif(hiredis_interop_LIBRARY_DEBUG)
      set(hiredis_interop_LIBRARY "${hiredis_interop_LIBRARY_DEBUG}")
    elseif(hiredis_interop_LIBRARY_RELEASE)
      set(hiredis_interop_LIBRARY "${hiredis_interop_LIBRARY_RELEASE}")
    endif()
    
    # check the result
    if(NOT hiredis_interop_LIBRARY)
      message(STATUS "Checking for hiredis' interop... no")
      message(STATUS "hiredis include directory: ${hiredis_INCLUDE_DIR}")
      message(STATUS "Could not find hiredis interop library")
      return()
    endif()
    
    
    # Sum up libraries
    # =================================================================================
    
    set(Ws2_32_LIBRARY "optimized;Ws2_32;debug;Ws2_32")
    set(
        hiredis_LIBRARIES
    
        ${hiredis_LIBRARY}
        ${hiredis_interop_LIBRARY}
        ${Ws2_32_LIBRARY}
    )
    
    
    # everything is found. just finish up
    # =================================================================================
    
    set(hiredis_FOUND TRUE CACHE BOOL "Whether hiredis is found on the system or not")
    set(hiredis_INCLUDE_DIR ${hiredis_INCLUDE_DIR} CACHE PATH "hiredis include directory")
    set(hiredis_LIBRARIES ${hiredis_LIBRARIES} CACHE FILEPATH "hiredis library for linking against")
    
    message(STATUS "Checking for hiredis... yes")
    

    include the find module in your top level CMakeLists.txt with this command:

    set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake")
    find_package(hiredis REQUIRED)
    

    Set custom definitions, include paths and link libraries in your cmake project:

    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /D_CRT_SECURE_NO_WARNINGS")
    set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")
    set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT")
    include_directories(${hiredis_INCLUDE_DIR})
    target_link_libraries(my-redis-application ${hiredis_LIBRARIES})
    

    That's it. And you're done.