BASIS  r3148
FindWeka.cmake
Go to the documentation of this file.
00001 ##############################################################################
00002 # @file  FindWeka.cmake
00003 # @brief Find Weka (http://www.cs.waikato.ac.nz/ml/weka/) package.
00004 #
00005 # @par Input variables:
00006 # <table border="0">
00007 #   <tr>
00008 #     @tp @b Weka_DIR @endtp
00009 #     <td>The Weka package files are searched under the specified root
00010 #         directory. If they are not found there, the default search paths
00011 #         are considered. This variable can also be set as environment variable.</td>
00012 #   </tr>
00013 #   <tr>
00014 #     @tp @b WEKA_DIR @endtp
00015 #     <td>Alternative environment variable for @c Weka_DIR.</td>
00016 #   </tr>
00017 #   <tr>
00018 #     @tp @b Weka_PACKAGES_DIR @endtp
00019 #     <td>Directory where additional Weka packages are installed. If they are
00020 #         not found there or if this variable is not set, this module will look
00021 #         in the standard installation directories. This variable can also be set
00022 #         as environment variable.</td>
00023 #   </tr>
00024 #   <tr>
00025 #     @tp @b WEKA_PACKAGES_DIR @endtp
00026 #     <td>Alternative environment variable for @c Weka_PACKAGES_DIR.</td>
00027 #   </tr>
00028 #   <tr>
00029 #     @tp <b>Weka_&lt;package&gt;_DIR</b> @endtp
00030 #     <td>The path of the given Weka package, i.e., the directory containing the
00031 #         <tt>&lt;package&gt;.jar</tt> file or a subdirectory named <tt>weka</tt>
00032 #         with the uncompressed <tt>.class</tt> files of the package.</td>
00033 #   </tr>
00034 #   <tr>
00035 #     @tp @b Weka_FIND_COMPONENTS @endtp
00036 #     <td>The @c COMPONENTS argument(s) of the find_package() command can
00037 #         be used to also look for additionally installed Weka packages.</td>
00038 #   </tr>
00039 #   <tr>
00040 #     @tp @b Weka_FIND_OPTIONAL_COMPONENTS @endtp
00041 #     <td>The @c OPTIONAL_COMPONENTS argument(s) of the find_package() command can
00042 #         be used to also look for additionally installed Weka packages.</td>
00043 #   </tr>
00044 #   <tr>
00045 #     @tp @b Weka_ADDITIONAL_VERSIONS @endtp
00046 #     <td>List of version numbers that should be taken into account when
00047 #         searching for Weka.</td>
00048 #   </tr>
00049 # </table>
00050 #
00051 # @par Output variables:
00052 # <table border="0">
00053 #   <tr>
00054 #     @tp @b Weka_FOUND @endtp
00055 #     <td>Whether the package was found and the following CMake variables are valid.</td>
00056 #   </tr>
00057 #   <tr>
00058 #     @tp @b Weka_HAS_PACKAGE_MANAGER @endtp
00059 #     <td>Whether the found version of Weka has a package manager.</td>
00060 #   </tr>
00061 #   <tr>
00062 #     @tp @b Weka_CLASSPATH @endtp
00063 #     <td>The path of the found <tt>weka.jar</tt> file.</td>
00064 #   </tr>
00065 #   <tr>
00066 #     @tp @b Weka_PACKAGES_CLASSPATH @endtp
00067 #     <td>The @c CLASSPATH of all found additional Weka packages (non-cached).</td>
00068 #   </tr>
00069 #   <tr>
00070 #     @tp @b Weka_CLASSPATHS @endtp
00071 #     <td>Combination of both @c Weka_CLASSPATH and @c Weka_PACKAGES_CLASSPATH.</td>
00072 #   </tr>
00073 # </table>
00074 #
00075 # Copyright (c) 2012 University of Pennsylvania. All rights reserved.<br />
00076 # See https://www.cbica.upenn.edu/sbia/software/license.html or COPYING file.
00077 #
00078 # Contact: SBIA Group <sbia-software at uphs.upenn.edu>
00079 #
00080 # @ingroup CMakeFindModules
00081 ##############################################################################
00082 
00083 # ============================================================================
00084 # helpers
00085 # ============================================================================
00086 
00087 # ----------------------------------------------------------------------------
00088 # @brief Determine if this Weka version has a package manager.
00089 #
00090 # @returns This macro sets the Weka_HAS_PACKAGE_MANAGER variable.
00091 macro (weka_has_package_manager)
00092   if (Weka_VERSION_MAJOR AND Weka_VERSION_MINOR)
00093     if (Weka_VERSION_MAJOR EQUAL 3)
00094       if (Weka_VERSION_MINOR GREATER 7 OR (Weka_VERSION_MINOR EQUAL 7 AND Weka_VERSION_PATCH GREATER 1))
00095         set (Weka_HAS_PACKAGE_MANAGER TRUE)
00096       else ()
00097         set (Weka_HAS_PACKAGE_MANAGER FALSE)
00098       endif ()
00099     elseif (Weka_VERSION_MAJOR GREATER 2)
00100       set (Weka_HAS_PACKAGE_MANAGER TRUE)
00101     else ()
00102       set (Weka_HAS_PACKAGE_MANAGER FALSE)
00103     endif ()
00104   else ()
00105     set (Weka_HAS_PACKAGE_MANAGER TRUE)
00106   endif ()
00107 endmacro ()
00108 
00109 # ----------------------------------------------------------------------------
00110 ## @brief Get list of Weka packages.
00111 #
00112 # @param [out] PACKAGES Name of variable storing the list of packages.
00113 # @param [in]  WHICH    Argument to -list-packages option of Weka package
00114 #                       manager, i.e., "all", "available", or "installed".
00115 function (weka_list_packages PACKAGES WHICH)
00116   string (TOLOWER "${WHICH}" WHICH) # ignore case of argument
00117   set (PKGS)
00118   if (NOT JAVA_EXECUTABLE)
00119     set (JAVA_EXECUTABLE java)
00120   endif ()
00121   if (Weka_VERSION_MAJOR AND Weka_VERSION_MINOR)
00122     if (Weka_VERSION_MAJOR EQUAL 3)
00123       if (Weka_VERSION_MINOR GREATER 7 OR (Weka_VERSION_MINOR EQUAL 7 AND Weka_VERSION_PATCH GREATER 1))
00124         set (HAS_PACKAGE_MANAGER TRUE)
00125       else ()
00126         set (HAS_PACKAGE_MANAGER FALSE)
00127       endif ()
00128     elseif (Weka_VERSION_MAJOR GREATER 2)
00129       set (HAS_PACKAGE_MANAGER TRUE)
00130     else ()
00131       set (HAS_PACKAGE_MANAGER FALSE)
00132     endif ()
00133   else ()
00134     set (HAS_PACKAGE_MANAGER TRUE)
00135   endif ()
00136   if (HAS_PACKAGE_MANAGER)
00137     if (Weka_CLASSPATH)
00138       execute_process (
00139         COMMAND "${JAVA_EXECUTABLE}"
00140                     -classpath "${Weka_CLASSPATH}"
00141                     weka.core.WekaPackageManager
00142                     -list-packages "${WHICH}"
00143         RESULT_VARIABLE STATUS
00144         OUTPUT_VARIABLE STDOUT
00145         ERROR_VARIABLE  STDERR
00146       )
00147       if (STATUS EQUAL 0)
00148         string (REPLACE ";"  "," STDOUT "${STDOUT}")
00149         string (REPLACE "\n" ";" STDOUT "${STDOUT}")
00150         foreach (LINE IN LISTS STDOUT)
00151           if (LINE MATCHES "^(-+|[0-9]+(\\.[0-9]+(\\.[0-9]+)))[ \t]+[0-9]+(\\.[0-9]+(\\.[0-9]+))[ \t]+([a-zA-Z_-]+):")
00152             list (APPEND PKGS "${CMAKE_MATCH_6}")
00153           endif ()
00154         endforeach ()
00155       else ()
00156         message (WARNING "Failed to retrieve list of ${WHICH} Weka packages! The command\n"
00157                          "\"${JAVA_EXECUTABLE}\" -classpath \"${Weka_CLASSPATH}\" weka.core.WekaPackageManager -list-packages ${WHICH}\n"
00158                          "failed with the error:\n${STDERR}")
00159       endif ()
00160     else ()
00161       message (WARNING "Cannot retrieve list of Weka packages because Weka_CLASSPATH is not set!")
00162     endif ()
00163   endif ()
00164   set (${PACKAGES} "${PKGS}" PARENT_SCOPE)
00165 endfunction ()
00166 
00167 # ----------------------------------------------------------------------------
00168 ## @brief Get Weka version.
00169 #
00170 # @param [out] VERSION Version string of Weka or 0.0.0.
00171 # @param [out] MAJOR   Major version of Weka or 0.
00172 # @param [out] MINOR   Minor version of Weka or 0.
00173 # @param [out] PATCH   Patch number of Weka or 0.
00174 function (weka_get_version VERSION MAJOR MINOR PATCH)
00175   set (VERSION_STRING "0.0.0")
00176   set (VERSION_MAJOR 0)
00177   set (VERSION_MINOR 0)
00178   set (VERSION_PATCH 0)
00179   if (NOT JAVA_EXECUTABLE)
00180     set (JAVA_EXECUTABLE java)
00181   endif ()
00182   if (Weka_CLASSPATH)
00183     execute_process (
00184       COMMAND "${JAVA_EXECUTABLE}" -classpath "${Weka_CLASSPATH}" weka.core.Version
00185       RESULT_VARIABLE RETVAL
00186       OUTPUT_VARIABLE STDOUT
00187       ERROR_VARIABLE  STDERR
00188     )
00189     if (STDOUT MATCHES "^([0-9]+)\\.([0-9]+)\\.([0-9]+)")
00190       set (VERSION_STRING "${CMAKE_MATCH_0}")
00191       set (VERSION_MAJOR  "${CMAKE_MATCH_1}")
00192       set (VERSION_MINOR  "${CMAKE_MATCH_2}")
00193       set (VERSION_PATCH  "${CMAKE_MATCH_3}")
00194     else ()
00195       message (WARNING "Failed to version of Weka installation. The command\n"
00196                        "\"${JAVA_EXECUTABLE}\" -classpath \"${Weka_CLASSPATH}\" weka.core.Version\n"
00197                        "failed with the error:\n${STDERR}")
00198     endif ()
00199   endif ()
00200   set (${VERSION} "${VERSION_STRING}" PARENT_SCOPE)
00201   set (${MAJOR}   "${VERSION_MAJOR}" PARENT_SCOPE)
00202   set (${MINOR}   "${VERSION_MINOR}" PARENT_SCOPE)
00203   set (${PATCH}   "${VERSION_PATCH}" PARENT_SCOPE)
00204 endfunction ()
00205 
00206 # ============================================================================
00207 # main
00208 # ============================================================================
00209 
00210 # ----------------------------------------------------------------------------
00211 # initialize search
00212 if (NOT Weka_DIR)
00213   if (NOT $ENV{WEKAHOME} STREQUAL "")
00214     set (Weka_DIR "$ENV{WEKAHOME}" CACHE PATH "Installation directory of Weka." FORCE)
00215   elseif (NOT $ENV{Weka_DIR} STREQUAL "")
00216     set (Weka_DIR "$ENV{Weka_DIR}" CACHE PATH "Installation directory of Weka." FORCE)
00217   else ()
00218     set (Weka_DIR "$ENV{WEKA_DIR}" CACHE PATH "Installation directory of Weka." FORCE)
00219   endif ()
00220 endif ()
00221 
00222 set (Weka_HINTS)
00223 if (CMAKE_HOST_APPLE)
00224   # TODO seach /Applications/weka-3-7-6.app/Contents and
00225   #      $ENV{HOME}/Applications/weka-3-7-6.app/Contents
00226   #      directories for all requested/known Weka versions
00227 endif ()
00228 string (REPLACE ":" ";" Weka_ENV_CLASSPATH "$ENV{CLASSPATH}")
00229 foreach (Weka_CLSDIR IN LISTS Weka_ENV_CLASSPATH)
00230   if (Weka_CLSDIR MATCHES "\\.jar")
00231     get_filename_component (Weka_CLSDIR "${Weka_CLSDIR}" PATH)
00232   endif ()
00233   list (APPEND Weka_HINTS "${Weka_CLSDIR}")
00234 endforeach ()
00235 unset (Weka_ENV_CLASSPATH)
00236 
00237 #-----------------------------------------------------------------------------
00238 # find weka.jar
00239 if (Weka_DIR)
00240   if (Weka_CLASSPATH AND NOT Weka_CLASSPATH MATCHES "^${Weka_DIR}/")
00241     set_property (CACHE Weka_CLASSPATH PROPERTY VALUE "Weka_CLASSPATH-NOTFOUND")
00242   endif ()
00243 
00244   find_file (
00245     Weka_CLASSPATH
00246     NAMES         weka.jar
00247     HINTS         "${Weka_DIR}"
00248     PATH_SUFFIXES "weka"
00249                   "Contents/Resources/Java"
00250                   "Resources/Java"
00251     DOC           "The Java library of the Weka package (weka.jar)."
00252     NO_DEFAULT_PATH
00253   )
00254 else ()
00255   find_file (
00256     Weka_CLASSPATH
00257     NAMES         weka.jar
00258     HINTS         ${Weka_HINTS}
00259     PATH_SUFFIXES "weka"
00260                   "Contents/Resources/Java"
00261                   "Resources/Java"
00262     DOC           "The Java library of the Weka package (weka.jar)."
00263   )
00264   if (Weka_CLASSPATH)
00265     get_filename_component (Weka_DIR "${Weka_CLASSPATH}" PATH)
00266     if (EXISTS "${Weka_DIR}/../WekaManual.pdf") # weka.jar is in weka/ subdirectory
00267       get_filename_component (Weka_DIR "${Weka_DIR}" PATH)
00268     elseif (Weka_DIR MATCHES "/Contents/Resources/Java$")
00269       string (REGEX REPLACE "/Contents/Resources/Java$" "" Weka_DIR "${Weka_DIR}")
00270     endif ()
00271     set (Weka_DIR "${Weka_DIR}" CACHE PATH "Installation directory of Weka." FORCE)
00272   endif ()
00273 endif ()
00274 mark_as_advanced (Weka_CLASSPATH)
00275 
00276 #-------------------------------------------------------------
00277 # determine Weka version
00278 weka_get_version (Weka_VERSION_STRING Weka_VERSION_MAJOR Weka_VERSION_MINOR Weka_VERSION_PATCH)
00279 weka_has_package_manager ()
00280 
00281 #-------------------------------------------------------------
00282 # find Weka packages
00283 if (Weka_HAS_PACKAGE_MANAGER)
00284   if (NOT Weka_PACKAGES_DIR AND Weka_DIR)
00285     if (IS_DIRECTORY "${Weka_DIR}/packages")
00286       set (Weka_PACKAGES_DIR "${Weka_DIR}/packages" CACHE PATH "Installation directory of Weka packages." FORCE)
00287     elseif (IS_DIRECTORY "$ENV{HOME}/wekafiles/packages")
00288       set (Weka_PACKAGES_DIR "$ENV{HOME}/wekafiles/packages" CACHE PATH "Installation directory of Weka packages." FORCE)
00289     endif ()
00290   endif ()
00291   set (Weka_REQUIRED_PACKAGE_VARS)
00292   if (Weka_FIND_COMPONENTS)
00293     foreach (Weka_PKG IN LISTS Weka_FIND_COMPONENTS)
00294       list (APPEND Weka_REQUIRED_PACKAGE_VARS "Weka_${Weka_PKG}_DIR")
00295     endforeach ()
00296   elseif (Weka_CLASSPATH)
00297     weka_list_packages (Weka_FIND_COMPONENTS installed)
00298   endif ()
00299   foreach (Weka_PKG IN LISTS Weka_FIND_COMPONENTS Weka_FIND_OPTIONAL_COMPONENTS)
00300     set (Weka_${Weka_PKG}_DIR "Weka_${Weka_PKG}_DIR-NOTFOUND" CACHE PATH "Directory of ${Weka_PKG} Weka package." FORCE)
00301     mark_as_advanced (Weka_${Weka_PKG}_DIR)
00302     if (IS_DIRECTORY "${Weka_PACKAGES_DIR}/${Weka_PKG}")
00303       if (EXISTS "${Weka_PACKAGES_DIR}/${Weka_PKG}/${Weka_PKG}.jar")
00304         set (Weka_${Weka_PKG}_CLASSPATH "${Weka_PACKAGES_DIR}/${Weka_PKG}/${Weka_PKG}.jar")
00305       elseif (IS_DIRECTORY "${Weka_PACKAGES_DIR}/${Weka_PKG}/weka")
00306         set (Weka_${Weka_PKG}_CLASSPATH "${Weka_PACKAGES_DIR}/${Weka_PKG}")
00307       elseif (IS_DIRECTORY "${Weka_PACKAGES_DIR}/${Weka_PACKAGE}/src/main/java/weka")
00308         set (Weka_${Weka_PKG}_CLASSPATH "${Weka_PACKAGES_DIR}/${Weka_PKG}/src/main/java")
00309       endif ()
00310     endif ()
00311     if (Weka_${Weka_PKG}_CLASSPATH)
00312       list (APPEND Weka_PACKAGES_CLASSPATH "${Weka_${Weka_PKG}_CLASSPATH}")
00313       set (Weka_${Weka_PKG}_DIR "${Weka_PACKAGES_DIR}/${Weka_PKG}" CACHE PATH "Directory of ${Weka_PKG} Weka package." FORCE)
00314     endif ()
00315   endforeach ()
00316   unset (Weka_PKG)
00317 else ()
00318   if (DEFINED Weka_PACKAGES_DIR)
00319     get_property (Weka_PACKAGES_DIR_SET CACHE Weka_PACKAGES_DIR PROPERTY TYPE SET)
00320     if (Weka_PACKAGES_DIR_SET)
00321       set_property (CACHE Weka_PACKAGES_DIR PROPERTY TYPE  INTERNAL)
00322       set_property (CACHE Weka_PACKAGES_DIR PROPERTY VALUE Weka_PACKAGES_DIR-NOTFOUND)
00323     endif ()
00324     unset (Weka_PACKAGES_DIR_SET)
00325   endif ()
00326   if (Weka_FIND_COMPONENTS AND Weka_FIND_REQUIRED)
00327     message (WARNING "This Weka version has no package manager and consists only of the core weka.jar package."
00328                      " The components required may not be available with this Weka version. Make sure that you"
00329                      " have installed and selected the proper Weka version required by this software package."
00330                      " Further, check the Weka_DIR variable and set it accordingly if it points to the wrong"
00331                      " installation of Weka.")
00332   endif ()
00333 endif ()
00334 
00335 # ----------------------------------------------------------------------------
00336 # Weka_CLASSPATHS
00337 set (Weka_CLASSPATHS)
00338 if (Weka_CLASSPATH)
00339   list (APPEND Weka_CLASSPATHS "${Weka_CLASSPATH}")
00340 endif ()
00341 if (Weka_PACKAGES_CLASSPATH)
00342   list (APPEND Weka_CLASSPATHS ${Weka_PACKAGES_CLASSPATH})
00343 endif ()
00344 
00345 # ----------------------------------------------------------------------------
00346 # debugging
00347 if (BASIS_DEBUG AND COMMAND basis_dump_variables)
00348   basis_dump_variables ("${CMAKE_CURRENT_BINARY_DIR}/FindWekaVariables.cmake")
00349 endif ()
00350 
00351 # ----------------------------------------------------------------------------
00352 # handle the QUIETLY and REQUIRED arguments and set *_FOUND to TRUE
00353 # if all listed variables are found or TRUE
00354 include (FindPackageHandleStandardArgs)
00355 
00356 find_package_handle_standard_args (
00357   Weka
00358   REQUIRED_VARS Weka_CLASSPATH ${Weka_REQUIRED_PACKAGE_VARS}
00359   VERSION_VAR   ${Weka_VERSION_STRING}
00360 )
00361 
00362 unset (Weka_HINTS)
00363 unset (Weka_REQUIRED_PACKAGE_VARS)