I’ve written already a blog post “Building PostgreSQL with MSYS2 and MinGW under Windows” a year ago. But this time I want to show you two important things:

  1. cross compiling (x86, x64) using the same run-time;
  2. compiling with the latest OpenSSL support.


That’s true nowadays you won’t find binaries or installations of PostgreSQL without OpenSSL support. It used not only for encryption but for compression as well.

Even though it’s Windows, let’s make all steps in command prompt only. Yes, I told you Linux guys, we can run console too!

Setting up the environment

First things first. I launch my msys2 shell. I assume you have it on your system, if not check installation instructions from my previous post.

c:\msys64\ is the msys2 installation folder.

C:\Users\pasha>c:\msys64\msys2_shell.cmd -mingw64 -conemu

I’m telling msys2 to run shell and use -mingw64 as a default chain. That means we will build x64 binaries. -conemu is an optional parameter, you may want to pass it in case you’re a fan of ConEmu as I am. If not, just skip it.

pasha@PG480 MINGW64 ~
$ mkdir /src

pasha@PG480 MINGW64 ~
$ cd /src

pasha@PG480 MINGW64 /src
$ git clone https://github.com/openssl/openssl.git --branch OpenSSL_1_1_1-stable --depth 1
Cloning into 'openssl'...
remote: Enumerating objects: 18297, done.
remote: Counting objects: 100% (18297/18297), done.
remote: Compressing objects: 100% (15182/15182), done.
remote: Total 18297 (delta 884), reused 14976 (delta 582), pack-reused 0
Receiving objects: 100% (18297/18297), 13.48 MiB | 1.38 MiB/s, done.
Resolving deltas: 100% (884/884), done.
Checking out files: 100% (18166/18166), done.

pasha@PG480 MINGW64 /src
$ git clone https://github.com/postgres/postgres.git --branch REL_11_STABLE --depth 1
Cloning into 'postgres'...
remote: Enumerating objects: 5868, done.
remote: Counting objects: 100% (5868/5868), done.
remote: Compressing objects: 100% (5365/5365), done.
remote: Total 5868 (delta 754), reused 1296 (delta 317), pack-reused 0
Receiving objects: 100% (5868/5868), 21.97 MiB | 7.36 MiB/s, done.
Resolving deltas: 100% (754/754), done.
Checking out files: 100% (5467/5467), done.

Inside msys2 we are using Unix-like filesystem with root / and Windows drives mounted as /c, /d, etc.

We’re creating /src/ folder for storing sources and cloning both PostgreSQL and OpenSSL sources.

By providing an argument of --depth 1 to the clone command, the process will copy only the latest revision of everything in the repository.

And of course, we want to build only stable releases for production, thus --branch *_STABLE. You may omit this parameter to build the latest sources from the master branch.

Building OpenSSL

pasha@PG480 MINGW64 /src
$ cd /src/openssl

