Skip to content

Commit 4a2d3be

Browse files
committed
Merge pull request #495 from java-native-access/w32-build-fix
Fix windows builds under MSVC, 32- and 64-bit
2 parents 101c996 + 52eed7b commit 4a2d3be

File tree

6 files changed

+33
-20
lines changed

6 files changed

+33
-20
lines changed

native/Makefile

+6-4
Original file line numberDiff line numberDiff line change
@@ -190,11 +190,11 @@ CC+= -m64
190190
FFI_CONFIG+=--host=x86_64-w64-mingw32
191191
endif
192192
FFI_CONFIG+= && rm -f include/ffitarget.h && cp $(FFI_SRC)/include/*.h $(FFI_SRC)/src/x86/ffitarget.h include
193-
FFI_ENV+=LD="$(LD)" CPP="$(CPP)"
193+
FFI_ENV+=LD="$(LD)" CPP="$(CPP)" CXXCPP="$(CPP)"
194194
EXTRAOBJS+=$(DLLCB)
195195
else
196-
PREFIX=i686-pc-mingw32-
197-
CC=$(PREFIX)gcc
196+
MINGW_PREFIX?=i686-pc-mingw32-
197+
CC=$(MINGW_PREFIX)gcc
198198
LDFLAGS=-o $@ -shared -Wl,--add-stdcall-alias
199199
LIBS=-lpsapi
200200
endif
@@ -203,7 +203,7 @@ ifeq ($(ARCH),amd64)
203203
# Undefine USE_MSVC to enable mingw64 cross compiler; ensure $(MINGW) is in
204204
# PATH. Should build properly as of 111121, but lacks SEH, so MSVC build is
205205
# preferred
206-
MINGW_PREFIX?=x86_64-pc-mingw32-
206+
MINGW_PREFIX?=x86_64-w64-mingw32-
207207
MINGW=$(MINGW_PREFIX)gcc
208208
# Need windres from mingw distribution, even if building with MSVC
209209
WINDRES=$(MINGW_PREFIX)windres
@@ -372,8 +372,10 @@ install:
372372
mkdir $(INSTALLDIR)
373373
cp $(LIBRARY) $(INSTALLDIR)
374374

375+
ifeq ($(ARCH), amd64)
375376
$(DLLCB): dll-callback.c
376377
$(MINGW) -DDEFINE_CALLBACKS -c $< $(COUT)
378+
endif
377379

378380
$(RSRC): $(BUILD)/jnidispatch.rc $(BUILD)/$(JNA_JNI_VERSION).stamp
379381
$(WINDRES) -i $< -o $@ \

native/libffi/src/x86/ffi.c

+9-7
Original file line numberDiff line numberDiff line change
@@ -99,12 +99,12 @@ unsigned int ffi_prep_args(char *stack, extended_cif *ecif)
9999
i != 0;
100100
i--, p_arg += dir, p_argv += dir)
101101
{
102+
size_t z = (*p_arg)->size;
103+
102104
/* Align if necessary */
103105
if ((sizeof(void*) - 1) & (size_t) argp)
104106
argp = (char *) ALIGN(argp, sizeof(void*));
105107

