Building the MySQL and PostgreSQL libraries on Windows

MySQL

MySQL does not support gcc on Windows, only MSVC. Moved to a separate page.

PostgreSQL

Both the C and C++ interfaces build fine “out of the box” (except for the LDFLAGS issue mentioned below) when building shared libraries.

There is a problem when building static libraries, though. The C interface uses the Win32 SSPI authentication interface (secur32.dll). This library is not linked in by default when linking statically, and the Makefiles don't know that. Furthermore, any configure script that uses AC_CHECK_LIB or similar instead of pg_config to look for libpq will also need to link with secur32.dll. There are two solutions: either fix the Makefile and all downstream consumers, or disable SSPI.

Keeping SSPI means a little more work right now (to build libpq and libpqxx) but potentially less pain down the line (as long as downstream consumers use pg_config and / or pkg-config so you don't have to specify -lsecur32 manually).

Another issue is that libpq includes its own implementation of certain POSIX or BSD functions that are missing on Windows, such as inet_aton(). This can conflict with other libraries (e.g. FFmpeg's libavformat) which also include their own private copies of these functions.

libpq (C interface)

PostgreSQL includes its own implementations of certain functions which are not available in Win32, such as inet_aton() and strlcat(). Unfortunately, so do the ffmpeg libraries. We resolve this conflict by using macros to transparently add a pq_ prefix to each of these functions.

NOTE: The PostgreSQL developers have stated quite unambiguously that they do not support static linking and will disable it completely in future releases. If / when that happens, it will be necessary to link libpq (and possibly also the ffmpeg libraries) dynamically.

First, get the latest source (currently 8.3.9 for the 8.3 branch) from http://www.postgresql.org/ftp/source/v8.3.9/ and extract it in a convenient place.

Next, apply the patch below. The easiest way is to just cd into the source directory and type

$ patch -b -l -p0

then copy & paste the patch.

--- src/include/port.h.orig	2009-11-14 16:39:41.000000000 +0100
+++ src/include/port.h	2010-03-10 13:17:27.000000000 +0100
@@ -337,6 +337,7 @@
* When necessary, these routines are provided by files in src/port/.
*/
#ifndef HAVE_CRYPT
+#define crypt pq_crypt
extern char *crypt(const char *key, const char *setting);
#endif
@@ -351,44 +352,60 @@
#endif
#ifndef HAVE_GETOPT
+#define getopt pq_getopt
extern int	getopt(int nargc, char *const * nargv, const char *ostr);
#endif
#ifndef HAVE_ISINF
+#define isinf pq_isinf
extern int	isinf(double x);
#endif
#ifndef HAVE_RINT
+#define rint pq_rint
extern double rint(double x);
#endif
#ifndef HAVE_INET_ATON
#include <netinet/in.h>
#include <arpa/inet.h>
+#define inet_aton pq_inet_aton
extern int	inet_aton(const char *cp, struct in_addr * addr);
#endif
#ifndef HAVE_STRDUP
+#define strdup pq_strdup
extern char *strdup(const char *str);
#endif
+#ifndef HAVE_STRLCAT
+#define strlcat pq_strlcat
+#endif
+
#if !HAVE_DECL_STRLCAT
extern size_t strlcat(char *dst, const char *src, size_t siz);
#endif
+#ifndef HAVE_STRLCPY
+#define strlcpy pq_strlcpy
+#endif
+
#if !HAVE_DECL_STRLCPY
extern size_t strlcpy(char *dst, const char *src, size_t siz);
#endif
#if !defined(HAVE_RANDOM) && !defined(__BORLANDC__)
+#define random pq_random
extern long random(void);
#endif
#ifndef HAVE_UNSETENV
+#define unsetenv pq_unsetenv
extern void unsetenv(const char *name);
#endif
#ifndef HAVE_SRANDOM
+#define srandom pq_srandom
extern void srandom(unsigned int seed);
#endif
--- src/Makefile.global.in.orig	2007-11-13 01:13:19.000000000 +0100
+++ src/Makefile.global.in	2010-03-10 13:42:04.000000000 +0100
@@ -435,9 +435,10 @@
endif
# to make ws2_32.lib the last library, and always link with shfolder,
-# so SHGetFolderName isn't picked up from shell32.dll
+# so SHGetFolderName isn't picked up from shell32.dll. Also link
+# with secur32 for SSPI.
ifeq ($(PORTNAME),win32)
-LIBS += -lws2_32 -lshfolder
+LIBS += -lws2_32 -lshfolder -lsecur32
endif
# Not really standard libc functions, used by the backend.
--- src/template/win32.orig	2004-11-08 06:23:26.000000000 +0100
+++ src/template/win32	2010-03-10 13:40:59.000000000 +0100
@@ -1,4 +1,4 @@
# This is required to link pg_dump because it finds pg_toupper() in
# libpq and pgport
-LDFLAGS="-Wl,--allow-multiple-definition"
+LDFLAGS="${LDFLAGS} -Wl,--allow-multiple-definition"

Then configure:

$ LDFLAGS=-L/c/met.no/lib CPPFLAGS=-I/c/met.no/include ./configure --prefix=/c/met.no --disable-shared

We don't want to install the entire package (server and all); we'll just install the library and headers and the pg_config tool which is used by other packages (such as libpqxx) that link against libpq. This complicates the build process a little, but saves a lot of time:

$ make -C src/port all
$ make -C src/backend utils/fmgroids.h
$ make -C src/backend ../../src/include/utils/fmgroids.h
$ make -C src/include all install
$ make -C src/interfaces/libpq all install
$ make -C src/bin/pg_config all install
$ cp COPYRIGHT /c/met.no/copyright/libpq.txt

libpqxx (C++ interface)

First, get the latest source (currently 3.0.2) from http://pqxx.org/development/libpqxx/wiki/DownloadPage and extract it in a convenient place.

Then configure:

$ LIBS=-lsecur32 LDFLAGS=-L/c/met.no/lib CPPFLAGS=-I/c/met.no/include PG_CONFIG=/c/met.no/bin/pg_config.exe ./configure --prefix=/c/met.no --disable-shared

The LIBS=-lsecur32 part is necessary because libpqxx's configure script uses a plain AC_CHECK_LIB instead of pg_config (which would have told it that it needed -lsecur32).

Finally, build and install:

$ make all install
$ cp AUTHORS /c/met.no/copyright/libpqxx.txt
$ cat COPYING >>/c/met.no/copyright/libpqxx.txt