In the previous blog post, we discussed the different Windows build variants that PostgreSQL supports. In this post, we’ll discuss how, as a Unix-based developer, you can check whether your patch might work on Windows. (For simplicity, I’ll say “Unix” to mean Linux, BSD, macOS, and similar.)
First, there are a few ways to check your patch without having to have Windows at all.
If your patch touches the build system, for example by adding new files, or more likely by adding conditionals, new build options, or additional ad-hoc logic, it might break the MSVC build scripts, which parse the Unix makefiles, as we discussed last time. But you can actually run those scripts on Unix as well. There is (almost) nothing specific to Windows in them, since all they really do is parse one set of files and produce another. You can just run
perl src/tools/msvc/mkvcbuild.pl
and see what happens. This works as of commit 73c8596. (Maybe save your work beforehand, because this might overwrite some generated files to are used by your local non-Windows configuration). This will produce project files for Visual Studio that you can’t do much with, but you can check whether the script ran at all, you can compare the output before and after, or if you have made “blind edits” to any of the files under src/tools/msvc/
you can verify those to some extent.
Another way is to exercise build options that are typically associated with Windows. Which one of these is useful depends on what your patch changes. For example, Windows builds with HAVE_UNIX_SOCKETS
undefined, so testing that manually might be worthwhile if you are making changes in network code. (But this is going away, since Windows does actually support Unix-domain sockets now.) Similarly, HAVE_WORKING_LINK
is undefined on Windows, although the impact of that is small (and it’s also going away; sometimes a consequence of writing blog posts like this one is to discover that the problems you wanted to describe shouldn’t be there in the first place, and you go fix them). You can change both of these options by editing src/include/pg_config_manual.h
. Another important option is EXEC_BACKEND
, which replaces the Unix-style fork()
call with a fork()
plus exec()
implementation that can be mapped to CreateProcess()
on Windows. This actually breaks surprisingly rarely, but if it does, you can debug and fix it entirely on a Unix system. To enable EXEC_BACKEND
, you can either edit src/Makefile.global
and add -DEXEC_BACKEND
to CPPFLAGS
, or perhaps add a define to src/include/pg_config_manual.h
. (Not sure why this is different from the other ones; perhaps another thing to fix sometime. [update: also fixed])
When these options are exhausted, then it’s perhaps time to spin up a real Windows system. I want to discuss two options that are easily available to the casual developer. First, you can download a demo Windows image from Microsoft and import it into VirtualBox or something similar. The current links for that that I can find are:
- https://developer.microsoft.com/en-us/windows/downloads/virtual-machines/
- https://developer.microsoft.com/en-us/microsoft-edge/tools/vms/
The second one of these is meant for browser testing, so perhaps the first one is better now, but the browser-testing route has been popular for some time. These are free of charge evaluation copies, but please read the license yourself.
Second, you can launch a cloud instance at a cloud computing provider. I’m not going to name them, but you know who they are.
When you have the Windows operating system running, I recommend installing MSYS2. (The first download link above from Microsoft also has Visual Studio installed, if you prefer that.) Use a browser (presumably Internet Explorer or whatever it’s called now) to go to msys2.org, run the installer, and in a few minutes you will have a full MSYS2/MinGW environment ready. Follow the instructions on the msys2.org web site to get the package manager up to date. Then, open a MinGW (not MSYS2) shell from the Start menu and run the following to get the packages needed for PostgreSQL development:
pacman -S git
Now you can git clone the repository. While that runs …
pacman -S ${MINGW_PACKAGE_PREFIX}-gcc ${MINGW_PACKAGE_PREFIX}-gettext ${MINGW_PACKAGE_PREFIX}-icu ${MINGW_PACKAGE_PREFIX}-libxml2 ${MINGW_PACKAGE_PREFIX}-libxslt ${MINGW_PACKAGE_PREFIX}-openssl bison flex make diffutils
MINGW_PACKAGE_PREFIX
is an environment variable that is set for you, so type in the commands like that. (It will be different for 32-bit and 64-bit MinGW.) The packages without prefix are MSYS2 (i.e., Cygwin) packages. See part 1 again if this is confusing. At this point, you’ll have a full MinGW build environment for PostgreSQL. You can run configure, make, make check, and so on. Additional packages may be required for some build options, but not all options actually work; for example no Readline (use Cygwin for that).
In the next part of this series, I will look at automatic build/continuous integration options for Windows that can be used to verify patches.