From 3f768634197d8f05a9eac8fbe73e3095360896a1 Mon Sep 17 00:00:00 2001 From: Larry Shaffer Date: Wed, 8 Jan 2014 20:56:37 -0700 Subject: [PATCH] FindJava, FindJNI: leverage java_home command on Mac (#14689) Mac has a utility, /usr/libexec/java_home, which returns the currently defined home for the system, similar to setting JAVA_HOME environment variable. Most users have always used the JavaVM.framework provided by Apple, but with Mac OS X 10.9 Apple no longer readily provides one (though a user may have a previous install lingering), but instead prompts users to download and install the latest from Oracle. To get FindJava and FindJNI modules to work on Mac, you usually have to set JAVA_HOME in the environment first, if you want to use a non-Apple Java install, e.g. Oracle's, even though /usr/libexec/java_home now correctly points to the non-Apple install. Also, if a user installs the Oracle Java, but still has a lingering previous Apple install, FindJNI returns mixed results unless CMAKE_FIND_FRAMEWORK = LAST (FIRST by default). It is not difficult to determine an Apple Java.framework install, when returned by /usr/libexec/java_home, since they all have a 'bundle' symlink in their root directory, while non-Apple installs do not. To choose any Java install (including an older Apple install) other than that returned by /usr/libexec/java_home, set the JAVA_HOME environment variable. Available versions can be listed with /usr/libexec/java_home -V. --- Modules/FindJNI.cmake | 22 +++++++++++++++++++++- Modules/FindJava.cmake | 10 +++++++++- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/Modules/FindJNI.cmake b/Modules/FindJNI.cmake index 29a247d9686..0f02a17d133 100644 --- a/Modules/FindJNI.cmake +++ b/Modules/FindJNI.cmake @@ -102,6 +102,12 @@ set(JAVA_AWT_LIBRARY_DIRECTORIES file(TO_CMAKE_PATH "$ENV{JAVA_HOME}" _JAVA_HOME) +if(APPLE AND NOT EXISTS ${_JAVA_HOME}) + execute_process(COMMAND /usr/libexec/java_home + OUTPUT_VARIABLE _JAVA_HOME OUTPUT_STRIP_TRAILING_WHITESPACE) + file(TO_CMAKE_PATH "${_JAVA_HOME}" _JAVA_HOME) +endif() + JAVA_APPEND_LIBRARY_DIRECTORIES(JAVA_AWT_LIBRARY_DIRECTORIES ${_JAVA_HOME}/jre/lib/{libarch} ${_JAVA_HOME}/jre/lib @@ -186,7 +192,10 @@ foreach(JAVA_PROG "${JAVA_RUNTIME}" "${JAVA_COMPILE}" "${JAVA_ARCHIVE}") endforeach() endforeach() -if(APPLE) +set(_APPLE_FIND_FRAMEWORK ${CMAKE_FIND_FRAMEWORK}) +set(_REVERT_FIND_FRAMEWORK 0) + +if(APPLE AND EXISTS "${_JAVA_HOME}/bundle") if(EXISTS ~/Library/Frameworks/JavaVM.framework) set(JAVA_HAVE_FRAMEWORK 1) endif() @@ -223,6 +232,12 @@ if(APPLE) ) endif() else() + if(APPLE) + # Redefine CMAKE_FIND_FRAMEWORK to ensure Apple's frameworks are not searched first + # (is reverted back below) + set(_REVERT_FIND_FRAMEWORK 1) + set(CMAKE_FIND_FRAMEWORK LAST) + endif() find_library(JAVA_AWT_LIBRARY jawt PATHS ${JAVA_AWT_LIBRARY_DIRECTORIES} ) @@ -255,6 +270,11 @@ include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) FIND_PACKAGE_HANDLE_STANDARD_ARGS(JNI DEFAULT_MSG JAVA_AWT_LIBRARY JAVA_JVM_LIBRARY JAVA_INCLUDE_PATH JAVA_INCLUDE_PATH2 JAVA_AWT_INCLUDE_PATH) +if(APPLE AND ${_REVERT_FIND_FRAMEWORK}) + # Revert back to defined CMAKE_FIND_FRAMEWORK + set(CMAKE_FIND_FRAMEWORK ${_APPLE_FIND_FRAMEWORK}) +endif() + mark_as_advanced( JAVA_AWT_LIBRARY JAVA_JVM_LIBRARY diff --git a/Modules/FindJava.cmake b/Modules/FindJava.cmake index e35fc1d80e9..e69b219b655 100644 --- a/Modules/FindJava.cmake +++ b/Modules/FindJava.cmake @@ -67,6 +67,14 @@ # (To distribute this file outside of CMake, substitute the full # License text for the above reference.) +file(TO_CMAKE_PATH "$ENV{JAVA_HOME}" _JAVA_HOME) + +if(APPLE AND NOT EXISTS ${_JAVA_HOME}) + execute_process(COMMAND /usr/libexec/java_home + OUTPUT_VARIABLE _JAVA_HOME OUTPUT_STRIP_TRAILING_WHITESPACE) + file(TO_CMAKE_PATH "${_JAVA_HOME}" _JAVA_HOME) +endif() + # The HINTS option should only be used for values computed from the system. set(_JAVA_HINTS "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\2.0;JavaHome]/bin" @@ -77,7 +85,7 @@ set(_JAVA_HINTS "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\1.5;JavaHome]/bin" "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\1.4;JavaHome]/bin" "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\1.3;JavaHome]/bin" - $ENV{JAVA_HOME}/bin + ${_JAVA_HOME}/bin ) # Hard-coded guesses should still go in PATHS. This ensures that the user # environment can always override hard guesses.