Thread: Building extensions on Windows using VS2008

Building extensions on Windows using VS2008

From
deepak
Date:
Hi!

I was trying to build PostgreSQL 9.0.1 using VS2008.  I am having problems building the C extensions.  I could build the main package, though.

Although, I can get a DLL by including the header files from postgres, that DLL is quite not usable.  When I try to create a function inside
psql, I get an error such as:
ERROR:  could not find function "<function-name>" in file  <dll-name>

Although the same C source file can be built using MinGW and is usable that way.  I don't want to use MinGW as I learn that it supports
only 32-bit binaries (which has performance implications).

Here is the CL command line I'm using to compile:
cl /I \pgsql\include\server /I \pgsql\include\server\port\win32 /LD \pgsql\lib\postgres.lib <c-filename>

--
Deepak

Re: Building extensions on Windows using VS2008

From
Craig Ringer
Date:
On 15/02/11 06:28, deepak wrote:
> Hi!
>
> I was trying to build PostgreSQL 9.0.1 using VS2008.  I am having
> problems building the C extensions.  I could build the main package, though.

The easiest way to do it on Windows is to make a new `contrib' module
and compile as part of the main build. Just copy the structure of an
existing contrib module to get the idea.

I don't know if pgxs works on Windows, having never tried it. If it
does, that's another alternative.

> Here is the CL command line I'm using to compile:
> cl /I \pgsql\include\server /I \pgsql\include\server\port\win32 /LD
> \pgsql\lib\postgres.lib <c-filename>

You're missing critical macro definitions, among other things. Don't try
to just invoke the compiler directly, use the build system to do it.

--
System & Network Administrator
POST Newspapers

Re: Building extensions on Windows using VS2008

From
deepak
Date:
Thanks for the information..

However, I'm still unable to figure how to do a clean build of extensions on Windows using VS 2008.

To start with, the main contrib module doesn't seem to have a nmake-compatible Makefile, and
I don't seem to find any project under 'contrib' which has a Windows-compatible build..

From the earlier command line I had posted, it appears that there's a conflict between 'errcode'
defined in VS (crtdefs.h) and the one that PostgreSQL brings (utils/elog.h).

Specifically, here is the error:
\pgsql\include\server\utils/elog.h(118) : error C2365: 'errcode' : redefinition; previous definition was 'typedef'
        C:\Program Files (x86)\Microsoft Visual Studio 2008 Professional Edition
 - ENU\VC\INCLUDE\crtdefs.h(548) : see declaration of 'errcode'


--
Deepak

On Mon, Feb 14, 2011 at 10:25 PM, Craig Ringer <craig@postnewspapers.com.au> wrote:
On 15/02/11 06:28, deepak wrote:
> Hi!
>
> I was trying to build PostgreSQL 9.0.1 using VS2008.  I am having
> problems building the C extensions.  I could build the main package, though.

The easiest way to do it on Windows is to make a new `contrib' module
and compile as part of the main build. Just copy the structure of an
existing contrib module to get the idea.

I don't know if pgxs works on Windows, having never tried it. If it
does, that's another alternative.

> Here is the CL command line I'm using to compile:
> cl /I \pgsql\include\server /I \pgsql\include\server\port\win32 /LD
> \pgsql\lib\postgres.lib <c-filename>

You're missing critical macro definitions, among other things. Don't try
to just invoke the compiler directly, use the build system to do it.

--
System & Network Administrator
POST Newspapers

Re: Building extensions on Windows using VS2008

From
Craig Ringer
Date:
On 02/20/2011 05:30 AM, deepak wrote:
> Thanks for the information..
>
> However, I'm still unable to figure how to do a clean build of
> extensions on Windows using VS 2008.
>
> To start with, the main contrib module doesn't seem to have a
> nmake-compatible Makefile, and
> I don't seem to find any project under 'contrib' which has a
> Windows-compatible build..

build.pl parses the Makefile to determine the list of sources, etc.
Essentially, your extension is built using the unix Makefile.  Since
you've already built Pg its self from sources you will have used
build.pl to do it (right?) and it'll be easy for you to add the contrib
module and re-run.

The downside of this approach is that build.pl isn't a complete Makefile
parser, and is easily confused by anything but the most trivial Makefile
syntax. I had problems when I was putting the crashdump module together
because build.pl didn't understand ifndef .

--
Craig Ringer

Re: Building extensions on Windows using VS2008

From
deepak
Date:


build.pl parses the Makefile to determine the list of sources, etc. Essentially, your extension is built using the unix Makefile.  Since you've already built Pg its self from sources you will have used build.pl to do it (right?) and it'll be easy for you to add the contrib module and re-run.

The downside of this approach is that build.pl isn't a complete Makefile parser, and is easily confused by anything but the most trivial Makefile syntax. I had problems when I was putting the crashdump module together because build.pl didn't understand ifndef .

--
Craig Ringer

Ok, I hadn't realized that the VS build system extrapolates information from unix Makefiles..

I briefly tried adding a new contrib module for my extension and re-running the VS build (src\tools\msvc\build.bat), and still get the same error.
(about redefinition of errcode).  Somehow, it seems to me that there's an inherent incompatibility..


--
Deepak

Re: Building extensions on Windows using VS2008

