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:
$ rdfdbrdfDB 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: