NOTE: This page is left for reference; Molekel is not however using MinGW anymore as the main Windows build environment, it is therefore not required to have a MinGW build of OpenBabel.

OpenBabel doesn't build out of the box with MinGW, this page describes how to build OpenBabel 2.0.2 and 2.1 (libs only) on Windows with MinGW. Actually OpenBabel libraries do not seem to be built on Windows using the provided VC++ project files neither.

OpenBabel requires libxml2 so make sure you have this library properly installed in your MinGW environment; libxml can be found here: http://xmlsoft.org

OpenBabel 2.1 (libs only)

1 - hash_map

When building OB 2.1 on MinGW you need to disable the usage of hash_map in obmolecformat.h: simply comment the lines where this class is used:

/*depending on the version of gcc installed you might or might not have hash_map in the include path.*/
//#ifdef _WIN32
//  #include <hash_map> 
//#endif

...

//#ifdef _WIN32
  //typedef stdext::hash_map<std::string, unsigned> NameIndexType;
//#else
  typedef std::map<std::string, unsigned> NameIndexType;
//#endif

Note that stdext::hash_map is MS version of something similar to tr1::unordered_map and GCC's __gnu_cxx::hash_map which is in fact a modified version of SGI's ::hash_map; these data types are not however compatible with each other(try to replace stdext::hash_map with __gnu_cxx::hash_map and check the error you get).

2 - gettimeofday()

OpenBabel does need the gettimeofday() function which might or might not be available in your MinGW environment; in case you install MinGW 5.1.3 (gcc 3.4.2) the function should be available as

int __cdecl gettimeofday(struct timeval *__restrict__,
			 void *__restrict__  /*	tzp (unused) */);

Also note that mingw-runtime 3.12 or later should contain a proper implementation of gettimeofday().

If the function is not available, you can simply replace include/sys/time.h with an include containing the following code:

#ifndef _SYS_TIME_H_
#define _SYS_TIME_H_
#include <time.h>

#include <windows.h>


#ifndef _TIMEVAL_DEFINED /* also in winsock[2].h */
#define _TIMEVAL_DEFINED
struct timeval {
  long tv_sec;
  long tv_usec;
};
#define timerisset(tvp)	 ((tvp)->tv_sec || (tvp)->tv_usec)
#define timercmp(tvp, uvp, cmp) \
	(((tvp)->tv_sec != (uvp)->tv_sec) ? \
	((tvp)->tv_sec cmp (uvp)->tv_sec) : \
	((tvp)->tv_usec cmp (uvp)->tv_usec))
#define timerclear(tvp)	 (tvp)->tv_sec = (tvp)->tv_usec = 0
#endif /* _TIMEVAL_DEFINED */

/* Provided for compatibility with code that assumes that
   the presence of gettimeofday function implies a definition
   of struct timezone. */
struct timezone
{
  int tz_minuteswest; /* of Greenwich */
  int tz_dsttime;     /* type of dst correction to apply */
};

/*
   Implementation as per:
   The Open Group Base Specifications, Issue 6
   IEEE Std 1003.1, 2004 Edition

   The timezone pointer arg is ignored.  Errors are ignored.
*/ 

#ifdef	__cplusplus

void  GetSystemTimeAsFileTime(FILETIME*);

inline int gettimeofday(struct timeval* p, void* tz /* IGNORED */)
{
	union {
	    long long ns100; /*time since 1 Jan 1601 in 100ns units */
		FILETIME ft;
	} now;

    GetSystemTimeAsFileTime( &(now.ft) );
    p->tv_usec=(long)((now.ns100 / 10LL) % 1000000LL );
    p->tv_sec= (long)((now.ns100-(116444736000000000LL))/10000000LL);
	return 0;
}

#else 
    /* Must be defined somewhere else */
	int gettimeofday(struct timeval* p, void* tz /* IGNORED */);
#endif

#endif /* _SYS_TIME_H_ */

That's it. With these two changes you'll be able to build the inchi and openbabel libraries.

OpenBabel 2.0.x

