FindGSS.cmake (12214B)
1 #*************************************************************************** 2 # _ _ ____ _ 3 # Project ___| | | | _ \| | 4 # / __| | | | |_) | | 5 # | (__| |_| | _ <| |___ 6 # \___|\___/|_| \_\_____| 7 # 8 # Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. 9 # 10 # This software is licensed as described in the file COPYING, which 11 # you should have received as part of this distribution. The terms 12 # are also available at https://curl.se/docs/copyright.html. 13 # 14 # You may opt to use, copy, modify, merge, publish, distribute and/or sell 15 # copies of the Software, and permit persons to whom the Software is 16 # furnished to do so, under the terms of the COPYING file. 17 # 18 # This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 19 # KIND, either express or implied. 20 # 21 # SPDX-License-Identifier: curl 22 # 23 ########################################################################### 24 # Find the GSS Kerberos library 25 # 26 # Input variables: 27 # 28 # - `GSS_ROOT_DIR`: Set this variable to the root installation of GSS. (also supported as environment) 29 # 30 # Result variables: 31 # 32 # - `GSS_FOUND`: System has the Heimdal library. 33 # - `GSS_FLAVOUR`: "GNU", "MIT" or "Heimdal" if anything found. 34 # - `GSS_INCLUDE_DIRS`: The GSS include directories. 35 # - `GSS_LIBRARIES`: The GSS library names. 36 # - `GSS_LIBRARY_DIRS`: The GSS library directories. 37 # - `GSS_PC_REQUIRES`: The GSS pkg-config packages. 38 # - `GSS_CFLAGS`: Required compiler flags. 39 # - `GSS_VERSION`: This is set to version advertised by pkg-config or read from manifest. 40 # In case the library is found but no version info available it is set to "unknown" 41 42 set(_gnu_modname "gss") 43 set(_mit_modname "mit-krb5-gssapi") 44 set(_heimdal_modname "heimdal-gssapi") 45 46 include(CheckIncludeFile) 47 include(CheckIncludeFiles) 48 include(CheckTypeSize) 49 50 set(_gss_root_hints 51 "${GSS_ROOT_DIR}" 52 "$ENV{GSS_ROOT_DIR}" 53 ) 54 55 set(_gss_CFLAGS "") 56 set(_gss_LIBRARY_DIRS "") 57 58 # Try to find library using system pkg-config if user did not specify root dir 59 if(NOT GSS_ROOT_DIR AND NOT "$ENV{GSS_ROOT_DIR}") 60 if(CURL_USE_PKGCONFIG) 61 find_package(PkgConfig QUIET) 62 pkg_search_module(_gss ${_gnu_modname} ${_mit_modname} ${_heimdal_modname}) 63 list(APPEND _gss_root_hints "${_gss_PREFIX}") 64 set(_gss_version "${_gss_VERSION}") 65 endif() 66 if(WIN32) 67 list(APPEND _gss_root_hints "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MIT\\Kerberos;InstallDir]") 68 endif() 69 endif() 70 71 if(NOT _gss_FOUND) # Not found by pkg-config. Let us take more traditional approach. 72 find_file(_gss_configure_script 73 NAMES 74 "krb5-config" 75 HINTS 76 ${_gss_root_hints} 77 PATH_SUFFIXES 78 "bin" 79 NO_CMAKE_PATH 80 NO_CMAKE_ENVIRONMENT_PATH 81 ) 82 83 # If not found in user-supplied directories, maybe system knows better 84 find_file(_gss_configure_script 85 NAMES 86 "krb5-config" 87 PATH_SUFFIXES 88 "bin" 89 ) 90 91 if(_gss_configure_script) 92 93 set(_gss_INCLUDE_DIRS "") 94 set(_gss_LIBRARIES "") 95 96 execute_process( 97 COMMAND ${_gss_configure_script} "--cflags" "gssapi" 98 OUTPUT_VARIABLE _gss_cflags_raw 99 RESULT_VARIABLE _gss_configure_failed 100 OUTPUT_STRIP_TRAILING_WHITESPACE 101 ) 102 message(STATUS "FindGSS krb5-config --cflags: ${_gss_cflags_raw}") 103 if(NOT _gss_configure_failed) # 0 means success 104 # Should also work in an odd case when multiple directories are given. 105 string(STRIP "${_gss_cflags_raw}" _gss_cflags_raw) 106 string(REGEX REPLACE " +-(I)" ";-\\1" _gss_cflags_raw "${_gss_cflags_raw}") 107 string(REGEX REPLACE " +-([^I][^ \\t;]*)" ";-\\1" _gss_cflags_raw "${_gss_cflags_raw}") 108 109 foreach(_flag IN LISTS _gss_cflags_raw) 110 if(_flag MATCHES "^-I") 111 string(REGEX REPLACE "^-I" "" _flag "${_flag}") 112 list(APPEND _gss_INCLUDE_DIRS "${_flag}") 113 else() 114 list(APPEND _gss_CFLAGS "${_flag}") 115 endif() 116 endforeach() 117 endif() 118 119 execute_process( 120 COMMAND ${_gss_configure_script} "--libs" "gssapi" 121 OUTPUT_VARIABLE _gss_lib_flags 122 RESULT_VARIABLE _gss_configure_failed 123 OUTPUT_STRIP_TRAILING_WHITESPACE 124 ) 125 message(STATUS "FindGSS krb5-config --libs: ${_gss_lib_flags}") 126 127 if(NOT _gss_configure_failed) # 0 means success 128 # This script gives us libraries and link directories. 129 string(STRIP "${_gss_lib_flags}" _gss_lib_flags) 130 string(REGEX REPLACE " +-(L|l)" ";-\\1" _gss_lib_flags "${_gss_lib_flags}") 131 string(REGEX REPLACE " +-([^Ll][^ \\t;]*)" ";-\\1" _gss_lib_flags "${_gss_lib_flags}") 132 133 foreach(_flag IN LISTS _gss_lib_flags) 134 if(_flag MATCHES "^-l") 135 string(REGEX REPLACE "^-l" "" _flag "${_flag}") 136 list(APPEND _gss_LIBRARIES "${_flag}") 137 elseif(_flag MATCHES "^-L") 138 string(REGEX REPLACE "^-L" "" _flag "${_flag}") 139 list(APPEND _gss_LIBRARY_DIRS "${_flag}") 140 endif() 141 endforeach() 142 endif() 143 144 execute_process( 145 COMMAND ${_gss_configure_script} "--version" 146 OUTPUT_VARIABLE _gss_version 147 RESULT_VARIABLE _gss_configure_failed 148 OUTPUT_STRIP_TRAILING_WHITESPACE 149 ) 150 151 # Older versions may not have the "--version" parameter. In this case we just do not care. 152 if(_gss_configure_failed) 153 set(_gss_version 0) 154 endif() 155 156 execute_process( 157 COMMAND ${_gss_configure_script} "--vendor" 158 OUTPUT_VARIABLE _gss_vendor 159 RESULT_VARIABLE _gss_configure_failed 160 OUTPUT_STRIP_TRAILING_WHITESPACE 161 ) 162 163 # Older versions may not have the "--vendor" parameter. In this case we just do not care. 164 if(_gss_configure_failed) 165 set(GSS_FLAVOUR "Heimdal") # most probably, should not really matter 166 else() 167 if(_gss_vendor MATCHES "H|heimdal") 168 set(GSS_FLAVOUR "Heimdal") 169 else() 170 set(GSS_FLAVOUR "MIT") 171 endif() 172 endif() 173 174 else() # Either there is no config script or we are on a platform that does not provide one (Windows?) 175 176 find_path(_gss_INCLUDE_DIRS NAMES "gssapi/gssapi.h" 177 HINTS 178 ${_gss_root_hints} 179 PATH_SUFFIXES 180 "include" 181 "inc" 182 ) 183 184 if(_gss_INCLUDE_DIRS) # jay, we have found something 185 cmake_push_check_state() 186 list(APPEND CMAKE_REQUIRED_INCLUDES "${_gss_INCLUDE_DIRS}") 187 check_include_files("gssapi/gssapi_generic.h;gssapi/gssapi_krb5.h" _gss_have_mit_headers) 188 189 if(_gss_have_mit_headers) 190 set(GSS_FLAVOUR "MIT") 191 else() 192 # Prevent compiling the header - just check if we can include it 193 list(APPEND CMAKE_REQUIRED_DEFINITIONS "-D__ROKEN_H__") 194 check_include_file("roken.h" _gss_have_roken_h) 195 196 check_include_file("heimdal/roken.h" _gss_have_heimdal_roken_h) 197 if(_gss_have_roken_h OR _gss_have_heimdal_roken_h) 198 set(GSS_FLAVOUR "Heimdal") 199 endif() 200 endif() 201 cmake_pop_check_state() 202 else() 203 # I am not convinced if this is the right way but this is what autotools do at the moment 204 find_path(_gss_INCLUDE_DIRS NAMES "gssapi.h" 205 HINTS 206 ${_gss_root_hints} 207 PATH_SUFFIXES 208 "include" 209 "inc" 210 ) 211 212 if(_gss_INCLUDE_DIRS) 213 set(GSS_FLAVOUR "Heimdal") 214 else() 215 find_path(_gss_INCLUDE_DIRS NAMES "gss.h" 216 HINTS 217 ${_gss_root_hints} 218 PATH_SUFFIXES 219 "include" 220 ) 221 222 if(_gss_INCLUDE_DIRS) 223 set(GSS_FLAVOUR "GNU") 224 set(GSS_PC_REQUIRES "gss") 225 endif() 226 endif() 227 endif() 228 229 # If we have headers, check if we can link libraries 230 if(GSS_FLAVOUR) 231 set(_gss_libdir_suffixes "") 232 set(_gss_libdir_hints ${_gss_root_hints}) 233 get_filename_component(_gss_calculated_potential_root "${_gss_INCLUDE_DIRS}" DIRECTORY) 234 list(APPEND _gss_libdir_hints ${_gss_calculated_potential_root}) 235 236 if(WIN32) 237 if(CMAKE_SIZEOF_VOID_P EQUAL 8) 238 list(APPEND _gss_libdir_suffixes "lib/AMD64") 239 if(GSS_FLAVOUR STREQUAL "GNU") 240 set(_gss_libname "gss") 241 elseif(GSS_FLAVOUR STREQUAL "MIT") 242 set(_gss_libname "gssapi64") 243 else() 244 set(_gss_libname "libgssapi") 245 endif() 246 else() 247 list(APPEND _gss_libdir_suffixes "lib/i386") 248 if(GSS_FLAVOUR STREQUAL "GNU") 249 set(_gss_libname "gss") 250 elseif(GSS_FLAVOUR STREQUAL "MIT") 251 set(_gss_libname "gssapi32") 252 else() 253 set(_gss_libname "libgssapi") 254 endif() 255 endif() 256 else() 257 list(APPEND _gss_libdir_suffixes "lib;lib64") # those suffixes are not checked for HINTS 258 if(GSS_FLAVOUR STREQUAL "GNU") 259 set(_gss_libname "gss") 260 elseif(GSS_FLAVOUR STREQUAL "MIT") 261 set(_gss_libname "gssapi_krb5") 262 else() 263 set(_gss_libname "gssapi") 264 endif() 265 endif() 266 267 find_library(_gss_LIBRARIES NAMES ${_gss_libname} 268 HINTS 269 ${_gss_libdir_hints} 270 PATH_SUFFIXES 271 ${_gss_libdir_suffixes} 272 ) 273 endif() 274 endif() 275 else() 276 # _gss_MODULE_NAME set since CMake 3.16 277 if(_gss_MODULE_NAME STREQUAL _gnu_modname OR _gss_${_gnu_modname}_VERSION) 278 set(GSS_FLAVOUR "GNU") 279 set(GSS_PC_REQUIRES "gss") 280 if(NOT _gss_version) # for old CMake versions? 281 set(_gss_version ${_gss_${_gnu_modname}_VERSION}) 282 endif() 283 elseif(_gss_MODULE_NAME STREQUAL _mit_modname OR _gss_${_mit_modname}_VERSION) 284 set(GSS_FLAVOUR "MIT") 285 set(GSS_PC_REQUIRES "mit-krb5-gssapi") 286 if(NOT _gss_version) # for old CMake versions? 287 set(_gss_version ${_gss_${_mit_modname}_VERSION}) 288 endif() 289 else() 290 set(GSS_FLAVOUR "Heimdal") 291 set(GSS_PC_REQUIRES "heimdal-gssapi") 292 if(NOT _gss_version) # for old CMake versions? 293 set(_gss_version ${_gss_${_heimdal_modname}_VERSION}) 294 endif() 295 endif() 296 message(STATUS "Found GSS/${GSS_FLAVOUR} (via pkg-config): ${_gss_INCLUDE_DIRS} (found version \"${_gss_version}\")") 297 endif() 298 299 string(REPLACE ";" " " _gss_CFLAGS "${_gss_CFLAGS}") 300 301 set(GSS_INCLUDE_DIRS ${_gss_INCLUDE_DIRS}) 302 set(GSS_LIBRARIES ${_gss_LIBRARIES}) 303 set(GSS_LIBRARY_DIRS ${_gss_LIBRARY_DIRS}) 304 set(GSS_CFLAGS ${_gss_CFLAGS}) 305 set(GSS_VERSION ${_gss_version}) 306 307 if(GSS_FLAVOUR) 308 if(NOT GSS_VERSION AND GSS_FLAVOUR STREQUAL "Heimdal") 309 if(CMAKE_SIZEOF_VOID_P EQUAL 8) 310 set(_heimdal_manifest_file "Heimdal.Application.amd64.manifest") 311 else() 312 set(_heimdal_manifest_file "Heimdal.Application.x86.manifest") 313 endif() 314 315 if(EXISTS "${GSS_INCLUDE_DIRS}/${_heimdal_manifest_file}") 316 file(STRINGS "${GSS_INCLUDE_DIRS}/${_heimdal_manifest_file}" _heimdal_version_str 317 REGEX "^.*version=\"[0-9]\\.[^\"]+\".*$") 318 319 string(REGEX MATCH "[0-9]\\.[^\"]+" GSS_VERSION "${_heimdal_version_str}") 320 endif() 321 322 if(NOT GSS_VERSION) 323 set(GSS_VERSION "Heimdal Unknown") 324 endif() 325 elseif(NOT GSS_VERSION AND GSS_FLAVOUR STREQUAL "MIT") 326 get_filename_component(_mit_version "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MIT\\Kerberos\\SDK\\CurrentVersion;VersionString]" NAME 327 CACHE) 328 if(WIN32 AND _mit_version) 329 set(GSS_VERSION "${_mit_version}") 330 else() 331 set(GSS_VERSION "MIT Unknown") 332 endif() 333 elseif(NOT GSS_VERSION AND GSS_FLAVOUR STREQUAL "GNU") 334 if(GSS_INCLUDE_DIRS AND EXISTS "${GSS_INCLUDE_DIRS}/gss.h") 335 set(_version_regex "#[\t ]*define[\t ]+GSS_VERSION[\t ]+\"([^\"]*)\"") 336 file(STRINGS "${GSS_INCLUDE_DIRS}/gss.h" _version_str REGEX "${_version_regex}") 337 string(REGEX REPLACE "${_version_regex}" "\\1" _version_str "${_version_str}") 338 set(GSS_VERSION "${_version_str}") 339 unset(_version_regex) 340 unset(_version_str) 341 endif() 342 endif() 343 endif() 344 345 include(FindPackageHandleStandardArgs) 346 find_package_handle_standard_args(GSS 347 REQUIRED_VARS 348 GSS_FLAVOUR 349 GSS_LIBRARIES 350 VERSION_VAR 351 GSS_VERSION 352 FAIL_MESSAGE 353 "Could NOT find GSS, try to set the path to GSS root folder in the system variable GSS_ROOT_DIR" 354 ) 355 356 mark_as_advanced( 357 _gss_CFLAGS 358 _gss_FOUND 359 _gss_INCLUDE_DIRS 360 _gss_LIBRARIES 361 _gss_LIBRARY_DIRS 362 _gss_MODULE_NAME 363 _gss_PREFIX 364 _gss_version 365 )