File ghc-use-system-libffi.patch of Package ghc

diff --git a/configure.ac b/configure.ac
index e43a59b..fc67ca7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -89,6 +89,57 @@ AC_ARG_WITH([ghc],
   fi
   WithGhc="$GHC"])
 
+# system libffi
+
+AC_ARG_WITH([system-libffi],
+[AC_HELP_STRING([--with-system-libffi=ARG],
+  [Use system provided module ARG for libffi for RTS [default=no]])
+])
+
+AS_IF([test "x$with_system_libffi" = "xyes"], [
+  with_system_libffi=libffi])
+
+AS_IF([test "x$with_system_libffi" = "x" ], [
+  with_system_libffi=no])
+
+AS_IF([test "x$with_system_libffi" = "xno"], [
+ UseSystemLibFFI="NO"
+ FFIIncludeDir=
+ FFILibDir=
+ LIBFFI_CFLAGS=
+ LIBFFI_LIBS="-optl -Wl,-rpath=\${ghclibdir} -Lrts/dist/build -lffi"
+])
+
+# Should use this but we cannot run aclocal as it would overwrite
+# FP_* macros in aclocal.m4
+# PKG_CHECK_MODULES([LIBFFI], [libffi])
+
+AS_IF([test "x$with_system_libffi" != "xno"], [
+ UseSystemLibFFI="YES"
+ FFIIncludeDir=`pkg-config --variable=includedir $with_system_libffi`
+ FFILibDir=`pkg-config --variable=libdir $with_system_libffi`
+ LIBFFI_CFLAGS=`pkg-config --cflags $with_system_libffi`
+ LIBFFI_LIBS=`pkg-config --libs $with_system_libffi`
+# temporarily set CFLAGS and LIBS
+ CFLAGS2="$CFLAGS"
+ CFLAGS="$LIBFFI_CFLAGS"
+ LIBS2="$LIBS"
+ LIBS="$LIBFFI_LIBS"
+ AS_IF([test "$UseSystemLibFFI" = "YES"], [
+ AC_CHECK_LIB(ffi, ffi_call,
+  [AC_CHECK_HEADERS([ffi/ffi.h ffi.h], [break], [])
+   AC_DEFINE([HAVE_LIBFFI], [1], [Define to 1 if you have libffi.])],
+  [UseSystemLibFFI="NO"])])
+ CFLAGS="$CFLAGS2"
+ LIBS="$LIBS2"
+])
+
+   
+AC_SUBST(UseSystemLibFFI)
+AC_SUBST(FFIIncludeDir)
+AC_SUBST(FFILibDir)
+AC_SUBST(LIBFFI_CFLAGS)
+AC_SUBST(LIBFFI_LIBS)
 
 dnl ** Tell the make system which OS we are using
 dnl $OSTYPE is set by the operating system to "msys" or "cygwin" or something 
diff --git a/ghc.mk b/ghc.mk
index 48d247a..eed3fa5 100644
--- a/ghc.mk
+++ b/ghc.mk
@@ -52,7 +52,7 @@
 #     * For each package:
 #	    o configure, generate package-data.mk and inplace-pkg-info
 #           o register each package into inplace/lib/package.conf
-#     * build libffi
+#     * build libffi (if not disabled by --with-system-libffi)
 #     * With bootstrapping compiler:
 #	    o Build libraries/{filepath,hpc,Cabal}
 #           o Build compiler (stage 1)
@@ -595,12 +595,18 @@ else
 MAYBE_GHCI=driver/ghci
 endif
 
+ifeq "$(UseSystemLibFFI)" "YES"
+MAYBE_LIBFFI=
+else
+MAYBE_LIBFFI=libffi
+endif
+
 BUILD_DIRS += \
    driver \
    $(MAYBE_GHCI) \
    driver/ghc \
    driver/haddock \
-   libffi \
+   $(MAYBE_LIBFFI) \
    includes \
    rts
 
@@ -994,10 +1000,11 @@ endif
 
 BIN_DIST_MK = $(BIN_DIST_PREP_DIR)/bindist.mk
 
+# don't include libffi when building with system libffi
 unix-binary-dist-prep:
 	$(call removeTrees,bindistprep/)
 	"$(MKDIRHIER)" $(BIN_DIST_PREP_DIR)