106-
size_t z = (*p_arg)->size;
107-
108108
#ifdef X86_WIN64
109109
if (z > FFI_SIZEOF_ARG
110110
|| ((*p_arg)->type == FFI_TYPE_STRUCT
@@ -202,6 +202,7 @@ unsigned int ffi_prep_args(char *stack, extended_cif *ecif)
202202
on top of stack, so that those can be moved to registers by call-handler. */
203203
if (stack_args_count > 0)
204204
{
205+
unsigned i;
205206
if (dir < 0 && stack_args_count > 1)
206207
{
207208
/* Reverse order if iterating arguments backwards */
@@ -210,7 +211,6 @@ unsigned int ffi_prep_args(char *stack, extended_cif *ecif)
210211
*(ffi_arg*) p_stack_data[stack_args_count - 1] = tmp;
211212
}
212213

213-
int i;
214214
for (i = 0; i < stack_args_count; i++)
215215
{
216216
if (p_stack_data[i] != argp2)
@@ -572,11 +572,12 @@ ffi_prep_incoming_args(char *stack, void **rvalue, void **avalue,
572572
i < cif->nargs && passed_regs < max_stack_count;
573573
i++, p_arg++)
574574
{
575+
size_t sz = (*p_arg)->size;
576+
575577
if ((*p_arg)->type == FFI_TYPE_FLOAT
576578
|| (*p_arg)->type == FFI_TYPE_STRUCT)
577579
continue;
578580

579-
size_t sz = (*p_arg)->size;
580581
if(sz == 0 || sz > FFI_SIZEOF_ARG)
581582
continue;
582583

@@ -602,12 +603,12 @@ ffi_prep_incoming_args(char *stack, void **rvalue, void **avalue,
602603
i != 0;
603604
i--, p_arg += dir, p_argv += dir)
604605
{
606+
size_t z = (*p_arg)->size;
607+
605608
/* Align if necessary */
606609
if ((sizeof(void*) - 1) & (size_t) argp)
607610
argp = (char *) ALIGN(argp, sizeof(void*));
608611

609-
size_t z = (*p_arg)->size;
610-
611612
#ifdef X86_WIN64
612613
if (z > FFI_SIZEOF_ARG
613614
|| ((*p_arg)->type == FFI_TYPE_STRUCT
@@ -858,11 +859,12 @@ ffi_prep_args_raw(char *stack, extended_cif *ecif)
858859

859860
for (i = 0; i < cif->nargs && passed_regs <= max_regs; i++)
860861
{
862+
size_t sz = cif->arg_types[i]->size;
863+
861864
if (cif->arg_types[i]->type == FFI_TYPE_FLOAT
862865
|| cif->arg_types[i]->type == FFI_TYPE_STRUCT)
863866
continue;
864867

865-
size_t sz = cif->arg_types[i]->size;
866868
if (sz == 0 || sz > FFI_SIZEOF_ARG)
867869
continue;
868870

native/libffi/src/x86/ffitarget.h

+2
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,9 @@
5050
#endif
5151

5252
#define FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION
53+
#ifndef _MSC_VER
5354
#define FFI_TARGET_HAS_COMPLEX_TYPE
55+
#endif
5456

5557
/* ---- Generic type definitions ----------------------------------------- */
5658

native/libffi/src/x86/win64.S

+2-2
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ ret_uint16$:
170170
mov rcx, QWORD PTR RVALUE[rbp]
171171
movzx rax, ax
172172
mov QWORD PTR [rcx], rax
173-
jmp SHORT ret_void$
173+
jmp ret_void$ ; too far with 'SHORT'
174174

175175
ret_sint16$:
176176
cmp DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_SINT16
@@ -179,7 +179,7 @@ ret_sint16$:
179179
mov rcx, QWORD PTR RVALUE[rbp]
180180
movsx rax, ax
181181
mov QWORD PTR [rcx], rax
182-
jmp SHORT ret_void$
182+
jmp ret_void$ ; too far with 'SHORT'
183183

184184
ret_uint32$:
185185
cmp DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_UINT32

test/com/sun/jna/win32/W32StdCallTest.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ public void testStdCallReturnInt32Argument() {
122122

123123
public void testStdCallReturnStructureByValueArgument() {
124124
TestLibrary.TestStructure.ByValue s = new TestLibrary.TestStructure.ByValue();
125-
assertEquals("Wrong value", s, testlib.returnStructureByValueArgumentStdCall(s));
125+
assertTrue("Wrong struct value", s.dataEquals(testlib.returnStructureByValueArgumentStdCall(s)));
126126
}
127127

128128
public void testStdCallCallback() {

www/WindowsDevelopmentEnvironment.md

+13-6
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,22 @@ When installing cygwin, include ssh, git, make, autotools, and
2929
mingw64-gcc-core. Ensure the mingw64 compiler (i686-pc-mingw64-gcc.exe) is on
3030
your path.
3131

32+
MSVC
33+
----
34+
3235
#### Visual Studio
3336

34-
You can optionally use the free MS Visual Studio C++ Express compiler to compile
35-
native bits. The MS compiler provides structured event handling (SEH),
36-
which allows JNA to trap native faults when run in protected mode.
37+
JNA uses the free MS Visual Studio C++ Express compiler to compile
38+
native bits if MSVC is set in the environment. The MS compiler provides
39+
structured event handling (SEH), which allows JNA to trap native faults when
40+
run in protected mode.
41+
42+
On 64-bit windows, you will still need to install mingw64-gcc-core in order to
43+
compile a small bit of inline assembly.
3744

38-
To use the MS compiler, ensure that the 64-bit versions of
39-
cl.exe/ml64.exe/link.exe are in your PATH and that the INCLUDE and LIB
40-
environment variables are set properly (as in VCVARS.BAT).
45+
To use the MS compiler, ensure that the appropriate 32-bit or 64-bit versions
46+
of cl.exe/ml.exe/ml64.exe/link.exe are in your PATH and that the INCLUDE and
47+
LIB environment variables are set properly (as in VCVARS.BAT).
4148

4249
Sample configuration setting up INCLUDE/LIB:
4350

0 commit comments

Comments
 (0)