Skip to content

Commit

Permalink
Fix to allow building pljava with Microsoft Visual C
Browse files Browse the repository at this point in the history
Code changes to allow compilation and linking with Microsoft
Visual C. Maven build process conditionalized to to detect Visual C
and adjust options appropriately. See msvc-build-notes.txt for
full details. Property names updated for clarity
  • Loading branch information
Kenneth Olson committed Jul 23, 2015
1 parent 328fc5d commit dbf2bdc
Show file tree
Hide file tree
Showing 8 changed files with 205 additions and 7 deletions.
74 changes: 74 additions & 0 deletions msvc-build-notes.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
pljava-so/pom.xml is conditionalized for Microsoft Visual C versus
other platforms based on the environment variable VCINSTALLDIR that
is defined in the MSVC vcvars*.bat files.

The Java architecture and shared library / dll architecture must
match - use a 32-bit JDK if you are building a 32-bit library and
use a 64-bit JDK if you are building a 64-bit library.

You must define environment variables:
JAVA6_HOME to point to a Java 6 JDK
JAVA_HOME MUST point to the same Java 6 JDK
This Java 6 JDK must be the FIRST Java found on your path
Fail do these things and the pljava-examples project will fail to build.

For compiling with Microsoft Visual C -
For Visual Studio 2013 -
. In the start menu, find Visual Studio 2013 | Visual Studio Tools and
use one of these links to open the appropriate command window. This
will make sure the appropriate environment variables are defined
for Visual C. (Use one of the "Native Tools Command Prompt" links)
. Or use one of the appropriate command lines below to define the
necessary environment variables.
Visual Studio 2013:
"C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" x86
"C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" amd64
Visual Studio 2012:
"C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\vcvarsall.bat" x86
"C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\vcvarsall.bat" amd64
Visual Studio 2010:
"C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" x86
"C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" amd64

Then, at a command prompt in the pljava folder, use
mvn clean package
to build the requisite jars and dll. The resulting files will be found under the
target directories of the various projects.

The code and scripts have been tested and build successfully with
Visual Studio 2010, 2012 and 2013 and with Postgresql releases
9.3.4, 9.2.8, 9.1.13, 9.0.17 and 8.4.21.

The build scripts were conditionalized to allow building with Visual Studio 2013
in Postgresql versions prior to 9.4.

The scripts have been verified to continue to work with Linux. They have NOT
been tested with mingw.

Postgresql 9.4beta1 -
A modification to Oid.c was necessary to accommodate a modified Postgresql API.

The modifications have been tested with Postgresql 9.4beta1 and build
correctly on Linux.

While the pljava code compiles with Visual Studio 2013 and Postgresql 9.4beta1,
the link fails with 3 unresolved symbols (which are successfully found in
previous Postgresql releases). This appears to be an artifact of the use of
Visual Studio 2013 to compile Postgresql 9.4beta1. I have not had a chance to
rebuild Postgresql 9.4beta1 from source to determine a workaround.

About the code changes for Visual Studio compilation:
Backend.c - need to dllexport functions referenced by Java JNI calls.
Function.c - need to define macros for strcasecmp and strncasecmp.
JNICalls.c - cannot change the linkage of previously declared fields.**
Oid.c - conditionalized code foe method signature change in 9.4.
Timestamp.c - cannot change the linkage of previously declared fields.**
Commands.java - removed reference to column no longer in pljava schema.
jvm.def - removed file (defines jvm exports, not pljava exports, causes link errors)

** These fields are the ones that become unresolved when linking against 9.4. I
suspect that ultimately the correct solution would be for Postgresql to declare
these dllexport and then adjusting the conditionalization in pljava to account
for this in 9.4 and above.


53 changes: 52 additions & 1 deletion pljava-so/build.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,42 @@
<?xml version="1.0"?>
<project name="project" default="pg_config">
<target name="pg_config">

<property environment="env" />
<condition property="msvc-present">
<and>
<os family="windows"/>
<or>
<available file="cl.exe" filepath="${env.Path}" />
<available file="cl.exe" filepath="${env.PATH}" />
</or>
</and>
</condition>

<target name="configure_msvc" if="msvc-present">
<exec executable="cl" outputproperty="MSVC_HEADER"
osfamily="windows" logError="false"
failifexecutionfails="false"
/>
<loadresource property="MSVC_VER">
<string value="${MSVC_HEADER}" />
<filterchain>
<tokenfilter>
<containsregex pattern="[^\d]*(\d+)\.(\d+).*$" replace="\1\2" />
</tokenfilter>
<striplinebreaks/>
</filterchain>
</loadresource>
<property name="MSVC_VER" value="0000"/>
</target>

<target name="configure_nomsvc" unless="msvc-present">
<property name="MSVC_VER" value=""/>
<property name="MSVC_RINT" value="msvc.rint"/>
</target>

<target name="configure_msvc_options" depends="configure_msvc, configure_nomsvc"/>

