1 # Distributed under the OSI-approved BSD 3-Clause License. See accompanying
2 # file Copyright.txt or https://cmake.org/licensing for details.
4 #[=======================================================================[.rst:
10 This module finds if Java is installed and determines where the
11 include files and libraries are. The caller may set variable ``JAVA_HOME``
12 to specify a Java installation prefix explicitly.
14 See also the :module:`FindJNI` module to find Java Native Interface (JNI).
16 .. versionadded:: 3.10
17 Added support for Java 9+ version parsing.
19 Specify one or more of the following components as you call this find module. See example below.
23 Runtime = Java Runtime Environment used to execute Java byte-compiled applications
24 Development = Development tools (java, javac, javah, jar and javadoc), includes Runtime component
25 IdlJ = Interface Description Language (IDL) to Java compiler
26 JarSigner = Signer and verifier tool for Java Archive (JAR) files
29 This module sets the following result variables:
33 Java_JAVA_EXECUTABLE = the full path to the Java runtime
34 Java_JAVAC_EXECUTABLE = the full path to the Java compiler
35 Java_JAVAH_EXECUTABLE = the full path to the Java header generator
36 Java_JAVADOC_EXECUTABLE = the full path to the Java documentation generator
37 Java_IDLJ_EXECUTABLE = the full path to the Java idl compiler
38 Java_JAR_EXECUTABLE = the full path to the Java archiver
39 Java_JARSIGNER_EXECUTABLE = the full path to the Java jar signer
40 Java_VERSION_STRING = Version of java found, eg. 1.6.0_12
41 Java_VERSION_MAJOR = The major version of the package found.
42 Java_VERSION_MINOR = The minor version of the package found.
43 Java_VERSION_PATCH = The patch version of the package found.
44 Java_VERSION_TWEAK = The tweak version of the package found (after '_')
45 Java_VERSION = This is set to: $major[.$minor[.$patch[.$tweak]]]
48 Added the ``Java_IDLJ_EXECUTABLE`` and ``Java_JARSIGNER_EXECUTABLE``
51 The minimum required version of Java can be specified using the
52 :command:`find_package` syntax, e.g.
56 find_package(Java 1.8)
58 NOTE: ``${Java_VERSION}`` and ``${Java_VERSION_STRING}`` are not guaranteed to
59 be identical. For example some java version may return:
60 ``Java_VERSION_STRING = 1.8.0_17`` and ``Java_VERSION = 1.8.0.17``
62 another example is the Java OEM, with: ``Java_VERSION_STRING = 1.8.0-oem``
63 and ``Java_VERSION = 1.8.0``
65 For these components the following variables are set:
69 Java_FOUND - TRUE if all components are found.
70 Java_<component>_FOUND - TRUE if <component> is found.
79 find_package(Java 1.8 REQUIRED)
80 find_package(Java COMPONENTS Runtime)
81 find_package(Java COMPONENTS Development)
82 #]=======================================================================]
84 include(${CMAKE_CURRENT_LIST_DIR}/CMakeFindJavaCommon.cmake)
86 # The HINTS option should only be used for values computed from the system.
89 list(APPEND _JAVA_HINTS ${_JAVA_HOME}/bin)
92 macro (_JAVA_GET_INSTALLED_VERSIONS _KIND)
93 cmake_host_system_information(RESULT _JAVA_VERSIONS
94 QUERY WINDOWS_REGISTRY "HKLM/SOFTWARE/JavaSoft/${_KIND}"
97 string (REGEX MATCHALL "[0-9._]+" _JAVA_VERSIONS "${_JAVA_VERSIONS}")
98 string (REGEX REPLACE "([0-9._]+)" "\\1" _JAVA_VERSIONS "${_JAVA_VERSIONS}")
100 # sort versions. Most recent first
101 list (SORT _JAVA_VERSIONS COMPARE NATURAL ORDER DESCENDING)
102 foreach (_JAVA_VERSION IN LISTS _JAVA_VERSIONS)
103 string(REPLACE "_" "." _JAVA_CMAKE_VERSION "${_JAVA_VERSION}")
104 if (Java_FIND_VERSION_EXACT
105 AND NOT _JAVA_CMAKE_VERSION MATCHES "^${Java_FIND_VERSION}")
108 list(APPEND _JAVA_HINTS "[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\${_KIND}\\${_JAVA_VERSION};JavaHome]/bin")
114 # for version 9 and upper
115 _JAVA_GET_INSTALLED_VERSIONS("JDK")
116 _JAVA_GET_INSTALLED_VERSIONS("JRE")
118 # for versions older than 9
119 _JAVA_GET_INSTALLED_VERSIONS("Java Development Kit")
120 _JAVA_GET_INSTALLED_VERSIONS("Java Runtime Environment")
123 # Hard-coded guesses should still go in PATHS. This ensures that the user
124 # environment can always override hard guesses.
129 /usr/local/java/share/bin
130 /usr/java/j2sdk1.4.2_04
131 /usr/lib/j2sdk1.4-sun/bin
132 /usr/java/j2sdk1.4.2_09/bin
133 /usr/lib/j2sdk1.5-sun/bin
134 /opt/sun-jdk-1.5.0.04/bin
135 /usr/local/jdk-1.7.0/bin
136 /usr/local/jdk-1.6.0/bin
138 find_program(Java_JAVA_EXECUTABLE
144 if(Java_JAVA_EXECUTABLE)
145 execute_process(COMMAND "${Java_JAVA_EXECUTABLE}" -version
146 RESULT_VARIABLE _java_res
147 OUTPUT_VARIABLE _java_var
148 ERROR_VARIABLE _java_var # sun-java output to stderr
149 OUTPUT_STRIP_TRAILING_WHITESPACE
150 ERROR_STRIP_TRAILING_WHITESPACE)
152 if(NOT Java_FIND_QUIETLY)
153 message(STATUS "Java version check failed: "
154 "${Java_JAVA_EXECUTABLE} -version returned an error: \"${_java_var}\"")
156 if(_java_var MATCHES "Unable to locate a Java Runtime|No Java runtime present, requesting install")
157 # macOS distributes a java stub that provides an error message
158 set(Java_JAVA_EXECUTABLE "Java_JAVA_EXECUTABLE-NOTFOUND" CACHE PATH
159 "Path to the Java executable" FORCE)
162 # Extract version components (up to 4 levels) from "java -version" output.
163 set(_java_version_regex [[(([0-9]+)(\.([0-9]+)(\.([0-9]+)(_([0-9]+))?)?)?.*)]])
164 if(_java_var MATCHES "java version \"${_java_version_regex}\"")
165 # Sun, GCJ, older OpenJDK
166 set(Java_VERSION_STRING "${CMAKE_MATCH_1}")
167 set(Java_VERSION_MAJOR "${CMAKE_MATCH_2}")
169 set(Java_VERSION_MINOR "${CMAKE_MATCH_4}")
171 set(Java_VERSION_MINOR 0)
174 set(Java_VERSION_PATCH "${CMAKE_MATCH_6}")
176 set(Java_VERSION_PATCH 0)
178 set(Java_VERSION_TWEAK "${CMAKE_MATCH_8}")
179 elseif(_java_var MATCHES "openjdk version \"${_java_version_regex}\"")
181 set(Java_VERSION_STRING "${CMAKE_MATCH_1}")
182 set(Java_VERSION_MAJOR "${CMAKE_MATCH_2}")
184 set(Java_VERSION_MINOR "${CMAKE_MATCH_4}")
186 set(Java_VERSION_MINOR 0)
189 set(Java_VERSION_PATCH "${CMAKE_MATCH_6}")
191 set(Java_VERSION_PATCH 0)
193 set(Java_VERSION_TWEAK "${CMAKE_MATCH_8}")
194 elseif(_java_var MATCHES "openjdk version \"([0-9]+)-[A-Za-z]+\"")
195 # OpenJDK 9 early access builds or locally built
196 set(Java_VERSION_STRING "1.${CMAKE_MATCH_1}.0")
197 set(Java_VERSION_MAJOR "1")
198 set(Java_VERSION_MINOR "${CMAKE_MATCH_1}")
199 set(Java_VERSION_PATCH "0")
200 set(Java_VERSION_TWEAK "")
201 elseif(_java_var MATCHES "java full version \"kaffe-${_java_version_regex}\"")
203 set(Java_VERSION_STRING "${CMAKE_MATCH_1}")
204 set(Java_VERSION_MAJOR "${CMAKE_MATCH_2}")
205 set(Java_VERSION_MINOR "${CMAKE_MATCH_4}")
206 set(Java_VERSION_PATCH "${CMAKE_MATCH_6}")
207 set(Java_VERSION_TWEAK "${CMAKE_MATCH_8}")
209 if(NOT Java_FIND_QUIETLY)
210 string(REPLACE "\n" "\n " ver_msg "\n${_java_var}")
211 message(WARNING "Java version not recognized:${ver_msg}\nPlease report.")
213 set(Java_VERSION_STRING "")
214 set(Java_VERSION_MAJOR "")
215 set(Java_VERSION_MINOR "")
216 set(Java_VERSION_PATCH "")
217 set(Java_VERSION_TWEAK "")
219 unset(_java_version_regex)
221 set(Java_VERSION "${Java_VERSION_MAJOR}")
222 if(NOT "x${Java_VERSION}" STREQUAL "x")
223 foreach(_java_c IN ITEMS "MINOR" "PATCH" "TWEAK")
224 if(NOT "x${Java_VERSION_${_java_c}}" STREQUAL "x")
225 string(APPEND Java_VERSION ".${Java_VERSION_${_java_c}}")
237 find_program(Java_JAR_EXECUTABLE
243 find_program(Java_JAVAC_EXECUTABLE
249 find_program(Java_JAVAH_EXECUTABLE
255 find_program(Java_JAVADOC_EXECUTABLE
261 find_program(Java_IDLJ_EXECUTABLE
267 find_program(Java_JARSIGNER_EXECUTABLE
273 include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
274 if(Java_FIND_COMPONENTS)
275 set(_JAVA_REQUIRED_VARS)
276 foreach(component IN LISTS Java_FIND_COMPONENTS)
277 # User just want to execute some Java byte-compiled
278 If(component STREQUAL "Runtime")
279 list(APPEND _JAVA_REQUIRED_VARS Java_JAVA_EXECUTABLE)
280 if(Java_JAVA_EXECUTABLE)
281 set(Java_Runtime_FOUND TRUE)
283 elseif(component STREQUAL "Development")
284 list(APPEND _JAVA_REQUIRED_VARS Java_JAVA_EXECUTABLE Java_JAVAC_EXECUTABLE
285 Java_JAR_EXECUTABLE Java_JAVADOC_EXECUTABLE)
286 if(Java_VERSION VERSION_LESS "10")
287 list(APPEND _JAVA_REQUIRED_VARS Java_JAVAH_EXECUTABLE)
288 if(Java_JAVA_EXECUTABLE AND Java_JAVAC_EXECUTABLE
289 AND Java_JAVAH_EXECUTABLE AND Java_JAR_EXECUTABLE AND Java_JAVADOC_EXECUTABLE)
290 set(Java_Development_FOUND TRUE)
293 if(Java_JAVA_EXECUTABLE AND Java_JAVAC_EXECUTABLE
294 AND Java_JAR_EXECUTABLE AND Java_JAVADOC_EXECUTABLE)
295 set(Java_Development_FOUND TRUE)
298 elseif(component STREQUAL "IdlJ")
299 list(APPEND _JAVA_REQUIRED_VARS Java_IDLJ_EXECUTABLE)
300 if(Java_IDLJ_EXECUTABLE)
301 set(Java_IdlJ_FOUND TRUE)
303 elseif(component STREQUAL "JarSigner")
304 list(APPEND _JAVA_REQUIRED_VARS Java_JARSIGNER_EXECUTABLE)
305 if(Java_JARSIGNER_EXECUTABLE)
306 set(Java_JarSigner_FOUND TRUE)
309 message(FATAL_ERROR "Comp: ${component} is not handled")
312 list (REMOVE_DUPLICATES _JAVA_REQUIRED_VARS)
313 find_package_handle_standard_args(Java
314 REQUIRED_VARS ${_JAVA_REQUIRED_VARS} HANDLE_COMPONENTS
315 VERSION_VAR Java_VERSION
318 foreach(component IN LISTS Java_FIND_COMPONENTS)
319 set(Java_${component}_FOUND TRUE)
322 unset(_JAVA_REQUIRED_VARS)
324 # Check for Development
325 if(Java_VERSION VERSION_LESS "10")
326 find_package_handle_standard_args(Java
327 REQUIRED_VARS Java_JAVA_EXECUTABLE Java_JAR_EXECUTABLE Java_JAVAC_EXECUTABLE
328 Java_JAVAH_EXECUTABLE Java_JAVADOC_EXECUTABLE
329 VERSION_VAR Java_VERSION
332 find_package_handle_standard_args(Java
333 REQUIRED_VARS Java_JAVA_EXECUTABLE Java_JAR_EXECUTABLE Java_JAVAC_EXECUTABLE
334 Java_JAVADOC_EXECUTABLE
335 VERSION_VAR Java_VERSION
344 Java_JAVAC_EXECUTABLE
345 Java_JAVAH_EXECUTABLE
346 Java_JAVADOC_EXECUTABLE
348 Java_JARSIGNER_EXECUTABLE
352 set(JAVA_RUNTIME ${Java_JAVA_EXECUTABLE})
353 set(JAVA_ARCHIVE ${Java_JAR_EXECUTABLE})
354 set(JAVA_COMPILE ${Java_JAVAC_EXECUTABLE})