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