Building extensions on Windows using VS2008

Started by deepakabout 15 years ago9 messagesgeneral
Jump to latest
#1deepak
deepak.pn@gmail.com

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

#2Craig Ringer
craig@2ndquadrant.com
In reply to: deepak (#1)
Re: Building extensions on Windows using VS2008

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

#3deepak
deepak.pn@gmail.com
In reply to: Craig Ringer (#2)
Re: Building extensions on Windows using VS2008

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:

Show quoted text

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

#4Craig Ringer
craig@2ndquadrant.com
In reply to: deepak (#3)
Re: Building extensions on Windows using VS2008

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

#5deepak
deepak.pn@gmail.com
In reply to: Craig Ringer (#4)
Re: Building extensions on Windows using VS2008

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

#6Craig Ringer
craig@2ndquadrant.com
In reply to: deepak (#5)
Re: Building extensions on Windows using VS2008

On 02/20/2011 09:38 AM, deepak wrote:

build.pl <http://build.pl&gt; 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&gt; 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&gt;
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&gt; 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

#7Magnus Hagander
magnus@hagander.net
In reply to: Craig Ringer (#6)
Re: Building extensions on Windows using VS2008

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&gt; 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&gt; 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&gt;
   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&gt; 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/

#8deepak
deepak.pn@gmail.com
In reply to: Craig Ringer (#6)
Re: Building extensions on Windows using VS2008

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

#9Tom Lane
tgl@sss.pgh.pa.us
In reply to: deepak (#8)
Re: Building extensions on Windows using VS2008

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