FindJNI.cmake 13.2 KB
Newer Older
1 2 3
# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.

4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
#[=======================================================================[.rst:
FindJNI
-------

Find Java Native Interface (JNI) libraries.

JNI enables Java code running in a Java Virtual Machine (JVM) to call
and be called by native applications and libraries written in other
languages such as C, C++.

This module finds if Java is installed and determines where the
include files and libraries are.  It also determines what the name of
the library is.  The caller may set variable ``JAVA_HOME`` to specify a
Java installation prefix explicitly.

Result Variables
^^^^^^^^^^^^^^^^

This module sets the following result variables:

``JNI_INCLUDE_DIRS``
  the include dirs to use
``JNI_LIBRARIES``
  the libraries to use (JAWT and JVM)
``JNI_FOUND``
  TRUE if JNI headers and libraries were found.

Cache Variables
^^^^^^^^^^^^^^^

The following cache variables are also available to set or use:

``JAVA_AWT_LIBRARY``
  the path to the Java AWT Native Interface (JAWT) library
``JAVA_JVM_LIBRARY``
  the path to the Java Virtual Machine (JVM) library
``JAVA_INCLUDE_PATH``
  the include path to jni.h
``JAVA_INCLUDE_PATH2``
  the include path to jni_md.h and jniport.h
``JAVA_AWT_INCLUDE_PATH``
  the include path to jawt.h
#]=======================================================================]
47

luz.paz's avatar
luz.paz committed
48
# Expand {libarch} occurrences to java_libarch subdirectory(-ies) and set ${_var}
49
macro(java_append_library_directories _var)
50
    # Determine java arch-specific library subdir
51 52 53
    # Mostly based on openjdk/jdk/make/common/shared/Platform.gmk as of openjdk
    # 1.6.0_18 + icedtea patches. However, it would be much better to base the
    # guess on the first part of the GNU config.guess platform triplet.
54
    if(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
55 56 57
      if(CMAKE_LIBRARY_ARCHITECTURE STREQUAL "x86_64-linux-gnux32")
        set(_java_libarch "x32" "amd64" "i386")
      else()
58
        set(_java_libarch "amd64" "i386")
59
      endif()
60 61 62 63 64
    elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^i.86$")
        set(_java_libarch "i386")
    elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^alpha")
        set(_java_libarch "alpha")
    elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^arm")
65
        # Subdir is "arm" for both big-endian (arm) and little-endian (armel).
66
        set(_java_libarch "arm" "aarch32")
67
    elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^mips")
68
        # mips* machines are bi-endian mostly so processor does not tell
luz.paz's avatar
luz.paz committed
69
        # endianness of the underlying system.
70 71 72 73
        set(_java_libarch "${CMAKE_SYSTEM_PROCESSOR}"
            "mips" "mipsel" "mipseb" "mipsr6" "mipsr6el"
            "mips64" "mips64el" "mips64r6" "mips64r6el"
            "mipsn32" "mipsn32el" "mipsn32r6" "mipsn32r6el")
74
    elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)64le")
75
        set(_java_libarch "ppc64" "ppc64le")
76
    elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)64")
77
        set(_java_libarch "ppc64" "ppc")
78
    elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)")
79
        set(_java_libarch "ppc" "ppc64")
80
    elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^sparc")
81
        # Both flavours can run on the same processor
82 83 84 85
        set(_java_libarch "${CMAKE_SYSTEM_PROCESSOR}" "sparc" "sparcv9")
    elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(parisc|hppa)")
        set(_java_libarch "parisc" "parisc64")
    elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^s390")
86
        # s390 binaries can run on s390x machines
87 88 89
        set(_java_libarch "${CMAKE_SYSTEM_PROCESSOR}" "s390" "s390x")
    elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^sh")
        set(_java_libarch "sh")
90
    else()
91
        set(_java_libarch "${CMAKE_SYSTEM_PROCESSOR}")
92
    endif()