-	set -e; for i in packages LICENSE compiler ghc rts libraries utils docs libffi includes driver mk rules Makefile aclocal.m4 config.sub config.guess install-sh settings.in ghc.mk inplace distrib/configure.ac distrib/README distrib/INSTALL; do ln -s ../../$$i $(BIN_DIST_PREP_DIR)/; done
+	set -e; for i in packages LICENSE compiler ghc rts libraries utils docs $(MAYBE_LIBFFI) includes driver mk rules Makefile aclocal.m4 config.sub config.guess install-sh settings.in ghc.mk inplace distrib/configure.ac distrib/README distrib/INSTALL; do ln -s ../../$$i $(BIN_DIST_PREP_DIR)/; done
 	echo "HADDOCK_DOCS       = $(HADDOCK_DOCS)"       >> $(BIN_DIST_MK)
 	echo "LATEX_DOCS         = $(LATEX_DOCS)"         >> $(BIN_DIST_MK)
 	echo "BUILD_DOCBOOK_HTML = $(BUILD_DOCBOOK_HTML)" >> $(BIN_DIST_MK)
diff --git a/mk/config.mk.in b/mk/config.mk.in
index 81298e4..258cdc0 100644
--- a/mk/config.mk.in
+++ b/mk/config.mk.in
@@ -362,6 +362,16 @@ GhcRtsWithPapi = NO
 PapiLibDir=
 PapiIncludeDir=
 
+# Configuration for libffi
+UseSystemLibFFI=@UseSystemLibFFI@
+# Flags to go into package.conf for rts
+FFILibDir=@FFILibDir@
+FFIIncludeDir=@FFIIncludeDir@
+# gcc flags needed for libffi
+LIBFFI_CFLAGS=@LIBFFI_CFLAGS@
+LIBFFI_LIBS=@LIBFFI_LIBS@
+
+
 ################################################################################
 #
 #		Paths (see paths.mk)
diff --git a/rts/Adjustor.c b/rts/Adjustor.c
index 1a0bc28..e088dce 100644
--- a/rts/Adjustor.c
+++ b/rts/Adjustor.c
@@ -43,7 +43,14 @@ Haskell side.
 #include "Stable.h"
 
 #if defined(USE_LIBFFI_FOR_ADJUSTORS)
+#include "ghcconfig.h"
+#ifdef HAVE_FFI_H
+#include <ffi.h>
+#elif defined(HAVE_FFI_FFI_H)
+#include <ffi/ffi.h>
+#else
 #include "ffi.h"
+#endif
 #include <string.h>
 #endif
 
diff --git a/rts/Interpreter.c b/rts/Interpreter.c
index d879fd3..7819fc9 100644
--- a/rts/Interpreter.c
+++ b/rts/Interpreter.c
@@ -37,7 +37,14 @@
 #endif
 #endif
 
+#include "ghcconfig.h"
+#ifdef HAVE_FFI_H
+#include <ffi.h>
+#elif defined(HAVE_FFI_FFI_H)
+#include <ffi/ffi.h>
+#else
 #include "ffi.h"
