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
|
||||
LIBFFI_LIB_PATH="${with_libffi}/lib"
|
||||
LIBFFI_LIBS="-L${with_libffi}/lib -lffi"
|
||||
if test "x${OPENJDK_TARGET_OS}" != "xwindows"; then
|
||||
LIBFFI_LIBS="-L${with_libffi}/lib -lffi"
|
||||
else
|
||||
LIBFFI_LIBS="${with_libffi}/lib/libffi.lib"
|
||||
fi
|
||||
LIBFFI_CFLAGS="-I${with_libffi}/include"
|
||||
LIBFFI_FOUND=yes
|
||||
fi
|
||||
@ -67,7 +71,11 @@ AC_DEFUN_ONCE([LIB_SETUP_LIBFFI],
|
||||
fi
|
||||
if test "x${with_libffi_lib}" != x; then
|
||||
LIBFFI_LIB_PATH="${with_libffi_lib}"
|
||||
LIBFFI_LIBS="-L${with_libffi_lib} -lffi"
|
||||
if test "x${OPENJDK_TARGET_OS}" != "xwindows"; then
|
||||
LIBFFI_LIBS="-L${with_libffi_lib} -lffi"
|
||||
else
|
||||
LIBFFI_LIBS="${with_libffi_lib}/libffi.lib"
|
||||
fi
|
||||
LIBFFI_FOUND=yes
|
||||
fi
|
||||
# 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])
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING([if libffi works])
|
||||
AC_LANG_PUSH(C)
|
||||
OLD_CFLAGS="$CFLAGS"
|
||||
CFLAGS="$CFLAGS $LIBFFI_CFLAGS"
|
||||
OLD_LIBS="$LIBS"
|
||||
LIBS="$LIBS $LIBFFI_LIBS"
|
||||
|
||||
AC_MSG_CHECKING([if libffi works])
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <ffi.h>],
|
||||
[
|
||||
ffi_call(NULL, NULL, NULL, NULL);
|
||||
@ -120,9 +129,6 @@ AC_DEFUN_ONCE([LIB_SETUP_LIBFFI],
|
||||
[LIBFFI_WORKS=yes],
|
||||
[LIBFFI_WORKS=no]
|
||||
)
|
||||
CFLAGS="$OLD_CFLAGS"
|
||||
LIBS="$OLD_LIBS"
|
||||
AC_LANG_POP(C)
|
||||
AC_MSG_RESULT([$LIBFFI_WORKS])
|
||||
|
||||
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])
|
||||
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
|
||||
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])
|
||||
if test "x${LIBFFI_LIB_PATH}" != x; then
|
||||
if test -e ${LIBFFI_LIB_PATH}/libffi.so.?; then
|
||||
LIBFFI_LIB_FILE="${LIBFFI_LIB_PATH}/libffi.so.?"
|
||||
if test -e ${LIBFFI_LIB_PATH}/${LIBFFI_LIB_FILE_NAME}; then
|
||||
LIBFFI_LIB_FILE="${LIBFFI_LIB_PATH}/${LIBFFI_LIB_FILE_NAME}"
|
||||
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
|
||||
else
|
||||
# If we don't have an explicit path, look in a few obvious places
|
||||
if test "x${OPENJDK_TARGET_CPU}" = "xx86"; then
|
||||
if test -e ${SYSROOT}/usr/lib/libffi.so.? ; then
|
||||
LIBFFI_LIB_FILE="${SYSROOT}/usr/lib/libffi.so.?"
|
||||
elif test -e ${SYSROOT}/usr/lib/i386-linux-gnu/libffi.so.? ; then
|
||||
LIBFFI_LIB_FILE="${SYSROOT}/usr/lib/i386-linux-gnu/libffi.so.?"
|
||||
if test -e ${SYSROOT}/usr/lib/${LIBFFI_LIB_FILE_NAME} ; then
|
||||
LIBFFI_LIB_FILE="${SYSROOT}/usr/lib/${LIBFFI_LIB_FILE_NAME}"
|
||||
elif test -e ${SYSROOT}/usr/lib/i386-linux-gnu/${LIBFFI_LIB_FILE_NAME} ; then
|
||||
LIBFFI_LIB_FILE="${SYSROOT}/usr/lib/i386-linux-gnu/${LIBFFI_LIB_FILE_NAME}"
|
||||
else
|
||||
AC_MSG_ERROR([Could not locate libffi.so.? for bundling])
|
||||
AC_MSG_ERROR([Could not locate ${LIBFFI_LIB_FILE_NAME} for bundling])
|
||||
fi
|
||||
elif test "x${OPENJDK_TARGET_CPU}" = "xx86_64" || test "x${OPENJDK_TARGET_CPU}" = "xaarch64"; then
|
||||
if test -e ${SYSROOT}/usr/lib64/libffi.so.? ; then
|
||||
LIBFFI_LIB_FILE="${SYSROOT}/usr/lib64/libffi.so.?"
|
||||
elif test -e ${SYSROOT}/usr/lib/x86_64-linux-gnu/libffi.so.? ; then
|
||||
LIBFFI_LIB_FILE="${SYSROOT}/usr/lib/x86_64-linux-gnu/libffi.so.?"
|
||||
if test -e ${SYSROOT}/usr/lib64/${LIBFFI_LIB_FILE_NAME} ; then
|
||||
LIBFFI_LIB_FILE="${SYSROOT}/usr/lib64/${LIBFFI_LIB_FILE_NAME}"
|
||||
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_LIB_FILE_NAME}"
|
||||
else
|
||||
AC_MSG_ERROR([Could not locate libffi.so.? for bundling])
|
||||
AC_MSG_ERROR([Could not locate ${LIBFFI_LIB_FILE_NAME} for bundling])
|
||||
fi
|
||||
else
|
||||
# Fallback on the default /usr/lib dir
|
||||
if test -e ${SYSROOT}/usr/lib/libffi.so.? ; then
|
||||
LIBFFI_LIB_FILE="${SYSROOT}/usr/lib/libffi.so.?"
|
||||
if test -e ${SYSROOT}/usr/lib/${LIBFFI_LIB_FILE_NAME} ; then
|
||||
LIBFFI_LIB_FILE="${SYSROOT}/usr/lib/${LIBFFI_LIB_FILE_NAME}"
|
||||
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
|
||||
|
@ -38,6 +38,38 @@
|
||||
# Note that the libtool and texinfo packages are needed to build libffi
|
||||
# $ 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
|
||||
|
||||
BUNDLE_NAME=libffi-$LIBFFI_VERSION.tar.gz
|
||||
@ -49,6 +81,7 @@ SRC_DIR="$OUTPUT_DIR/src"
|
||||
DOWNLOAD_DIR="$OUTPUT_DIR/download"
|
||||
INSTALL_DIR="$OUTPUT_DIR/install"
|
||||
IMAGE_DIR="$OUTPUT_DIR/image"
|
||||
OS_NAME=$(uname -s)
|
||||
|
||||
USAGE="$0 <devkit dir>"
|
||||
|
||||
@ -81,8 +114,33 @@ cd $LIBFFI_DIR
|
||||
if [ ! -e $LIBFFI_DIR/configure ]; then
|
||||
bash ./autogen.sh
|
||||
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
|
||||
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.
|
||||
nice make $MAKE_ARGS install
|
||||
@ -90,10 +148,9 @@ nice make $MAKE_ARGS install
|
||||
mkdir -p $IMAGE_DIR
|
||||
# Extract what we need into an image
|
||||
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
|
||||
# For Linux/x86 it's under /lib/ instead of /lib64/
|
||||
cp -a $INSTALL_DIR/lib64/libffi.so* $IMAGE_DIR/lib/
|
||||
cp -a $INSTALL_DIR/${LIB_FOLDER}/${LIB_NAME} $IMAGE_DIR/lib/
|
||||
fi
|
||||
if [ ! -e $IMAGE_DIR/include/ ]; then
|
||||
echo "Copying include to image"
|
||||
|
@ -228,6 +228,7 @@ ifeq ($(ENABLE_FALLBACK_LINKER), true)
|
||||
LDFLAGS := $(LDFLAGS_JDKLIB) \
|
||||
$(call SET_SHARED_LIBRARY_ORIGIN), \
|
||||
LIBS := $(LIBFFI_LIBS), \
|
||||
LIBS_windows := $(LIBFFI_LIBS) ws2_32.lib, \
|
||||
))
|
||||
|
||||
TARGETS += $(BUILD_LIBFALLBACKLINKER)
|
||||
|
@ -32,10 +32,6 @@
|
||||
|
||||
#define SUPPORT_MONITOR_COUNT
|
||||
|
||||
#ifdef __APPLE__
|
||||
#define FFI_GO_CLOSURES 0
|
||||
#endif
|
||||
|
||||
#include <ffi.h>
|
||||
|
||||
// Indicates whether the C calling conventions require that
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include <ffi.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
#ifdef _WIN64
|
||||
#include <Windows.h>
|
||||
#include <Winsock2.h>
|
||||
|
@ -25,6 +25,7 @@
|
||||
* @test
|
||||
* @enablePreview
|
||||
* @requires jdk.foreign.linker != "UNSUPPORTED"
|
||||
* @requires (!(os.name == "Mac OS X" & os.arch == "aarch64") | jdk.foreign.linker != "FALLBACK")
|
||||
* @modules java.base/jdk.internal.foreign
|
||||
* @build NativeTestHelper CallGeneratorHelper TestUpcallBase
|
||||
*
|
||||
|
@ -26,6 +26,7 @@
|
||||
* @enablePreview
|
||||
* @library ../
|
||||
* @requires jdk.foreign.linker != "UNSUPPORTED"
|
||||
* @requires (!(os.name == "Mac OS X" & os.arch == "aarch64") | jdk.foreign.linker != "FALLBACK")
|
||||
* @modules java.base/jdk.internal.foreign
|
||||
* @run testng/othervm
|
||||
* --enable-native-access=ALL-UNNAMED
|
||||
@ -39,6 +40,7 @@
|
||||
* @enablePreview
|
||||
* @library ../
|
||||
* @requires jdk.foreign.linker != "UNSUPPORTED"
|
||||
* @requires (!(os.name == "Mac OS X" & os.arch == "aarch64") | jdk.foreign.linker != "FALLBACK")
|
||||
* @modules java.base/jdk.internal.foreign
|
||||
* @run testng/othervm
|
||||
* --enable-native-access=ALL-UNNAMED
|
||||
|
Loading…
Reference in New Issue
Block a user