Skip to content

Commit

Permalink
Merge pull request #495 from java-native-access/w32-build-fix
Browse files Browse the repository at this point in the history
Fix windows builds under MSVC, 32- and 64-bit
  • Loading branch information
twall committed Sep 1, 2015
2 parents 101c996 + 52eed7b commit 4a2d3be
Show file tree
Hide file tree
Showing 6 changed files with 33 additions and 20 deletions.
10 changes: 6 additions & 4 deletions native/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -190,11 +190,11 @@ CC+= -m64
FFI_CONFIG+=--host=x86_64-w64-mingw32
endif
FFI_CONFIG+= && rm -f include/ffitarget.h && cp $(FFI_SRC)/include/*.h $(FFI_SRC)/src/x86/ffitarget.h include
FFI_ENV+=LD="$(LD)" CPP="$(CPP)"
FFI_ENV+=LD="$(LD)" CPP="$(CPP)" CXXCPP="$(CPP)"
EXTRAOBJS+=$(DLLCB)
else
PREFIX=i686-pc-mingw32-
CC=$(PREFIX)gcc
MINGW_PREFIX?=i686-pc-mingw32-
CC=$(MINGW_PREFIX)gcc
LDFLAGS=-o $@ -shared -Wl,--add-stdcall-alias
LIBS=-lpsapi
endif
Expand All @@ -203,7 +203,7 @@ ifeq ($(ARCH),amd64)
# Undefine USE_MSVC to enable mingw64 cross compiler; ensure $(MINGW) is in
# PATH. Should build properly as of 111121, but lacks SEH, so MSVC build is
# preferred
MINGW_PREFIX?=x86_64-pc-mingw32-
MINGW_PREFIX?=x86_64-w64-mingw32-
MINGW=$(MINGW_PREFIX)gcc
# Need windres from mingw distribution, even if building with MSVC
WINDRES=$(MINGW_PREFIX)windres
Expand Down Expand Up @@ -372,8 +372,10 @@ install:
mkdir $(INSTALLDIR)
cp $(LIBRARY) $(INSTALLDIR)

ifeq ($(ARCH), amd64)
$(DLLCB): dll-callback.c
$(MINGW) -DDEFINE_CALLBACKS -c $< $(COUT)
endif

$(RSRC): $(BUILD)/jnidispatch.rc $(BUILD)/$(JNA_JNI_VERSION).stamp
$(WINDRES) -i $< -o $@ \
Expand Down
16 changes: 9 additions & 7 deletions native/libffi/src/x86/ffi.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,12 +99,12 @@ unsigned int ffi_prep_args(char *stack, extended_cif *ecif)
i != 0;
i--, p_arg += dir, p_argv += dir)
{
size_t z = (*p_arg)->size;

/* Align if necessary */
if ((sizeof(void*) - 1) & (size_t) argp)
argp = (char *) ALIGN(argp, sizeof(void*));

size_t z = (*p_arg)->size;

