FindJava.cmake 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438
  1. # Distributed under the OSI-approved BSD 3-Clause License. See accompanying
  2. # file LICENSE.rst or https://cmake.org/licensing for details.
  3. #[=======================================================================[.rst:
  4. FindJava
  5. --------
  6. Finds the Java installation and determines its runtime tools and development
  7. components:
  8. .. code-block:: cmake
  9. find_package(Java [<version>] [COMPONENTS <components>...] [...])
  10. .. versionadded:: 3.10
  11. Support for Java 9+ version parsing.
  12. Components
  13. ^^^^^^^^^^
  14. This module supports optional components, which can be specified with the
  15. :command:`find_package` command:
  16. .. code-block:: cmake
  17. find_package(Java [COMPONENTS <components>...])
  18. Supported components include:
  19. ``Runtime``
  20. Finds the Java Runtime Environment used to execute Java byte-compiled
  21. applications.
  22. ``Development``
  23. Finds development tools (``java``, ``javac``, ``javah``, ``jar``, and
  24. ``javadoc``). Specifying this component also implies the ``Runtime``
  25. component.
  26. ``IdlJ``
  27. .. versionadded:: 3.4
  28. Finds the Interface Description Language (IDL) to Java compiler.
  29. ``JarSigner``
  30. .. versionadded:: 3.4
  31. Finds the signer and verifier tool for Java Archive (JAR) files.
  32. If no components are specified, the module searches for the ``Runtime``
  33. component by default.
  34. Result Variables
  35. ^^^^^^^^^^^^^^^^
  36. This module defines the following variables:
  37. ``Java_FOUND``
  38. .. versionadded:: 3.3
  39. Boolean indicating whether (the requested version of) Java with all
  40. specified components was found.
  41. ``Java_<component>_FOUND``
  42. Boolean indicating whether the ``<component>`` was found.
  43. ``Java_VERSION``
  44. Version of Java found. This is set to:
  45. ``<major>[.<minor>[.<patch>[.<tweak>]]]``.
  46. ``Java_VERSION_MAJOR``
  47. The major version of Java found.
  48. ``Java_VERSION_MINOR``
  49. The minor version of Java found.
  50. ``Java_VERSION_PATCH``
  51. The patch version of Java found.
  52. ``Java_VERSION_TWEAK``
  53. The tweak version of Java found (part after the underscore character ``_``).
  54. ``Java_VERSION_STRING``
  55. Version of Java found, e.g., ``1.6.0_12``.
  56. .. note::
  57. ``Java_VERSION`` and ``Java_VERSION_STRING`` are not guaranteed to be
  58. identical. For example, some Java versions may return:
  59. ``Java_VERSION_STRING = 1.8.0_17`` and ``Java_VERSION = 1.8.0.17``.
  60. Another example is the Java OEM, with ``Java_VERSION_STRING = 1.8.0-oem``
  61. and ``Java_VERSION = 1.8.0``.
  62. Cache Variables
  63. ^^^^^^^^^^^^^^^
  64. The following cache variables may also be set:
  65. ``Java_JAVA_EXECUTABLE``
  66. The full path to the Java runtime.
  67. ``Java_JAVAC_EXECUTABLE``
  68. The full path to the Java compiler.
  69. ``Java_JAVAH_EXECUTABLE``
  70. The full path to the Java header generator.
  71. ``Java_JAVADOC_EXECUTABLE``
  72. The full path to the Java documentation generator.
  73. ``Java_IDLJ_EXECUTABLE``
  74. .. versionadded:: 3.4
  75. The full path to the Java idl compiler.
  76. ``Java_JAR_EXECUTABLE``
  77. The full path to the Java archiver.
  78. ``Java_JARSIGNER_EXECUTABLE``
  79. .. versionadded:: 3.4
  80. The full path to the Java jar signer.
  81. Hints
  82. ^^^^^
  83. This module accepts the following variables:
  84. ``JAVA_HOME``
  85. The caller can set this variable to specify the installation directory of Java
  86. explicitly.
  87. Examples
  88. ^^^^^^^^
  89. Finding Java:
  90. .. code-block:: cmake
  91. find_package(Java)
  92. Finding Java with at least the specified minimum version:
  93. .. code-block:: cmake
  94. find_package(Java 1.8)
  95. Finding Java and making it required (if Java is not found, processing stops with
  96. an error message):
  97. .. code-block:: cmake
  98. find_package(Java 1.8 REQUIRED)
  99. Specifying the needed Java components to find:
  100. .. code-block:: cmake
  101. find_package(Java COMPONENTS Development JarSigner)
  102. See Also
  103. ^^^^^^^^
  104. * The :module:`FindJNI` module to find Java Native Interface (JNI).
  105. * The :module:`UseJava` module to use Java in CMake.
  106. #]=======================================================================]
  107. include(${CMAKE_CURRENT_LIST_DIR}/CMakeFindJavaCommon.cmake)
  108. # The HINTS option should only be used for values computed from the system.
  109. set(_JAVA_HINTS)
  110. if(_JAVA_HOME)
  111. list(APPEND _JAVA_HINTS ${_JAVA_HOME}/bin)
  112. endif()
  113. if (WIN32)
  114. macro (_JAVA_GET_INSTALLED_VERSIONS _KIND)
  115. cmake_host_system_information(RESULT _JAVA_VERSIONS
  116. QUERY WINDOWS_REGISTRY "HKLM/SOFTWARE/JavaSoft/${_KIND}"
  117. SUBKEYS)
  118. if (_JAVA_VERSIONS)
  119. string (REGEX MATCHALL "[0-9._]+" _JAVA_VERSIONS "${_JAVA_VERSIONS}")
  120. string (REGEX REPLACE "([0-9._]+)" "\\1" _JAVA_VERSIONS "${_JAVA_VERSIONS}")
  121. if (_JAVA_VERSIONS)
  122. # sort versions. Most recent first
  123. list (SORT _JAVA_VERSIONS COMPARE NATURAL ORDER DESCENDING)
  124. foreach (_JAVA_VERSION IN LISTS _JAVA_VERSIONS)
  125. string(REPLACE "_" "." _JAVA_CMAKE_VERSION "${_JAVA_VERSION}")
  126. if (Java_FIND_VERSION_EXACT
  127. AND NOT _JAVA_CMAKE_VERSION MATCHES "^${Java_FIND_VERSION}")
  128. continue()
  129. endif()
  130. list(APPEND _JAVA_HINTS "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\${_KIND}\\${_JAVA_VERSION};JavaHome]/bin")
  131. endforeach()
  132. endif()
  133. endif()
  134. endmacro()
  135. # for version 9 and upper
  136. _JAVA_GET_INSTALLED_VERSIONS("JDK")
  137. _JAVA_GET_INSTALLED_VERSIONS("JRE")
  138. # for versions older than 9
  139. _JAVA_GET_INSTALLED_VERSIONS("Java Development Kit")
  140. _JAVA_GET_INSTALLED_VERSIONS("Java Runtime Environment")
  141. endif()
  142. # Hard-coded guesses should still go in PATHS. This ensures that the user
  143. # environment can always override hard guesses.
  144. set(_JAVA_PATHS
  145. /usr/lib/java/bin
  146. /usr/share/java/bin
  147. /usr/local/java/bin
  148. /usr/local/java/share/bin
  149. /usr/java/j2sdk1.4.2_04
  150. /usr/lib/j2sdk1.4-sun/bin
  151. /usr/java/j2sdk1.4.2_09/bin
  152. /usr/lib/j2sdk1.5-sun/bin
  153. /opt/sun-jdk-1.5.0.04/bin
  154. /usr/local/jdk-1.7.0/bin
  155. /usr/local/jdk-1.6.0/bin
  156. )
  157. find_program(Java_JAVA_EXECUTABLE
  158. NAMES java
  159. HINTS ${_JAVA_HINTS}
  160. PATHS ${_JAVA_PATHS}
  161. )
  162. if(Java_JAVA_EXECUTABLE)
  163. execute_process(COMMAND "${Java_JAVA_EXECUTABLE}" -version
  164. RESULT_VARIABLE _java_res
  165. OUTPUT_VARIABLE _java_var
  166. ERROR_VARIABLE _java_var # sun-java output to stderr
  167. OUTPUT_STRIP_TRAILING_WHITESPACE
  168. ERROR_STRIP_TRAILING_WHITESPACE)
  169. if(_java_res)
  170. if(NOT Java_FIND_QUIETLY)
  171. message(STATUS "Java version check failed: "
  172. "${Java_JAVA_EXECUTABLE} -version returned an error: \"${_java_var}\"")
  173. endif()
  174. if(_java_var MATCHES "Unable to locate a Java Runtime|No Java runtime present, requesting install")
  175. # macOS distributes a java stub that provides an error message
  176. set(Java_JAVA_EXECUTABLE "Java_JAVA_EXECUTABLE-NOTFOUND" CACHE PATH
  177. "Path to the Java executable" FORCE)
  178. endif()
  179. else()
  180. # Extract version components (up to 4 levels) from "java -version" output.
  181. set(_java_version_regex [[(([0-9]+)(\.([0-9]+)(\.([0-9]+)(_([0-9]+))?)?)?.*)]])
  182. if(_java_var MATCHES "java version \"${_java_version_regex}\"")
  183. # Sun, GCJ, older OpenJDK
  184. set(Java_VERSION_STRING "${CMAKE_MATCH_1}")
  185. set(Java_VERSION_MAJOR "${CMAKE_MATCH_2}")
  186. if (CMAKE_MATCH_4)
  187. set(Java_VERSION_MINOR "${CMAKE_MATCH_4}")
  188. else()
  189. set(Java_VERSION_MINOR 0)
  190. endif()
  191. if (CMAKE_MATCH_6)
  192. set(Java_VERSION_PATCH "${CMAKE_MATCH_6}")
  193. else()
  194. set(Java_VERSION_PATCH 0)
  195. endif()
  196. set(Java_VERSION_TWEAK "${CMAKE_MATCH_8}")
  197. elseif(_java_var MATCHES "openjdk version \"${_java_version_regex}\"")
  198. # OpenJDK
  199. set(Java_VERSION_STRING "${CMAKE_MATCH_1}")
  200. set(Java_VERSION_MAJOR "${CMAKE_MATCH_2}")
  201. if (CMAKE_MATCH_4)
  202. set(Java_VERSION_MINOR "${CMAKE_MATCH_4}")
  203. else()
  204. set(Java_VERSION_MINOR 0)
  205. endif()
  206. if (CMAKE_MATCH_6)
  207. set(Java_VERSION_PATCH "${CMAKE_MATCH_6}")
  208. else()
  209. set(Java_VERSION_PATCH 0)
  210. endif()
  211. set(Java_VERSION_TWEAK "${CMAKE_MATCH_8}")
  212. elseif(_java_var MATCHES "openjdk version \"([0-9]+)-[A-Za-z]+\"")
  213. # OpenJDK 9 early access builds or locally built
  214. set(Java_VERSION_STRING "1.${CMAKE_MATCH_1}.0")
  215. set(Java_VERSION_MAJOR "1")
  216. set(Java_VERSION_MINOR "${CMAKE_MATCH_1}")
  217. set(Java_VERSION_PATCH "0")
  218. set(Java_VERSION_TWEAK "")
  219. elseif(_java_var MATCHES "java full version \"kaffe-${_java_version_regex}\"")
  220. # Kaffe style
  221. set(Java_VERSION_STRING "${CMAKE_MATCH_1}")
  222. set(Java_VERSION_MAJOR "${CMAKE_MATCH_2}")
  223. set(Java_VERSION_MINOR "${CMAKE_MATCH_4}")
  224. set(Java_VERSION_PATCH "${CMAKE_MATCH_6}")
  225. set(Java_VERSION_TWEAK "${CMAKE_MATCH_8}")
  226. else()
  227. if(NOT Java_FIND_QUIETLY)
  228. string(REPLACE "\n" "\n " ver_msg "\n${_java_var}")
  229. message(WARNING "Java version not recognized:${ver_msg}\nPlease report.")
  230. endif()
  231. set(Java_VERSION_STRING "")
  232. set(Java_VERSION_MAJOR "")
  233. set(Java_VERSION_MINOR "")
  234. set(Java_VERSION_PATCH "")
  235. set(Java_VERSION_TWEAK "")
  236. endif()
  237. unset(_java_version_regex)
  238. unset(_java_var)
  239. set(Java_VERSION "${Java_VERSION_MAJOR}")
  240. if(NOT "x${Java_VERSION}" STREQUAL "x")
  241. foreach(_java_c IN ITEMS "MINOR" "PATCH" "TWEAK")
  242. if(NOT "x${Java_VERSION_${_java_c}}" STREQUAL "x")
  243. string(APPEND Java_VERSION ".${Java_VERSION_${_java_c}}")
  244. else()
  245. break()
  246. endif()
  247. endforeach()
  248. unset(_java_c)
  249. endif()
  250. endif()
  251. unset(_java_res)
  252. endif()
  253. find_program(Java_JAR_EXECUTABLE
  254. NAMES jar
  255. HINTS ${_JAVA_HINTS}
  256. PATHS ${_JAVA_PATHS}
  257. )
  258. find_program(Java_JAVAC_EXECUTABLE
  259. NAMES javac
  260. HINTS ${_JAVA_HINTS}
  261. PATHS ${_JAVA_PATHS}
  262. )
  263. find_program(Java_JAVAH_EXECUTABLE
  264. NAMES javah
  265. HINTS ${_JAVA_HINTS}
  266. PATHS ${_JAVA_PATHS}
  267. )
  268. find_program(Java_JAVADOC_EXECUTABLE
  269. NAMES javadoc
  270. HINTS ${_JAVA_HINTS}
  271. PATHS ${_JAVA_PATHS}
  272. )
  273. find_program(Java_IDLJ_EXECUTABLE
  274. NAMES idlj
  275. HINTS ${_JAVA_HINTS}
  276. PATHS ${_JAVA_PATHS}
  277. )
  278. find_program(Java_JARSIGNER_EXECUTABLE
  279. NAMES jarsigner
  280. HINTS ${_JAVA_HINTS}
  281. PATHS ${_JAVA_PATHS}
  282. )
  283. include(FindPackageHandleStandardArgs)
  284. if(Java_FIND_COMPONENTS)
  285. set(_JAVA_REQUIRED_VARS)
  286. foreach(component IN LISTS Java_FIND_COMPONENTS)
  287. # User just want to execute some Java byte-compiled
  288. If(component STREQUAL "Runtime")
  289. list(APPEND _JAVA_REQUIRED_VARS Java_JAVA_EXECUTABLE)
  290. if(Java_JAVA_EXECUTABLE)
  291. set(Java_Runtime_FOUND TRUE)
  292. endif()
  293. elseif(component STREQUAL "Development")
  294. list(APPEND _JAVA_REQUIRED_VARS Java_JAVA_EXECUTABLE Java_JAVAC_EXECUTABLE
  295. Java_JAR_EXECUTABLE Java_JAVADOC_EXECUTABLE)
  296. if(Java_VERSION VERSION_LESS "10")
  297. list(APPEND _JAVA_REQUIRED_VARS Java_JAVAH_EXECUTABLE)
  298. if(Java_JAVA_EXECUTABLE AND Java_JAVAC_EXECUTABLE
  299. AND Java_JAVAH_EXECUTABLE AND Java_JAR_EXECUTABLE AND Java_JAVADOC_EXECUTABLE)
  300. set(Java_Development_FOUND TRUE)
  301. endif()
  302. else()
  303. if(Java_JAVA_EXECUTABLE AND Java_JAVAC_EXECUTABLE
  304. AND Java_JAR_EXECUTABLE AND Java_JAVADOC_EXECUTABLE)
  305. set(Java_Development_FOUND TRUE)
  306. endif()
  307. endif()
  308. elseif(component STREQUAL "IdlJ")
  309. list(APPEND _JAVA_REQUIRED_VARS Java_IDLJ_EXECUTABLE)
  310. if(Java_IDLJ_EXECUTABLE)
  311. set(Java_IdlJ_FOUND TRUE)
  312. endif()
  313. elseif(component STREQUAL "JarSigner")
  314. list(APPEND _JAVA_REQUIRED_VARS Java_JARSIGNER_EXECUTABLE)
  315. if(Java_JARSIGNER_EXECUTABLE)
  316. set(Java_JarSigner_FOUND TRUE)
  317. endif()
  318. else()
  319. message(FATAL_ERROR "Comp: ${component} is not handled")
  320. endif()
  321. endforeach()
  322. list (REMOVE_DUPLICATES _JAVA_REQUIRED_VARS)
  323. find_package_handle_standard_args(Java
  324. REQUIRED_VARS ${_JAVA_REQUIRED_VARS} HANDLE_COMPONENTS
  325. VERSION_VAR Java_VERSION
  326. )
  327. if(Java_FOUND)
  328. foreach(component IN LISTS Java_FIND_COMPONENTS)
  329. set(Java_${component}_FOUND TRUE)
  330. endforeach()
  331. endif()
  332. unset(_JAVA_REQUIRED_VARS)
  333. else()
  334. # Check for Development
  335. if(Java_VERSION VERSION_LESS "10")
  336. find_package_handle_standard_args(Java
  337. REQUIRED_VARS Java_JAVA_EXECUTABLE Java_JAR_EXECUTABLE Java_JAVAC_EXECUTABLE
  338. Java_JAVAH_EXECUTABLE Java_JAVADOC_EXECUTABLE
  339. VERSION_VAR Java_VERSION
  340. )
  341. else()
  342. find_package_handle_standard_args(Java
  343. REQUIRED_VARS Java_JAVA_EXECUTABLE Java_JAR_EXECUTABLE Java_JAVAC_EXECUTABLE
  344. Java_JAVADOC_EXECUTABLE
  345. VERSION_VAR Java_VERSION
  346. )
  347. endif()
  348. endif()
  349. mark_as_advanced(
  350. Java_JAVA_EXECUTABLE
  351. Java_JAR_EXECUTABLE
  352. Java_JAVAC_EXECUTABLE
  353. Java_JAVAH_EXECUTABLE
  354. Java_JAVADOC_EXECUTABLE
  355. Java_IDLJ_EXECUTABLE
  356. Java_JARSIGNER_EXECUTABLE
  357. )
  358. # LEGACY
  359. set(JAVA_RUNTIME ${Java_JAVA_EXECUTABLE})
  360. set(JAVA_ARCHIVE ${Java_JAR_EXECUTABLE})
  361. set(JAVA_COMPILE ${Java_JAVAC_EXECUTABLE})