Wednesday, April 22, 2015

build redis3m on windows

Foreword

Recently I've needed to build redis c++ client on windows with support of EVAL command.
There are exists some client:
    https://github.com/mrpi/redis-cplusplus-client
and here are it's port to Windows:
    http://sourceforge.net/p/rediscplusplusc
but it had last update "2012-07-24", and eval support in server appeared only in september of 2012. So, it's not my case. redis3m looks good for my case.


tools & versions

  • Windows 8.1
  • Visual Studio 2013 professional
  • Boost 1.57 in directory D:\projects\libraries\boost_1_57_0 with libraries in D:\projects\libraries\boost_1_57_0\stage-x64
Will suppose we are working in D:\tmp dir


action

1) Take "Microsoft Open Technologies" redis (it takes ~3 minutes) (exec in D:\tmp)
    git clone https://github.com/MSOpenTech/redis.git
    Now the last version is "Redis 2.8.19"

2) Open solution
    D:\tmp\redis\msvs\RedisServer.sln
    Choose platform which you need & Build.
    Also here probably you want to insert some defines to get rid of linking errors - [link]
3) Take redis3m (exec in D:\tmp)
    git clone https://github.com/luca3m/redis3m.git
4) Open solution
    D:\tmp\redis3m\Redis3M-VisualStudio\Redis3M-VisualStudio.sln
5) Go to "Redis3M-VisualStudio" -> "properties" -> C/C++ -> General -> "Additional Include Directories"
    replace "E:\github\redis\deps" to "D:\tmp\redis\deps"
6) You need to do something with ERROR bcs in wingdi.h there are:
    /* Region Flags */
    #define ERROR 0
and then you have in reply.h:
enum class type_t
{
    STRING = 1,
    ARRAY = 2,
    INTEGER = 3,
    NIL = 4,
    STATUS = 5,
    ERROR = 6
};


so, one of variants - you can just #undef ERROR. go to files
  • reply.cpp
  • connection.cpp
and after "#include <hiredis/hiredis.h>" insert:
#ifdef ERROR
#undef ERROR
#endif


(another solution - replace every occurrence of type_t::ERROR on something anohter - for example on type_t::MY_LOVELY_ERROR)

7) Build "Redis3M-VisualStudio"

And now you have everything what you need to compile stuff, which uses redis3m.


build simple.cpp example of redis3m

A) Create new project in visual studio

B) Set platform & mode which you want

C) Insert to "Properties" -> "C/C++" -> General -> "Additional Include Directories"
    "D:\tmp\redis3m\include"
    "D:\projects\libraries\boost_1_57_0"

D) Choose in "Properties" -> "C/C++" -> "Code Generation" -> "Runtime library" mode "/MTd" (for debug, or /MT for release)

E) Insert to "Properties" -> Linker -> General -> "Additional Library Directories":
for x64 debug:
    D:\tmp\redis\msvs\x64\Debug
    D:\tmp\redis3m\Redis3M-VisualStudio\Debug\x64
    D:\projects\libraries\boost_1_57_0\stage-x64
for x64 release:
    D:\tmp\redis\msvs\x64\Release
    D:\tmp\redis3m\Redis3M-VisualStudio\Release\x64
    D:\projects\libraries\boost_1_57_0\stage-x64

F) Insert to "Properties" -> Linker -> Input -> "Additional Dependencies":
    redis3m.lib
    Win32_Interop.lib
    hiredis.lib

G) Take "simple.cpp" example from redis3m examples
---------------------------------------------------------
#include <redis3m/redis3m.hpp>
#include <iostream>

using namespace redis3m;

int main(int argc, char **argv)
{
        connection::ptr_t conn = connection::create();
        conn->run(command("SET") << "foo" << "bar" );
        reply r = conn->run(command("GET") << "foo" );   
        std::cout << "FOO is: " << r.str() << std::endl;
}
---------------------------------------------------------

it must compiles


possible errors (for googling people):

If you didn't specify path to 'hiredis/hiredis.h':
-----------------------------------------------------------------------------------------------------------------------------------
1>d:\tmp\redis3m\src\reply.cpp(4): fatal error C1083: Cannot open include file: 'hiredis/hiredis.h': No such file or directory
1>d:\tmp\redis3m\src\connection.cpp(5): fatal error C1083: Cannot open include file: 'hiredis/hiredis.h': No such file or directory
-----------------------------------------------------------------------------------------------------------------------------------
what to do: go to step 5

If you didn't solve problem with ERROR in wingdi.h:
-----------------------------------------------------------------------------------------------------------------------------------
1>d:\tmp\redis3m\include\redis3m\reply.h(30): error C2059: syntax error : 'constant'
1>d:\tmp\redis3m\include\redis3m\reply.h(30): error C3805: 'constant': unexpected token, expected either '}' or a ','
1>d:\tmp\redis3m\include\redis3m\reply.h(60): error C2589: 'constant' : illegal token on right side of '::'
1>d:\tmp\redis3m\include\redis3m\reply.h(60): error C2059: syntax error : '::'
1>d:\tmp\redis3m\include\redis3m\reply.h(61): error C2143: syntax error : missing ';' before '{'
1>d:\tmp\redis3m\include\redis3m\reply.h(64): error C2181: illegal else without matching if
1>d:\tmp\redis3m\src\reply.cpp(10): error C2589: 'constant' : illegal token on right side of '::'
1>d:\tmp\redis3m\src\reply.cpp(10): error C2143: syntax error : missing ')' before '::'
1>d:\tmp\redis3m\src\reply.cpp(10): error C2612: trailing '::' illegal in base/member initializer list
1>d:\tmp\redis3m\src\reply.cpp(32): fatal error C1004: unexpected end-of-file found
1>d:\tmp\redis3m\src\connection.cpp(54): error C2589: 'constant' : illegal token on right side of '::'
1>d:\tmp\redis3m\src\connection.cpp(54): error C2059: syntax error : '::'
1>d:\tmp\redis3m\src\connection.cpp(56): error C2143: syntax error : missing ';' before '{'
-----------------------------------------------------------------------------------------------------------------------------------
what to do: go to step 6 in the note


1 comment: