Building rdfDB on Windows

I've been exploring various RDF databases and I thought I'd give Guha's rdfDB a go. But I wanted to run it on Windows because I do lots of development on my laptop while I'm travelling. Here are the steps I had to go through to get version 0.46 to compile under Windows 2000.

Install MinGW

The first task is to get Windows to act a little bit more UNIXish. MinGW is a port of gcc and many other UNIX based development tools to Windows. I downloaded and installed MinGW-2.0.0-3.exe and MSYS-1.0.8.exe. MSYS offers a BASH shell and various utilities to let you run makefiles and configure scripts.I installed MSYS into the same directory as MinGW for convenience.

Berkeley DB

rdfDB uses Berkeley DB for its various triple stores. Compiling Berkely DB under windows usually requires Visual C++ but there is a way to do it with a combination of MinGW and CygWin. Meilof Veeningen has written up instructions and also conveniently provides binary downloads. I used the 'C' version (bdb-4.0-c-mingw.zip) and unpacked it into the MinGW directory so that the includes and libs went into the appropriate directory.

Pthreads

Pthreads is another UNIXish dependency for rdfDB. RedHat provide a port for Windows. I used pthreads-2003-05-10.exe, which is the latest stable version at the time of writing. I unpacked it and put the includes and libs in the appropriate MinGW directories.

rdfDB

I used version 0.46 from Guha's download page. I unpacked the sources into my home directory and set about building. After some fiddling back and forth I ended up with a version that built

makefile changes

These are the first four lines of my Makefile, the remaining lines were unchanged:

CC = e:mingwbingcc -g
INCLUDES = -I /include -I expat/xmltok -I expat/xmlparse
LIBS     = -ldb -lpthreadGC -lwsock32
CPPFLAGS = $(INCLUDES) -L  e:mingwincludelib
librdf/ncontentSource.c changes

I replaced the UNIX specific networking includes with the Windows winsock equivilent. The includes for this file now look like this:

#ifdef __MINGW32__
        #include 
#else
        #include                        /* for struct hostent */
        #include                        /* for AF_INET */
        #include                        /* for struct in_addr */
        #include                        /* for inet_ntoa() */
#endif
#include 
#include 
#include "contentSource.h"
#include 
#include 
#include "../utils/utils.h"
librdf/rdflib.c changes

While building I got the following errors:

librdf/rdflib.c: In function `RDF_LoadFileAssert':
librdf/rdflib.c:201: conflicting types for `rdfpGetFile'
librdf/rdflib.c:200: previous declaration of `rdfpGetFile'

I fixed this error by moving the declaration of rdfpGetFile above line 200, i.e. from:

200  if (!addRemoveTriple(db, source, arc, target, type,
201                       RDF_ASSERT, getFileCode(rdfp)) && (rdfpGetFile(rdfp))) {
202    extern FILE *rdfpGetFile(RDF_Parser rdfp);
203    FILE *file = rdfpGetFile(rdfp);

to:

200  extern FILE *rdfpGetFile(RDF_Parser rdfp);
201  if (!addRemoveTriple(db, source, arc, target, type,
202                      RDF_ASSERT, getFileCode(rdfp)) && (rdfpGetFile(rdfp))) {
203    FILE *file = rdfpGetFile(rdfp);
librdf/db.c changes

While building I got the following error:

librdf/db.c: In function `openDB':
librdf/db.c:225: `S_IRWXO' undeclared (first use in this function)

It turns out that MinGW doesn't define S_IRWXO (usually found in stat.h). Besides, Windows doesn't support these kind of permissions so I redefined the mkdir function with a macro. I replaced

37 #define ALL_PERMS (S_IRWXU | S_IRWXO | S_IRWXG)

with:

37 #ifdef __MINGW32__
38   #define mkdir(a,b) mkdir(a)
39   #define ALL_PERMS 0
40 #else
41   #define ALL_PERMS (S_IRWXU | S_IRWXO | S_IRWXG)
42 #endif
query/processQuery.c changes

I had to #include <sys/types.h> in this file to get the time_t declaration.

server/loop.c changes

Again, I had to replace the UNIX style network includes with Windows style ones:

#ifdef __MINGW32__
        #include 
#else
        #include        
        #include        
        #include        
#endif

Also, the signalling subsystem of Windows is so different from UNIX that I had to remove references to SIGPIPE for platforms where it's not supported, i.e. line 42:

#ifdef SIGPIPE
  signal(SIGPIPE, catchBrokenPipe);
#endif

and line 164:

#ifdef SIGPIPE
  signal(SIGPIPE, catchBrokenPipe);
#endif

Update 2003-06-19:Windows sockets requires a call to WSAStartup before any sockets are used, so I added the following before the first socket call in the openService function:

#ifdef __MINGW32__
        WSADATA info;
  if (WSAStartup(MAKELONG(1, 1), &info) == SOCKET_ERROR) {
                printf("server: could not initialize socket library.");
    exit(1);
  }
#endif
utils/utils.c changes

For some reason MinGW doesn't define the bzero function, so I used a macro just after the includes section to replace it with a call to memset:

#ifdef __MINGW32__
        #define bzero(ptr,size) memset (ptr, 0, size);
#endif

Running rdfDB

After all those changes, I finally had an rdfDB.exe file in my build directory. To run it I had to copy pthreadGC.dll and libdb.dll to same directory (I could have copied them to my Windows directory instead). It runs . . . but it doesn't work, the server doesn't respond to commands after I connect to it via telnet:

$ rdfdb

rdfDB server 0.46 (Sept 17 2000). For more information see http://www.guha.com/rdfdb/

Binding = 70001 Binding local socket …

If anyone who knows UNIX network programming better than I do has a suggestion, please email me. Thanks.

Links that might be of interest:

Permalink: http://blog.iandavis.com/2003/06/building-rdfdb-on-windows/

Other posts tagged as rdf, technology

Earlier Posts