93 94 95

    # Append default list architectures if CMAKE_SYSTEM_PROCESSOR was empty or
    # system is non-Linux (where the code above has not been well tested)
96 97
    if(NOT _java_libarch OR NOT (CMAKE_SYSTEM_NAME MATCHES "Linux"))
        list(APPEND _java_libarch "i386" "amd64" "ppc")
98
    endif()
99 100 101

    # Sometimes ${CMAKE_SYSTEM_PROCESSOR} is added to the list to prefer
    # current value to a hardcoded list. Remove possible duplicates.
102
    list(REMOVE_DUPLICATES _java_libarch)
103

104 105 106 107
    foreach(_path ${ARGN})
        if(_path MATCHES "{libarch}")
            foreach(_libarch ${_java_libarch})
                string(REPLACE "{libarch}" "${_libarch}" _newpath "${_path}")
108 109 110
                if(EXISTS ${_newpath})
                    list(APPEND ${_var} "${_newpath}")
                endif()
111 112
            endforeach()
        else()
113 114 115
            if(EXISTS ${_path})
                list(APPEND ${_var} "${_path}")
            endif()
116 117 118
        endif()
    endforeach()
endmacro()
119

120
include(${CMAKE_CURRENT_LIST_DIR}/CMakeFindJavaCommon.cmake)
121

122 123 124 125 126 127 128 129 130 131 132
# Save CMAKE_FIND_FRAMEWORK
if(DEFINED CMAKE_FIND_FRAMEWORK)
  set(_JNI_CMAKE_FIND_FRAMEWORK ${CMAKE_FIND_FRAMEWORK})
else()
  unset(_JNI_CMAKE_FIND_FRAMEWORK)
endif()

if(_JAVA_HOME_EXPLICIT)
  set(CMAKE_FIND_FRAMEWORK NEVER)
endif()

133 134 135 136 137
set(JAVA_AWT_LIBRARY_DIRECTORIES)
if(_JAVA_HOME)
  JAVA_APPEND_LIBRARY_DIRECTORIES(JAVA_AWT_LIBRARY_DIRECTORIES
    ${_JAVA_HOME}/jre/lib/{libarch}
    ${_JAVA_HOME}/jre/lib
138
    ${_JAVA_HOME}/lib/{libarch}
139 140 141 142
    ${_JAVA_HOME}/lib
    ${_JAVA_HOME}
    )
endif()
143

144 145
if (WIN32)
  set (_JNI_HINTS)
146
  execute_process(COMMAND REG QUERY HKLM\\SOFTWARE\\JavaSoft\\JDK
147 148 149 150
    RESULT_VARIABLE _JNI_RESULT
    OUTPUT_VARIABLE _JNI_VERSIONS
    ERROR_QUIET)
  if (NOT  _JNI_RESULT)
151
    string (REGEX MATCHALL "HKEY_LOCAL_MACHINE\\\\SOFTWARE\\\\JavaSoft\\\\JDK\\\\[0-9.]+" _JNI_VERSIONS "${_JNI_VERSIONS}")
152 153 154 155 156 157 158 159 160 161 162 163
    if (_JNI_VERSIONS)
      # sort versions. Most recent first
      ## handle version 9 apart from other versions to get correct ordering
      set (_JNI_V9 ${_JNI_VERSIONS})
      list (FILTER _JNI_VERSIONS EXCLUDE REGEX "JDK\\\\9")
      list (SORT _JNI_VERSIONS)
      list (REVERSE _JNI_VERSIONS)
      list (FILTER _JNI_V9 INCLUDE REGEX "JDK\\\\9")
      list (SORT _JNI_V9)
      list (REVERSE _JNI_V9)
      list (APPEND _JNI_VERSIONS ${_JNI_V9})
      foreach (_JNI_HINT IN LISTS _JNI_VERSIONS)
164
        list(APPEND _JNI_HINTS "[${_JNI_HINT};JavaHome]")
165 166
      endforeach()
    endif()