From
Craig Ringer
Date:
On 02/20/2011 09:38 AM, deepak wrote:
>
>
>     build.pl <http://build.pl> parses the Makefile to determine the list
>     of sources, etc. Essentially, your extension is built using the unix
>     Makefile.  Since you've already built Pg its self from sources you
>     will have used build.pl <http://build.pl> to do it (right?) and
>     it'll be easy for you to add the contrib module and re-run.
>
>     The downside of this approach is that build.pl <http://build.pl>
>     isn't a complete Makefile parser, and is easily confused by anything
>     but the most trivial Makefile syntax. I had problems when I was
>     putting the crashdump module together because build.pl
>     <http://build.pl> didn't understand ifndef .
>
>     --
>     Craig Ringer
>
>
> Ok, I hadn't realized that the VS build system extrapolates information
> from unix Makefiles..
>
> I briefly tried adding a new contrib module for my extension and
> re-running the VS build (src\tools\msvc\build.bat), and still get the
> same error.
> (about redefinition of errcode).  Somehow, it seems to me that there's
> an inherent incompatibility..

OK, so you're building it within the main Pg build system. Pg was
successfully compiled, including files that use elog.h . Yet your
extension doesn't compile, complaining about a macro/typedef conflict.

This makes me wonder: what's different?

Can you post the full sources of your extension, including the Makefile?

--
Craig Ringer

Re: Building extensions on Windows using VS2008

From
Magnus Hagander
Date:
On Sun, Feb 20, 2011 at 05:39, Craig Ringer <craig@postnewspapers.com.au> wrote:
> On 02/20/2011 09:38 AM, deepak wrote:
>>
>>
>>    build.pl <http://build.pl> parses the Makefile to determine the list
>>    of sources, etc. Essentially, your extension is built using the unix
>>    Makefile.  Since you've already built Pg its self from sources you
>>    will have used build.pl <http://build.pl> to do it (right?) and
>>    it'll be easy for you to add the contrib module and re-run.
>>
>>    The downside of this approach is that build.pl <http://build.pl>
>>    isn't a complete Makefile parser, and is easily confused by anything
>>    but the most trivial Makefile syntax. I had problems when I was
>>    putting the crashdump module together because build.pl
>>    <http://build.pl> didn't understand ifndef .
>>
>>    --
>>    Craig Ringer
>>
>>
>> Ok, I hadn't realized that the VS build system extrapolates information
>> from unix Makefiles..
>>
>> I briefly tried adding a new contrib module for my extension and
>> re-running the VS build (src\tools\msvc\build.bat), and still get the
>> same error.
>> (about redefinition of errcode).  Somehow, it seems to me that there's
>> an inherent incompatibility..
>
> OK, so you're building it within the main Pg build system. Pg was
> successfully compiled, including files that use elog.h . Yet your extension
> doesn't compile, complaining about a macro/typedef conflict.
>
> This makes me wonder: what's different?

First check would be that you are including postgres.h *at the top* of
your files. It will bring in some defines that affects the windows
header files.

It does (through c.h) have specific handling of errcode on MSVC, for
example.... See around line 60.

--
 Magnus Hagander
 Me: http://www.hagander.net/
 Work: http://www.redpill-linpro.com/

Re: Building extensions on Windows using VS2008

From
deepak
Date:

OK, so you're building it within the main Pg build system. Pg was successfully compiled, including files that use elog.h . Yet your extension doesn't compile, complaining about a macro/typedef conflict.

This makes me wonder: what's different?

Can you post the full sources of your extension, including the Makefile?

--
Craig Ringer

Here's the trimmed down version of the source and the Makefile (copied and modified from the 'cube' contrib project)
(with which I see the error related to redefinition)

/* myext.c */

#include <string.h>
#include <math.h>
#include "postgres.h"
#include "fmgr.h"

#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif

PG_FUNCTION_INFO_V1(total_seconds);
PGDLLEXPORT Datum total_seconds(PG_FUNCTION_ARGS) {
    PG_RETURN_INT64(0);
}


# Makefile

MODULE_big = myext
OBJS= myext.o

DATA_built = myext.sql
DATA = uninstall_myext.sql
REGRESS = myext

SHLIB_LINK += $(filter -lm, $(LIBS))

ifdef USE_PGXS
PG_CONFIG = pg_config
PGXS := $(shell $(PG_CONFIG) --pgxs)
include $(PGXS)
else
subdir = contrib/myext
top_builddir = ../..
include $(top_builddir)/src/Makefile.global
include $(top_srcdir)/contrib/contrib-global.mk
endif


myext.o: myext.c

clean:
    rm -f myext.o

Re: Building extensions on Windows using VS2008

From
Tom Lane
Date:
deepak <deepak.pn@gmail.com> writes:
> Here's the trimmed down version of the source and the Makefile (copied and
> modified from the 'cube' contrib project)
> (with which I see the error related to redefinition)

> /* myext.c */

> #include <string.h>
> #include <math.h>
> #include "postgres.h"
> #include "fmgr.h"

As was noted upthread, this ordering is pretty unsafe.  postgres.h
should always be included *first* in any C file that's meant to run in
the backend environment.  There are platforms in which failing to do so
causes crashes because of 32-vs-64-bit issues.  Not sure if this
explains your Windows issue too, but in any case the above is wrong.

> myext.o: myext.c

> clean:
>     rm -f myext.o

BTW, these rules are unnecessary --- having listed myext.o in OBJS is
sufficient.

            regards, tom lane