939bd7be798718df085d3d56b4e97afc9f0ed341
[platform/upstream/cmake.git] / Modules / UseJava.cmake
1 # Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
2 # file Copyright.txt or https://cmake.org/licensing for details.
3
4 #.rst:
5 # UseJava
6 # -------
7 #
8 # Use Module for Java
9 #
10 # This file provides functions for Java.  It is assumed that
11 # FindJava.cmake has already been loaded.  See FindJava.cmake for
12 # information on how to load Java into your CMake project.
13 #
14 # ::
15 #
16 #  add_jar(target_name
17 #          [SOURCES] source1 [source2 ...] [resource1 ...]
18 #          [INCLUDE_JARS jar1 [jar2 ...]]
19 #          [ENTRY_POINT entry]
20 #          [VERSION version]
21 #          [OUTPUT_NAME name]
22 #          [OUTPUT_DIR dir]
23 #          [GENERATE_NATIVE_HEADERS target [DESTINATION dir]]
24 #          )
25 #
26 # This command creates a <target_name>.jar.  It compiles the given
27 # source files (source) and adds the given resource files (resource) to
28 # the jar file.  Source files can be java files or listing files
29 # (prefixed by '@').  If only resource files are given then just a jar file
30 # is created.  The list of include jars are added to the classpath when
31 # compiling the java sources and also to the dependencies of the target.
32 # INCLUDE_JARS also accepts other target names created by add_jar.  For
33 # backwards compatibility, jar files listed as sources are ignored (as
34 # they have been since the first version of this module).
35 #
36 # The default OUTPUT_DIR can also be changed by setting the variable
37 # CMAKE_JAVA_TARGET_OUTPUT_DIR.
38 #
39 # Optionaly, using option GENERATE_NATIVE_HEADERS, native header files can be generated
40 # for methods declared as native. These files provide the connective glue that allow your
41 # Java and C code to interact. An INTERFACE target will be created for an easy usage
42 # of generated files. Sub-option DESTINATION can be used to specify output directory for
43 # generated header files.
44 #
45 # GENERATE_NATIVE_HEADERS option requires, at least, version 1.8 of the JDK.
46 #
47 # Additional instructions:
48 #
49 # ::
50 #
51 #    To add compile flags to the target you can set these flags with
52 #    the following variable:
53 #
54 #
55 #
56 # ::
57 #
58 #        set(CMAKE_JAVA_COMPILE_FLAGS -nowarn)
59 #
60 #
61 #
62 # ::
63 #
64 #    To add a path or a jar file to the class path you can do this
65 #    with the CMAKE_JAVA_INCLUDE_PATH variable.
66 #
67 #
68 #
69 # ::
70 #
71 #        set(CMAKE_JAVA_INCLUDE_PATH /usr/share/java/shibboleet.jar)
72 #
73 #
74 #
75 # ::
76 #
77 #    To use a different output name for the target you can set it with:
78 #
79 #
80 #
81 # ::
82 #
83 #        add_jar(foobar foobar.java OUTPUT_NAME shibboleet.jar)
84 #
85 #
86 #
87 # ::
88 #
89 #    To use a different output directory than CMAKE_CURRENT_BINARY_DIR
90 #    you can set it with:
91 #
92 #
93 #
94 # ::
95 #
96 #        add_jar(foobar foobar.java OUTPUT_DIR ${PROJECT_BINARY_DIR}/bin)
97 #
98 #
99 #
100 # ::
101 #
102 #    To define an entry point in your jar you can set it with the ENTRY_POINT
103 #    named argument:
104 #
105 #
106 #
107 # ::
108 #
109 #        add_jar(example ENTRY_POINT com/examples/MyProject/Main)
110 #
111 #
112 #
113 # ::
114 #
115 #    To define a custom manifest for the jar, you can set it with the manifest
116 #    named argument:
117 #
118 #
119 #
120 # ::
121 #
122 #        add_jar(example MANIFEST /path/to/manifest)
123 #
124 #
125 #
126 # ::
127 #
128 #    To add a VERSION to the target output name you can set it using
129 #    the VERSION named argument to add_jar. This will create a jar file with the
130 #    name shibboleet-1.0.0.jar and will create a symlink shibboleet.jar
131 #    pointing to the jar with the version information.
132 #
133 #
134 #
135 # ::
136 #
137 #        add_jar(shibboleet shibbotleet.java VERSION 1.2.0)
138 #
139 #
140 #
141 # ::
142 #
143 #     If the target is a JNI library, utilize the following commands to
144 #     create a JNI symbolic link:
145 #
146 #
147 #
148 # ::
149 #
150 #        set(CMAKE_JNI_TARGET TRUE)
151 #        add_jar(shibboleet shibbotleet.java VERSION 1.2.0)
152 #        install_jar(shibboleet ${LIB_INSTALL_DIR}/shibboleet)
153 #        install_jni_symlink(shibboleet ${JAVA_LIB_INSTALL_DIR})
154 #
155 #
156 #
157 # ::
158 #
159 #     If a single target needs to produce more than one jar from its
160 #     java source code, to prevent the accumulation of duplicate class
161 #     files in subsequent jars, set/reset CMAKE_JAR_CLASSES_PREFIX prior
162 #     to calling the add_jar() function:
163 #
164 #
165 #
166 # ::
167 #
168 #        set(CMAKE_JAR_CLASSES_PREFIX com/redhat/foo)
169 #        add_jar(foo foo.java)
170 #
171 #
172 #
173 # ::
174 #
175 #        set(CMAKE_JAR_CLASSES_PREFIX com/redhat/bar)
176 #        add_jar(bar bar.java)
177 #
178 #
179 #
180 # ::
181 #
182 #     For an optimum usage of option GENERATE_NATIVE_HEADERS, it is recommended to
183 #     include module JNI before any call to add_jar. The produced target for native
184 #     headers can then be used to compile C/C++ sources with command
185 #     target_link_libraries.
186 #
187 #
188 # ::
189 #
190 #        find_package(JNI)
191 #        add_jar(foo foo.java GENERATE_NATIVE_HEADERS foo-native)
192 #        add_library(bar bar.cpp)
193 #        target_link_libraries(bar PRIVATE foo-native)
194 #
195 #
196 # Target Properties:
197 #
198 # ::
199 #
200 #    The add_jar() function sets some target properties. You can get these
201 #    properties with the
202 #       get_property(TARGET <target_name> PROPERTY <propery_name>)
203 #    command.
204 #
205 #
206 #
207 # ::
208 #
209 #    INSTALL_FILES      The files which should be installed. This is used by
210 #                       install_jar().
211 #    JNI_SYMLINK        The JNI symlink which should be installed.
212 #                       This is used by install_jni_symlink().
213 #    JAR_FILE           The location of the jar file so that you can include
214 #                       it.
215 #    CLASSDIR           The directory where the class files can be found. For
216 #                       example to use them with javah.
217 #
218 # ::
219 #
220 #  find_jar(<VAR>
221 #           name | NAMES name1 [name2 ...]
222 #           [PATHS path1 [path2 ... ENV var]]
223 #           [VERSIONS version1 [version2]]
224 #           [DOC "cache documentation string"]
225 #           )
226 #
227 # This command is used to find a full path to the named jar.  A cache
228 # entry named by <VAR> is created to stor the result of this command.
229 # If the full path to a jar is found the result is stored in the
230 # variable and the search will not repeated unless the variable is
231 # cleared.  If nothing is found, the result will be <VAR>-NOTFOUND, and
232 # the search will be attempted again next time find_jar is invoked with
233 # the same variable.  The name of the full path to a file that is
234 # searched for is specified by the names listed after NAMES argument.
235 # Additional search locations can be specified after the PATHS argument.
236 # If you require special a version of a jar file you can specify it with
237 # the VERSIONS argument.  The argument after DOC will be used for the
238 # documentation string in the cache.
239 #
240 # ::
241 #
242 #  install_jar(target_name destination)
243 #  install_jar(target_name DESTINATION destination [COMPONENT component])
244 #
245 # This command installs the TARGET_NAME files to the given DESTINATION.
246 # It should be called in the same scope as add_jar() or it will fail.
247 #
248 # Target Properties:
249 #
250 # ::
251 #
252 #    The install_jar() function sets the INSTALL_DESTINATION target property
253 #    on jars so installed. This property holds the DESTINATION as described
254 #    above, and is used by install_jar_exports(). You can get this property
255 #    with the
256 #       get_property(TARGET <target_name> PROPERTY INSTALL_DESTINATION)
257 #    command.
258 #
259 #
260 #
261 # ::
262 #
263 #  install_jni_symlink(target_name destination)
264 #  install_jni_symlink(target_name DESTINATION destination [COMPONENT component])
265 #
266 # This command installs the TARGET_NAME JNI symlinks to the given
267 # DESTINATION.  It should be called in the same scope as add_jar() or it
268 # will fail.
269 #
270 # ::
271 #
272 #  install_jar_exports(TARGETS jars...
273 #                      [NAMESPACE <namespace>]
274 #                      FILE <filename>
275 #                      DESTINATION <dir> [COMPONENT <component>])
276 #
277 # This command installs a target export file ``<filename>`` for the named jar
278 # targets to the given ``DESTINATION``. Its function is similar to that of
279 # :command:`install(EXPORTS ...)`.
280 #
281 # ::
282 #
283 #  export_jars(TARGETS jars...
284 #              [NAMESPACE <namespace>]
285 #              FILE <filename>)
286 #
287 # This command writes a target export file ``<filename>`` for the named jar
288 # targets. Its function is similar to that of :command:`export(...)`.
289 #
290 # ::
291 #
292 #  create_javadoc(<VAR>
293 #                 PACKAGES pkg1 [pkg2 ...]
294 #                 [SOURCEPATH <sourcepath>]
295 #                 [CLASSPATH <classpath>]
296 #                 [INSTALLPATH <install path>]
297 #                 [DOCTITLE "the documentation title"]
298 #                 [WINDOWTITLE "the title of the document"]
299 #                 [AUTHOR TRUE|FALSE]
300 #                 [USE TRUE|FALSE]
301 #                 [VERSION TRUE|FALSE]
302 #                 )
303 #
304 # Create java documentation based on files or packages.  For more
305 # details please read the javadoc manpage.
306 #
307 # There are two main signatures for create_javadoc.  The first signature
308 # works with package names on a path with source files:
309 #
310 # ::
311 #
312 #    Example:
313 #    create_javadoc(my_example_doc
314 #      PACKAGES com.example.foo com.example.bar
315 #      SOURCEPATH "${CMAKE_CURRENT_SOURCE_DIR}"
316 #      CLASSPATH ${CMAKE_JAVA_INCLUDE_PATH}
317 #      WINDOWTITLE "My example"
318 #      DOCTITLE "<h1>My example</h1>"
319 #      AUTHOR TRUE
320 #      USE TRUE
321 #      VERSION TRUE
322 #    )
323 #
324 #
325 #
326 # The second signature for create_javadoc works on a given list of
327 # files.
328 #
329 # ::
330 #
331 #    create_javadoc(<VAR>
332 #                   FILES file1 [file2 ...]
333 #                   [CLASSPATH <classpath>]
334 #                   [INSTALLPATH <install path>]
335 #                   [DOCTITLE "the documentation title"]
336 #                   [WINDOWTITLE "the title of the document"]
337 #                   [AUTHOR TRUE|FALSE]
338 #                   [USE TRUE|FALSE]
339 #                   [VERSION TRUE|FALSE]
340 #                  )
341 #
342 #
343 #
344 # Example:
345 #
346 # ::
347 #
348 #    create_javadoc(my_example_doc
349 #      FILES ${example_SRCS}
350 #      CLASSPATH ${CMAKE_JAVA_INCLUDE_PATH}
351 #      WINDOWTITLE "My example"
352 #      DOCTITLE "<h1>My example</h1>"
353 #      AUTHOR TRUE
354 #      USE TRUE
355 #      VERSION TRUE
356 #    )
357 #
358 #
359 #
360 # Both signatures share most of the options.  These options are the same
361 # as what you can find in the javadoc manpage.  Please look at the
362 # manpage for CLASSPATH, DOCTITLE, WINDOWTITLE, AUTHOR, USE and VERSION.
363 #
364 # The documentation will be by default installed to
365 #
366 # ::
367 #
368 #    ${CMAKE_INSTALL_PREFIX}/share/javadoc/<VAR>
369 #
370 #
371 #
372 # if you don't set the INSTALLPATH.
373 #
374 # ::
375 #
376 #  create_javah(TARGET <target>
377 #               GENERATED_FILES <VAR>
378 #               CLASSES <class>...
379 #               [CLASSPATH <classpath>...]
380 #               [DEPENDS <depend>...]
381 #               [OUTPUT_NAME <path>|OUTPUT_DIR <path>]
382 #               )
383 #
384 # Create C header files from java classes. These files provide the connective glue
385 # that allow your Java and C code to interact.
386 #
387 # This command will no longer be supported starting with version 1.10 of the JDK due
388 # to the `suppression of javah tool <http://openjdk.java.net/jeps/313>`_.
389 # Command ``add_jar(GENERATE_NATIVE_HEADERS)`` must be used instead.
390 #
391 # There are two main signatures for create_javah.  The first signature
392 # returns generated files through variable specified by GENERATED_FILES option:
393 #
394 # ::
395 #
396 #    Example:
397 #    Create_javah(GENERATED_FILES files_headers
398 #      CLASSES org.cmake.HelloWorld
399 #      CLASSPATH hello.jar
400 #    )
401 #
402 #
403 #
404 # The second signature for create_javah creates a target which encapsulates
405 # header files generation.
406 #
407 # ::
408 #
409 #    Example:
410 #    Create_javah(TARGET target_headers
411 #      CLASSES org.cmake.HelloWorld
412 #      CLASSPATH hello.jar
413 #    )
414 #
415 #
416 #
417 # Both signatures share same options.
418 #
419 #  ``CLASSES <class>...``
420 #    Specifies Java classes used to generate headers.
421 #
422 #  ``CLASSPATH <classpath>...``
423 #    Specifies various paths to look up classes. Here .class files, jar files or targets
424 #    created by command add_jar can be used.
425 #
426 #  ``DEPENDS <depend>...``
427 #    Targets on which the javah target depends
428 #
429 #  ``OUTPUT_NAME <path>``
430 #    Concatenates the resulting header files for all the classes listed by option CLASSES
431 #    into <path>. Same behavior as option '-o' of javah tool.
432 #
433 #  ``OUTPUT_DIR <path>``
434 #    Sets the directory where the header files will be generated. Same behavior as option
435 #    '-d' of javah tool. If not specified, ${CMAKE_CURRENT_BINARY_DIR} is used as output directory.
436
437 function (__java_copy_file src dest comment)
438     add_custom_command(
439         OUTPUT  ${dest}
440         COMMAND ${CMAKE_COMMAND} -E copy_if_different
441         ARGS    ${src}
442                 ${dest}
443         DEPENDS ${src}
444         COMMENT ${comment})
445 endfunction ()
446
447 function(__java_lcat VAR)
448     foreach(_line ${ARGN})
449         string(APPEND ${VAR} "${_line}\n")
450     endforeach()
451
452     set(${VAR} "${${VAR}}" PARENT_SCOPE)
453 endfunction()
454
455 function(__java_export_jar VAR TARGET PATH)
456     get_target_property(_jarpath ${TARGET} JAR_FILE)
457     get_filename_component(_jarname ${_jarpath} NAME)
458     set(_target "${_jar_NAMESPACE}${TARGET}")
459     __java_lcat(${VAR}
460       "# Create imported target ${_target}"
461       "add_library(${_target} IMPORTED STATIC)"
462       "set_target_properties(${_target} PROPERTIES"
463       "  IMPORTED_LOCATION \"${PATH}/${_jarname}\""
464       "  JAR_FILE \"${PATH}/${_jarname}\")"
465       ""
466     )
467     set(${VAR} "${${VAR}}" PARENT_SCOPE)
468 endfunction()
469
470 # define helper scripts
471 set(_JAVA_EXPORT_TARGETS_SCRIPT ${CMAKE_CURRENT_LIST_DIR}/javaTargets.cmake.in)
472 set(_JAVA_CLASS_FILELIST_SCRIPT ${CMAKE_CURRENT_LIST_DIR}/UseJavaClassFilelist.cmake)
473 set(_JAVA_SYMLINK_SCRIPT ${CMAKE_CURRENT_LIST_DIR}/UseJavaSymlinks.cmake)
474
475 function(add_jar _TARGET_NAME)
476
477     cmake_parse_arguments(_add_jar
478       ""
479       "VERSION;OUTPUT_DIR;OUTPUT_NAME;ENTRY_POINT;MANIFEST"
480       "SOURCES;INCLUDE_JARS;GENERATE_NATIVE_HEADERS"
481       ${ARGN}
482     )
483
484     # In CMake < 2.8.12, add_jar used variables which were set prior to calling
485     # add_jar for customizing the behavior of add_jar. In order to be backwards
486     # compatible, check if any of those variables are set, and use them to
487     # initialize values of the named arguments. (Giving the corresponding named
488     # argument will override the value set here.)
489     #
490     # New features should use named arguments only.
491     if(NOT DEFINED _add_jar_VERSION AND DEFINED CMAKE_JAVA_TARGET_VERSION)
492         set(_add_jar_VERSION "${CMAKE_JAVA_TARGET_VERSION}")
493     endif()
494     if(NOT DEFINED _add_jar_OUTPUT_DIR AND DEFINED CMAKE_JAVA_TARGET_OUTPUT_DIR)
495         set(_add_jar_OUTPUT_DIR "${CMAKE_JAVA_TARGET_OUTPUT_DIR}")
496     endif()
497     if(NOT DEFINED _add_jar_OUTPUT_NAME AND DEFINED CMAKE_JAVA_TARGET_OUTPUT_NAME)
498         set(_add_jar_OUTPUT_NAME "${CMAKE_JAVA_TARGET_OUTPUT_NAME}")
499         # reset
500         set(CMAKE_JAVA_TARGET_OUTPUT_NAME)
501     endif()
502     if(NOT DEFINED _add_jar_ENTRY_POINT AND DEFINED CMAKE_JAVA_JAR_ENTRY_POINT)
503         set(_add_jar_ENTRY_POINT "${CMAKE_JAVA_JAR_ENTRY_POINT}")
504     endif()
505
506     set(_JAVA_SOURCE_FILES ${_add_jar_SOURCES} ${_add_jar_UNPARSED_ARGUMENTS})
507
508     if (NOT DEFINED _add_jar_OUTPUT_DIR)
509         set(_add_jar_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR})
510     else()
511         get_filename_component(_add_jar_OUTPUT_DIR ${_add_jar_OUTPUT_DIR} ABSOLUTE)
512     endif()
513     # ensure output directory exists
514     file (MAKE_DIRECTORY "${_add_jar_OUTPUT_DIR}")
515
516     if (_add_jar_ENTRY_POINT)
517         set(_ENTRY_POINT_OPTION e)
518         set(_ENTRY_POINT_VALUE ${_add_jar_ENTRY_POINT})
519     endif ()
520
521     if (_add_jar_MANIFEST)
522         set(_MANIFEST_OPTION m)
523         get_filename_component (_MANIFEST_VALUE "${_add_jar_MANIFEST}" ABSOLUTE)
524     endif ()
525
526     unset (_GENERATE_NATIVE_HEADERS)
527     if (_add_jar_GENERATE_NATIVE_HEADERS)
528       # Raise an error if JDK version is less than 1.8 because javac -h is not supported
529       # by earlier versions.
530       if ("${Java_VERSION}" VERSION_LESS 1.8)
531         message (FATAL_ERROR "ADD_JAR: GENERATE_NATIVE_HEADERS is not supported with this version of Java.")
532       endif()
533       cmake_parse_arguments (_add_jar_GENERATE_NATIVE_HEADERS "" "DESTINATION" "" ${_add_jar_GENERATE_NATIVE_HEADERS})
534       if (NOT _add_jar_GENERATE_NATIVE_HEADERS_UNPARSED_ARGUMENTS)
535         message (FATAL_ERROR "ADD_JAR: GENERATE_NATIVE_HEADERS: missing required argument.")
536       endif()
537       list (LENGTH _add_jar_GENERATE_NATIVE_HEADERS_UNPARSED_ARGUMENTS length)
538       if (length GREATER 1)
539         list (REMOVE_AT _add_jar_GENERATE_NATIVE_HEADERS_UNPARSED_ARGUMENTS 0)
540         message (FATAL_ERROR "ADD_JAR: GENERATE_NATIVE_HEADERS: ${_add_jar_GENERATE_NATIVE_HEADERS_UNPARSED_ARGUMENTS}: unexpected argument(s).")
541       endif()
542       if (NOT _add_jar_GENERATE_NATIVE_HEADERS_DESTINATION)
543         set (_add_jar_GENERATE_NATIVE_HEADERS_DESTINATION "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${_TARGET_NAME}.dir/native_headers")
544       endif()
545
546       set (_GENERATE_NATIVE_HEADERS_TARGET ${_add_jar_GENERATE_NATIVE_HEADERS_UNPARSED_ARGUMENTS})
547       set (_GENERATE_NATIVE_HEADERS_OUTPUT_DIR "${_add_jar_GENERATE_NATIVE_HEADERS_DESTINATION}")
548       set (_GENERATE_NATIVE_HEADERS -h "${_GENERATE_NATIVE_HEADERS_OUTPUT_DIR}")
549     endif()
550
551     if (LIBRARY_OUTPUT_PATH)
552         set(CMAKE_JAVA_LIBRARY_OUTPUT_PATH ${LIBRARY_OUTPUT_PATH})
553     else ()
554         set(CMAKE_JAVA_LIBRARY_OUTPUT_PATH ${_add_jar_OUTPUT_DIR})
555     endif ()
556
557     set(CMAKE_JAVA_INCLUDE_PATH
558         ${CMAKE_JAVA_INCLUDE_PATH}
559         ${CMAKE_CURRENT_SOURCE_DIR}
560         ${CMAKE_JAVA_OBJECT_OUTPUT_PATH}
561         ${CMAKE_JAVA_LIBRARY_OUTPUT_PATH}
562     )
563
564     if (CMAKE_HOST_WIN32 AND NOT CYGWIN AND CMAKE_HOST_SYSTEM_NAME MATCHES "Windows")
565         set(CMAKE_JAVA_INCLUDE_FLAG_SEP ";")
566     else ()
567         set(CMAKE_JAVA_INCLUDE_FLAG_SEP ":")
568     endif()
569
570     foreach (JAVA_INCLUDE_DIR ${CMAKE_JAVA_INCLUDE_PATH})
571        string(APPEND CMAKE_JAVA_INCLUDE_PATH_FINAL "${CMAKE_JAVA_INCLUDE_FLAG_SEP}${JAVA_INCLUDE_DIR}")
572     endforeach()
573
574     set(CMAKE_JAVA_CLASS_OUTPUT_PATH "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${_TARGET_NAME}.dir")
575
576     set(_JAVA_TARGET_OUTPUT_NAME "${_TARGET_NAME}.jar")
577     if (_add_jar_OUTPUT_NAME AND _add_jar_VERSION)
578         set(_JAVA_TARGET_OUTPUT_NAME "${_add_jar_OUTPUT_NAME}-${_add_jar_VERSION}.jar")
579         set(_JAVA_TARGET_OUTPUT_LINK "${_add_jar_OUTPUT_NAME}.jar")
580     elseif (_add_jar_VERSION)
581         set(_JAVA_TARGET_OUTPUT_NAME "${_TARGET_NAME}-${_add_jar_VERSION}.jar")
582         set(_JAVA_TARGET_OUTPUT_LINK "${_TARGET_NAME}.jar")
583     elseif (_add_jar_OUTPUT_NAME)
584         set(_JAVA_TARGET_OUTPUT_NAME "${_add_jar_OUTPUT_NAME}.jar")
585     endif ()
586
587     set(_JAVA_CLASS_FILES)
588     set(_JAVA_COMPILE_FILES)
589     set(_JAVA_COMPILE_FILELISTS)
590     set(_JAVA_DEPENDS)
591     set(_JAVA_COMPILE_DEPENDS)
592     set(_JAVA_RESOURCE_FILES)
593     set(_JAVA_RESOURCE_FILES_RELATIVE)
594     foreach(_JAVA_SOURCE_FILE ${_JAVA_SOURCE_FILES})
595         get_filename_component(_JAVA_EXT ${_JAVA_SOURCE_FILE} EXT)
596         get_filename_component(_JAVA_FILE ${_JAVA_SOURCE_FILE} NAME_WE)
597         get_filename_component(_JAVA_PATH ${_JAVA_SOURCE_FILE} PATH)
598         get_filename_component(_JAVA_FULL ${_JAVA_SOURCE_FILE} ABSOLUTE)
599
600         if (_JAVA_SOURCE_FILE MATCHES "^@(.+)$")
601             get_filename_component(_JAVA_FULL ${CMAKE_MATCH_1} ABSOLUTE)
602             list(APPEND _JAVA_COMPILE_FILELISTS ${_JAVA_FULL})
603
604         elseif (_JAVA_EXT MATCHES ".java")
605             file(RELATIVE_PATH _JAVA_REL_BINARY_PATH ${CMAKE_CURRENT_BINARY_DIR} ${_JAVA_FULL})
606             file(RELATIVE_PATH _JAVA_REL_SOURCE_PATH ${CMAKE_CURRENT_SOURCE_DIR} ${_JAVA_FULL})
607             string(LENGTH ${_JAVA_REL_BINARY_PATH} _BIN_LEN)
608             string(LENGTH ${_JAVA_REL_SOURCE_PATH} _SRC_LEN)
609             if (${_BIN_LEN} LESS ${_SRC_LEN})
610                 set(_JAVA_REL_PATH ${_JAVA_REL_BINARY_PATH})
611             else ()
612                 set(_JAVA_REL_PATH ${_JAVA_REL_SOURCE_PATH})
613             endif ()
614             get_filename_component(_JAVA_REL_PATH ${_JAVA_REL_PATH} PATH)
615
616             list(APPEND _JAVA_COMPILE_FILES ${_JAVA_SOURCE_FILE})
617             set(_JAVA_CLASS_FILE "${CMAKE_JAVA_CLASS_OUTPUT_PATH}/${_JAVA_REL_PATH}/${_JAVA_FILE}.class")
618             set(_JAVA_CLASS_FILES ${_JAVA_CLASS_FILES} ${_JAVA_CLASS_FILE})
619
620         elseif (_JAVA_EXT MATCHES ".jar"
621                 OR _JAVA_EXT MATCHES ".war"
622                 OR _JAVA_EXT MATCHES ".ear"
623                 OR _JAVA_EXT MATCHES ".sar")
624             # Ignored for backward compatibility
625
626         elseif (_JAVA_EXT STREQUAL "")
627             list(APPEND CMAKE_JAVA_INCLUDE_PATH ${JAVA_JAR_TARGET_${_JAVA_SOURCE_FILE}} ${JAVA_JAR_TARGET_${_JAVA_SOURCE_FILE}_CLASSPATH})
628             list(APPEND _JAVA_DEPENDS ${JAVA_JAR_TARGET_${_JAVA_SOURCE_FILE}})
629
630         else ()
631             __java_copy_file(${CMAKE_CURRENT_SOURCE_DIR}/${_JAVA_SOURCE_FILE}
632                              ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/${_JAVA_SOURCE_FILE}
633                              "Copying ${_JAVA_SOURCE_FILE} to the build directory")
634             list(APPEND _JAVA_RESOURCE_FILES ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/${_JAVA_SOURCE_FILE})
635             list(APPEND _JAVA_RESOURCE_FILES_RELATIVE ${_JAVA_SOURCE_FILE})
636         endif ()
637     endforeach()
638
639     foreach(_JAVA_INCLUDE_JAR ${_add_jar_INCLUDE_JARS})
640         if (TARGET ${_JAVA_INCLUDE_JAR})
641             get_target_property(_JAVA_JAR_PATH ${_JAVA_INCLUDE_JAR} JAR_FILE)
642             if (_JAVA_JAR_PATH)
643                 string(APPEND CMAKE_JAVA_INCLUDE_PATH_FINAL "${CMAKE_JAVA_INCLUDE_FLAG_SEP}${_JAVA_JAR_PATH}")
644                 list(APPEND CMAKE_JAVA_INCLUDE_PATH ${_JAVA_JAR_PATH})
645                 list(APPEND _JAVA_DEPENDS ${_JAVA_INCLUDE_JAR})
646                 list(APPEND _JAVA_COMPILE_DEPENDS ${_JAVA_INCLUDE_JAR})
647             else ()
648                 message(SEND_ERROR "add_jar: INCLUDE_JARS target ${_JAVA_INCLUDE_JAR} is not a jar")
649             endif ()
650         else ()
651             string(APPEND CMAKE_JAVA_INCLUDE_PATH_FINAL "${CMAKE_JAVA_INCLUDE_FLAG_SEP}${_JAVA_INCLUDE_JAR}")
652             list(APPEND CMAKE_JAVA_INCLUDE_PATH "${_JAVA_INCLUDE_JAR}")
653             list(APPEND _JAVA_DEPENDS "${_JAVA_INCLUDE_JAR}")
654             list(APPEND _JAVA_COMPILE_DEPENDS "${_JAVA_INCLUDE_JAR}")
655         endif ()
656     endforeach()
657
658     if (_JAVA_COMPILE_FILES OR _JAVA_COMPILE_FILELISTS)
659         set (_JAVA_SOURCES_FILELISTS)
660
661         if (_JAVA_COMPILE_FILES)
662             # Create the list of files to compile.
663             set(_JAVA_SOURCES_FILE ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_sources)
664             string(REPLACE ";" "\"\n\"" _JAVA_COMPILE_STRING "\"${_JAVA_COMPILE_FILES}\"")
665             file(WRITE ${_JAVA_SOURCES_FILE} ${_JAVA_COMPILE_STRING})
666             list (APPEND _JAVA_SOURCES_FILELISTS "@${_JAVA_SOURCES_FILE}")
667         endif()
668         if (_JAVA_COMPILE_FILELISTS)
669             foreach (_JAVA_FILELIST IN LISTS _JAVA_COMPILE_FILELISTS)
670                 list (APPEND _JAVA_SOURCES_FILELISTS "@${_JAVA_FILELIST}")
671             endforeach()
672         endif()
673
674         # Compile the java files and create a list of class files
675         add_custom_command(
676             # NOTE: this command generates an artificial dependency file
677             OUTPUT ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_compiled_${_TARGET_NAME}
678             COMMAND ${Java_JAVAC_EXECUTABLE}
679                 ${CMAKE_JAVA_COMPILE_FLAGS}
680                 -classpath "${CMAKE_JAVA_INCLUDE_PATH_FINAL}"
681                 -d ${CMAKE_JAVA_CLASS_OUTPUT_PATH}
682                 ${_GENERATE_NATIVE_HEADERS}
683                 ${_JAVA_SOURCES_FILELISTS}
684             COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_compiled_${_TARGET_NAME}
685             DEPENDS ${_JAVA_COMPILE_FILES} ${_JAVA_COMPILE_FILELISTS} ${_JAVA_COMPILE_DEPENDS}
686             WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
687             COMMENT "Building Java objects for ${_TARGET_NAME}.jar"
688         )
689         add_custom_command(
690             OUTPUT ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_class_filelist
691             COMMAND ${CMAKE_COMMAND}
692                 -DCMAKE_JAVA_CLASS_OUTPUT_PATH=${CMAKE_JAVA_CLASS_OUTPUT_PATH}
693                 -DCMAKE_JAR_CLASSES_PREFIX="${CMAKE_JAR_CLASSES_PREFIX}"
694                 -P ${_JAVA_CLASS_FILELIST_SCRIPT}
695             DEPENDS ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_compiled_${_TARGET_NAME}
696             WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
697         )
698     else ()
699         # create an empty java_class_filelist
700         if (NOT EXISTS ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_class_filelist)
701             file(WRITE ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_class_filelist "")
702         endif()
703     endif ()
704
705     # create the jar file
706     set(_JAVA_JAR_OUTPUT_PATH
707       ${_add_jar_OUTPUT_DIR}/${_JAVA_TARGET_OUTPUT_NAME})
708     if (CMAKE_JNI_TARGET)
709         add_custom_command(
710             OUTPUT ${_JAVA_JAR_OUTPUT_PATH}
711             COMMAND ${Java_JAR_EXECUTABLE}
712                 -cf${_ENTRY_POINT_OPTION}${_MANIFEST_OPTION} ${_JAVA_JAR_OUTPUT_PATH} ${_ENTRY_POINT_VALUE} ${_MANIFEST_VALUE}
713                 ${_JAVA_RESOURCE_FILES_RELATIVE} @java_class_filelist
714             COMMAND ${CMAKE_COMMAND}
715                 -D_JAVA_TARGET_DIR=${_add_jar_OUTPUT_DIR}
716                 -D_JAVA_TARGET_OUTPUT_NAME=${_JAVA_TARGET_OUTPUT_NAME}
717                 -D_JAVA_TARGET_OUTPUT_LINK=${_JAVA_TARGET_OUTPUT_LINK}
718                 -P ${_JAVA_SYMLINK_SCRIPT}
719             COMMAND ${CMAKE_COMMAND}
720                 -D_JAVA_TARGET_DIR=${_add_jar_OUTPUT_DIR}
721                 -D_JAVA_TARGET_OUTPUT_NAME=${_JAVA_JAR_OUTPUT_PATH}
722                 -D_JAVA_TARGET_OUTPUT_LINK=${_JAVA_TARGET_OUTPUT_LINK}
723                 -P ${_JAVA_SYMLINK_SCRIPT}
724             DEPENDS ${_JAVA_RESOURCE_FILES} ${_JAVA_DEPENDS} ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_class_filelist
725             WORKING_DIRECTORY ${CMAKE_JAVA_CLASS_OUTPUT_PATH}
726             COMMENT "Creating Java archive ${_JAVA_TARGET_OUTPUT_NAME}"
727         )
728     else ()
729         add_custom_command(
730             OUTPUT ${_JAVA_JAR_OUTPUT_PATH}
731             COMMAND ${Java_JAR_EXECUTABLE}
732                 -cf${_ENTRY_POINT_OPTION}${_MANIFEST_OPTION} ${_JAVA_JAR_OUTPUT_PATH} ${_ENTRY_POINT_VALUE} ${_MANIFEST_VALUE}
733                 ${_JAVA_RESOURCE_FILES_RELATIVE} @java_class_filelist
734             COMMAND ${CMAKE_COMMAND}
735                 -D_JAVA_TARGET_DIR=${_add_jar_OUTPUT_DIR}
736                 -D_JAVA_TARGET_OUTPUT_NAME=${_JAVA_TARGET_OUTPUT_NAME}
737                 -D_JAVA_TARGET_OUTPUT_LINK=${_JAVA_TARGET_OUTPUT_LINK}
738                 -P ${_JAVA_SYMLINK_SCRIPT}
739             WORKING_DIRECTORY ${CMAKE_JAVA_CLASS_OUTPUT_PATH}
740             DEPENDS ${_JAVA_RESOURCE_FILES} ${_JAVA_DEPENDS} ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_class_filelist
741             COMMENT "Creating Java archive ${_JAVA_TARGET_OUTPUT_NAME}"
742         )
743     endif ()
744
745     # Add the target and make sure we have the latest resource files.
746     add_custom_target(${_TARGET_NAME} ALL DEPENDS ${_JAVA_JAR_OUTPUT_PATH})
747
748     set_property(
749         TARGET
750             ${_TARGET_NAME}
751         PROPERTY
752             INSTALL_FILES
753                 ${_JAVA_JAR_OUTPUT_PATH}
754     )
755
756     if (_JAVA_TARGET_OUTPUT_LINK)
757         set_property(
758             TARGET
759                 ${_TARGET_NAME}
760             PROPERTY
761                 INSTALL_FILES
762                     ${_JAVA_JAR_OUTPUT_PATH}
763                     ${_add_jar_OUTPUT_DIR}/${_JAVA_TARGET_OUTPUT_LINK}
764         )
765
766         if (CMAKE_JNI_TARGET)
767             set_property(
768                 TARGET
769                     ${_TARGET_NAME}
770                 PROPERTY
771                     JNI_SYMLINK
772                         ${_add_jar_OUTPUT_DIR}/${_JAVA_TARGET_OUTPUT_LINK}
773             )
774         endif ()
775     endif ()
776
777     set_property(
778         TARGET
779             ${_TARGET_NAME}
780         PROPERTY
781             JAR_FILE
782                 ${_JAVA_JAR_OUTPUT_PATH}
783     )
784
785     set_property(
786         TARGET
787             ${_TARGET_NAME}
788         PROPERTY
789             CLASSDIR
790                 ${CMAKE_JAVA_CLASS_OUTPUT_PATH}
791     )
792
793   if (_GENERATE_NATIVE_HEADERS)
794     # create an INTERFACE library encapsulating include directory for generated headers
795     add_library (${_GENERATE_NATIVE_HEADERS_TARGET} INTERFACE)
796     target_include_directories (${_GENERATE_NATIVE_HEADERS_TARGET} INTERFACE
797       "${_GENERATE_NATIVE_HEADERS_OUTPUT_DIR}"
798       ${JNI_INCLUDE_DIRS})
799     # this INTERFACE library depends on jar generation
800     add_dependencies (${_GENERATE_NATIVE_HEADERS_TARGET} ${_TARGET_NAME})
801
802     set_property (DIRECTORY PROPERTY ADDITIONAL_MAKE_CLEAN_FILES "${_GENERATE_NATIVE_HEADERS_OUTPUT_DIR}")
803   endif()
804 endfunction()
805
806 function(INSTALL_JAR _TARGET_NAME)
807     if (ARGC EQUAL 2)
808       set (_DESTINATION ${ARGV1})
809     else()
810       cmake_parse_arguments(_install_jar
811         ""
812         "DESTINATION;COMPONENT"
813         ""
814         ${ARGN})
815       if (_install_jar_DESTINATION)
816         set (_DESTINATION ${_install_jar_DESTINATION})
817       else()
818         message(SEND_ERROR "install_jar: ${_TARGET_NAME}: DESTINATION must be specified.")
819       endif()
820
821       if (_install_jar_COMPONENT)
822         set (_COMPONENT COMPONENT ${_install_jar_COMPONENT})
823       endif()
824     endif()
825
826     get_property(__FILES
827         TARGET
828             ${_TARGET_NAME}
829         PROPERTY
830             INSTALL_FILES
831     )
832     set_property(
833         TARGET
834             ${_TARGET_NAME}
835         PROPERTY
836             INSTALL_DESTINATION
837             ${_DESTINATION}
838     )
839
840     if (__FILES)
841         install(
842             FILES
843                 ${__FILES}
844             DESTINATION
845                 ${_DESTINATION}
846             ${_COMPONENT}
847         )
848     else ()
849         message(SEND_ERROR "install_jar: The target ${_TARGET_NAME} is not known in this scope.")
850     endif ()
851 endfunction()
852
853 function(INSTALL_JNI_SYMLINK _TARGET_NAME)
854     if (ARGC EQUAL 2)
855       set (_DESTINATION ${ARGV1})
856     else()
857       cmake_parse_arguments(_install_jni_symlink
858         ""
859         "DESTINATION;COMPONENT"
860         ""
861         ${ARGN})
862       if (_install_jni_symlink_DESTINATION)
863         set (_DESTINATION ${_install_jni_symlink_DESTINATION})
864       else()
865         message(SEND_ERROR "install_jni_symlink: ${_TARGET_NAME}: DESTINATION must be specified.")
866       endif()
867
868       if (_install_jni_symlink_COMPONENT)
869         set (_COMPONENT COMPONENT ${_install_jni_symlink_COMPONENT})
870       endif()
871     endif()
872
873     get_property(__SYMLINK
874         TARGET
875             ${_TARGET_NAME}
876         PROPERTY
877             JNI_SYMLINK
878     )
879
880     if (__SYMLINK)
881         install(
882             FILES
883                 ${__SYMLINK}
884             DESTINATION
885                 ${_DESTINATION}
886             ${_COMPONENT}
887         )
888     else ()
889         message(SEND_ERROR "install_jni_symlink: The target ${_TARGET_NAME} is not known in this scope.")
890     endif ()
891 endfunction()
892
893 function (find_jar VARIABLE)
894     set(_jar_names)
895     set(_jar_files)
896     set(_jar_versions)
897     set(_jar_paths
898         /usr/share/java/
899         /usr/local/share/java/
900         ${Java_JAR_PATHS})
901     set(_jar_doc "NOTSET")
902
903     set(_state "name")
904
905     foreach (arg ${ARGN})
906         if (${_state} STREQUAL "name")
907             if (${arg} STREQUAL "VERSIONS")
908                 set(_state "versions")
909             elseif (${arg} STREQUAL "NAMES")
910                 set(_state "names")
911             elseif (${arg} STREQUAL "PATHS")
912                 set(_state "paths")
913             elseif (${arg} STREQUAL "DOC")
914                 set(_state "doc")
915             else ()
916                 set(_jar_names ${arg})
917                 if (_jar_doc STREQUAL "NOTSET")
918                     set(_jar_doc "Finding ${arg} jar")
919                 endif ()
920             endif ()
921         elseif (${_state} STREQUAL "versions")
922             if (${arg} STREQUAL "NAMES")
923                 set(_state "names")
924             elseif (${arg} STREQUAL "PATHS")
925                 set(_state "paths")
926             elseif (${arg} STREQUAL "DOC")
927                 set(_state "doc")
928             else ()
929                 set(_jar_versions ${_jar_versions} ${arg})
930             endif ()
931         elseif (${_state} STREQUAL "names")
932             if (${arg} STREQUAL "VERSIONS")
933                 set(_state "versions")
934             elseif (${arg} STREQUAL "PATHS")
935                 set(_state "paths")
936             elseif (${arg} STREQUAL "DOC")
937                 set(_state "doc")
938             else ()
939                 set(_jar_names ${_jar_names} ${arg})
940                 if (_jar_doc STREQUAL "NOTSET")
941                     set(_jar_doc "Finding ${arg} jar")
942                 endif ()
943             endif ()
944         elseif (${_state} STREQUAL "paths")
945             if (${arg} STREQUAL "VERSIONS")
946                 set(_state "versions")
947             elseif (${arg} STREQUAL "NAMES")
948                 set(_state "names")
949             elseif (${arg} STREQUAL "DOC")
950                 set(_state "doc")
951             else ()
952                 set(_jar_paths ${_jar_paths} ${arg})
953             endif ()
954         elseif (${_state} STREQUAL "doc")
955             if (${arg} STREQUAL "VERSIONS")
956                 set(_state "versions")
957             elseif (${arg} STREQUAL "NAMES")
958                 set(_state "names")
959             elseif (${arg} STREQUAL "PATHS")
960                 set(_state "paths")
961             else ()
962                 set(_jar_doc ${arg})
963             endif ()
964         endif ()
965     endforeach ()
966
967     if (NOT _jar_names)
968         message(FATAL_ERROR "find_jar: No name to search for given")
969     endif ()
970
971     foreach (jar_name ${_jar_names})
972         foreach (version ${_jar_versions})
973             set(_jar_files ${_jar_files} ${jar_name}-${version}.jar)
974         endforeach ()
975         set(_jar_files ${_jar_files} ${jar_name}.jar)
976     endforeach ()
977
978     find_file(${VARIABLE}
979         NAMES   ${_jar_files}
980         PATHS   ${_jar_paths}
981         DOC     ${_jar_doc}
982         NO_DEFAULT_PATH)
983 endfunction ()
984
985 function(create_javadoc _target)
986     set(_javadoc_packages)
987     set(_javadoc_files)
988     set(_javadoc_sourcepath)
989     set(_javadoc_classpath)
990     set(_javadoc_installpath "${CMAKE_INSTALL_PREFIX}/share/javadoc")
991     set(_javadoc_doctitle)
992     set(_javadoc_windowtitle)
993     set(_javadoc_author FALSE)
994     set(_javadoc_version FALSE)
995     set(_javadoc_use FALSE)
996
997     set(_state "package")
998
999     foreach (arg ${ARGN})
1000         if (${_state} STREQUAL "package")
1001             if (${arg} STREQUAL "PACKAGES")
1002                 set(_state "packages")
1003             elseif (${arg} STREQUAL "FILES")
1004                 set(_state "files")
1005             elseif (${arg} STREQUAL "SOURCEPATH")
1006                 set(_state "sourcepath")
1007             elseif (${arg} STREQUAL "CLASSPATH")
1008                 set(_state "classpath")
1009             elseif (${arg} STREQUAL "INSTALLPATH")
1010                 set(_state "installpath")
1011             elseif (${arg} STREQUAL "DOCTITLE")
1012                 set(_state "doctitle")
1013             elseif (${arg} STREQUAL "WINDOWTITLE")
1014                 set(_state "windowtitle")
1015             elseif (${arg} STREQUAL "AUTHOR")
1016                 set(_state "author")
1017             elseif (${arg} STREQUAL "USE")
1018                 set(_state "use")
1019             elseif (${arg} STREQUAL "VERSION")
1020                 set(_state "version")
1021             else ()
1022                 set(_javadoc_packages ${arg})
1023                 set(_state "packages")
1024             endif ()
1025         elseif (${_state} STREQUAL "packages")
1026             if (${arg} STREQUAL "FILES")
1027                 set(_state "files")
1028             elseif (${arg} STREQUAL "SOURCEPATH")
1029                 set(_state "sourcepath")
1030             elseif (${arg} STREQUAL "CLASSPATH")
1031                 set(_state "classpath")
1032             elseif (${arg} STREQUAL "INSTALLPATH")
1033                 set(_state "installpath")
1034             elseif (${arg} STREQUAL "DOCTITLE")
1035                 set(_state "doctitle")
1036             elseif (${arg} STREQUAL "WINDOWTITLE")
1037                 set(_state "windowtitle")
1038             elseif (${arg} STREQUAL "AUTHOR")
1039                 set(_state "author")
1040             elseif (${arg} STREQUAL "USE")
1041                 set(_state "use")
1042             elseif (${arg} STREQUAL "VERSION")
1043                 set(_state "version")
1044             else ()
1045                 list(APPEND _javadoc_packages ${arg})
1046             endif ()
1047         elseif (${_state} STREQUAL "files")
1048             if (${arg} STREQUAL "PACKAGES")
1049                 set(_state "packages")
1050             elseif (${arg} STREQUAL "SOURCEPATH")
1051                 set(_state "sourcepath")
1052             elseif (${arg} STREQUAL "CLASSPATH")
1053                 set(_state "classpath")
1054             elseif (${arg} STREQUAL "INSTALLPATH")
1055                 set(_state "installpath")
1056             elseif (${arg} STREQUAL "DOCTITLE")
1057                 set(_state "doctitle")
1058             elseif (${arg} STREQUAL "WINDOWTITLE")
1059                 set(_state "windowtitle")
1060             elseif (${arg} STREQUAL "AUTHOR")
1061                 set(_state "author")
1062             elseif (${arg} STREQUAL "USE")
1063                 set(_state "use")
1064             elseif (${arg} STREQUAL "VERSION")
1065                 set(_state "version")
1066             else ()
1067                 list(APPEND _javadoc_files ${arg})
1068             endif ()
1069         elseif (${_state} STREQUAL "sourcepath")
1070             if (${arg} STREQUAL "PACKAGES")
1071                 set(_state "packages")
1072             elseif (${arg} STREQUAL "FILES")
1073                 set(_state "files")
1074             elseif (${arg} STREQUAL "CLASSPATH")
1075                 set(_state "classpath")
1076             elseif (${arg} STREQUAL "INSTALLPATH")
1077                 set(_state "installpath")
1078             elseif (${arg} STREQUAL "DOCTITLE")
1079                 set(_state "doctitle")
1080             elseif (${arg} STREQUAL "WINDOWTITLE")
1081                 set(_state "windowtitle")
1082             elseif (${arg} STREQUAL "AUTHOR")
1083                 set(_state "author")
1084             elseif (${arg} STREQUAL "USE")
1085                 set(_state "use")
1086             elseif (${arg} STREQUAL "VERSION")
1087                 set(_state "version")
1088             else ()
1089                 list(APPEND _javadoc_sourcepath ${arg})
1090             endif ()
1091         elseif (${_state} STREQUAL "classpath")
1092             if (${arg} STREQUAL "PACKAGES")
1093                 set(_state "packages")
1094             elseif (${arg} STREQUAL "FILES")
1095                 set(_state "files")
1096             elseif (${arg} STREQUAL "SOURCEPATH")
1097                 set(_state "sourcepath")
1098             elseif (${arg} STREQUAL "INSTALLPATH")
1099                 set(_state "installpath")
1100             elseif (${arg} STREQUAL "DOCTITLE")
1101                 set(_state "doctitle")
1102             elseif (${arg} STREQUAL "WINDOWTITLE")
1103                 set(_state "windowtitle")
1104             elseif (${arg} STREQUAL "AUTHOR")
1105                 set(_state "author")
1106             elseif (${arg} STREQUAL "USE")
1107                 set(_state "use")
1108             elseif (${arg} STREQUAL "VERSION")
1109                 set(_state "version")
1110             else ()
1111                 list(APPEND _javadoc_classpath ${arg})
1112             endif ()
1113         elseif (${_state} STREQUAL "installpath")
1114             if (${arg} STREQUAL "PACKAGES")
1115                 set(_state "packages")
1116             elseif (${arg} STREQUAL "FILES")
1117                 set(_state "files")
1118             elseif (${arg} STREQUAL "SOURCEPATH")
1119                 set(_state "sourcepath")
1120             elseif (${arg} STREQUAL "DOCTITLE")
1121                 set(_state "doctitle")
1122             elseif (${arg} STREQUAL "WINDOWTITLE")
1123                 set(_state "windowtitle")
1124             elseif (${arg} STREQUAL "AUTHOR")
1125                 set(_state "author")
1126             elseif (${arg} STREQUAL "USE")
1127                 set(_state "use")
1128             elseif (${arg} STREQUAL "VERSION")
1129                 set(_state "version")
1130             else ()
1131                 set(_javadoc_installpath ${arg})
1132             endif ()
1133         elseif (${_state} STREQUAL "doctitle")
1134             if (${arg} STREQUAL "PACKAGES")
1135                 set(_state "packages")
1136             elseif (${arg} STREQUAL "FILES")
1137                 set(_state "files")
1138             elseif (${arg} STREQUAL "SOURCEPATH")
1139                 set(_state "sourcepath")
1140             elseif (${arg} STREQUAL "INSTALLPATH")
1141                 set(_state "installpath")
1142             elseif (${arg} STREQUAL "CLASSPATH")
1143                 set(_state "classpath")
1144             elseif (${arg} STREQUAL "WINDOWTITLE")
1145                 set(_state "windowtitle")
1146             elseif (${arg} STREQUAL "AUTHOR")
1147                 set(_state "author")
1148             elseif (${arg} STREQUAL "USE")
1149                 set(_state "use")
1150             elseif (${arg} STREQUAL "VERSION")
1151                 set(_state "version")
1152             else ()
1153                 set(_javadoc_doctitle ${arg})
1154             endif ()
1155         elseif (${_state} STREQUAL "windowtitle")
1156             if (${arg} STREQUAL "PACKAGES")
1157                 set(_state "packages")
1158             elseif (${arg} STREQUAL "FILES")
1159                 set(_state "files")
1160             elseif (${arg} STREQUAL "SOURCEPATH")
1161                 set(_state "sourcepath")
1162             elseif (${arg} STREQUAL "CLASSPATH")
1163                 set(_state "classpath")
1164             elseif (${arg} STREQUAL "INSTALLPATH")
1165                 set(_state "installpath")
1166             elseif (${arg} STREQUAL "DOCTITLE")
1167                 set(_state "doctitle")
1168             elseif (${arg} STREQUAL "AUTHOR")
1169                 set(_state "author")
1170             elseif (${arg} STREQUAL "USE")
1171                 set(_state "use")
1172             elseif (${arg} STREQUAL "VERSION")
1173                 set(_state "version")
1174             else ()
1175                 set(_javadoc_windowtitle ${arg})
1176             endif ()
1177         elseif (${_state} STREQUAL "author")
1178             if (${arg} STREQUAL "PACKAGES")
1179                 set(_state "packages")
1180             elseif (${arg} STREQUAL "FILES")
1181                 set(_state "files")
1182             elseif (${arg} STREQUAL "SOURCEPATH")
1183                 set(_state "sourcepath")
1184             elseif (${arg} STREQUAL "CLASSPATH")
1185                 set(_state "classpath")
1186             elseif (${arg} STREQUAL "INSTALLPATH")
1187                 set(_state "installpath")
1188             elseif (${arg} STREQUAL "DOCTITLE")
1189                 set(_state "doctitle")
1190             elseif (${arg} STREQUAL "WINDOWTITLE")
1191                 set(_state "windowtitle")
1192             elseif (${arg} STREQUAL "AUTHOR")
1193                 set(_state "author")
1194             elseif (${arg} STREQUAL "USE")
1195                 set(_state "use")
1196             elseif (${arg} STREQUAL "VERSION")
1197                 set(_state "version")
1198             else ()
1199                 set(_javadoc_author ${arg})
1200             endif ()
1201         elseif (${_state} STREQUAL "use")
1202             if (${arg} STREQUAL "PACKAGES")
1203                 set(_state "packages")
1204             elseif (${arg} STREQUAL "FILES")
1205                 set(_state "files")
1206             elseif (${arg} STREQUAL "SOURCEPATH")
1207                 set(_state "sourcepath")
1208             elseif (${arg} STREQUAL "CLASSPATH")
1209                 set(_state "classpath")
1210             elseif (${arg} STREQUAL "INSTALLPATH")
1211                 set(_state "installpath")
1212             elseif (${arg} STREQUAL "DOCTITLE")
1213                 set(_state "doctitle")
1214             elseif (${arg} STREQUAL "WINDOWTITLE")
1215                 set(_state "windowtitle")
1216             elseif (${arg} STREQUAL "AUTHOR")
1217                 set(_state "author")
1218             elseif (${arg} STREQUAL "USE")
1219                 set(_state "use")
1220             elseif (${arg} STREQUAL "VERSION")
1221                 set(_state "version")
1222             else ()
1223                 set(_javadoc_use ${arg})
1224             endif ()
1225         elseif (${_state} STREQUAL "version")
1226             if (${arg} STREQUAL "PACKAGES")
1227                 set(_state "packages")
1228             elseif (${arg} STREQUAL "FILES")
1229                 set(_state "files")
1230             elseif (${arg} STREQUAL "SOURCEPATH")
1231                 set(_state "sourcepath")
1232             elseif (${arg} STREQUAL "CLASSPATH")
1233                 set(_state "classpath")
1234             elseif (${arg} STREQUAL "INSTALLPATH")
1235                 set(_state "installpath")
1236             elseif (${arg} STREQUAL "DOCTITLE")
1237                 set(_state "doctitle")
1238             elseif (${arg} STREQUAL "WINDOWTITLE")
1239                 set(_state "windowtitle")
1240             elseif (${arg} STREQUAL "AUTHOR")
1241                 set(_state "author")
1242             elseif (${arg} STREQUAL "USE")
1243                 set(_state "use")
1244             elseif (${arg} STREQUAL "VERSION")
1245                 set(_state "version")
1246             else ()
1247                 set(_javadoc_version ${arg})
1248             endif ()
1249         endif ()
1250     endforeach ()
1251
1252     set(_javadoc_builddir ${CMAKE_CURRENT_BINARY_DIR}/javadoc/${_target})
1253     set(_javadoc_options -d ${_javadoc_builddir})
1254
1255     if (_javadoc_sourcepath)
1256         set(_start TRUE)
1257         foreach(_path ${_javadoc_sourcepath})
1258             if (_start)
1259                 set(_sourcepath ${_path})
1260                 set(_start FALSE)
1261             else ()
1262                 set(_sourcepath ${_sourcepath}:${_path})
1263             endif ()
1264         endforeach()
1265         set(_javadoc_options ${_javadoc_options} -sourcepath ${_sourcepath})
1266     endif ()
1267
1268     if (_javadoc_classpath)
1269         set(_start TRUE)
1270         foreach(_path ${_javadoc_classpath})
1271             if (_start)
1272                 set(_classpath ${_path})
1273                 set(_start FALSE)
1274             else ()
1275                 set(_classpath ${_classpath}:${_path})
1276             endif ()
1277         endforeach()
1278         set(_javadoc_options ${_javadoc_options} -classpath "${_classpath}")
1279     endif ()
1280
1281     if (_javadoc_doctitle)
1282         set(_javadoc_options ${_javadoc_options} -doctitle '${_javadoc_doctitle}')
1283     endif ()
1284
1285     if (_javadoc_windowtitle)
1286         set(_javadoc_options ${_javadoc_options} -windowtitle '${_javadoc_windowtitle}')
1287     endif ()
1288
1289     if (_javadoc_author)
1290         set(_javadoc_options ${_javadoc_options} -author)
1291     endif ()
1292
1293     if (_javadoc_use)
1294         set(_javadoc_options ${_javadoc_options} -use)
1295     endif ()
1296
1297     if (_javadoc_version)
1298         set(_javadoc_options ${_javadoc_options} -version)
1299     endif ()
1300
1301     add_custom_target(${_target}_javadoc ALL
1302         COMMAND ${Java_JAVADOC_EXECUTABLE} ${_javadoc_options}
1303                             ${_javadoc_files}
1304                             ${_javadoc_packages}
1305         WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
1306     )
1307
1308     install(
1309         DIRECTORY ${_javadoc_builddir}
1310         DESTINATION ${_javadoc_installpath}
1311     )
1312 endfunction()
1313
1314 function (create_javah)
1315   if ("${Java_VERSION}" VERSION_GREATER_EQUAL 1.10)
1316     message (FATAL_ERROR "create_javah: not supported with this Java version. Use add_jar(GENERATE_NATIVE_HEADERS) instead.")
1317   elseif ("${Java_VERSION}" VERSION_GREATER_EQUAL 1.8)
1318     message (DEPRECATION "create_javah: this command will no longer be supported starting with version 1.10 of JDK. Update your project by using command add_jar(GENERATE_NATIVE_HEADERS) instead.")
1319   endif()
1320
1321     cmake_parse_arguments(_create_javah
1322       ""
1323       "TARGET;GENERATED_FILES;OUTPUT_NAME;OUTPUT_DIR"
1324       "CLASSES;CLASSPATH;DEPENDS"
1325       ${ARGN})
1326
1327     # ckeck parameters
1328     if (NOT _create_javah_TARGET AND NOT _create_javah_GENERATED_FILES)
1329       message (FATAL_ERROR "create_javah: TARGET or GENERATED_FILES must be specified.")
1330     endif()
1331     if (_create_javah_OUTPUT_NAME AND _create_javah_OUTPUT_DIR)
1332       message (FATAL_ERROR "create_javah: OUTPUT_NAME and OUTPUT_DIR are mutually exclusive.")
1333     endif()
1334
1335     if (NOT _create_javah_CLASSES)
1336       message (FATAL_ERROR "create_javah: CLASSES is a required parameter.")
1337     endif()
1338
1339     set (_output_files)
1340     if (WIN32 AND NOT CYGWIN AND CMAKE_HOST_SYSTEM_NAME MATCHES "Windows")
1341       set(_classpath_sep "$<SEMICOLON>")
1342     else ()
1343       set(_classpath_sep ":")
1344     endif()
1345
1346     # handle javah options
1347     set (_javah_options)
1348
1349     if (_create_javah_CLASSPATH)
1350       # CLASSPATH can specify directories, jar files or targets created with add_jar command
1351       set (_classpath)
1352       foreach (_path IN LISTS _create_javah_CLASSPATH)
1353         if (TARGET ${_path})
1354           get_target_property (_jar_path ${_path} JAR_FILE)
1355           if (_jar_path)
1356             list (APPEND _classpath "${_jar_path}")
1357             list (APPEND _create_javah_DEPENDS "${_path}")
1358           else()
1359             message(SEND_ERROR "create_javah: CLASSPATH target ${_path} is not a jar.")
1360           endif()
1361         elseif (EXISTS "${_path}")
1362           list (APPEND _classpath "${_path}")
1363           if (NOT IS_DIRECTORY "${_path}")
1364             list (APPEND _create_javah_DEPENDS "${_path}")
1365           endif()
1366         else()
1367           message(SEND_ERROR "create_javah: CLASSPATH entry ${_path} does not exist.")
1368         endif()
1369       endforeach()
1370       string (REPLACE ";" "${_classpath_sep}" _classpath "${_classpath}")
1371       list (APPEND _javah_options -classpath "${_classpath}")
1372     endif()
1373
1374     if (_create_javah_OUTPUT_DIR)
1375       list (APPEND _javah_options -d "${_create_javah_OUTPUT_DIR}")
1376     endif()
1377
1378     if (_create_javah_OUTPUT_NAME)
1379       list (APPEND _javah_options -o "${_create_javah_OUTPUT_NAME}")
1380       set (_output_files "${_create_javah_OUTPUT_NAME}")
1381
1382       get_filename_component (_create_javah_OUTPUT_DIR "${_create_javah_OUTPUT_NAME}" DIRECTORY)
1383       get_filename_component (_create_javah_OUTPUT_DIR "${_create_javah_OUTPUT_DIR}" ABSOLUTE)
1384     endif()
1385
1386     if (NOT _create_javah_OUTPUT_DIR)
1387       set (_create_javah_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}")
1388     endif()
1389
1390     if (NOT _create_javah_OUTPUT_NAME)
1391       # compute output names
1392       foreach (_class IN LISTS _create_javah_CLASSES)
1393         string (REPLACE "." "_" _c_header "${_class}")
1394         set (_c_header  "${_create_javah_OUTPUT_DIR}/${_c_header}.h")
1395         list (APPEND _output_files "${_c_header}")
1396       endforeach()
1397     endif()
1398
1399     # finalize custom command arguments
1400     if (_create_javah_DEPENDS)
1401       list (INSERT _create_javah_DEPENDS 0 DEPENDS)
1402     endif()
1403
1404     add_custom_command (OUTPUT ${_output_files}
1405       COMMAND "${Java_JAVAH_EXECUTABLE}" ${_javah_options} -jni ${_create_javah_CLASSES}
1406       ${_create_javah_DEPENDS}
1407       WORKING_DIRECTORY ${_create_javah_OUTPUT_DIR}
1408       COMMENT "Building C header files from classes...")
1409
1410     if (_create_javah_TARGET)
1411       add_custom_target (${_create_javah_TARGET} ALL DEPENDS ${_output_files})
1412     endif()
1413     if (_create_javah_GENERATED_FILES)
1414       set (${_create_javah_GENERATED_FILES} ${_output_files} PARENT_SCOPE)
1415     endif()
1416 endfunction()
1417
1418 function(export_jars)
1419     # Parse and validate arguments
1420     cmake_parse_arguments(_export_jars
1421       ""
1422       "FILE;NAMESPACE"
1423       "TARGETS"
1424       ${ARGN}
1425     )
1426     if (NOT _export_jars_FILE)
1427       message(SEND_ERROR "export_jars: FILE must be specified.")
1428     endif()
1429     if (NOT _export_jars_TARGETS)
1430       message(SEND_ERROR "export_jars: TARGETS must be specified.")
1431     endif()
1432     set(_jar_NAMESPACE "${_export_jars_NAMESPACE}")
1433
1434     # Set content of generated exports file
1435     string(REPLACE ";" " " __targets__ "${_export_jars_TARGETS}")
1436     set(__targetdefs__ "")
1437     foreach(_target ${_export_jars_TARGETS})
1438         get_target_property(_jarpath ${_target} JAR_FILE)
1439         get_filename_component(_jarpath ${_jarpath} PATH)
1440         __java_export_jar(__targetdefs__ ${_target} "${_jarpath}")
1441     endforeach()
1442
1443     # Generate exports file
1444     configure_file(
1445       ${_JAVA_EXPORT_TARGETS_SCRIPT}
1446       ${_export_jars_FILE}
1447       @ONLY
1448     )
1449 endfunction()
1450
1451 function(install_jar_exports)
1452     # Parse and validate arguments
1453     cmake_parse_arguments(_install_jar_exports
1454       ""
1455       "FILE;DESTINATION;COMPONENT;NAMESPACE"
1456       "TARGETS"
1457       ${ARGN}
1458     )
1459     if (NOT _install_jar_exports_FILE)
1460       message(SEND_ERROR "install_jar_exports: FILE must be specified.")
1461     endif()
1462     if (NOT _install_jar_exports_DESTINATION)
1463       message(SEND_ERROR "install_jar_exports: DESTINATION must be specified.")
1464     endif()
1465     if (NOT _install_jar_exports_TARGETS)
1466       message(SEND_ERROR "install_jar_exports: TARGETS must be specified.")
1467     endif()
1468     set(_jar_NAMESPACE "${_install_jar_exports_NAMESPACE}")
1469
1470     if (_install_jar_exports_COMPONENT)
1471       set (_COMPONENT COMPONENT ${_install_jar_exports_COMPONENT})
1472     endif()
1473
1474     # Determine relative path from installed export file to install prefix
1475     if(IS_ABSOLUTE ${_install_jar_exports_DESTINATION})
1476       file(RELATIVE_PATH _relpath
1477         ${_install_jar_exports_DESTINATION}
1478         ${CMAKE_INSTALL_PREFIX}
1479       )
1480     else()
1481       file(RELATIVE_PATH _relpath
1482         ${CMAKE_INSTALL_PREFIX}/${_install_jar_exports_DESTINATION}
1483         ${CMAKE_INSTALL_PREFIX}
1484       )
1485     endif()
1486
1487     # Set up unique location for generated exports file
1488     string(SHA256 _hash "${_install_jar_exports_DESTINATION}")
1489     set(_tmpdir ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/JavaExports/${_hash})
1490
1491     # Set content of generated exports file
1492     string(REPLACE ";" " " __targets__ "${_install_jar_exports_TARGETS}")
1493     set(__targetdefs__ "set(_prefix \${CMAKE_CURRENT_LIST_DIR}/${_relpath})\n\n")
1494     foreach(_target ${_install_jar_exports_TARGETS})
1495         get_target_property(_dir ${_target} INSTALL_DESTINATION)
1496         __java_export_jar(__targetdefs__ ${_target} "\${_prefix}/${_dir}")
1497     endforeach()
1498     __java_lcat(__targetdefs__ "\nunset(_prefix)")
1499
1500     # Generate and install exports file
1501     configure_file(
1502       ${_JAVA_EXPORT_TARGETS_SCRIPT}
1503       ${_tmpdir}/${_install_jar_exports_FILE}
1504       @ONLY
1505     )
1506     install(FILES ${_tmpdir}/${_install_jar_exports_FILE}
1507             DESTINATION ${_install_jar_exports_DESTINATION}
1508             ${_COMPONENT})
1509 endfunction()