167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187
  endif()

  foreach (_JNI_HINT IN LISTS _JNI_HINTS)
    list(APPEND JAVA_AWT_LIBRARY_DIRECTORIES "${_JNI_HINT}/lib")
  endforeach()

  get_filename_component(java_install_version
    "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit;CurrentVersion]" NAME)

  list(APPEND JAVA_AWT_LIBRARY_DIRECTORIES
    "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\1.9;JavaHome]/lib"
    "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\1.8;JavaHome]/lib"
    "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\1.7;JavaHome]/lib"
    "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\1.6;JavaHome]/lib"
    "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\1.5;JavaHome]/lib"
    "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\1.4;JavaHome]/lib"
    "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\1.3;JavaHome]/lib"
    "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\${java_install_version};JavaHome]/lib"
    )
endif()

188 189 190 191 192 193 194 195 196 197 198 199 200 201
set(_JNI_JAVA_DIRECTORIES_BASE
  /usr/lib/jvm/java
  /usr/lib/java
  /usr/lib/jvm
  /usr/local/lib/java
  /usr/local/share/java
  /usr/lib/j2sdk1.4-sun
  /usr/lib/j2sdk1.5-sun
  /opt/sun-jdk-1.5.0.04
  /usr/lib/jvm/java-6-sun
  /usr/lib/jvm/java-1.5.0-sun
  /usr/lib/jvm/java-6-sun-1.6.0.00       # can this one be removed according to #8821 ? Alex
  /usr/lib/jvm/java-6-openjdk
  /usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0        # fedora
202
  # Debian specific paths for default JVM
203
  /usr/lib/jvm/default-java
204
  # Arch Linux specific paths for default JVM
205
  /usr/lib/jvm/default
206
  # Ubuntu specific paths for default JVM
207 208 209 210
  /usr/lib/jvm/java-11-openjdk-{libarch}    # Ubuntu 18.04 LTS
  /usr/lib/jvm/java-8-openjdk-{libarch}     # Ubuntu 15.10
  /usr/lib/jvm/java-7-openjdk-{libarch}     # Ubuntu 15.10
  /usr/lib/jvm/java-6-openjdk-{libarch}     # Ubuntu 15.10
211
  # OpenBSD specific paths for default JVM
212 213 214 215
  /usr/local/jdk-1.7.0
  /usr/local/jre-1.7.0
  /usr/local/jdk-1.6.0
  /usr/local/jre-1.6.0
216
  # SuSE specific paths for default JVM
217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238
  /usr/lib64/jvm/java
  /usr/lib64/jvm/jre
  )

set(_JNI_JAVA_AWT_LIBRARY_TRIES)
set(_JNI_JAVA_INCLUDE_TRIES)

foreach(_java_dir IN LISTS _JNI_JAVA_DIRECTORIES_BASE)
  list(APPEND _JNI_JAVA_AWT_LIBRARY_TRIES
    ${_java_dir}/jre/lib/{libarch}
    ${_java_dir}/jre/lib
    ${_java_dir}/lib/{libarch}
    ${_java_dir}/lib
    ${_java_dir}
  )
  list(APPEND _JNI_JAVA_INCLUDE_TRIES
    ${_java_dir}/include
  )
endforeach()

JAVA_APPEND_LIBRARY_DIRECTORIES(JAVA_AWT_LIBRARY_DIRECTORIES
    ${_JNI_JAVA_AWT_LIBRARY_TRIES}
239
  )
240

241 242
set(JAVA_JVM_LIBRARY_DIRECTORIES)
foreach(dir ${JAVA_AWT_LIBRARY_DIRECTORIES})
243
  list(APPEND JAVA_JVM_LIBRARY_DIRECTORIES
244 245 246
    "${dir}"
    "${dir}/client"
    "${dir}/server"
247 248 249
    # IBM SDK, Java Technology Edition, specific paths
    "${dir}/j9vm"
    "${dir}/default"
250
    )
251
endforeach()
252