+#endif
 
 /* --------------------------------------------------------------------------
  * The bytecode interpreter
diff --git a/rts/ghc.mk b/rts/ghc.mk
index 9fdf6be..408e485 100644
--- a/rts/ghc.mk
+++ b/rts/ghc.mk
@@ -104,6 +104,10 @@ $(foreach lib,$(ALL_RTS_DEF_LIBNAMES),$(eval $(call make-importlib-def,$(lib))))
 endif
 
 ifneq "$(BINDIST)" "YES"
+ifeq "$(UseSystemLibFFI)" "YES"
+rts_ffi_objs_stamp =
+rts_ffi_objs       =
+else
 rts_ffi_objs_stamp = rts/dist/ffi/stamp
 rts_ffi_objs       = rts/dist/ffi/*.o
 $(rts_ffi_objs_stamp): $(libffi_STATIC_LIB) $(TOUCH_DEP) | $$(dir $$@)/.
@@ -118,6 +122,7 @@ rts/dist/build/libffi$(soext): libffi/build/inst/lib/libffi$(soext)
 rts/dist/build/$(LIBFFI_DLL): libffi/build/inst/bin/$(LIBFFI_DLL)
 	cp $< $@
 endif
+endif
 
 #-----------------------------------------------------------------------------
 # Building one way
@@ -174,6 +179,12 @@ endif
 
 rts_dist_$1_CC_OPTS += -DRtsWay=\"rts_$1\"
 
+ifeq "$(UseSystemLibFFI)" "NO"
+rts_dist_FFI_SO = rts/dist/build/libffi$(soext)
+else
+rts_dist_FFI_SO =
+endif
+
 # Making a shared library for the RTS.
 ifneq "$$(findstring dyn, $1)" ""
 ifeq "$$(HostOS_CPP)" "mingw32" 
@@ -182,10 +193,10 @@ $$(rts_$1_LIB) : $$(rts_$1_OBJS) $$(ALL_RTS_DEF_LIBS) rts/libs.depend rts/dist/b
 	"$$(rts_dist_HC)" -package-name rts -shared -dynamic -dynload deploy \
 	  -no-auto-link-packages -Lrts/dist/build -l$(LIBFFI_WINDOWS_LIB) `cat rts/libs.depend` $$(rts_$1_OBJS) $$(ALL_RTS_DEF_LIBS) -o $$@
 else
-$$(rts_$1_LIB) : $$(rts_$1_OBJS) $$(rts_$1_DTRACE_OBJS) rts/libs.depend rts/dist/build/libffi$$(soext)
+$$(rts_$1_LIB) : $$(rts_$1_OBJS) $$(rts_$1_DTRACE_OBJS) rts/libs.depend $$(rts_dist_FFI_SO)
 	"$$(RM)" $$(RM_OPTS) $$@
 	"$$(rts_dist_HC)" -package-name rts -shared -dynamic -dynload deploy \
-	  -no-auto-link-packages -Lrts/dist/build -lffi `cat rts/libs.depend` $$(rts_$1_OBJS) \
+	  -no-auto-link-packages $$(LIBFFI_LIBS) `cat rts/libs.depend` $$(rts_$1_OBJS) \
 	  $$(rts_$1_DTRACE_OBJS) -o $$@
 ifeq "$$(darwin_HOST_OS)" "1"
 	# Ensure library's install name is correct before anyone links with it.
@@ -374,10 +385,11 @@ rts/dist/build/AutoApply_HC_OPTS += -fno-PIC -static
 endif
 endif
 
+# add CFLAGS for libffi
 # ffi.h triggers prototype warnings, so disable them here:
-rts/Interpreter_CC_OPTS += -Wno-strict-prototypes
-rts/Adjustor_CC_OPTS    += -Wno-strict-prototypes
-rts/sm/Storage_CC_OPTS  += -Wno-strict-prototypes
+rts/Interpreter_CC_OPTS += -Wno-strict-prototypes $(LIBFFI_CFLAGS)
+rts/Adjustor_CC_OPTS    += -Wno-strict-prototypes $(LIBFFI_CFLAGS)
+rts/sm/Storage_CC_OPTS  += -Wno-strict-prototypes $(LIBFFI_CFLAGS)
 
 # inlining warnings happen in Compact
 rts/sm/Compact_CC_OPTS += -Wno-inline
@@ -435,6 +447,21 @@ rts_PACKAGE_CPP_OPTS += -DPAPI_LIB_DIR=""
 
 endif
 
+#-----------------------------------------------------------------------------
+# Use system provided libffi
+
+ifeq "$(UseSystemLibFFI)" "YES"
+
+rts_PACKAGE_CPP_OPTS    += -DFFI_INCLUDE_DIR=$(FFIIncludeDir)
+rts_PACKAGE_CPP_OPTS    += -DFFI_LIB_DIR=$(FFILibDir)
+
+else # UseSystemLibFFI==YES
+
+rts_PACKAGE_CPP_OPTS += -DFFI_INCLUDE_DIR=""
+rts_PACKAGE_CPP_OPTS += -DFFI_LIB_DIR=""
+
+endif
+
 # -----------------------------------------------------------------------------
 # dependencies
 
@@ -512,7 +539,11 @@ INSTALL_LIBS += $(ALL_RTS_LIBS)
 INSTALL_LIBS += $(wildcard rts/dist/build/libffi$(soext)*)
 INSTALL_LIBS += $(wildcard rts/dist/build/$(LIBFFI_DLL))
 
+ifneq "$(UseSystemLibFFI)" "YES"
 install: install_libffi_headers
+else
+install:
+endif
 
 .PHONY: install_libffi_headers
 install_libffi_headers :
diff --git a/rts/package.conf.in b/rts/package.conf.in
index 727b586..6bf3b50 100644
--- a/rts/package.conf.in
+++ b/rts/package.conf.in
@@ -33,6 +33,9 @@ extra-libraries:
 #ifdef HAVE_LIBDL
 			      , "dl"
 #endif
+#ifdef HAVE_LIBFFI
+                              , "ffi"
+#endif
 #ifdef mingw32_HOST_OS
 			      ,"wsock32"    /* for the linker */
 			      ,"gdi32"      /* for the linker */
diff --git a/rts/sm/Storage.c b/rts/sm/Storage.c
index f645cd4..0315d6f 100644
--- a/rts/sm/Storage.c
+++ b/rts/sm/Storage.c
@@ -32,7 +32,14 @@
 
 #include <string.h>
 
+#include "ghcconfig.h"
+#ifdef HAVE_FFI_H
+#include <ffi.h>
+#elif defined(HAVE_FFI_FFI_H)
+#include <ffi/ffi.h>
+#else
 #include "ffi.h"
+#endif
 
 /* 
  * All these globals require sm_mutex to access in THREADED_RTS mode.