summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfwg <fwg@users.noreply.github.com>2018-04-02 13:55:31 +0200
committerAnthony Green <green@moxielogic.com>2018-04-02 06:55:31 -0500
commitaf6773d6ab4db0577bc6b932ab5a2f98a0a8dca2 (patch)
tree812b6d0727d5104317df93387c2ac341aaf60b9e
parent48bdb02867edb7e9f3785ccb4bdff1087fb44246 (diff)
downloadlibffi-af6773d6ab4db0577bc6b932ab5a2f98a0a8dca2.tar.gz
Fix appveyor windows build (#420)
* Fix msvcc dll build by adding dllexport decorations to all API declarations * Fix appveyor build for VS 2013 Use the new -DFFI_BUILDING_DLL for producing a working DLL. Update the msvcc.sh wrapper script to successfully compile the testsuite files. * MSVC build: suppress warnings in testsuite * fix testsuite on appveyor
-rw-r--r--.appveyor.yml8
-rw-r--r--include/ffi.h.in74
-rwxr-xr-xmsvcc.sh65
-rw-r--r--src/types.c4
-rw-r--r--testsuite/libffi.bhaible/bhaible.exp10
-rw-r--r--testsuite/libffi.bhaible/test-call.c7
-rw-r--r--testsuite/libffi.bhaible/test-callback.c7
-rw-r--r--testsuite/libffi.call/call.exp15
8 files changed, 138 insertions, 52 deletions
diff --git a/.appveyor.yml b/.appveyor.yml
index ccb918a..c388fc6 100644
--- a/.appveyor.yml
+++ b/.appveyor.yml
@@ -28,8 +28,8 @@ install:
$env:HOST="x86-pc-windows"
} Else {
$env:VCVARS_PLATFORM="amd64"
- $env:BUILD="x86_64-pc-cygwin"
- $env:HOST="x86_64-pc-winnt"
+ $env:BUILD="x86_64-w64-cygwin"
+ $env:HOST="x86_64-w64-cygwin"
}
- 'appveyor DownloadFile http://cygwin.com/setup-x86.exe -FileName setup.exe'
- 'setup.exe -qnNdO -R "%CYG_ROOT%" -s "%CYG_MIRROR%" -l "%CYG_CACHE%" -P dejagnu >NUL'
@@ -40,7 +40,9 @@ install:
build_script:
- c:\cygwin\bin\sh -lc "(cd $OLDPWD; ./autogen.sh;)"
- - c:\cygwin\bin\sh -lc "(cd $OLDPWD; ./configure CC='/cygdrive/c/projects/libffi/.travis/compile cl -nologo' CXX='/cygdrive/c/projects/libffi/.travis/compile cl -nologo' LD=link CPP='cl -nologo -EP' AR='/cygdrive/c/projects/libffi/.travis/ar-lib lib' NM='dumpbin -symbols' STRIP=':' --build=$BUILD --host=$HOST; cp src/x86/ffitarget.h include; make; find .; make check; cat `find ./ -name libffi.log`)"
+ - c:\cygwin\bin\sh -lc "(cd $OLDPWD; ./configure CC='/cygdrive/c/projects/libffi/msvcc.sh -m64' CXX='/cygdrive/c/projects/libffi/msvcc.sh -m64' LD='link' CPP='cl -nologo -EP' CXXCPP='cl -nologo -EP' CPPFLAGS='-DFFI_BUILDING_DLL' AR='/cygdrive/c/projects/libffi/.travis/ar-lib lib' NM='dumpbin -symbols' STRIP=':' --build=$BUILD --host=$HOST;)"
+ - c:\cygwin\bin\sh -lc "(cd $OLDPWD; cp src/x86/ffitarget.h include; make; find .;)"
+ - c:\cygwin\bin\sh -lc "(cd $OLDPWD; cp `find . -name 'libffi-?.dll'` $HOST/testsuite/; make check; cat `find ./ -name libffi.log`)"
# FIXME: "make check" currently fails. It just looks like msvcc needs
# to learn about -L and -l options. If you add "make check; cat `find
diff --git a/include/ffi.h.in b/include/ffi.h.in
index d76d8e6..39cde46 100644
--- a/include/ffi.h.in
+++ b/include/ffi.h.in
@@ -108,6 +108,32 @@ typedef struct _ffi_type
struct _ffi_type **elements;
} ffi_type;
+/* Need minimal decorations for DLLs to work on Windows. GCC has
+ autoimport and autoexport. Always mark externally visible symbols
+ as dllimport for MSVC clients, even if it means an extra indirection
+ when using the static version of the library.
+ Besides, as a workaround, they can define FFI_BUILDING if they
+ *know* they are going to link with the static library. */
+#if defined _MSC_VER
+# if defined FFI_BUILDING_DLL /* Building libffi.DLL with msvcc.sh */
+# define FFI_API __declspec(dllexport)
+# elif !defined FFI_BUILDING /* Importing libffi.DLL */
+# define FFI_API __declspec(dllimport)
+# else /* Building/linking static library */
+# define FFI_API
+# endif
+#else
+# define FFI_API
+#endif
+
+/* The externally visible type declarations also need the MSVC DLL
+ decorations, or they will not be exported from the object file. */
+#if defined LIBFFI_HIDE_BASIC_TYPES
+# define FFI_EXTERN FFI_API
+#else
+# define FFI_EXTERN extern FFI_API
+#endif
+
#ifndef LIBFFI_HIDE_BASIC_TYPES
#if SCHAR_MAX == 127
# define ffi_type_uchar ffi_type_uint8
@@ -157,19 +183,6 @@ typedef struct _ffi_type
#error "long size not supported"
#endif
-/* Need minimal decorations for DLLs to works on Windows. GCC has
- autoimport and autoexport. Rely on Libtool to help MSVC export
- from a DLL, but always declare data to be imported for MSVC
- clients. This costs an extra indirection for MSVC clients using
- the static version of the library, but don't worry about that.
- Besides, as a workaround, they can define FFI_BUILDING if they
- *know* they are going to link with the static library. */
-#if defined _MSC_VER && !defined FFI_BUILDING
-#define FFI_EXTERN extern __declspec(dllimport)
-#else
-#define FFI_EXTERN extern
-#endif
-
/* These are defined in types.c. */
FFI_EXTERN ffi_type ffi_type_void;
FFI_EXTERN ffi_type ffi_type_uint8;
@@ -256,26 +269,31 @@ typedef ffi_raw ffi_java_raw;
#endif
+FFI_API
void ffi_raw_call (ffi_cif *cif,
void (*fn)(void),
void *rvalue,
ffi_raw *avalue);
-void ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw);
-void ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args);
-size_t ffi_raw_size (ffi_cif *cif);
+FFI_API void ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw);
+FFI_API void ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args);
+FFI_API size_t ffi_raw_size (ffi_cif *cif);
/* This is analogous to the raw API, except it uses Java parameter
packing, even on 64-bit machines. I.e. on 64-bit machines longs
and doubles are followed by an empty 64-bit word. */
+FFI_API
void ffi_java_raw_call (ffi_cif *cif,
void (*fn)(void),
void *rvalue,
ffi_java_raw *avalue);
+FFI_API
void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_java_raw *raw);
+FFI_API
void ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_java_raw *raw, void **args);
+FFI_API
size_t ffi_java_raw_size (ffi_cif *cif);
/* ---- Definitions for closures ----------------------------------------- */
@@ -307,10 +325,10 @@ typedef struct {
# endif
#endif
-void *ffi_closure_alloc (size_t size, void **code);
-void ffi_closure_free (void *);
+FFI_API void *ffi_closure_alloc (size_t size, void **code);
+FFI_API void ffi_closure_free (void *);
-ffi_status
+FFI_API ffi_status
ffi_prep_closure (ffi_closure*,
ffi_cif *,
void (*fun)(ffi_cif*,void*,void**,void*),
@@ -322,7 +340,7 @@ ffi_prep_closure (ffi_closure*,
#endif
;
-ffi_status
+FFI_API ffi_status
ffi_prep_closure_loc (ffi_closure*,
ffi_cif *,
void (*fun)(ffi_cif*,void*,void**,void*),
@@ -383,26 +401,26 @@ typedef struct {
} ffi_java_raw_closure;
-ffi_status
+FFI_API ffi_status
ffi_prep_raw_closure (ffi_raw_closure*,
ffi_cif *cif,
void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
void *user_data);
-ffi_status
+FFI_API ffi_status
ffi_prep_raw_closure_loc (ffi_raw_closure*,
ffi_cif *cif,
void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
void *user_data,
void *codeloc);
-ffi_status
+FFI_API ffi_status
ffi_prep_java_raw_closure (ffi_java_raw_closure*,
ffi_cif *cif,
void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),
void *user_data);
-ffi_status
+FFI_API ffi_status
ffi_prep_java_raw_closure_loc (ffi_java_raw_closure*,
ffi_cif *cif,
void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),
@@ -419,22 +437,24 @@ typedef struct {
void (*fun)(ffi_cif*,void*,void**,void*);
} ffi_go_closure;
-ffi_status ffi_prep_go_closure (ffi_go_closure*, ffi_cif *,
+FFI_API ffi_status ffi_prep_go_closure (ffi_go_closure*, ffi_cif *,
void (*fun)(ffi_cif*,void*,void**,void*));
-void ffi_call_go (ffi_cif *cif, void (*fn)(void), void *rvalue,
+FFI_API void ffi_call_go (ffi_cif *cif, void (*fn)(void), void *rvalue,
void **avalue, void *closure);
#endif /* FFI_GO_CLOSURES */
/* ---- Public interface definition -------------------------------------- */
+FFI_API
ffi_status ffi_prep_cif(ffi_cif *cif,
ffi_abi abi,
unsigned int nargs,
ffi_type *rtype,
ffi_type **atypes);
+FFI_API
ffi_status ffi_prep_cif_var(ffi_cif *cif,
ffi_abi abi,
unsigned int nfixedargs,
@@ -442,11 +462,13 @@ ffi_status ffi_prep_cif_var(ffi_cif *cif,
ffi_type *rtype,
ffi_type **atypes);
+FFI_API
void ffi_call(ffi_cif *cif,
void (*fn)(void),
void *rvalue,
void **avalue);
+FFI_API
ffi_status ffi_get_struct_offsets (ffi_abi abi, ffi_type *struct_type,
size_t *offsets);
diff --git a/msvcc.sh b/msvcc.sh
index 9ed6bd1..9a252f8 100755
--- a/msvcc.sh
+++ b/msvcc.sh
@@ -52,11 +52,17 @@ ml="ml"
safeseh="-safeseh"
output=
libpaths=
+libversion=7
+verbose=
while [ $# -gt 0 ]
do
case $1
in
+ --verbose)
+ $verbose=1
+ shift 1
+ ;;
--version)
args="-help"
shift 1
@@ -162,23 +168,30 @@ do
;;
-L)
p=$(cygpath -m $2)
- linkargs="$linkargs /LIBPATH:$p"
+ linkargs="$linkargs -LIBPATH:$p"
shift 2
;;
-L*)
p=$(cygpath -m ${1#-L})
- linkargs="$linkargs /LIBPATH:$p"
+ linkargs="$linkargs -LIBPATH:$p"
shift 1
;;
+ -link)
+ # add next argument verbatim to linker args
+ linkargs="$linkargs $2"
+ shift 2
+ ;;
-l*)
case $1
in
- -lffi)
- linkargs="$linkargs lib${1#-l}.a"
- ;;
- *)
- # linkargs="$linkargs ${1#-l}.lib"
- ;;
+ -lffi)
+ linkargs="$linkargs lib${1#-l}-${libversion}.lib"
+ ;;
+ *)
+ # ignore other libraries like -lm, hope they are
+ # covered by MSVCRT
+ # linkargs="$linkargs ${1#-l}.lib"
+ ;;
esac
shift 1
;;
@@ -195,6 +208,15 @@ do
# libffi tests -pedantic with -Wall, so drop it also.
shift 1
;;
+ -warn)
+ # ignore -warn all from libtool as well.
+ if test "$2" = "all"; then
+ shift 2
+ else
+ args="$args -warn"
+ shift 1
+ fi
+ ;;
-Werror)
args="$args -WX"
shift 1
@@ -248,7 +270,7 @@ if [ -n "$linkargs" ]; then
linkargs="$linkargs -OPT:REF -OPT:ICF -INCREMENTAL:NO"
fi
- args="$args /link $linkargs"
+ args="$args -link $linkargs"
fi
if [ -n "$static_crt" ]; then
@@ -266,12 +288,19 @@ if [ -n "$assembly" ]; then
outdir="."
fi
ppsrc="$outdir/$(basename $src|sed 's/.S$/.asm/g')"
- echo "$cl -nologo -EP $includes $defines $src > $ppsrc"
+
+ if test -n "$verbose"; then
+ echo "$cl -nologo -EP $includes $defines $src > $ppsrc"
+ fi
+
"$cl" -nologo -EP $includes $defines $src > $ppsrc || exit $?
output="$(echo $output | sed 's%/F[dpa][^ ]*%%g')"
args="-nologo $safeseh $single $output $ppsrc"
- echo "$ml $args"
+ if test -n "$verbose"; then
+ echo "$ml $args"
+ fi
+
eval "\"$ml\" $args"
result=$?
@@ -279,13 +308,21 @@ if [ -n "$assembly" ]; then
#mv *.obj $outdir
else
args="$md $args"
- echo "$cl $args"
+
+ if test -n "$verbose"; then
+ echo "$cl $args"
+ fi
# Return an error code of 1 if an invalid command line parameter is passed
- # instead of just ignoring it.
+ # instead of just ignoring it. Any output that is not a warning or an
+ # error is filtered so this command behaves more like gcc. cl.exe prints
+ # the name of the compiled file otherwise, which breaks the dejagnu checks
+ # for excess warnings and errors.
eval "(\"$cl\" $args 2>&1 1>&3 | \
- awk '{print \$0} /D9002/ {error=1} END{exit error}' >&2) 3>&1"
+ awk '{print \$0} /D9002/ {error=1} END{exit error}' >&2) 3>&1 | \
+ awk '/warning|error/'"
result=$?
fi
exit $result
+# vim: noai:ts=4:sw=4
diff --git a/src/types.c b/src/types.c
index 7e80aec..9ec27f6 100644
--- a/src/types.c
+++ b/src/types.c
@@ -38,6 +38,7 @@ struct struct_align_##name { \
char c; \
type x; \
}; \
+FFI_EXTERN \
maybe_const ffi_type ffi_type_##name = { \
sizeof(type), \
offsetof(struct struct_align_##name, x), \
@@ -52,6 +53,7 @@ struct struct_align_complex_##name { \
char c; \
_Complex type x; \
}; \
+FFI_EXTERN \
maybe_const ffi_type ffi_type_complex_##name = { \
sizeof(_Complex type), \
offsetof(struct struct_align_complex_##name, x), \
@@ -60,7 +62,7 @@ maybe_const ffi_type ffi_type_complex_##name = { \
}
/* Size and alignment are fake here. They must not be 0. */
-const ffi_type ffi_type_void = {
+FFI_EXTERN const ffi_type ffi_type_void = {
1, 1, FFI_TYPE_VOID, NULL
};
diff --git a/testsuite/libffi.bhaible/bhaible.exp b/testsuite/libffi.bhaible/bhaible.exp
index 7f615e6..6a0bb45 100644
--- a/testsuite/libffi.bhaible/bhaible.exp
+++ b/testsuite/libffi.bhaible/bhaible.exp
@@ -25,7 +25,15 @@ global compiler_vendor
# flags to disable warnings for now.
if { [string match $compiler_vendor "gnu"] } {
set warning_options "-Wno-unused-variable -Wno-unused-parameter -Wno-unused-but-set-variable -Wno-uninitialized";
-} else {
+}
+if { [string match $compiler_vendor "microsoft"] } {
+ # -wd4996 suggest use of vsprintf_s instead of vsprintf
+ # -wd4116 unnamed type definition
+ # -wd4101 unreferenced local variable
+ # -wd4244 warning about implicit double to float conversion
+ set warning_options "-wd4996 -wd4116 -wd4101 -wd4244";
+}
+if { ![string match $compiler_vendor "microsoft"] && ![string match $compiler_vendor "gnu"] } {
set warning_options "-Wno-unused-variable -Wno-unused-parameter -Wno-uninitialized";
}
diff --git a/testsuite/libffi.bhaible/test-call.c b/testsuite/libffi.bhaible/test-call.c
index 82cc79e..5897887 100644
--- a/testsuite/libffi.bhaible/test-call.c
+++ b/testsuite/libffi.bhaible/test-call.c
@@ -25,8 +25,6 @@
#include "alignof.h"
#include <stdarg.h>
-#include "testcases.c"
-
/* libffi testsuite local changes -------------------------------- */
#ifdef DGTEST
/* Redefine exit(1) as a test failure */
@@ -34,7 +32,7 @@
int count = 0;
char rbuf1[2048];
char rbuf2[2048];
-int fprintf(FILE *stream, const char *format, ...)
+int _fprintf(FILE *stream, const char *format, ...)
{
va_list args;
va_start(args, format);
@@ -60,9 +58,12 @@ int fprintf(FILE *stream, const char *format, ...)
return 0;
}
+#define fprintf _fprintf
#endif
/* --------------------------------------------------------------- */
+#include "testcases.c"
+
#ifndef ABI_NUM
#define ABI_NUM FFI_DEFAULT_ABI
#endif
diff --git a/testsuite/libffi.bhaible/test-callback.c b/testsuite/libffi.bhaible/test-callback.c
index 7a435ae..7ddee68 100644
--- a/testsuite/libffi.bhaible/test-callback.c
+++ b/testsuite/libffi.bhaible/test-callback.c
@@ -25,8 +25,6 @@
#include "alignof.h"
#include <stdarg.h>
-#include "testcases.c"
-
/* libffi testsuite local changes -------------------------------- */
#ifdef DGTEST
/* Redefine exit(1) as a test failure */
@@ -34,7 +32,7 @@
int count = 0;
char rbuf1[2048];
char rbuf2[2048];
-int fprintf(FILE *stream, const char *format, ...)
+int _fprintf(FILE *stream, const char *format, ...)
{
va_list args;
va_start(args, format);
@@ -60,9 +58,12 @@ int fprintf(FILE *stream, const char *format, ...)
return 0;
}
+#define fprintf _fprintf
#endif
/* --------------------------------------------------------------- */
+#include "testcases.c"
+
#ifndef ABI_NUM
#define ABI_NUM FFI_DEFAULT_ABI
#endif
diff --git a/testsuite/libffi.call/call.exp b/testsuite/libffi.call/call.exp
index bc2bdc3..ab47415 100644
--- a/testsuite/libffi.call/call.exp
+++ b/testsuite/libffi.call/call.exp
@@ -19,9 +19,22 @@ libffi-init
global srcdir subdir
+if { [string match $compiler_vendor "microsoft"] } {
+ # -wd4005 macro redefinition
+ # -wd4244 implicit conversion to type of smaller size
+ # -wd4305 truncation to smaller type
+ # -wd4477 printf %lu of uintptr_t
+ # -wd4312 implicit conversion to type of greater size
+ # -wd4311 pointer truncation to unsigned long
+ # -EHsc C++ Exception Handling (no SEH exceptions)
+ set additional_options "-wd4005 -wd4244 -wd4305 -wd4477 -wd4312 -wd4311 -EHsc";
+} else {
+ set additional_options "";
+}
+
set tlist [lsort [glob -nocomplain -- $srcdir/$subdir/*.{c,cc}]]
-run-many-tests $tlist ""
+run-many-tests $tlist $additional_options
dg-finish