253 254 255 256
set(JAVA_AWT_INCLUDE_DIRECTORIES)
if(_JAVA_HOME)
  list(APPEND JAVA_AWT_INCLUDE_DIRECTORIES ${_JAVA_HOME}/include)
endif()
257 258 259 260 261 262 263 264 265 266 267 268 269 270 271
if (WIN32)
  foreach (_JNI_HINT IN LISTS _JNI_HINTS)
    list(APPEND JAVA_AWT_INCLUDE_DIRECTORIES "${_JNI_HINT}/include")
  endforeach()
  list(APPEND JAVA_AWT_INCLUDE_DIRECTORIES
    "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\1.9;JavaHome]/include"
    "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\1.8;JavaHome]/include"
    "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\1.7;JavaHome]/include"
    "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\1.6;JavaHome]/include"
    "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\1.5;JavaHome]/include"
    "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\1.4;JavaHome]/include"
    "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\1.3;JavaHome]/include"
    "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\${java_install_version};JavaHome]/include"
    )
endif()
272 273

JAVA_APPEND_LIBRARY_DIRECTORIES(JAVA_AWT_INCLUDE_DIRECTORIES
274
  ${_JNI_JAVA_INCLUDE_TRIES}
275 276
  )

277 278 279 280
foreach(JAVA_PROG "${JAVA_RUNTIME}" "${JAVA_COMPILE}" "${JAVA_ARCHIVE}")
  get_filename_component(jpath "${JAVA_PROG}" PATH)
  foreach(JAVA_INC_PATH ../include ../java/include ../share/java/include)
    if(EXISTS ${jpath}/${JAVA_INC_PATH})
281
      list(APPEND JAVA_AWT_INCLUDE_DIRECTORIES "${jpath}/${JAVA_INC_PATH}")
282 283
    endif()
  endforeach()
284
  foreach(JAVA_LIB_PATH
285 286
    ../lib ../jre/lib ../jre/lib/i386
    ../java/lib ../java/jre/lib ../java/jre/lib/i386
287
    ../share/java/lib ../share/java/jre/lib ../share/java/jre/lib/i386)
288
    if(EXISTS ${jpath}/${JAVA_LIB_PATH})
289
      list(APPEND JAVA_AWT_LIBRARY_DIRECTORIES "${jpath}/${JAVA_LIB_PATH}")
290 291 292
    endif()
  endforeach()
endforeach()
293

294
if(APPLE)
295 296 297 298 299 300 301 302
  if(CMAKE_FIND_FRAMEWORK STREQUAL "ONLY")
    set(_JNI_SEARCHES FRAMEWORK)
  elseif(CMAKE_FIND_FRAMEWORK STREQUAL "NEVER")
    set(_JNI_SEARCHES NORMAL)
  elseif(CMAKE_FIND_FRAMEWORK STREQUAL "LAST")
    set(_JNI_SEARCHES NORMAL FRAMEWORK)
  else()
    set(_JNI_SEARCHES FRAMEWORK NORMAL)
303
  endif()
304 305 306 307 308
  set(_JNI_FRAMEWORK_JVM NAMES JavaVM)
  set(_JNI_FRAMEWORK_JAWT "${_JNI_FRAMEWORK_JVM}")
else()
  set(_JNI_SEARCHES NORMAL)
endif()
Bill Hoffman's avatar
Bill Hoffman committed
309

310 311 312 313
set(_JNI_NORMAL_JVM
  NAMES jvm
  PATHS ${JAVA_JVM_LIBRARY_DIRECTORIES}
  )
Bill Hoffman's avatar
Bill Hoffman committed
314

315 316 317 318
set(_JNI_NORMAL_JAWT
  NAMES jawt
  PATHS ${JAVA_AWT_LIBRARY_DIRECTORIES}
  )
Bill Hoffman's avatar
Bill Hoffman committed
319

