Home | History | Annotate | Download | only in CMake
      1 # - Try to find the GSS Kerberos library
      2 # Once done this will define
      3 #
      4 #  GSS_ROOT_DIR - Set this variable to the root installation of GSS
      5 #
      6 # Read-Only variables:
      7 #  GSS_FOUND - system has the Heimdal library
      8 #  GSS_FLAVOUR - "MIT" or "Heimdal" if anything found.
      9 #  GSS_INCLUDE_DIR - the Heimdal include directory
     10 #  GSS_LIBRARIES - The libraries needed to use GSS
     11 #  GSS_LINK_DIRECTORIES - Directories to add to linker search path
     12 #  GSS_LINKER_FLAGS - Additional linker flags
     13 #  GSS_COMPILER_FLAGS - Additional compiler flags
     14 #  GSS_VERSION - This is set to version advertised by pkg-config or read from manifest.
     15 #                In case the library is found but no version info availabe it'll be set to "unknown"
     16 
     17 set(_MIT_MODNAME mit-krb5-gssapi)
     18 set(_HEIMDAL_MODNAME heimdal-gssapi)
     19 
     20 include(CheckIncludeFile)
     21 include(CheckIncludeFiles)
     22 include(CheckTypeSize)
     23 
     24 set(_GSS_ROOT_HINTS
     25     "${GSS_ROOT_DIR}"
     26     "$ENV{GSS_ROOT_DIR}"
     27 )
     28 
     29 # try to find library using system pkg-config if user didn't specify root dir
     30 if(NOT GSS_ROOT_DIR AND NOT "$ENV{GSS_ROOT_DIR}")
     31     if(UNIX)
     32         find_package(PkgConfig QUIET)
     33         pkg_search_module(_GSS_PKG ${_MIT_MODNAME} ${_HEIMDAL_MODNAME})
     34         list(APPEND _GSS_ROOT_HINTS "${_GSS_PKG_PREFIX}")
     35     elseif(WIN32)
     36         list(APPEND _GSS_ROOT_HINTS "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MIT\\Kerberos;InstallDir]")
     37     endif()
     38 endif()
     39 
     40 if(NOT _GSS_FOUND) #not found by pkg-config. Let's take more traditional approach.
     41     find_file(_GSS_CONFIGURE_SCRIPT
     42         NAMES
     43             "krb5-config"
     44         HINTS
     45             ${_GSS_ROOT_HINTS}
     46         PATH_SUFFIXES
     47             bin
     48         NO_CMAKE_PATH
     49         NO_CMAKE_ENVIRONMENT_PATH
     50     )
     51 
     52     # if not found in user-supplied directories, maybe system knows better
     53     find_file(_GSS_CONFIGURE_SCRIPT
     54         NAMES
     55             "krb5-config"
     56         PATH_SUFFIXES
     57             bin
     58     )
     59 
     60     if(_GSS_CONFIGURE_SCRIPT)
     61         execute_process(
     62             COMMAND ${_GSS_CONFIGURE_SCRIPT} "--cflags" "gssapi"
     63             OUTPUT_VARIABLE _GSS_CFLAGS
     64             RESULT_VARIABLE _GSS_CONFIGURE_FAILED
     65         )
     66 message(STATUS "CFLAGS: ${_GSS_CFLAGS}")
     67         if(NOT _GSS_CONFIGURE_FAILED) # 0 means success
     68             # should also work in an odd case when multiple directories are given
     69             string(STRIP "${_GSS_CFLAGS}" _GSS_CFLAGS)
     70             string(REGEX REPLACE " +-I" ";" _GSS_CFLAGS "${_GSS_CFLAGS}")
     71             string(REGEX REPLACE " +-([^I][^ \\t;]*)" ";-\\1"_GSS_CFLAGS "${_GSS_CFLAGS}")
     72 
     73             foreach(_flag ${_GSS_CFLAGS})
     74                 if(_flag MATCHES "^-I.*")
     75                     string(REGEX REPLACE "^-I" "" _val "${_flag}")
     76                     list(APPEND _GSS_INCLUDE_DIR "${_val}")
     77                 else()
     78                     list(APPEND _GSS_COMPILER_FLAGS "${_flag}")
     79                 endif()
     80             endforeach()
     81         endif()
     82 
     83         execute_process(
     84             COMMAND ${_GSS_CONFIGURE_SCRIPT} "--libs" "gssapi"
     85             OUTPUT_VARIABLE _GSS_LIB_FLAGS
     86             RESULT_VARIABLE _GSS_CONFIGURE_FAILED
     87         )
     88 message(STATUS "LDFLAGS: ${_GSS_LIB_FLAGS}")
     89         if(NOT _GSS_CONFIGURE_FAILED) # 0 means success
     90             # this script gives us libraries and link directories. Blah. We have to deal with it.
     91             string(STRIP "${_GSS_LIB_FLAGS}" _GSS_LIB_FLAGS)
     92             string(REGEX REPLACE " +-(L|l)" ";-\\1" _GSS_LIB_FLAGS "${_GSS_LIB_FLAGS}")
     93             string(REGEX REPLACE " +-([^Ll][^ \\t;]*)" ";-\\1"_GSS_LIB_FLAGS "${_GSS_LIB_FLAGS}")
     94 
     95             foreach(_flag ${_GSS_LIB_FLAGS})
     96                 if(_flag MATCHES "^-l.*")
     97                     string(REGEX REPLACE "^-l" "" _val "${_flag}")
     98                     list(APPEND _GSS_LIBRARIES "${_val}")
     99                 elseif(_flag MATCHES "^-L.*")
    100                     string(REGEX REPLACE "^-L" "" _val "${_flag}")
    101                     list(APPEND _GSS_LINK_DIRECTORIES "${_val}")
    102                 else()
    103                     list(APPEND _GSS_LINKER_FLAGS "${_flag}")
    104                 endif()
    105             endforeach()
    106         endif()
    107 
    108 
    109         execute_process(
    110             COMMAND ${_GSS_CONFIGURE_SCRIPT} "--version"
    111             OUTPUT_VARIABLE _GSS_VERSION
    112             RESULT_VARIABLE _GSS_CONFIGURE_FAILED
    113         )
    114 
    115         # older versions may not have the "--version" parameter. In this case we just don't care.
    116         if(_GSS_CONFIGURE_FAILED)
    117             set(_GSS_VERSION 0)
    118         endif()
    119 
    120 
    121         execute_process(
    122             COMMAND ${_GSS_CONFIGURE_SCRIPT} "--vendor"
    123             OUTPUT_VARIABLE _GSS_VENDOR
    124             RESULT_VARIABLE _GSS_CONFIGURE_FAILED
    125         )
    126 
    127         # older versions may not have the "--vendor" parameter. In this case we just don't care.
    128         if(_GSS_CONFIGURE_FAILED)
    129             set(GSS_FLAVOUR "Heimdal") # most probably, shouldn't really matter
    130         else()
    131             if(_GSS_VENDOR MATCHES ".*H|heimdal.*")
    132                 set(GSS_FLAVOUR "Heimdal")
    133             else()
    134                 set(GSS_FLAVOUR "MIT")
    135             endif()
    136         endif()
    137 
    138     else() # either there is no config script or we are on platform that doesn't provide one (Windows?)
    139 
    140         find_path(_GSS_INCLUDE_DIR
    141             NAMES
    142                 "gssapi/gssapi.h"
    143             HINTS
    144                 ${_GSS_ROOT_HINTS}
    145             PATH_SUFFIXES
    146                 include
    147                 inc
    148         )
    149 
    150         if(_GSS_INCLUDE_DIR) #jay, we've found something
    151             set(CMAKE_REQUIRED_INCLUDES "${_GSS_INCLUDE_DIR}")
    152             check_include_files( "gssapi/gssapi_generic.h;gssapi/gssapi_krb5.h" _GSS_HAVE_MIT_HEADERS)
    153 
    154             if(_GSS_HAVE_MIT_HEADERS)
    155                 set(GSS_FLAVOUR "MIT")
    156             else()
    157                 # prevent compiling the header - just check if we can include it
    158                 set(CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS} -D__ROKEN_H__")
    159                 check_include_file( "roken.h" _GSS_HAVE_ROKEN_H)
    160 
    161                 check_include_file( "heimdal/roken.h" _GSS_HAVE_HEIMDAL_ROKEN_H)
    162                 if(_GSS_HAVE_ROKEN_H OR _GSS_HAVE_HEIMDAL_ROKEN_H)
    163                     set(GSS_FLAVOUR "Heimdal")
    164                 endif()
    165                 set(CMAKE_REQUIRED_DEFINITIONS "")
    166             endif()
    167         else()
    168             # I'm not convienced if this is the right way but this is what autotools do at the moment
    169             find_path(_GSS_INCLUDE_DIR
    170                 NAMES
    171                     "gssapi.h"
    172                 HINTS
    173                     ${_GSS_ROOT_HINTS}
    174                 PATH_SUFFIXES
    175                     include
    176                     inc
    177             )
    178 
    179             if(_GSS_INCLUDE_DIR)
    180                 set(GSS_FLAVOUR "Heimdal")
    181             endif()
    182         endif()
    183 
    184         # if we have headers, check if we can link libraries
    185         if(GSS_FLAVOUR)
    186             set(_GSS_LIBDIR_SUFFIXES "")
    187             set(_GSS_LIBDIR_HINTS ${_GSS_ROOT_HINTS})
    188             get_filename_component(_GSS_CALCULATED_POTENTIAL_ROOT "${_GSS_INCLUDE_DIR}" PATH)
    189             list(APPEND _GSS_LIBDIR_HINTS ${_GSS_CALCULATED_POTENTIAL_ROOT})
    190 
    191             if(WIN32)
    192                 if(CMAKE_SIZEOF_VOID_P EQUAL 8)
    193                     list(APPEND _GSS_LIBDIR_SUFFIXES "lib/AMD64")
    194                     if(GSS_FLAVOUR STREQUAL "MIT")
    195                         set(_GSS_LIBNAME "gssapi64")
    196                     else()
    197                         set(_GSS_LIBNAME "libgssapi")
    198                     endif()
    199                 else()
    200                     list(APPEND _GSS_LIBDIR_SUFFIXES "lib/i386")
    201                     if(GSS_FLAVOUR STREQUAL "MIT")
    202                         set(_GSS_LIBNAME "gssapi32")
    203                     else()
    204                         set(_GSS_LIBNAME "libgssapi")
    205                     endif()
    206                 endif()
    207             else()
    208                 list(APPEND _GSS_LIBDIR_SUFFIXES "lib;lib64") # those suffixes are not checked for HINTS
    209                 if(GSS_FLAVOUR STREQUAL "MIT")
    210                     set(_GSS_LIBNAME "gssapi_krb5")
    211                 else()
    212                     set(_GSS_LIBNAME "gssapi")
    213                 endif()
    214             endif()
    215 
    216             find_library(_GSS_LIBRARIES
    217                 NAMES
    218                     ${_GSS_LIBNAME}
    219                 HINTS
    220                     ${_GSS_LIBDIR_HINTS}
    221                 PATH_SUFFIXES
    222                     ${_GSS_LIBDIR_SUFFIXES}
    223             )
    224 
    225         endif()
    226 
    227     endif()
    228 else()
    229     if(_GSS_PKG_${_MIT_MODNAME}_VERSION)
    230         set(GSS_FLAVOUR "MIT")
    231         set(_GSS_VERSION _GSS_PKG_${_MIT_MODNAME}_VERSION)
    232     else()
    233         set(GSS_FLAVOUR "Heimdal")
    234         set(_GSS_VERSION _GSS_PKG_${_MIT_HEIMDAL}_VERSION)
    235     endif()
    236 endif()
    237 
    238 set(GSS_INCLUDE_DIR ${_GSS_INCLUDE_DIR})
    239 set(GSS_LIBRARIES ${_GSS_LIBRARIES})
    240 set(GSS_LINK_DIRECTORIES ${_GSS_LINK_DIRECTORIES})
    241 set(GSS_LINKER_FLAGS ${_GSS_LINKER_FLAGS})
    242 set(GSS_COMPILER_FLAGS ${_GSS_COMPILER_FLAGS})
    243 set(GSS_VERSION ${_GSS_VERSION})
    244 
    245 if(GSS_FLAVOUR)
    246 
    247     if(NOT GSS_VERSION AND GSS_FLAVOUR STREQUAL "Heimdal")
    248         if(CMAKE_SIZEOF_VOID_P EQUAL 8)
    249             set(HEIMDAL_MANIFEST_FILE "Heimdal.Application.amd64.manifest")
    250         else()
    251             set(HEIMDAL_MANIFEST_FILE "Heimdal.Application.x86.manifest")
    252         endif()
    253 
    254         if(EXISTS "${GSS_INCLUDE_DIR}/${HEIMDAL_MANIFEST_FILE}")
    255             file(STRINGS "${GSS_INCLUDE_DIR}/${HEIMDAL_MANIFEST_FILE}" heimdal_version_str
    256                  REGEX "^.*version=\"[0-9]\\.[^\"]+\".*$")
    257 
    258             string(REGEX MATCH "[0-9]\\.[^\"]+"
    259                    GSS_VERSION "${heimdal_version_str}")
    260         endif()
    261 
    262         if(NOT GSS_VERSION)
    263             set(GSS_VERSION "Heimdal Unknown")
    264         endif()
    265     elseif(NOT GSS_VERSION AND GSS_FLAVOUR STREQUAL "MIT")
    266         get_filename_component(_MIT_VERSION "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MIT\\Kerberos\\SDK\\CurrentVersion;VersionString]" NAME CACHE)
    267         if(WIN32 AND _MIT_VERSION)
    268             set(GSS_VERSION "${_MIT_VERSION}")
    269         else()
    270             set(GSS_VERSION "MIT Unknown")
    271         endif()
    272     endif()
    273 endif()
    274 
    275 
    276 include(FindPackageHandleStandardArgs)
    277 
    278 set(_GSS_REQUIRED_VARS GSS_LIBRARIES GSS_FLAVOUR)
    279 
    280 find_package_handle_standard_args(GSS
    281     REQUIRED_VARS
    282         ${_GSS_REQUIRED_VARS}
    283     VERSION_VAR
    284         GSS_VERSION
    285     FAIL_MESSAGE
    286         "Could NOT find GSS, try to set the path to GSS root folder in the system variable GSS_ROOT_DIR"
    287 )
    288 
    289 mark_as_advanced(GSS_INCLUDE_DIR GSS_LIBRARIES)
    290