This is the mail archive of the libffi-discuss@sourceware.org mailing list for the libffi project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH 0/6] MSVC fixes


Peter Rosin skrev 2012-03-23 08:35:
> Anthony Green skrev 2012-03-23 01:23:
>> On 3/22/2012 7:25 PM, Peter Rosin wrote:
>>> This series fixes a number of problems that MSVC has with libffi.
>>
>> Thanks Peter.   Do you know if MS makes a Free-as-in-Beer MSVC distribution?
> 
> Yes, they do, Microsoft named them the "Express" edition.
> 
> Latest non-beta version here:
> http://www.microsoft.com/visualstudio/en-us/products/2010-editions/express
> 
> I have a few wrapper scripts and hacks in the environment to make it work, and
> one more small unfinished patch that's needed for the testsuite to work with
> MSVC when libffi is a dll.  I'll write something up to describe my environment
> later, things are interfering...

Notes on using libffi with MSVC

MSVC is best run from MSYS.  MSVC is *much* more similar in nature to
the MinGW-GCC than to the more posixy-expecting toolchains provided
by Cygwin.

The testsuite needs dejagnu/expect/tcl and I selected to use the Cygwin
versions.  But doing that and running from MSYS forces you to set up
an "identify mount" (google it) so that the posix tools in Cygwin
finds the same files as the native Win32 tools do.  I created my
identity mount in an unorthodox way because I already had everything
installed in a way not compatible with an ordinary identity mount
setting.

I have Cygwin installed in C:\Cygwin, MinGW in c:\MinGW and the MSYS
root in C:\MinGW\msys\1.0.  The cygdrive prefix for Cygwin is "/cygdrive"
and for MSYS it's just plain old "/".  I.e., the defaults.

Then add a mount to Cygwin so that Cygwin processes sees /c/Cygwin
the same way as MSYS processes does:

cygwin$ mount C:/ /c

Then create a junction named "C:\c" pointing back to "C:\" so that
native Win32 processes sees /c/Cygwin the same way too.  In a cmd window:

C:\> mklink /D c:\c c:\

With this everybody can access the same files as /c/Cygwin/bla/bla, at
least as long as the current drive of native Win32 processes is C:, but
that's a fairly easy promise to keep in this setting.

Using Cygwin, I then checkout libffi:

cygwin$ cd   # Now in C:\Cygwin\home\<username>
cygwin$ git clone git://.../libffi.git

Then fool the libffi testsuite into thinking that MSYS has dejagnu etc
like this:  

cygwin$ cat << 'EOF' > dejagnu/runtest
#! /bin/sh
export DEJAGNULIBS=/c/Cygwin/usr/share/dejagnu
/c/Cygwin/bin/runtest "$@"
EOF
cygwin$ chmod +x dejagnu/runtest
cygwin$ cat << 'EOF' > libffi/expect/expect
#! /bin/sh
/c/Cygwin/bin/expect "$@"
EOF
cygwin$ chmod +x libffi/expect/expect

Then provide the libffi testsuite with an xgcc wrapper that invokes MSVC
with a hacked version of the latest version of the compile script from
automake (attached, this hacked version works better than the provided
msvcc.sh):

cygwin$ cat << 'EOF' > libffi/xgcc
#! /bin/sh
/c/Cygwin/home/<username>/libffi/compile cl -nologo -Zi -MD "$@"
EOF
cygwin$ chmod +x libffi/xgcc

Then replace the compile script as provided by libffi (the one in
/c/Cygwin/home/<username>/libffi/compile) with the above mentioned
version.

I'm using this script to set up the environment for running MSVC,
but I don't know how the directories map to the "Express" edition?
I think there's an install option to add these directories to the
Windows environment, making MSVC visible allover (but I don't like
that so I'm using my script instead).


cygwin$ cat << 'EOF' > /c/Cygwin/home/peda/bin/vccvars.sh
case `uname` in
CYGWIN*) c=/cygdrive/c ;;
*)       c=/c ;;
esac

COMNTOOLS=$c'/Program Files (x86)/Microsoft Visual Studio 10.0/'
PSDK=$c'/Program Files (x86)/Microsoft SDKs/Windows/v7.0A/'

VS100COMNTOOLS=$COMNTOOLS'Common7/Tools/'
WindowsSdkDir=$PSDK
VCINSTALLDIR=$COMNTOOLS'VC/'
VSINSTALLDIR=$COMNTOOLS
DevEnvDir=$COMNTOOLS'Common7/IDE/'

export PATH=$c'/Program Files (x86)/Microsoft F#/v4.0/:'\
$COMNTOOLS'VSTSDB/Deploy:'\
$DevEnvDir':'\
$VCINSTALLDIR'BIN':\
$VS100COMNTOOLS':'\
$c'/Windows/Microsoft.NET/Framework/v4.0.30319:'\
$c'/Windows/Microsoft.NET/Framework/v3.5:'\
$VCINSTALLDIR'VCPackages:'\
$c'/Program Files (x86)/HTML Help Workshop:'\
$COMNTOOLS'Team Tools/Performance Tools:'\
$PSDK'bin/NETFX 4.0 Tools:'$PATH