320 321 322 323 324
foreach(search ${_JNI_SEARCHES})
  find_library(JAVA_JVM_LIBRARY ${_JNI_${search}_JVM})
  find_library(JAVA_AWT_LIBRARY ${_JNI_${search}_JAWT})
  if(JAVA_JVM_LIBRARY)
    break()
325
  endif()
326 327 328 329 330 331 332 333 334 335
endforeach()
unset(_JNI_SEARCHES)
unset(_JNI_FRAMEWORK_JVM)
unset(_JNI_FRAMEWORK_JAWT)
unset(_JNI_NORMAL_JVM)
unset(_JNI_NORMAL_JAWT)

# Find headers matching the library.
if("${JAVA_JVM_LIBRARY};${JAVA_AWT_LIBRARY};" MATCHES "(/JavaVM.framework|-framework JavaVM);")
  set(CMAKE_FIND_FRAMEWORK ONLY)
336
else()
337
  set(CMAKE_FIND_FRAMEWORK NEVER)
338
endif()
339

340
# add in the include path
341
find_path(JAVA_INCLUDE_PATH jni.h
342
  ${JAVA_AWT_INCLUDE_DIRECTORIES}
Ken Martin's avatar
Ken Martin committed
343 344
)

345 346
find_path(JAVA_INCLUDE_PATH2 NAMES jni_md.h jniport.h
  PATHS
347
  ${JAVA_INCLUDE_PATH}
348
  ${JAVA_INCLUDE_PATH}/darwin
Ken Martin's avatar
Ken Martin committed
349 350
  ${JAVA_INCLUDE_PATH}/win32
  ${JAVA_INCLUDE_PATH}/linux
351
  ${JAVA_INCLUDE_PATH}/freebsd
352
  ${JAVA_INCLUDE_PATH}/openbsd
353
  ${JAVA_INCLUDE_PATH}/solaris
354 355
  ${JAVA_INCLUDE_PATH}/hp-ux
  ${JAVA_INCLUDE_PATH}/alpha
356
  ${JAVA_INCLUDE_PATH}/aix
Ken Martin's avatar
Ken Martin committed
357
)
Ken Martin's avatar
Ken Martin committed
358

359
find_path(JAVA_AWT_INCLUDE_PATH jawt.h
Bill Hoffman's avatar
Bill Hoffman committed
360 361
  ${JAVA_INCLUDE_PATH}
)
362

363 364 365 366 367 368 369 370
# Restore CMAKE_FIND_FRAMEWORK
if(DEFINED _JNI_CMAKE_FIND_FRAMEWORK)
  set(CMAKE_FIND_FRAMEWORK ${_JNI_CMAKE_FIND_FRAMEWORK})
  unset(_JNI_CMAKE_FIND_FRAMEWORK)
else()
  unset(CMAKE_FIND_FRAMEWORK)
endif()

371
include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
372 373 374 375 376
FIND_PACKAGE_HANDLE_STANDARD_ARGS(JNI  DEFAULT_MSG  JAVA_AWT_LIBRARY
                                                    JAVA_JVM_LIBRARY
                                                    JAVA_INCLUDE_PATH
                                                    JAVA_INCLUDE_PATH2
                                                    JAVA_AWT_INCLUDE_PATH)
377

378
mark_as_advanced(
379
  JAVA_AWT_LIBRARY
Andy Cedilnik's avatar
Andy Cedilnik committed
380
  JAVA_JVM_LIBRARY
381 382 383 384
  JAVA_AWT_INCLUDE_PATH
  JAVA_INCLUDE_PATH
  JAVA_INCLUDE_PATH2
)
385

386
set(JNI_LIBRARIES
387 388 389 390
  ${JAVA_AWT_LIBRARY}
  ${JAVA_JVM_LIBRARY}
)

391
set(JNI_INCLUDE_DIRS
392 393 394 395
  ${JAVA_INCLUDE_PATH}
  ${JAVA_INCLUDE_PATH2}
  ${JAVA_AWT_INCLUDE_PATH}
)