8309880: Add support for linking libffi on Windows and Mac
Co-authored-by: Aleksey Shipilev <shade@openjdk.org> Co-authored-by: Jorn Vernee <jvernee@openjdk.org> Reviewed-by: erikj
This commit is contained in:
parent
1d1ed0d8f7
commit
4c18b9e1fa
@ -57,7 +57,11 @@ AC_DEFUN_ONCE([LIB_SETUP_LIBFFI],
|
|||||||
|
|
||||||
if test "x${with_libffi}" != x; then
|
if test "x${with_libffi}" != x; then
|
||||||
LIBFFI_LIB_PATH="${with_libffi}/lib"
|
LIBFFI_LIB_PATH="${with_libffi}/lib"
|
||||||
|
if test "x${OPENJDK_TARGET_OS}" != "xwindows"; then
|
||||||
LIBFFI_LIBS="-L${with_libffi}/lib -lffi"
|
LIBFFI_LIBS="-L${with_libffi}/lib -lffi"
|
||||||
|
else
|
||||||
|
LIBFFI_LIBS="${with_libffi}/lib/libffi.lib"
|
||||||
|
fi
|
||||||
LIBFFI_CFLAGS="-I${with_libffi}/include"
|
LIBFFI_CFLAGS="-I${with_libffi}/include"
|
||||||
LIBFFI_FOUND=yes
|
LIBFFI_FOUND=yes
|
||||||
fi
|
fi
|
||||||
@ -67,7 +71,11 @@ AC_DEFUN_ONCE([LIB_SETUP_LIBFFI],
|
|||||||
fi
|
fi
|
||||||
if test "x${with_libffi_lib}" != x; then
|
if test "x${with_libffi_lib}" != x; then
|
||||||
LIBFFI_LIB_PATH="${with_libffi_lib}"
|
LIBFFI_LIB_PATH="${with_libffi_lib}"
|
||||||
|
if test "x${OPENJDK_TARGET_OS}" != "xwindows"; then
|
||||||
LIBFFI_LIBS="-L${with_libffi_lib} -lffi"
|
LIBFFI_LIBS="-L${with_libffi_lib} -lffi"
|
||||||
|
else
|
||||||
|
LIBFFI_LIBS="${with_libffi_lib}/libffi.lib"
|
||||||
|
fi
|
||||||
LIBFFI_FOUND=yes
|
LIBFFI_FOUND=yes
|
||||||
fi
|
fi
|
||||||
# Do not try pkg-config if we have a sysroot set.
|
# Do not try pkg-config if we have a sysroot set.
|
||||||
@ -106,12 +114,13 @@ AC_DEFUN_ONCE([LIB_SETUP_LIBFFI],
|
|||||||
AC_MSG_ERROR([Could not find libffi! $HELP_MSG])
|
AC_MSG_ERROR([Could not find libffi! $HELP_MSG])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
AC_MSG_CHECKING([if libffi works])
|
|
||||||
AC_LANG_PUSH(C)
|
AC_LANG_PUSH(C)
|
||||||
OLD_CFLAGS="$CFLAGS"
|
OLD_CFLAGS="$CFLAGS"
|
||||||
CFLAGS="$CFLAGS $LIBFFI_CFLAGS"
|
CFLAGS="$CFLAGS $LIBFFI_CFLAGS"
|
||||||
OLD_LIBS="$LIBS"
|
OLD_LIBS="$LIBS"
|
||||||
LIBS="$LIBS $LIBFFI_LIBS"
|
LIBS="$LIBS $LIBFFI_LIBS"
|
||||||
|
|
||||||
|
AC_MSG_CHECKING([if libffi works])
|
||||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <ffi.h>],
|
AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <ffi.h>],
|
||||||
[
|
[
|
||||||
ffi_call(NULL, NULL, NULL, NULL);
|
ffi_call(NULL, NULL, NULL, NULL);
|
||||||
@ -120,9 +129,6 @@ AC_DEFUN_ONCE([LIB_SETUP_LIBFFI],
|
|||||||
[LIBFFI_WORKS=yes],
|
[LIBFFI_WORKS=yes],
|
||||||
[LIBFFI_WORKS=no]
|
[LIBFFI_WORKS=no]
|
||||||
)
|
)
|
||||||
CFLAGS="$OLD_CFLAGS"
|
|
||||||
LIBS="$OLD_LIBS"
|
|
||||||
AC_LANG_POP(C)
|
|
||||||
AC_MSG_RESULT([$LIBFFI_WORKS])
|
AC_MSG_RESULT([$LIBFFI_WORKS])
|
||||||
|
|
||||||
if test "x$LIBFFI_WORKS" = xno; then
|
if test "x$LIBFFI_WORKS" = xno; then
|
||||||
@ -130,39 +136,71 @@ AC_DEFUN_ONCE([LIB_SETUP_LIBFFI],
|
|||||||
AC_MSG_ERROR([Found libffi but could not link and compile with it. $HELP_MSG])
|
AC_MSG_ERROR([Found libffi but could not link and compile with it. $HELP_MSG])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Check if FFI_GO_CLOSURES is properly defined. On some distributions, notably MacOS AArch64,
|
||||||
|
# ffitarget.h (included from ffi.h) does not explicitly define FFI_GO_CLOSURES. This makes the
|
||||||
|
# further include of ffi.h trigger the "FFI_GO_CLOSURES is undefined" warning, which fails
|
||||||
|
# the build when warnings are fatal.
|
||||||
|
AC_MSG_CHECKING([for FFI_GO_CLOSURES definition])
|
||||||
|
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([
|
||||||
|
#include <ffi.h>
|
||||||
|
#ifndef FFI_GO_CLOSURES
|
||||||
|
#error "FFI_GO_CLOSURES is not defined"
|
||||||
|
#endif
|
||||||
|
][])],
|
||||||
|
[
|
||||||
|
AC_MSG_RESULT([yes])
|
||||||
|
],
|
||||||
|
[
|
||||||
|
AC_MSG_RESULT([no, defining])
|
||||||
|
LIBFFI_CFLAGS="$LIBFFI_CFLAGS -DFFI_GO_CLOSURES=0"
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
CFLAGS="$OLD_CFLAGS"
|
||||||
|
LIBS="$OLD_LIBS"
|
||||||
|
AC_LANG_POP(C)
|
||||||
|
|
||||||
# Find the libffi.so.X to bundle
|
# Find the libffi.so.X to bundle
|
||||||
if test "x${ENABLE_LIBFFI_BUNDLING}" = "xtrue"; then
|
if test "x${ENABLE_LIBFFI_BUNDLING}" = "xtrue"; then
|
||||||
|
if test "x${OPENJDK_TARGET_OS}" = "xmacosx"; then
|
||||||
|
LIBFFI_LIB_FILE_NAME=libffi.?.dylib
|
||||||
|
elif test "x${OPENJDK_TARGET_OS}" = "xwindows"; then
|
||||||
|
LIBFFI_LIB_FILE_NAME=libffi.dll
|
||||||
|
else
|
||||||
|
LIBFFI_LIB_FILE_NAME=libffi.so.?
|
||||||
|
fi
|
||||||
|
|
||||||
AC_MSG_CHECKING([for libffi lib file location])
|
AC_MSG_CHECKING([for libffi lib file location])
|
||||||
if test "x${LIBFFI_LIB_PATH}" != x; then
|
if test "x${LIBFFI_LIB_PATH}" != x; then
|
||||||
if test -e ${LIBFFI_LIB_PATH}/libffi.so.?; then
|
if test -e ${LIBFFI_LIB_PATH}/${LIBFFI_LIB_FILE_NAME}; then
|
||||||
LIBFFI_LIB_FILE="${LIBFFI_LIB_PATH}/libffi.so.?"
|
LIBFFI_LIB_FILE="${LIBFFI_LIB_PATH}/${LIBFFI_LIB_FILE_NAME}"
|
||||||
else
|
else
|
||||||
AC_MSG_ERROR([Could not locate libffi.so.? for bundling in ${LIBFFI_LIB_PATH}])
|
AC_MSG_ERROR([Could not locate ${LIBFFI_LIB_FILE_NAME} for bundling in ${LIBFFI_LIB_PATH}])
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
# If we don't have an explicit path, look in a few obvious places
|
# If we don't have an explicit path, look in a few obvious places
|
||||||
if test "x${OPENJDK_TARGET_CPU}" = "xx86"; then
|
if test "x${OPENJDK_TARGET_CPU}" = "xx86"; then
|
||||||
if test -e ${SYSROOT}/usr/lib/libffi.so.? ; then
|
if test -e ${SYSROOT}/usr/lib/${LIBFFI_LIB_FILE_NAME} ; then
|
||||||
LIBFFI_LIB_FILE="${SYSROOT}/usr/lib/libffi.so.?"
|
LIBFFI_LIB_FILE="${SYSROOT}/usr/lib/${LIBFFI_LIB_FILE_NAME}"
|
||||||
elif test -e ${SYSROOT}/usr/lib/i386-linux-gnu/libffi.so.? ; then
|
elif test -e ${SYSROOT}/usr/lib/i386-linux-gnu/${LIBFFI_LIB_FILE_NAME} ; then
|
||||||
LIBFFI_LIB_FILE="${SYSROOT}/usr/lib/i386-linux-gnu/libffi.so.?"
|
LIBFFI_LIB_FILE="${SYSROOT}/usr/lib/i386-linux-gnu/${LIBFFI_LIB_FILE_NAME}"
|
||||||
else
|
else
|
||||||
AC_MSG_ERROR([Could not locate libffi.so.? for bundling])
|
AC_MSG_ERROR([Could not locate ${LIBFFI_LIB_FILE_NAME} for bundling])
|
||||||
fi
|
fi
|
||||||
elif test "x${OPENJDK_TARGET_CPU}" = "xx86_64" || test "x${OPENJDK_TARGET_CPU}" = "xaarch64"; then
|
elif test "x${OPENJDK_TARGET_CPU}" = "xx86_64" || test "x${OPENJDK_TARGET_CPU}" = "xaarch64"; then
|
||||||
if test -e ${SYSROOT}/usr/lib64/libffi.so.? ; then
|
if test -e ${SYSROOT}/usr/lib64/${LIBFFI_LIB_FILE_NAME} ; then
|
||||||
LIBFFI_LIB_FILE="${SYSROOT}/usr/lib64/libffi.so.?"
|
LIBFFI_LIB_FILE="${SYSROOT}/usr/lib64/${LIBFFI_LIB_FILE_NAME}"
|
||||||
elif test -e ${SYSROOT}/usr/lib/x86_64-linux-gnu/libffi.so.? ; then
|
elif test -e ${SYSROOT}/usr/lib/x86_64-linux-gnu/${LIBFFI_LIB_FILE_NAME} ; then
|
||||||
LIBFFI_LIB_FILE="${SYSROOT}/usr/lib/x86_64-linux-gnu/libffi.so.?"
|
LIBFFI_LIB_FILE="${SYSROOT}/usr/lib/x86_64-linux-gnu/${LIBFFI_LIB_FILE_NAME}"
|
||||||
else
|
else
|
||||||
AC_MSG_ERROR([Could not locate libffi.so.? for bundling])
|
AC_MSG_ERROR([Could not locate ${LIBFFI_LIB_FILE_NAME} for bundling])
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
# Fallback on the default /usr/lib dir
|
# Fallback on the default /usr/lib dir
|
||||||
if test -e ${SYSROOT}/usr/lib/libffi.so.? ; then
|
if test -e ${SYSROOT}/usr/lib/${LIBFFI_LIB_FILE_NAME} ; then
|
||||||
LIBFFI_LIB_FILE="${SYSROOT}/usr/lib/libffi.so.?"
|
LIBFFI_LIB_FILE="${SYSROOT}/usr/lib/${LIBFFI_LIB_FILE_NAME}"
|
||||||
else
|
else
|
||||||
AC_MSG_ERROR([Could not locate libffi.so.? for bundling])
|
AC_MSG_ERROR([Could not locate ${LIBFFI_LIB_FILE_NAME} for bundling])
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
@ -38,6 +38,38 @@
|
|||||||
# Note that the libtool and texinfo packages are needed to build libffi
|
# Note that the libtool and texinfo packages are needed to build libffi
|
||||||
# $ sudo apt install libtool texinfo
|
# $ sudo apt install libtool texinfo
|
||||||
|
|
||||||
|
# Note that while the build system supports linking against libffi on Windows (x64),
|
||||||
|
# I couldn't get this script working with a Windows devkit, and instead had to manually create
|
||||||
|
# a libffi bundle for Windows. The steps I took were as follows:
|
||||||
|
#
|
||||||
|
# 1. run 'x64 Native Tools Command Prompt for VS 2022'. After that, cl.exe and link.exe should be on path
|
||||||
|
#
|
||||||
|
# 2. in the same shell, run `ucrt64` (this is one of the shell environments that comes with MSYS2).
|
||||||
|
# This should carry over the environment set up by the VS dev prompt into the ucrt64 prompt.
|
||||||
|
#
|
||||||
|
# 3. then, in the libffi repo root folder:
|
||||||
|
# 3.a run `autogen.sh`
|
||||||
|
# 3.b run:
|
||||||
|
# ```
|
||||||
|
# bash configure \
|
||||||
|
# CC="/path/to/libffi/msvcc.sh -m64" \
|
||||||
|
# CXX="/path/to/libffi/msvcc.sh -m64" \
|
||||||
|
# CPPFLAGS="-DFFI_BUILDING_DLL" \
|
||||||
|
# --disable-docs \
|
||||||
|
# --prefix=<install dest>
|
||||||
|
# ```
|
||||||
|
# (`<install dest>` can be whatever you like. That's what you point `--with-libffi` to).
|
||||||
|
#
|
||||||
|
# 4. run `make install`. This should create the `<install dest>` directory with the files:
|
||||||
|
# `include/ffi.h`, `include/ffitarget.h`, `lib/libffi.dll`. It also creates a `lib/libffi.lib` file,
|
||||||
|
# but it is of the wrong file type, `DLL` rather than `LIBRARY`.
|
||||||
|
#
|
||||||
|
# 5. Manually create a working `.lib` file (in the <install dest>/lib dir):
|
||||||
|
# 5.a use `dumpbin /exports libffi.dll` to get a list of exported symbols
|
||||||
|
# 5.b put them in a `libffi.def` file: `EXPORTS` on the first line, then a symbol on each line following
|
||||||
|
# 5.c run `lib /def:libffi.def /machine:x64 /out:libffi.lib` to create the right `.lib` file (`lib` is a visual studio tool)
|
||||||
|
#
|
||||||
|
|
||||||
LIBFFI_VERSION=3.4.2
|
LIBFFI_VERSION=3.4.2
|
||||||
|
|
||||||
BUNDLE_NAME=libffi-$LIBFFI_VERSION.tar.gz
|
BUNDLE_NAME=libffi-$LIBFFI_VERSION.tar.gz
|
||||||
@ -49,6 +81,7 @@ SRC_DIR="$OUTPUT_DIR/src"
|
|||||||
DOWNLOAD_DIR="$OUTPUT_DIR/download"
|
DOWNLOAD_DIR="$OUTPUT_DIR/download"
|
||||||
INSTALL_DIR="$OUTPUT_DIR/install"
|
INSTALL_DIR="$OUTPUT_DIR/install"
|
||||||
IMAGE_DIR="$OUTPUT_DIR/image"
|
IMAGE_DIR="$OUTPUT_DIR/image"
|
||||||
|
OS_NAME=$(uname -s)
|
||||||
|
|
||||||
USAGE="$0 <devkit dir>"
|
USAGE="$0 <devkit dir>"
|
||||||
|
|
||||||
@ -81,8 +114,33 @@ cd $LIBFFI_DIR
|
|||||||
if [ ! -e $LIBFFI_DIR/configure ]; then
|
if [ ! -e $LIBFFI_DIR/configure ]; then
|
||||||
bash ./autogen.sh
|
bash ./autogen.sh
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
case $OS_NAME in
|
||||||
|
Linux)
|
||||||
|
CC=$DEVKIT_DIR/bin/gcc
|
||||||
|
CXX=$DEVKIT_DIR/bin/g++
|
||||||
|
# For Linux/x86 it's under /lib/ instead of /lib64/
|
||||||
|
LIB_FOLDER=lib64
|
||||||
|
LIB_NAME=libffi.so*
|
||||||
|
;;
|
||||||
|
Darwin)
|
||||||
|
CC=$DEVKIT_DIR/Xcode/Contents/Developer/usr/bin/gcc
|
||||||
|
CXX=$DEVKIT_DIR/Xcode/Contents/Developer/usr/bin/gcc
|
||||||
|
LIB_FOLDER=lib
|
||||||
|
LIB_NAME=libffi.*.dylib
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo " Unsupported OS: $OS_NAME"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
# For Linux/x86, add --build=i686-pc-linux-gnu CFLAGS=-m32 CXXFLAGS=-m32 LDFLAGS=-m32
|
# For Linux/x86, add --build=i686-pc-linux-gnu CFLAGS=-m32 CXXFLAGS=-m32 LDFLAGS=-m32
|
||||||
bash ./configure --prefix=$INSTALL_DIR CC=$DEVKIT_DIR/bin/gcc CXX=$DEVKIT_DIR/bin/g++
|
bash ./configure \
|
||||||
|
--disable-docs \
|
||||||
|
--prefix=$INSTALL_DIR \
|
||||||
|
CC=$CC \
|
||||||
|
CXX=$CXX
|
||||||
|
|
||||||
# Run with nice to keep system usable during build.
|
# Run with nice to keep system usable during build.
|
||||||
nice make $MAKE_ARGS install
|
nice make $MAKE_ARGS install
|
||||||
@ -90,10 +148,9 @@ nice make $MAKE_ARGS install
|
|||||||
mkdir -p $IMAGE_DIR
|
mkdir -p $IMAGE_DIR
|
||||||
# Extract what we need into an image
|
# Extract what we need into an image
|
||||||
if [ ! -e $IMAGE_DIR/lib/libffi.so ]; then
|
if [ ! -e $IMAGE_DIR/lib/libffi.so ]; then
|
||||||
echo "Copying libffi.so* to image"
|
echo "Copying ${LIB_NAME} to image"
|
||||||
mkdir -p $IMAGE_DIR/lib
|
mkdir -p $IMAGE_DIR/lib
|
||||||
# For Linux/x86 it's under /lib/ instead of /lib64/
|
cp -a $INSTALL_DIR/${LIB_FOLDER}/${LIB_NAME} $IMAGE_DIR/lib/
|
||||||
cp -a $INSTALL_DIR/lib64/libffi.so* $IMAGE_DIR/lib/
|
|
||||||
fi
|
fi
|
||||||
if [ ! -e $IMAGE_DIR/include/ ]; then
|
if [ ! -e $IMAGE_DIR/include/ ]; then
|
||||||
echo "Copying include to image"
|
echo "Copying include to image"
|
||||||
|
@ -228,6 +228,7 @@ ifeq ($(ENABLE_FALLBACK_LINKER), true)
|
|||||||
LDFLAGS := $(LDFLAGS_JDKLIB) \
|
LDFLAGS := $(LDFLAGS_JDKLIB) \
|
||||||
$(call SET_SHARED_LIBRARY_ORIGIN), \
|
$(call SET_SHARED_LIBRARY_ORIGIN), \
|
||||||
LIBS := $(LIBFFI_LIBS), \
|
LIBS := $(LIBFFI_LIBS), \
|
||||||
|
LIBS_windows := $(LIBFFI_LIBS) ws2_32.lib, \
|
||||||
))
|
))
|
||||||
|
|
||||||
TARGETS += $(BUILD_LIBFALLBACKLINKER)
|
TARGETS += $(BUILD_LIBFALLBACKLINKER)
|
||||||
|
@ -32,10 +32,6 @@
|
|||||||
|
|
||||||
#define SUPPORT_MONITOR_COUNT
|
#define SUPPORT_MONITOR_COUNT
|
||||||
|
|
||||||
#ifdef __APPLE__
|
|
||||||
#define FFI_GO_CLOSURES 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <ffi.h>
|
#include <ffi.h>
|
||||||
|
|
||||||
// Indicates whether the C calling conventions require that
|
// Indicates whether the C calling conventions require that
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#include <ffi.h>
|
#include <ffi.h>
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <stdint.h>
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
#include <Winsock2.h>
|
#include <Winsock2.h>
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
* @test
|
* @test
|
||||||
* @enablePreview
|
* @enablePreview
|
||||||
* @requires jdk.foreign.linker != "UNSUPPORTED"
|
* @requires jdk.foreign.linker != "UNSUPPORTED"
|
||||||
|
* @requires (!(os.name == "Mac OS X" & os.arch == "aarch64") | jdk.foreign.linker != "FALLBACK")
|
||||||
* @modules java.base/jdk.internal.foreign
|
* @modules java.base/jdk.internal.foreign
|
||||||
* @build NativeTestHelper CallGeneratorHelper TestUpcallBase
|
* @build NativeTestHelper CallGeneratorHelper TestUpcallBase
|
||||||
*
|
*
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
* @enablePreview
|
* @enablePreview
|
||||||
* @library ../
|
* @library ../
|
||||||
* @requires jdk.foreign.linker != "UNSUPPORTED"
|
* @requires jdk.foreign.linker != "UNSUPPORTED"
|
||||||
|
* @requires (!(os.name == "Mac OS X" & os.arch == "aarch64") | jdk.foreign.linker != "FALLBACK")
|
||||||
* @modules java.base/jdk.internal.foreign
|
* @modules java.base/jdk.internal.foreign
|
||||||
* @run testng/othervm
|
* @run testng/othervm
|
||||||
* --enable-native-access=ALL-UNNAMED
|
* --enable-native-access=ALL-UNNAMED
|
||||||
@ -39,6 +40,7 @@
|
|||||||
* @enablePreview
|
* @enablePreview
|
||||||
* @library ../
|
* @library ../
|
||||||
* @requires jdk.foreign.linker != "UNSUPPORTED"
|
* @requires jdk.foreign.linker != "UNSUPPORTED"
|
||||||
|
* @requires (!(os.name == "Mac OS X" & os.arch == "aarch64") | jdk.foreign.linker != "FALLBACK")
|
||||||
* @modules java.base/jdk.internal.foreign
|
* @modules java.base/jdk.internal.foreign
|
||||||
* @run testng/othervm
|
* @run testng/othervm
|
||||||
* --enable-native-access=ALL-UNNAMED
|
* --enable-native-access=ALL-UNNAMED
|
||||||
|
Loading…
Reference in New Issue
Block a user