pasha@PG480 MINGW64 /src/openssl
$ rm -rf test/*

pasha@PG480 MINGW64 /src/openssl                                                 
$ ./Configure --prefix=/usr/local/openssl64 no-idea no-mdc2 no-rc5 shared mingw64
Configuring OpenSSL version 1.1.1d-dev (0x10101040L) for mingw64                 
Using os-specific seed configuration                                             
Creating configdata.pm                                                           
Creating Makefile                                                                
***                                                                ***           
***   OpenSSL has been successfully configured                     ***           
***                                                                ***           
***   If you encounter a problem while building, please open an    ***           
***   issue on GitHub <https://github.com/openssl/openssl/issues>  ***           
***   and include the output from the following command:           ***           
***                                                                ***           
***       perl configdata.pm --dump                                ***           
***                                                                ***           
***   (If you are new to OpenSSL, you might want to consult the    ***           
***   'Troubleshooting' section in the INSTALL file first)         ***           
***                                                                ***           

pasha@PG480 MINGW64 /src/openssl
$ make clean && make -j4 install_dev
rm -f libcrypto-1_1-x64.dll
rm -f libcrypto.dll.a
rm -f libssl-1_1-x64.dll
rm -f libssl.dll.a
rm -f apps/libapps.a libcrypto.a libssl.a
rm -f *.map
created directory `/usr/local/openssl64/lib'
install libcrypto.a -> /usr/local/openssl64/lib/libcrypto.a
install libssl.a -> /usr/local/openssl64/lib/libssl.a
install libcrypto.dll.a -> /usr/local/openssl64/lib/libcrypto.dll.a
install libssl.dll.a -> /usr/local/openssl64/lib/libssl.dll.a
created directory `/usr/local/openssl64/lib/pkgconfig'
install libcrypto.pc -> /usr/local/openssl64/lib/pkgconfig/libcrypto.pc
install libssl.pc -> /usr/local/openssl64/lib/pkgconfig/libssl.pc
install openssl.pc -> /usr/local/openssl64/lib/pkgconfig/openssl.pc

Removing tests test/* is not necessary, but it may take a lot of time during development and constant remaking.

Configure OpenSSL installation with output folder /usr/local/openssl64, force produce shared libraries and use mingw64 chain.

make install_dev will install everything needed for development and further PostgreSQL build process.

Building PostgreSQL

pasha@PG480 MINGW64 /src/openssl
$ cd /src/postgres

pasha@PG480 MINGW64 /src/postgres
$ ./configure --prefix=/usr/local/postgres64 --with-openssl --with-includes=/usr/local/openssl64/include --with-libraries=/usr/local/openssl64/lib
configure: loading site script /mingw64/etc/config.site
checking build system type... x86_64-w64-mingw32
checking host system type... x86_64-w64-mingw32
checking which template to use... win32
checking whether NLS is wanted... no
checking for default port number... 5432
checking for block size... 8kB
checking for segment size... 1GB
checking for WAL block size... 8kB
checking for gcc... gcc
checking for library containing CRYPTO_new_ex_data... -lcrypto
checking for library containing SSL_new... -lssl
checking for SSL_clear_options... yes
checking for SSL_get_current_compression... yes
checking for X509_get_signature_nid... yes
checking for OPENSSL_init_ssl... yes
config.status: linking src/backend/port/dynloader/win32.c to src/backend/port/dynloader.c
config.status: linking src/backend/port/win32_sema.c to src/backend/port/pg_sema.c
config.status: linking src/backend/port/win32_shmem.c to src/backend/port/pg_shmem.c
config.status: linking src/backend/port/dynloader/win32.h to src/include/dynloader.h
config.status: linking src/include/port/win32.h to src/include/pg_config_os.h
config.status: linking src/makefiles/Makefile.win32 to src/Makefile.port
config.status: executing check_win32_symlinks commands

pasha@PG480 MINGW64 /src/postgres
$ make clean && make -j4 -C src/common && make -j4 -C src/interfaces install
make -C doc clean
make[1]: Entering directory '/src/postgres/doc'
make -C src clean
make[2]: Entering directory '/src/postgres/doc/src'
make -C sgml clean
make[3]: Entering directory '/src/postgres/doc/src/sgml'
/usr/bin/install -c -m 644  libecpg_compat.a '/usr/local/postgres64/lib/libecpg_compat.a'
/usr/bin/install -c -m 755  libecpg_compat.dll '/usr/local/postgres64/bin/libecpg_compat.dll'
make[2]: Leaving directory '/src/postgres/src/interfaces/ecpg/compatlib'
make[1]: Leaving directory '/src/postgres/src/interfaces/ecpg'
make: Leaving directory '/src/postgres/src/interfaces'

Configure PostgreSQL installation with output folder /usr/local/postgres64, use OpenSSL --with-openssl, use additional includes /usr/local/openssl64/include and libraries from /usr/local/openssl64/lib. As you can see all paths are pointing to freshly installed OpenSSL.

In configure output pay attention to highlighted lines 17-22. In case of any trouble, you will see the proper message there.

If you want to build the whole tree, just run make. But in my example, I’m showing how to build a portion of it, in this particular case I’m building only interfaces, e.g. libpq, ecpg, etc. This is a common task for packaging and deploy of client software.


All built binaries are available at /usr/local/openssl64 and /usr/local/postgres64. Let’s check:

pasha@PG480 MINGW64 /src/postgres
$ ls /usr/local/postgres64/bin
ecpg.exe  libecpg.dll  libecpg_compat.dll  libpgtypes.dll  libpq.dll

To make that same process produce x86 binaries one should start msys2 shell with the command:

C:\Users\pasha>c:\msys64\msys2_shell.cmd -mingw32

Super easy! I hope now it’s become clearer. Next time I will show you how to build PostgreSQL extensions. Even if they are not supposed to be Windows ready and have no Visual Studio packages.