#ifdef X86_WIN64
if (z > FFI_SIZEOF_ARG
|| ((*p_arg)->type == FFI_TYPE_STRUCT
Expand Down Expand Up @@ -202,6 +202,7 @@ unsigned int ffi_prep_args(char *stack, extended_cif *ecif)
on top of stack, so that those can be moved to registers by call-handler. */
if (stack_args_count > 0)
{
unsigned i;
if (dir < 0 && stack_args_count > 1)
{
/* Reverse order if iterating arguments backwards */
Expand All @@ -210,7 +211,6 @@ unsigned int ffi_prep_args(char *stack, extended_cif *ecif)
*(ffi_arg*) p_stack_data[stack_args_count - 1] = tmp;
}

int i;
for (i = 0; i < stack_args_count; i++)
{
if (p_stack_data[i] != argp2)
Expand Down Expand Up @@ -572,11 +572,12 @@ ffi_prep_incoming_args(char *stack, void **rvalue, void **avalue,
i < cif->nargs && passed_regs < max_stack_count;
i++, p_arg++)
{
size_t sz = (*p_arg)->size;

if ((*p_arg)->type == FFI_TYPE_FLOAT
|| (*p_arg)->type == FFI_TYPE_STRUCT)
continue;

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

Expand All @@ -602,12 +603,12 @@ ffi_prep_incoming_args(char *stack, void **rvalue, void **avalue,
i != 0;
i--, p_arg += dir, p_argv += dir)
{
size_t z = (*p_arg)->size;

/* Align if necessary */
if ((sizeof(void*) - 1) & (size_t) argp)
argp = (char *) ALIGN(argp, sizeof(void*));

size_t z = (*p_arg)->size;

#ifdef X86_WIN64
if (z > FFI_SIZEOF_ARG
|| ((*p_arg)->type == FFI_TYPE_STRUCT
Expand Down Expand Up @@ -858,11 +859,12 @@ ffi_prep_args_raw(char *stack, extended_cif *ecif)

for (i = 0; i < cif->nargs && passed_regs <= max_regs; i++)
{
size_t sz = cif->arg_types[i]->size;

if (cif->arg_types[i]->type == FFI_TYPE_FLOAT
|| cif->arg_types[i]->type == FFI_TYPE_STRUCT)
continue;

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

Expand Down
2 changes: 2 additions & 0 deletions native/libffi/src/x86/ffitarget.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@
#endif

#define FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION
#ifndef _MSC_VER
#define FFI_TARGET_HAS_COMPLEX_TYPE
#endif

/* ---- Generic type definitions ----------------------------------------- */

Expand Down
4 changes: 2 additions & 2 deletions native/libffi/src/x86/win64.S
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ ret_uint16$:
mov rcx, QWORD PTR RVALUE[rbp]
movzx rax, ax
mov QWORD PTR [rcx], rax
jmp SHORT ret_void$
jmp ret_void$ ; too far with 'SHORT'

ret_sint16$:
cmp DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_SINT16
Expand All @@ -179,7 +179,7 @@ ret_sint16$:
mov rcx, QWORD PTR RVALUE[rbp]
movsx rax, ax
mov QWORD PTR [rcx], rax
jmp SHORT ret_void$
jmp ret_void$ ; too far with 'SHORT'

ret_uint32$:
cmp DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_UINT32
Expand Down
2 changes: 1 addition & 1 deletion test/com/sun/jna/win32/W32StdCallTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ public void testStdCallReturnInt32Argument() {

public void testStdCallReturnStructureByValueArgument() {
TestLibrary.TestStructure.ByValue s = new TestLibrary.TestStructure.ByValue();
assertEquals("Wrong value", s, testlib.returnStructureByValueArgumentStdCall(s));
assertTrue("Wrong struct value", s.dataEquals(testlib.returnStructureByValueArgumentStdCall(s)));
}

public void testStdCallCallback() {
Expand Down
19 changes: 13 additions & 6 deletions www/WindowsDevelopmentEnvironment.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,22 @@ When installing cygwin, include ssh, git, make, autotools, and
mingw64-gcc-core. Ensure the mingw64 compiler (i686-pc-mingw64-gcc.exe) is on
your path.

MSVC
----

#### Visual Studio

You can optionally use the free MS Visual Studio C++ Express compiler to compile
native bits. The MS compiler provides structured event handling (SEH),
which allows JNA to trap native faults when run in protected mode.
JNA uses the free MS Visual Studio C++ Express compiler to compile
native bits if MSVC is set in the environment. The MS compiler provides
structured event handling (SEH), which allows JNA to trap native faults when
run in protected mode.

On 64-bit windows, you will still need to install mingw64-gcc-core in order to
compile a small bit of inline assembly.

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

Sample configuration setting up INCLUDE/LIB:

Expand Down

0 comments on commit 4a2d3be

Please sign in to comment.