<target name="pg_config" depends="configure_msvc_options">
<!-- First gather all values from the pg_config executable. -->
<exec executable="pg_config" outputproperty="PGSQL_PKGLIBDIR">
<arg line="--pkglibdir"/>
Expand All @@ -23,6 +59,7 @@
<string value="${PGSQL_VER}" />
<filterchain>
<tokenfilter>
<replaceregex pattern="devel.*|alpha.*|beta.*|rc.*$" replace="\.99" flags="si" />
<containsregex pattern="[^\d]*(\d+)\.(\d+)\.(\d+)$" replace="\1" />
</tokenfilter>
</filterchain>
Expand All @@ -31,6 +68,7 @@
<string value="${PGSQL_VER}" />
<filterchain>
<tokenfilter>
<replaceregex pattern="devel.*|alpha.*|beta.*|rc.*$" replace="\.99" flags="si" />
<containsregex pattern="[^\d]*(\d+)\.(\d+)\.(\d+)$" replace="\2" />
</tokenfilter>
</filterchain>
Expand All @@ -39,11 +77,23 @@
<string value="${PGSQL_VER}" />
<filterchain>
<tokenfilter>
<replaceregex pattern="devel.*|alpha.*|beta.*|rc.*$" replace="\.99" flags="si" />
<containsregex pattern="[^\d]*(\d+)\.(\d+)\.(\d+)$" replace="\3" />
</tokenfilter>
</filterchain>
</loadresource>

<script language="javascript"><![CDATA[
var msvc_version = parseInt(project.getProperty('MSVC_VER'));
var pg_major_version = parseInt(project.getProperty('PGSQL_MAJOR_VER'));
var pg_minor_version = parseInt(project.getProperty('PGSQL_MINOR_VER'));
if (msvc_version >= 1800 && (pg_major_version < 9 || (pg_major_version == 9 && pg_minor_version < 4))) {
project.setProperty('MSVC_RINT', 'HAVE_RINT=1' );
} else {
project.setProperty('MSVC_RINT', 'msvc.rint' );
}
]]></script>

<!-- Finally write all properties to a file which Maven understands. -->
<propertyfile file="pgsql.properties" jdkproperties="true">
<entry key="PGSQL_PKGLIBDIR" value="${PGSQL_PKGLIBDIR}" />
Expand All @@ -53,6 +103,7 @@
<entry key="PGSQL_MAJOR_VER" value="${PGSQL_MAJOR_VER}" />
<entry key="PGSQL_MINOR_VER" value="${PGSQL_MINOR_VER}" />
<entry key="PGSQL_PATCH_VER" value="${PGSQL_PATCH_VER}" />
<entry key="MSVC_RINT" value="${MSVC_RINT}" />
</propertyfile>
</target>
</project>
49 changes: 47 additions & 2 deletions pljava-so/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,42 @@
<name>pl/java server side library</name>
<description>Generates the pljava.so library which gets loaded by the PostgreSQL server.</description>
<packaging>nar</packaging>

<properties>
<!-- default values when NOT using Microsoft Visual C compiler -->
<msvc.pkglibdir>"target/lib/"</msvc.pkglibdir>
<msvc.rint>msvc.rint</msvc.rint>
<msvc.include.win32></msvc.include.win32>
<msvc.include.win32.msvc></msvc.include.win32.msvc>
<!-- TODO: Check how this works for gcj. -->
<msvc.jvm.lib.dir>${sun.boot.library.path}/server</msvc.jvm.lib.dir>
<!-- MSVC requires postgres.lib, so supply dummy reference for other platforms -->
<msvc.postgres.lib.name>jvm</msvc.postgres.lib.name>
<msvc.postgres.lib.path>${msvc.jvm.lib.dir}</msvc.postgres.lib.path>
</properties>

<profiles>
<profile>
<id>compiler-msvc</id>
<activation>
<property>
<name>env.VCINSTALLDIR</name>
</property>
</activation>
<properties>
<!-- override values when using Microsoft Visual C compiler -->
<msvc.pkglibdir>\"target/lib/\"</msvc.pkglibdir>
<msvc.include.win32>port/win32</msvc.include.win32>
<msvc.include.win32.msvc>port/win32_msvc</msvc.include.win32.msvc>
<msvc.jvm.lib.dir>${JAVA6_HOME}/lib</msvc.jvm.lib.dir>
<msvc.postgres.lib.name>postgres</msvc.postgres.lib.name>
<msvc.postgres.lib.path>${PGSQL_PKGLIBDIR}</msvc.postgres.lib.path>
<!-- Need this for Visual Studio 2013 and Postgresql v9.3 and below -->
<msvc.rint>${MSVC_RINT}</msvc.rint>
</properties>
</profile>
</profiles>

<build>
<plugins>

