diff options
author | fwg <fwg@users.noreply.github.com> | 2018-04-02 13:55:31 +0200 |
---|---|---|
committer | Anthony Green <green@moxielogic.com> | 2018-04-02 06:55:31 -0500 |
commit | af6773d6ab4db0577bc6b932ab5a2f98a0a8dca2 (patch) | |
tree | 812b6d0727d5104317df93387c2ac341aaf60b9e | |
parent | 48bdb02867edb7e9f3785ccb4bdff1087fb44246 (diff) | |
download | libffi-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.yml | 8 | ||||
-rw-r--r-- | include/ffi.h.in | 74 | ||||
-rwxr-xr-x | msvcc.sh | 65 | ||||
-rw-r--r-- | src/types.c | 4 | ||||
-rw-r--r-- | testsuite/libffi.bhaible/bhaible.exp | 10 | ||||
-rw-r--r-- | testsuite/libffi.bhaible/test-call.c | 7 | ||||
-rw-r--r-- | testsuite/libffi.bhaible/test-callback.c | 7 | ||||
-rw-r--r-- | testsuite/libffi.call/call.exp | 15 |
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); @@ -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 |