Compiling PostgreSQL extensions with Visual Studio 2026 on Windows

February 17, 2026

This blog was co-authored by Craig Ringer and Xavier Fischer. This is an updated version of Craig Ringer's Compiling PostgreSQL extensions with Visual Studio on Windows blog post, with Visual Studio 2026.

I’ve seen a number of users struggling with building PostgreSQL extensions under Visual Studio, so I thought I’d see what’s involved in getting it working. The result is this tutorial, showing how to compile a simple extension with Visual Studio 2026 Community.

Requirements

You will need a supported version of Visual Studio installed. These instructions refer to Visual Studio 2026 Community Edition. It is not necessary to use the same Visual Studio version as PostgreSQL was compiled with, or the same version I’m using here. You do need to make sure your Visual Studio version is supported by the release of PostgreSQL you’re targeting (or modify Configuration Properties -> General -> Platform Toolkit to use an older, supported toolkit). If you’re not using VS 2026, some details will of course differ.

You will also need the "Desktop development with C++" workload, which can be downloaded via the "Visual Studio Installer" program.

C++ workload installation

To follow these instructions step by step you’ll also need a x64 PostgreSQL install.

Bugs and caveats

I’ve only tested against PostgreSQL 18.2 64-bit version, on Windows 11 with MS Visual Studio 2026. I used the v145 (default) toolchain for the 64-bit build.

There's no more issues with 64-bit toolchain or missing libintl.h; as you'll see the process in now pretty straightforward.

Step by step

Create a new Project (and new Solution if there isn’t one already) with File->New, Project. Use the Empty Project C++ template. I’ll call my example DemoExtension.

Add the source file

Open the new project tree for DemoExtension. Right-click on “Source files” and choose “Add -> New Item”. Create a new C++ source file with your choice of name. Mine is DemoExtension.c. You must explicitly enter the file extension as .c; otherwise Visual Studio will compile the sources as C++, which won’t work with PostgreSQL.

DemoExtension code file

Now paste the example extension code from the PostgreSQL documentation section “Version 1 Calling Conventions” – from the start includes and PG_MODULE_MAGIC to the end of the add_one function. Insert PGDLLEXPORT before Datum on the line before add_one. You should also add a prototype marked PGDLLEXPORT for the function so that MSVC knows to export its symbol.

#include "postgres.h"
#include <string.h>
#include "fmgr.h"
#include "utils/geo_decls.h"

#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif

/* Add a prototype marked PGDLLEXPORT */
PGDLLEXPORT Datum add_one(PG_FUNCTION_ARGS);

PG_FUNCTION_INFO_V1(add_one);

Datum
add_one(PG_FUNCTION_ARGS)
{
    int32   arg = PG_GETARG_INT32(0);

    PG_RETURN_INT32(arg + 1);
}

Visual Studio doesn’t know where the headers are, so it’ll highlight most of the file with error markers. We need to tell it where PostgreSQL’s headers and libraries are before we can build the project – and make a few other changes while we’re at it.

Project configuration

Select the DemoExtension project in the Solution Explorer and click the Get properties wrench icon.

Project properties

In “Configuration” (top left), choose “All Configurations”.

All configurations

General settings

  • Under Configuration Properties -> General, set “Configuration Type” to “Dynamic Library (.dll)”.
     
  • Under C/C++ -> Code Generation, set “Enable C++ Exceptions” to “No”, and under “Advanced” set “Compile As” to “C Code”.
     
  • Under Linker -> Manifest File, set “Generate Manifest” to “No”.
     
  • Under Linker -> Input -> Additional Dependencies, add postgres.lib to the library list. Do not uncheck “Inherit from parent or project defaults”. Trivial extensions don’t require this, but if you link to any server functions you’ll require it.

Include and library directories

Now you need to add the required include directories.

In the properties dialog, go to Configuration Properties -> C/C++ -> General. In Additional Include Directories, pull down the arrow in the right of the textbox and choose “Edit...”. Now, by pasting paths or by folder selection, add the following folders inside your PostgreSQL install directory in this order:

C:\Program Files\PostgreSQL\18\include\server\port\win32_msvc
C:\Program Files\PostgreSQL\18\include\server\port\win32
C:\Program Files\PostgreSQL\18\include\server
C:\Program Files\PostgreSQL\18\include

On my system that looks like:

Additional includes

You’ll also need to set the library path. Under “Linker”->”General”, in Additional Library Directories. In my case that’s C:\Program Files\PostgreSQL\18\lib. While you’re there, set Link Library Dependencies to No.

Click “OK”. The error highlights on your extension file should go away when you return to the source file.

Building the project

Choose “Release” from the pull-down menu.

Release mode

Right-click on your project in the solution explorer and choose “Build”.

You should get no errors in the build output.

Installation and testing

At this point you must fish the DLL out of the project and copy it into PostgreSQL’s lib directory. In my case that means copying <project root>\x64\Release\DemoExtension.dll to C:\Program Files\PostgreSQL\18\lib.

Since we have not defined the control file or setup file for an extension, we’ll just manually load the extension by connecting as user postgres or another superuser, and running:

CREATE FUNCTION add_one(integer) RETURNS integer
     AS 'DemoExtension', 'add_one'
     LANGUAGE C STRICT;

If all goes well, you can now use your brand new extension:

postgres=# CREATE FUNCTION add_one(integer) RETURNS integer
postgres-#      AS 'DemoExtension', 'add_one'
postgres-#      LANGUAGE C STRICT;
CREATE FUNCTION
postgres=# SELECT add_one(4);
 add_one
---------
       5
(1 row)

If you were to deploy your extension to others, you’d want to create a .control file and an extension SQL setup file, per the PostgreSQL documentation.

Related work

Shortly after finishing this, while searching for reports of users who’d been struggling with building extensions on Windows, I found Build PostgreSQL C Functions on Windows by Tim Child. I didn’t use his article as a resource when writing this, and thankfully a few things have improved since then. It looks like a good resource, so if you find yourself stuck take a look at it.

Share this