Following the instructions in this section you'll be able to build all the libraries and tools except for obgrep which has a dependency on a library which is not included in the OpenBabel distribution: XGetopt and that you can download from here: http://www.codeproject.com/cpp/xgetopt.asp?df=100.

If you try to build OpenBabel 2.0.2 on Windows with MinGW you might get something similar to the following:

./configure
...
make
...
../../src/obutil.h:73: error: `gettimeofday' undeclared (first use this function)      

The compiler is complaining about a missing function; gettimeofday is in fact missing in some MinGW environments (mingw-runtime 3.12 or better should contain a proper implementation of gettimeofday).

To fix this you can do the following:

1. Open src/babelconfig.h.in and add the following declaration:

void gettimeofday( struct timeval* p, void* );

If you build now you get a brand new error message: bondtyper.cpp:21: bondtyp.h: No such file or directory

The problem is that there are a number of files in the data dir which need to be accessible and they are not because this directory is not in the include path, here is part of the gcc command line you get when invoking make: -I. -I. -I. -I../data

To fix this problem you need to add the data dir (where the bondtyp.h resides) to the include path.

2. before running ./configure set the CPPFLAGS evironment variable: export CPPFLAGS="-I <absolute path to data dir>"

Now everything compiles but doesn't link yet because there is no definition of function gettimeofday so in case you try to link you get the following error: undefined reference to `gettimeofday( timeval*, void* ) We need to write the definition of this function in a c++ file and then modify the makefile to include this new source file.

3. create a file gettimeofday.cpp and add the following code into it:

   #include <windows.h>
   #include <sys/time.h>

   void __stdcall GetSystemTimeAsFileTime(FILETIME*);

   void gettimeofday(struct timeval* p, void* tz /* IGNORED */)
   {
	  union {
	     long long ns100; /*time since 1 Jan 1601 in 100ns units */
		 FILETIME ft;
	  } now;

      GetSystemTimeAsFileTime( &(now.ft) );
      p->tv_usec=(long)((now.ns100 / 10LL) % 1000000LL );
      p->tv_sec= (long)((now.ns100-(116444736000000000LL))/10000000LL);
   }

4. Modify Makefile.in adding gettimeofday.cpp to the list of source files:

 ...
   @BUILD_SHARED_TRUE@ fingerprints/libfingerprints.la @LTLIBOBJS@
   am__libopenbabel_la_SOURCES_DIST = gettimeofday.cpp atom.cpp base.cpp bitvec.cpp \
   ...
   @BUILD_SHARED_TRUE@am__objects_1 = dlhandler_unix.lo
   am_libopenbabel_la_OBJECTS = gettimeofday.lo base.lo bitvec.lo bond.lo \
   ...
   libopenbabel_la_SOURCES = \
		gettimeofday.cpp atom.cpp base.cpp bitvec.cpp bond.cpp \
   ...

If you build it with the current configuration you will incur in another problem: the dynamic library handler is set to unix

5. substitute all the instances of dlhandler_unix.xxx in Makefile.in with dlhandler_win32.xxx, there should be a total of five occurrences in the file. The use of a dynamic library handler should be automatically enabled when shared library support is turned on (default). In case dlhandler is set to null in Makefile you'll have to manually remove @BUILD_SHARED_TRUE@ in front of am_objects_1 AND dlhandler =dlhandler_win32.cpp you have to do this if you get a link error about an undefined symbol __imp_XXXDLHandler9openFileXXXX

At this point the libraries build but not the executables.

6. if you want to build the executables you'll have to open all the cpp files in the test and tools folder and comment #define USING_OBDLL i.e.

// used to set import/export for Cygwin DLLs
#ifdef WIN32
//#define USING_OBDLL
#endif

7. run configure --prefix=<installation folder> then make: this will build the libraries into src/.libs, and the executables in the src, tools and test folders. You can then run make install. Note that to have make install succeed you have to also fix obgrep.cpp so that it can somehow build: either you get the XGetopt library mentioned at the beginning of this document, build it with MinGW and link with it or you can simply comment the code in obgrep.cpp main function.