COMNTOOLS='c:\Program Files (x86)\Microsoft Visual Studio 10.0\'
PSDK='c:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\'

export VS100COMNTOOLS=$COMNTOOLS'Common7\Tools\'
export WindowsSdkDir=$PSDK
export VCINSTALLDIR=$COMNTOOLS'VC\'
export VSINSTALLDIR=$COMNTOOLS
export DevEnvDir=$COMNTOOLS'Common7\IDE\'

export INCLUDE=$PSDK'INCLUDE;'$INCLUDE
export INCLUDE=$VCINSTALLDIR'ATLMFC\INCLUDE;'$INCLUDE
export INCLUDE=$VCINSTALLDIR'INCLUDE;'$INCLUDE
export LIB=$PSDK'LIB;'$LIB
export LIB=$VCINSTALLDIR'ATLMFC\LIB;'$LIB
export LIB=$VCINSTALLDIR'LIB;'$LIB
export LIBPATH=$PSDK'LIB;'$LIBPATH
export LIBPATH=$VCINSTALLDIR'ATLMFC\LIB;'$LIBPATH
export LIBPATH=$VCINSTALLDIR'LIB;'$LIBPATH
export DevEnvDir=$COMNTOOLS'Common7\IDE\'
EOF
cygwin$ chmod -x /c/Cygwin/home/<username>/bin/vcvars.sh


Set up the MSYS environment to run MSVC.

msys$ . /c/Cygwin/home/<username>/bin/vcvars.sh

Finally, build the dang thing:

msys$ cd /c/Cygwin/home/<username>/libffi
msys$ cd msvc
msys$ ../configure \
  CC="/c/Cygwin/home/<usename>/libffi/compile cl -nologo" \
  CFLAGS="-MD -Zi" \
  CXX="/c/Cygwin/home/<username>/libffi/compile cl -nologo" \
  CXXFLAGS="-MD -Zi" \
  NM="dumpbin -symbols" \
  --enable-dependency-tracking \
  --disable-shared
msys$ make
msys$ make check | grep -v "excess errors"  # MSVC is *noisy*


Hmmm, I wonder what I forgot?

One thing is that I can't remember if I had to do anything special
to prevent Cygwin from creating symbolic links (MSYS and native
Win32 processes don't understand those).

Oh, along those lines, one thing to keep in mind is that MSYS does
not provide symbolic links at all (ln -s makes a copy), so I have to
run ./config.status to recopy ../src/x86/ffitarget.h to the build
tree in case it has changed.



With the below patch, I can configure with the below args
and get a DLL that can be used by the testsuite, but that
FFI_BUILDING define should be added to a Makefile instead of
burdening the user to add it to CFLAGS so the patch is not
finished (but perhaps it's not an acceptable approach to add
an FFI_BUILDING define?).

Cheers,
Peter


msys$ ../configure \
  CC="/c/Cygwin/home/<usename>/libffi/compile cl -nologo" \
  CFLAGS="-MD -Zi -DFFI_BUILDING" \
  CXX="/c/Cygwin/home/<username>/libffi/compile cl -nologo" \
  CXXFLAGS="-MD -Zi -DFFI_BUILDING" \
  NM="dumpbin -symbols" \
  --enable-dependency-tracking


diff --git a/include/ffi.h.in b/include/ffi.h.in
index 84017f1..100ec04 100644
--- a/include/ffi.h.in
+++ b/include/ffi.h.in
@@ -166,19 +166,25 @@ typedef struct _ffi_type
  #error "long size not supported"
 #endif

+#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 */
-extern ffi_type ffi_type_void;
-extern ffi_type ffi_type_uint8;
-extern ffi_type ffi_type_sint8;
-extern ffi_type ffi_type_uint16;
-extern ffi_type ffi_type_sint16;
-extern ffi_type ffi_type_uint32;
-extern ffi_type ffi_type_sint32;
-extern ffi_type ffi_type_uint64;
-extern ffi_type ffi_type_sint64;
-extern ffi_type ffi_type_float;
-extern ffi_type ffi_type_double;
-extern ffi_type ffi_type_pointer;
+FFI_EXTERN ffi_type ffi_type_void;
+FFI_EXTERN ffi_type ffi_type_uint8;
+FFI_EXTERN ffi_type ffi_type_sint8;
+FFI_EXTERN ffi_type ffi_type_uint16;
+FFI_EXTERN ffi_type ffi_type_sint16;
+FFI_EXTERN ffi_type ffi_type_uint32;
+FFI_EXTERN ffi_type ffi_type_sint32;
+FFI_EXTERN ffi_type ffi_type_uint64;
+FFI_EXTERN ffi_type ffi_type_sint64;
+FFI_EXTERN ffi_type ffi_type_float;
+FFI_EXTERN ffi_type ffi_type_double;
+FFI_EXTERN ffi_type ffi_type_pointer;

 #if @HAVE_LONG_DOUBLE@
 extern ffi_type ffi_type_longdouble;

Attachment: compile
Description: Text document


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]