2
0

FindGSS.cmake 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  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
  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_LDFLAGS Required linker flags
  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. set(_gnu_modname "gss")
  42. set(_mit_modname "mit-krb5-gssapi")
  43. set(_heimdal_modname "heimdal-gssapi")
  44. include(CheckIncludeFile)
  45. include(CheckIncludeFiles)
  46. include(CheckTypeSize)
  47. set(_gss_root_hints
  48. "${GSS_ROOT_DIR}"
  49. "$ENV{GSS_ROOT_DIR}"
  50. )
  51. # Try to find library using system pkg-config if user did not specify root dir
  52. if(NOT GSS_ROOT_DIR AND NOT "$ENV{GSS_ROOT_DIR}")
  53. if(CURL_USE_PKGCONFIG)
  54. find_package(PkgConfig QUIET)
  55. pkg_search_module(_GSS ${_gnu_modname} ${_mit_modname} ${_heimdal_modname})
  56. list(APPEND _gss_root_hints "${_GSS_PREFIX}")
  57. endif()
  58. if(WIN32)
  59. list(APPEND _gss_root_hints "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MIT\\Kerberos;InstallDir]")
  60. endif()
  61. endif()
  62. if(NOT _GSS_FOUND) # Not found by pkg-config. Let us take more traditional approach.
  63. find_file(_gss_configure_script
  64. NAMES
  65. "krb5-config"
  66. HINTS
  67. ${_gss_root_hints}
  68. PATH_SUFFIXES
  69. "bin"
  70. NO_CMAKE_PATH
  71. NO_CMAKE_ENVIRONMENT_PATH
  72. )
  73. # If not found in user-supplied directories, maybe system knows better
  74. find_file(_gss_configure_script
  75. NAMES
  76. "krb5-config"
  77. PATH_SUFFIXES
  78. "bin"
  79. )
  80. if(_gss_configure_script)
  81. execute_process(
  82. COMMAND ${_gss_configure_script} "--cflags" "gssapi"
  83. OUTPUT_VARIABLE _GSS_CFLAGS
  84. RESULT_VARIABLE _gss_configure_failed
  85. OUTPUT_STRIP_TRAILING_WHITESPACE
  86. )
  87. message(STATUS "FindGSS CFLAGS: ${_GSS_CFLAGS}")
  88. if(NOT _gss_configure_failed) # 0 means success
  89. # Should also work in an odd case when multiple directories are given
  90. string(STRIP "${_GSS_CFLAGS}" _GSS_CFLAGS)
  91. string(REGEX REPLACE " +-I" ";" _GSS_CFLAGS "${_GSS_CFLAGS}")
  92. string(REGEX REPLACE " +-([^I][^ \\t;]*)" ";-\\1" _GSS_CFLAGS "${_GSS_CFLAGS}")
  93. foreach(_flag IN LISTS _GSS_CFLAGS)
  94. if(_flag MATCHES "^-I.*")
  95. string(REGEX REPLACE "^-I" "" _val "${_flag}")
  96. list(APPEND _GSS_INCLUDE_DIRS "${_val}")
  97. else()
  98. list(APPEND _GSS_CFLAGS "${_flag}")
  99. endif()
  100. endforeach()
  101. endif()
  102. execute_process(
  103. COMMAND ${_gss_configure_script} "--libs" "gssapi"
  104. OUTPUT_VARIABLE _gss_lib_flags
  105. RESULT_VARIABLE _gss_configure_failed
  106. OUTPUT_STRIP_TRAILING_WHITESPACE
  107. )
  108. message(STATUS "FindGSS LDFLAGS: ${_gss_lib_flags}")
  109. if(NOT _gss_configure_failed) # 0 means success
  110. # This script gives us libraries and link directories. Blah. We have to deal with it.
  111. string(STRIP "${_gss_lib_flags}" _gss_lib_flags)
  112. string(REGEX REPLACE " +-(L|l)" ";-\\1" _gss_lib_flags "${_gss_lib_flags}")
  113. string(REGEX REPLACE " +-([^Ll][^ \\t;]*)" ";-\\1" _gss_lib_flags "${_gss_lib_flags}")
  114. foreach(_flag IN LISTS _gss_lib_flags)
  115. if(_flag MATCHES "^-l.*")
  116. string(REGEX REPLACE "^-l" "" _val "${_flag}")
  117. list(APPEND _GSS_LIBRARIES "${_val}")
  118. elseif(_flag MATCHES "^-L.*")
  119. string(REGEX REPLACE "^-L" "" _val "${_flag}")
  120. list(APPEND _GSS_LIBRARY_DIRS "${_val}")
  121. else()
  122. list(APPEND _GSS_LDFLAGS "${_flag}")
  123. endif()
  124. endforeach()
  125. endif()
  126. execute_process(
  127. COMMAND ${_gss_configure_script} "--version"
  128. OUTPUT_VARIABLE _GSS_VERSION
  129. RESULT_VARIABLE _gss_configure_failed
  130. OUTPUT_STRIP_TRAILING_WHITESPACE
  131. )
  132. # Older versions may not have the "--version" parameter. In this case we just do not care.
  133. if(_gss_configure_failed)
  134. set(_GSS_VERSION 0)
  135. endif()
  136. execute_process(
  137. COMMAND ${_gss_configure_script} "--vendor"
  138. OUTPUT_VARIABLE _gss_vendor
  139. RESULT_VARIABLE _gss_configure_failed
  140. OUTPUT_STRIP_TRAILING_WHITESPACE
  141. )
  142. # Older versions may not have the "--vendor" parameter. In this case we just do not care.
  143. if(_gss_configure_failed)
  144. set(GSS_FLAVOUR "Heimdal") # most probably, should not really matter
  145. else()
  146. if(_gss_vendor MATCHES ".*H|heimdal.*")
  147. set(GSS_FLAVOUR "Heimdal")
  148. else()
  149. set(GSS_FLAVOUR "MIT")
  150. endif()
  151. endif()
  152. else() # Either there is no config script or we are on a platform that does not provide one (Windows?)
  153. find_path(_GSS_INCLUDE_DIRS NAMES "gssapi/gssapi.h"
  154. HINTS
  155. ${_gss_root_hints}
  156. PATH_SUFFIXES
  157. "include"
  158. "inc"
  159. )
  160. if(_GSS_INCLUDE_DIRS) # jay, we have found something
  161. set(CMAKE_REQUIRED_INCLUDES "${_GSS_INCLUDE_DIRS}")
  162. check_include_files("gssapi/gssapi_generic.h;gssapi/gssapi_krb5.h" _gss_have_mit_headers)
  163. if(_gss_have_mit_headers)
  164. set(GSS_FLAVOUR "MIT")
  165. else()
  166. # Prevent compiling the header - just check if we can include it
  167. list(APPEND CMAKE_REQUIRED_DEFINITIONS "-D__ROKEN_H__")
  168. check_include_file("roken.h" _gss_have_roken_h)
  169. check_include_file("heimdal/roken.h" _gss_have_heimdal_roken_h)
  170. if(_gss_have_roken_h OR _gss_have_heimdal_roken_h)
  171. set(GSS_FLAVOUR "Heimdal")
  172. endif()
  173. list(REMOVE_ITEM CMAKE_REQUIRED_DEFINITIONS "-D__ROKEN_H__")
  174. endif()
  175. else()
  176. # I am not convinced if this is the right way but this is what autotools do at the moment
  177. find_path(_GSS_INCLUDE_DIRS NAMES "gssapi.h"
  178. HINTS
  179. ${_gss_root_hints}
  180. PATH_SUFFIXES
  181. "include"
  182. "inc"
  183. )
  184. if(_GSS_INCLUDE_DIRS)
  185. set(GSS_FLAVOUR "Heimdal")
  186. else()
  187. find_path(_GSS_INCLUDE_DIRS NAMES "gss.h"
  188. HINTS
  189. ${_gss_root_hints}
  190. PATH_SUFFIXES
  191. "include"
  192. )
  193. if(_GSS_INCLUDE_DIRS)
  194. set(GSS_FLAVOUR "GNU")
  195. endif()
  196. endif()
  197. endif()
  198. # If we have headers, check if we can link libraries
  199. if(GSS_FLAVOUR)
  200. set(_gss_libdir_suffixes "")
  201. set(_gss_libdir_hints ${_gss_root_hints})
  202. get_filename_component(_gss_calculated_potential_root "${_GSS_INCLUDE_DIRS}" DIRECTORY)
  203. list(APPEND _gss_libdir_hints ${_gss_calculated_potential_root})
  204. if(WIN32)
  205. if(CMAKE_SIZEOF_VOID_P EQUAL 8)
  206. list(APPEND _gss_libdir_suffixes "lib/AMD64")
  207. if(GSS_FLAVOUR STREQUAL "GNU")
  208. set(_gss_libname "gss")
  209. elseif(GSS_FLAVOUR STREQUAL "MIT")
  210. set(_gss_libname "gssapi64")
  211. else()
  212. set(_gss_libname "libgssapi")
  213. endif()
  214. else()
  215. list(APPEND _gss_libdir_suffixes "lib/i386")
  216. if(GSS_FLAVOUR STREQUAL "GNU")
  217. set(_gss_libname "gss")
  218. elseif(GSS_FLAVOUR STREQUAL "MIT")
  219. set(_gss_libname "gssapi32")
  220. else()
  221. set(_gss_libname "libgssapi")
  222. endif()
  223. endif()
  224. else()
  225. list(APPEND _gss_libdir_suffixes "lib;lib64") # those suffixes are not checked for HINTS
  226. if(GSS_FLAVOUR STREQUAL "GNU")
  227. set(_gss_libname "gss")
  228. elseif(GSS_FLAVOUR STREQUAL "MIT")
  229. set(_gss_libname "gssapi_krb5")
  230. else()
  231. set(_gss_libname "gssapi")
  232. endif()
  233. endif()
  234. find_library(_GSS_LIBRARIES NAMES ${_gss_libname}
  235. HINTS
  236. ${_gss_libdir_hints}
  237. PATH_SUFFIXES
  238. ${_gss_libdir_suffixes}
  239. )
  240. endif()
  241. endif()
  242. else()
  243. # _GSS_MODULE_NAME set since CMake 3.16
  244. if(_GSS_MODULE_NAME STREQUAL _gnu_modname OR _GSS_${_gnu_modname}_VERSION)
  245. set(GSS_FLAVOUR "GNU")
  246. if(NOT _GSS_VERSION) # for old CMake versions?
  247. set(_GSS_VERSION ${_GSS_${_gnu_modname}_VERSION})
  248. endif()
  249. elseif(_GSS_MODULE_NAME STREQUAL _mit_modname OR _GSS_${_mit_modname}_VERSION)
  250. set(GSS_FLAVOUR "MIT")
  251. if(NOT _GSS_VERSION) # for old CMake versions?
  252. set(_GSS_VERSION ${_GSS_${_mit_modname}_VERSION})
  253. endif()
  254. else()
  255. set(GSS_FLAVOUR "Heimdal")
  256. if(NOT _GSS_VERSION) # for old CMake versions?
  257. set(_GSS_VERSION ${_GSS_${_heimdal_modname}_VERSION})
  258. endif()
  259. endif()
  260. message(STATUS "Found GSS/${GSS_FLAVOUR} (via pkg-config): ${_GSS_INCLUDE_DIRS} (found version \"${_GSS_VERSION}\")")
  261. endif()
  262. set(GSS_INCLUDE_DIRS ${_GSS_INCLUDE_DIRS})
  263. set(GSS_LIBRARIES ${_GSS_LIBRARIES})
  264. set(GSS_LIBRARY_DIRS ${_GSS_LIBRARY_DIRS})
  265. set(GSS_LDFLAGS ${_GSS_LDFLAGS})
  266. set(GSS_CFLAGS ${_GSS_CFLAGS})
  267. set(GSS_VERSION ${_GSS_VERSION})
  268. if(GSS_FLAVOUR)
  269. if(NOT GSS_VERSION AND GSS_FLAVOUR STREQUAL "Heimdal")
  270. if(CMAKE_SIZEOF_VOID_P EQUAL 8)
  271. set(_heimdal_manifest_file "Heimdal.Application.amd64.manifest")
  272. else()
  273. set(_heimdal_manifest_file "Heimdal.Application.x86.manifest")
  274. endif()
  275. if(EXISTS "${GSS_INCLUDE_DIRS}/${_heimdal_manifest_file}")
  276. file(STRINGS "${GSS_INCLUDE_DIRS}/${_heimdal_manifest_file}" _heimdal_version_str
  277. REGEX "^.*version=\"[0-9]\\.[^\"]+\".*$")
  278. string(REGEX MATCH "[0-9]\\.[^\"]+" GSS_VERSION "${_heimdal_version_str}")
  279. endif()
  280. if(NOT GSS_VERSION)
  281. set(GSS_VERSION "Heimdal Unknown")
  282. endif()
  283. elseif(NOT GSS_VERSION AND GSS_FLAVOUR STREQUAL "MIT")
  284. get_filename_component(_mit_version "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MIT\\Kerberos\\SDK\\CurrentVersion;VersionString]" NAME
  285. CACHE)
  286. if(WIN32 AND _mit_version)
  287. set(GSS_VERSION "${_mit_version}")
  288. else()
  289. set(GSS_VERSION "MIT Unknown")
  290. endif()
  291. elseif(NOT GSS_VERSION AND GSS_FLAVOUR STREQUAL "GNU")
  292. if(GSS_INCLUDE_DIRS AND EXISTS "${GSS_INCLUDE_DIRS}/gss.h")
  293. set(_version_regex "#[\t ]*define[\t ]+GSS_VERSION[\t ]+\"([^\"]*)\"")
  294. file(STRINGS "${GSS_INCLUDE_DIRS}/gss.h" _version_str REGEX "${_version_regex}")
  295. string(REGEX REPLACE "${_version_regex}" "\\1" _version_str "${_version_str}")
  296. set(GSS_VERSION "${_version_str}")
  297. unset(_version_regex)
  298. unset(_version_str)
  299. endif()
  300. endif()
  301. endif()
  302. include(FindPackageHandleStandardArgs)
  303. find_package_handle_standard_args(GSS
  304. REQUIRED_VARS
  305. GSS_FLAVOUR
  306. GSS_LIBRARIES
  307. VERSION_VAR
  308. GSS_VERSION
  309. FAIL_MESSAGE
  310. "Could NOT find GSS, try to set the path to GSS root folder in the system variable GSS_ROOT_DIR"
  311. )
  312. mark_as_advanced(
  313. _GSS_CFLAGS
  314. _GSS_FOUND
  315. _GSS_INCLUDE_DIRS
  316. _GSS_LDFLAGS
  317. _GSS_LIBRARIES
  318. _GSS_LIBRARY_DIRS
  319. _GSS_MODULE_NAME
  320. _GSS_PREFIX
  321. _GSS_VERSION
  322. )