Expand Down Expand Up @@ -104,15 +139,20 @@
<name>${CPP_COMPILER}</name>
-->
<defines>
<define>PKGLIBDIR="target/lib/"</define>
<define>PKGLIBDIR=${msvc.pkglibdir}</define>
<define>PGSQL_MAJOR_VER=${PGSQL_MAJOR_VER}</define>
<define>PGSQL_MINOR_VER=${PGSQL_MINOR_VER}</define>
<define>PGSQL_PATCH_VER=${PGSQL_PATCH_VER}</define>
<!-- for MSVC -->
<define>${msvc.rint}</define>
</defines>
<includePaths>
<!-- TODO: hardcoded paths -->
<includePath>${PGSQL_INCLUDEDIR}</includePath>
<includePath>${PGSQL_INCLUDEDIR-SERVER}</includePath>
<!-- include paths for MSVC required headers -->
<includePath>${PGSQL_INCLUDEDIR-SERVER}/${msvc.include.win32}</includePath>
<includePath>${PGSQL_INCLUDEDIR-SERVER}/${msvc.include.win32.msvc}</includePath>
<includePath>${basedir}/src/main/include/</includePath>
<includePath>${basedir}/target/nar/javah-include/</includePath>
</includePaths>
Expand All @@ -124,7 +164,12 @@
<lib>
<name>jvm</name>
<type>shared</type>
<directory>${sun.boot.library.path}/server</directory>
<directory>${msvc.jvm.lib.dir}</directory>
</lib>
<lib>
<name>${msvc.postgres.lib.name}</name>
<type>shared</type>
<directory>${msvc.postgres.lib.path}</directory>
</lib>
<lib>
<name>ecpg</name>
Expand Down
12 changes: 12 additions & 0 deletions pljava-so/src/main/c/Backend.c
Original file line number Diff line number Diff line change
Expand Up @@ -751,7 +751,13 @@ static void initializeJavaVM(void)

static Datum internalCallHandler(bool trusted, PG_FUNCTION_ARGS);

#if (PGSQL_MAJOR_VER > 8)
extern PGDLLEXPORT Datum javau_call_handler(PG_FUNCTION_ARGS);
#elif defined(_MSC_VER)
extern __declspec (dllexport) Datum javau_call_handler(PG_FUNCTION_ARGS);
#else
extern Datum javau_call_handler(PG_FUNCTION_ARGS);
#endif
PG_FUNCTION_INFO_V1(javau_call_handler);

/*
Expand All @@ -762,7 +768,13 @@ Datum javau_call_handler(PG_FUNCTION_ARGS)
return internalCallHandler(false, fcinfo);
}

#if (PGSQL_MAJOR_VER > 9)
extern PGDLLEXPORT Datum java_call_handler(PG_FUNCTION_ARGS);
#elif defined(_MSC_VER)
extern __declspec (dllexport) Datum java_call_handler(PG_FUNCTION_ARGS);
#else
extern Datum java_call_handler(PG_FUNCTION_ARGS);
#endif
PG_FUNCTION_INFO_V1(java_call_handler);

/*
Expand Down
5 changes: 5 additions & 0 deletions pljava-so/src/main/c/Function.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@
#include <funcapi.h>
#include <utils/typcache.h>

#ifdef _MSC_VER
# define strcasecmp _stricmp
# define strncasecmp _strnicmp
#endif

#if (PGSQL_MAJOR_VER == 8 && PGSQL_MINOR_VER == 0)
# define PARAM_OIDS(procStruct) (procStruct)->proargtypes
#else
Expand Down
8 changes: 8 additions & 0 deletions pljava-so/src/main/c/JNICalls.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,21 @@

JNIEnv* jniEnv;

/* MSVC will not allow redefinition WITH dllimport after seeing
* the definition in guc.h that does not include dllimport.
*/
#ifdef _MSC_VER
extern int log_min_error_statement;
extern int client_min_messages;
#else
#if (PGSQL_MAJOR_VER > 8 || (PGSQL_MAJOR_VER == 8 && PGSQL_MINOR_VER >= 3))
extern PGDLLIMPORT int log_min_messages;
extern PGDLLIMPORT int client_min_messages;
#else
extern DLLIMPORT int log_min_messages;
extern DLLIMPORT int client_min_messages;
#endif
#endif
static jobject s_threadLock;

#define BEGIN_JAVA { JNIEnv* env = jniEnv; jniEnv = 0;
Expand Down
4 changes: 0 additions & 4 deletions pljava-so/src/main/c/jvm.def

This file was deleted.

7 changes: 7 additions & 0 deletions pljava-so/src/main/c/type/Timestamp.c
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,14 @@ static Datum _Timestamptz_coerceObject(Type self, jobject ts)

#if !(PGSQL_MAJOR_VER == 8 && PGSQL_MINOR_VER == 0)
#if (PGSQL_MAJOR_VER > 8 || (PGSQL_MAJOR_VER == 8 && PGSQL_MINOR_VER >= 3))
/* MSVC will not allow redefinition WITH dllimport after seeing
* the definition in pgtime.h that does not include dllimport.
*/
#ifdef _MSC_VER
extern pg_tz *session_timezone;
#else
extern PGDLLIMPORT pg_tz* session_timezone;
#endif
#else
extern DLLIMPORT pg_tz* global_timezone;
#endif
Expand Down

0 comments on commit dbf2bdc

Please sign in to comment.