Autoconf test for JNI include dir
Asked Answered
S

3

5

I'm working on a configuration script for a JNI wrapper. One of the configuration parameters is the path to jni.h. What's a good quick-and-dirty Autoconf test for whether this parameter is set correctly for C++ compilation? You can assume you're running on Linux and g++ is available.

Alternatively, is there a way to get javah (or a supporting tool) to give me this path directly?

Seasonseasonable answered 2/10, 2008 at 18:8 Comment(0)
F
5

Checking for headers is easy; just use AC_CHECK_HEADER. If it's in a weird place (i.e., one the compiler doesn't know about), it's entirely reasonable to expect users to set CPPFLAGS.

The hard part is actually locating libjvm. You typically don't want to link with this; but you may want to default to a location to dlopen it from if JAVA_HOME is not set at run time.

But I don't have a better solution than requiring that JAVA_HOME be set at configure time. There's just too much variation in how this stuff is deployed across various OSes (even just Linux distributions). This is what I do:

AC_CHECK_HEADER([jni.h], [have_jni=yes])
AC_ARG_VAR([JAVA_HOME], [Java Runtime Environment (JRE) location])
AC_ARG_ENABLE([java-feature],
              [AC_HELP_STRING([--disable-java-feature],
                              [disable Java feature])])
case $target_cpu in
     x86_64) JVM_ARCH=amd64 ;;
     i?86)   JVM_ARCH=i386 ;;
     *)      JVM_ARCH=$target_cpu ;;
esac
AC_SUBST([JVM_ARCH])
AS_IF([test X$enable_java_feature != Xno],
[AS_IF([test X$have_jni != Xyes],
       [AC_MSG_FAILURE([The Java Native Interface is required for Java feature.])])
AS_IF([test -z "$JAVA_HOME"],
[AC_MSG_WARN([JAVA_HOME has not been set.  JAVA_HOME must be set at run time to locate libjvm.])],
[save_LDFLAGS=$LDFLAGS
LDFLAGS="-L$JAVA_HOME/lib/$JVM_ARCH/client -L$JAVA_HOME/lib/$JVM_ARCH/server $LDFLAGS"
AC_CHECK_LIB([jvm], [JNI_CreateJavaVM], [LIBS=$LIBS],
             [AC_MSG_WARN([no libjvm found at JAVA_HOME])])
LDFLAGS=$save_LDFLAGS
])])
Fluker answered 2/10, 2008 at 19:8 Comment(1)
FWIW, this autoconf rune does not help with locating jni.h itself, so doesn't much help with the original question.Sadye
F
7

Then there is the easy way: http://www.gnu.org/software/autoconf-archive/ax_jni_include_dir.html

Sometimes it is best to just use the standard recipies.

Fussbudget answered 27/6, 2013 at 9:0 Comment(3)
If you look at the date on the question and the copyright date on that file, you'll see that there wasn't a "standard recipe" when the above answer was accepted.Seasonseasonable
If anyone is wondering how to use this m4 thing, you need to install the package and for debian/ubuntu the name of the package you need is autoconf-archive. Thanks to his helpful [post](`github.com/gpoo/ccfinderx/issues/1#issuecomment-197734028)Octoroon
As of November 2020, that circa 2008 script (serial 15) fails to detect the headers on MacOS Big Sur if you installed Oracle's JDK.Pastime
F
5

Checking for headers is easy; just use AC_CHECK_HEADER. If it's in a weird place (i.e., one the compiler doesn't know about), it's entirely reasonable to expect users to set CPPFLAGS.

The hard part is actually locating libjvm. You typically don't want to link with this; but you may want to default to a location to dlopen it from if JAVA_HOME is not set at run time.

But I don't have a better solution than requiring that JAVA_HOME be set at configure time. There's just too much variation in how this stuff is deployed across various OSes (even just Linux distributions). This is what I do:

AC_CHECK_HEADER([jni.h], [have_jni=yes])
AC_ARG_VAR([JAVA_HOME], [Java Runtime Environment (JRE) location])
AC_ARG_ENABLE([java-feature],
              [AC_HELP_STRING([--disable-java-feature],
                              [disable Java feature])])
case $target_cpu in
     x86_64) JVM_ARCH=amd64 ;;
     i?86)   JVM_ARCH=i386 ;;
     *)      JVM_ARCH=$target_cpu ;;
esac
AC_SUBST([JVM_ARCH])
AS_IF([test X$enable_java_feature != Xno],
[AS_IF([test X$have_jni != Xyes],
       [AC_MSG_FAILURE([The Java Native Interface is required for Java feature.])])
AS_IF([test -z "$JAVA_HOME"],
[AC_MSG_WARN([JAVA_HOME has not been set.  JAVA_HOME must be set at run time to locate libjvm.])],
[save_LDFLAGS=$LDFLAGS
LDFLAGS="-L$JAVA_HOME/lib/$JVM_ARCH/client -L$JAVA_HOME/lib/$JVM_ARCH/server $LDFLAGS"
AC_CHECK_LIB([jvm], [JNI_CreateJavaVM], [LIBS=$LIBS],
             [AC_MSG_WARN([no libjvm found at JAVA_HOME])])
LDFLAGS=$save_LDFLAGS
])])
Fluker answered 2/10, 2008 at 19:8 Comment(1)
FWIW, this autoconf rune does not help with locating jni.h itself, so doesn't much help with the original question.Sadye
M
0

FYI - the patch below against the latest ax_jni_include_dir.m4 works for me on Macos 11.1.

--- a/m4/ax_jni_include_dir.m4
+++ b/m4/ax_jni_include_dir.m4
@@ -73,13 +73,19 @@ fi
 
 case "$host_os" in
         darwin*)        # Apple Java headers are inside the Xcode bundle.
-            macos_version=$(sw_vers -productVersion | sed -n -e 's/^@<:@0-9@:>@
*.\(@<:@0-9@:>@*\).@<:@0-9@:>@*/\1/p')
-            if @<:@ "$macos_version" -gt "7" @:>@; then
-                _JTOPDIR="$(xcrun --show-sdk-path)/System/Library/Frameworks/JavaVM.framework"
-                _JINC="$_JTOPDIR/Headers"
+            major_macos_version=$(sw_vers -productVersion | sed -n -e 's/^\(@<:@0-9@:>@*\).@<:@0-9@:>@*.@<:@0-9@:>@*/\1/p')
+            if @<:@ "$major_macos_version" -gt "10" @:>@; then
+                _JTOPDIR="$(/usr/libexec/java_home)"
+                _JINC="$_JTOPDIR/include"
             else
-                _JTOPDIR="/System/Library/Frameworks/JavaVM.framework"
-                _JINC="$_JTOPDIR/Headers"
+                macos_version=$(sw_vers -productVersion | sed -n -e 's/^@<:@0-9@:>@*.\(@<:@0-9@:>@*\).@<:@0-9@:>@*/\1/p')
+                if @<:@ "$macos_version" -gt "7" @:>@; then
+                    _JTOPDIR="$(xcrun --show-sdk-path)/System/Library/Frameworks/JavaVM.framework"
+                    _JINC="$_JTOPDIR/Headers"
+                else
+                    _JTOPDIR="/System/Library/Frameworks/JavaVM.framework"
+                    _JINC="$_JTOPDIR/Headers"
+                fi
             fi
             ;;
         *) _JINC="$_JTOPDIR/include";;
Meissner answered 20/12, 2020 at 3:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.