Skip to content

Commit a20e3c3

Browse files
committed
Windows port with mingw-w64 and msys.
1 parent f791207 commit a20e3c3

File tree

6 files changed

+130
-26
lines changed

6 files changed

+130
-26
lines changed

Makefile

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,12 @@ LD := $(CXX)
88
SRC_DIR := src/native
99
BUILD_DIR := build
1010
OUT_DIR := output
11+
12+
ifeq ($(OS),Windows_NT)
13+
SHRLIB_EXT := dll
14+
else
1115
SHRLIB_EXT := so
16+
endif
1217

1318
OBJ_DIR := $(BUILD_DIR)/$(TARGET)
1419
BIN_DIR := $(OUT_DIR)/$(TARGET)/bin
@@ -20,7 +25,11 @@ OBJ_DIRS := $(addprefix $(OBJ_DIR)/,$(MODULES))
2025
SRCS := $(foreach sdir,$(SRC_DIRS),$(wildcard $(sdir)/*.cpp))
2126
OBJS := $(patsubst $(SRC_DIR)/%.cpp,$(OBJ_DIR)/%.o,$(SRCS))
2227

23-
CXX_FLAGS := -ggdb -fPIC -MMD -MP
28+
CXX_FLAGS := -ggdb -MMD -MP
29+
30+
ifneq ($(OS),Windows_NT)
31+
CXX_FLAGS += -fPIC
32+
endif
2433

2534
ifeq ($(TARGET),release)
2635
CXX_FLAGS += -O3
@@ -45,7 +54,7 @@ all: mkdirs \
4554
mkdirs: $(OBJ_DIRS) $(BIN_DIR) $(LIB_DIR)
4655

4756
$(OBJ_DIRS) $(BIN_DIR) $(LIB_DIR):
48-
@mkdir -p $@
57+
@"mkdir" -p $@
4958

5059
clean:
5160
@rm -rf $(BUILD_DIR) $(OUT_DIR)

src/etc/bin/create-package.sh

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,22 @@
33
THIS_DIR=`readlink -f $0`
44
THIS_DIR=`dirname $THIS_DIR`
55

6+
if [ "$OS" = "Windows_NT" ]; then
7+
THIS_DIR=`echo "$THIS_DIR" | tr \\\\ /`
8+
fi
9+
610
BASE_DIR=$THIS_DIR/../../..
711
TARGET_DIR=`readlink -f $1`
812
CONFIG=release
913

14+
if [ "$OS" = "Windows_NT" ]; then
15+
SHRLIB_EXT=dll
16+
SHELL_EXT=bat
17+
else
18+
SHRLIB_EXT=so
19+
SHELL_EXT=sh
20+
fi
21+
1022
cd $BASE_DIR
1123
make TARGET=$CONFIG
1224

@@ -20,18 +32,24 @@ mkdir -p \
2032
$TARGET_DIR/lib \
2133
$TARGET_DIR/scripts
2234

23-
cp $BASE_DIR/src/etc/bin/setenv.sh $TARGET_DIR/bin
24-
cp $BASE_DIR/src/etc/bin/fbjava-deployer.sh $TARGET_DIR/bin
35+
cp $BASE_DIR/src/etc/bin/setenv.$SHELL_EXT $TARGET_DIR/bin
36+
cp $BASE_DIR/src/etc/bin/fbjava-deployer.$SHELL_EXT $TARGET_DIR/bin
2537
cp $BASE_DIR/src/fbjava/target/*.jar $TARGET_DIR/jar
2638
cp $BASE_DIR/src/fbjava/target/dependency/*.jar $TARGET_DIR/jar
27-
cp $BASE_DIR/output/$CONFIG/lib/libfbjava.so $TARGET_DIR/lib
39+
cp $BASE_DIR/output/$CONFIG/lib/libfbjava.$SHRLIB_EXT $TARGET_DIR/lib
2840
cp $BASE_DIR/src/fbjava/src/main/resources/org/firebirdsql/fbjava/*.sql $TARGET_DIR/scripts
2941
cp $BASE_DIR/src/etc/conf/fbjava.conf $TARGET_DIR/conf
3042
cp $BASE_DIR/src/etc/scripts/java-security.sql $TARGET_DIR/scripts
3143

32-
if [ -f $TARGET_DIR/conf/java-security.fdb ]; then
33-
rm $TARGET_DIR/conf/java-security.fdb
44+
cd $TARGET_DIR/conf/
45+
46+
if [ -f java-security.fdb ]; then
47+
rm java-security.fdb
3448
fi
3549

36-
echo "create database '$TARGET_DIR/conf/java-security.fdb' default character set utf8;" | isql -q
50+
echo "create database 'java-security.fdb' default character set utf8;" | isql -q
3751
isql $TARGET_DIR/conf/java-security.fdb -q -i $TARGET_DIR/scripts/java-security.sql
52+
53+
# Transform file name to lower case in Windows
54+
mv java-security.fdb java-security.tmp
55+
mv java-security.tmp java-security.fdb

src/etc/bin/fbjava-deployer.bat

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
@echo off
2+
setlocal
3+
4+
set THIS_DIR=%~dp0
5+
6+
call "%THIS_DIR%\setenv.bat"
7+
8+
set PATH=%FB_DIR%\bin;%PATH%
9+
10+
"%JAVA_HOME%\bin\java" -cp "%JAR_DIR%\*" ^
11+
"-Djava.library.path=%NATIVE_DIR%" ^
12+
org.firebirdsql.fbjava.Deployer %*

src/etc/bin/setenv.bat

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
set BIN_DIR=%THIS_DIR%
2+
set JAR_DIR=%THIS_DIR%\..\jar

src/etc/conf/fbjava.conf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
Plugin = JAVA {
2-
Module = $(this)/../lib/libfbjava.so
2+
Module = $(this)/../lib/libfbjava
33
Config = JAVA_config
44
}
55

src/native/fbjava/fbjava.cpp

Lines changed: 80 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,13 @@
3030
#include <stdio.h>
3131
#include <sys/stat.h>
3232
#include <dirent.h>
33+
34+
#ifdef WIN32
35+
#include <windows.h>
36+
#else
3337
#include <dlfcn.h>
38+
#endif
39+
3440
#include "jni.h"
3541

3642
using namespace Firebird;
@@ -44,34 +50,62 @@ using std::vector;
4450
//------------------------------------------------------------------------------
4551

4652

47-
class DynLibrary //// TODO: Windows port
53+
#ifdef WIN32
54+
static const char DEFAULT_PATH_SEP = '\\';
55+
static HMODULE hDllInstance = NULL;
56+
#else
57+
static const char DEFAULT_PATH_SEP = '/';
58+
#endif
59+
60+
61+
//------------------------------------------------------------------------------
62+
63+
64+
class DynLibrary
4865
{
4966
public:
5067
DynLibrary(const string& filename)
5168
: filename(filename)
5269
{
70+
#ifdef WIN32
71+
module = LoadLibrary(filename.c_str());
72+
#else
5373
module = dlopen(filename.c_str(), RTLD_NOW);
74+
#endif
5475
}
5576

5677
~DynLibrary()
5778
{
79+
#ifdef WIN32
80+
FreeLibrary(module);
81+
#else
5882
dlclose(module);
83+
#endif
5984
}
6085

6186
public:
6287
// Lookup a library symbol. Throw exception in case of error.
6388
template <typename T>
6489
void findSymbol(const char* name, T& ptr)
6590
{
91+
#ifdef WIN32
92+
ptr = reinterpret_cast<T>(GetProcAddress(module, name));
93+
#else
6694
ptr = reinterpret_cast<T>(dlsym(module, name));
95+
#endif
6796

6897
if (!ptr)
6998
throw runtime_error(string("Symbol '") + name + "' not found in '" + filename + "'.");
7099
}
71100

72101
private:
73102
string filename;
103+
104+
#ifdef WIN32
105+
HMODULE module;
106+
#else
74107
void* module;
108+
#endif
75109
};
76110

77111

@@ -100,8 +134,8 @@ static string findJvmLibrary(const char* javaHome)
100134
{
101135
#ifdef WIN32
102136
static const char* const DEFAULT_PLACES[] = {
103-
"\\jre\\bin\\\\server\\jvm.dll",
104-
"\\jre\\lib\\\\client\\jvm.dll"
137+
"\\jre\\bin\\server\\jvm.dll",
138+
"\\jre\\lib\\client\\jvm.dll"
105139
};
106140
#else
107141
#ifdef __amd64
@@ -227,10 +261,26 @@ static jmethodID getMethodID(JNIEnv* env, jclass cls, const char* name, const ch
227261

228262
static void init()
229263
{
264+
#ifdef WIN32
265+
string libFile;
266+
267+
{ // scope
268+
char buffer[MAX_PATH];
269+
GetModuleFileName(hDllInstance, buffer, sizeof(buffer));
270+
libFile = buffer;
271+
}
272+
#else
230273
Dl_info dlInfo;
231274
if (dladdr((void*) init, &dlInfo) == 0)
232275
throw runtime_error("Cannot get the plugin library path.");
233276

277+
string libFile(dlInfo.dli_fname);
278+
#endif
279+
280+
string libDir(libFile.substr(0, strrchr(libFile.c_str(), DEFAULT_PATH_SEP) - libFile.c_str()));
281+
libDir += DEFAULT_PATH_SEP;
282+
libDir += "../jar";
283+
234284
const char* javaHome = getenv("JAVA_HOME");
235285

236286
if (!javaHome)
@@ -296,16 +346,6 @@ static void init()
296346
jmethodID urlClassLoaderLoadClassId = getMethodID(env, urlClassLoaderCls, "loadClass",
297347
"(Ljava/lang/String;Z)Ljava/lang/Class;");
298348

299-
#ifdef WIN32
300-
static const char DEFAULT_PATH_SEP = '\\';
301-
#else
302-
static const char DEFAULT_PATH_SEP = '/';
303-
#endif
304-
305-
string libDir(dlInfo.dli_fname, strrchr(dlInfo.dli_fname, DEFAULT_PATH_SEP) - dlInfo.dli_fname);
306-
libDir += DEFAULT_PATH_SEP;
307-
libDir += "../jar";
308-
309349
vector<string> classPathEntries;
310350

311351
DIR* dir = opendir(libDir.c_str());
@@ -317,12 +357,24 @@ static void init()
317357

318358
while ((dent = readdir(dir)))
319359
{
360+
string name(dent->d_name);
361+
362+
#ifdef WIN32
363+
if (name != "." && name != "..")
364+
#else
320365
if (dent->d_type == DT_REG || dent->d_type == DT_LNK)
366+
#endif
321367
{
322-
string name(dent->d_name);
323-
324368
if (name.length() > 4 && name.substr(name.length() - 4) == ".jar")
325-
classPathEntries.push_back("file://" + libDir + DEFAULT_PATH_SEP + dent->d_name);
369+
{
370+
string protocol("file://");
371+
372+
#ifdef WIN32
373+
protocol += "/";
374+
#endif
375+
376+
classPathEntries.push_back(protocol + libDir + DEFAULT_PATH_SEP + dent->d_name);
377+
}
326378
}
327379
}
328380

@@ -364,7 +416,7 @@ static void init()
364416
jmethodID mainInitializeId = getStaticMethodID(env, mainCls, "initialize", "(Ljava/lang/String;)V");
365417
checkJavaException(env);
366418

367-
jstring nativeLibrary = env->NewStringUTF(dlInfo.dli_fname);
419+
jstring nativeLibrary = env->NewStringUTF(libFile.c_str());
368420
if (!nativeLibrary)
369421
checkJavaException(env);
370422

@@ -387,3 +439,14 @@ extern "C" void /*FB_EXPORTED*/ FB_PLUGIN_ENTRY_POINT(IMaster* master)
387439
fprintf(stderr, "%s\n", e.what());
388440
}
389441
}
442+
443+
444+
#ifdef WIN32
445+
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, void*)
446+
{
447+
if (dwReason == DLL_PROCESS_ATTACH)
448+
hDllInstance = hInstance;
449+
450+
return TRUE;
451+
}
452+
#endif

0 commit comments

Comments
 (0)