FindJava.cmake 13 KB

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