• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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# by Tetetest and Sukender (Benoit Neil)
25
26# Note: By default this CMake build script detects the version of some
27# dependencies using `check_symbol_exists`.  Those checks do not work
28# in the case that both CURL and its dependency are included as
29# sub-projects in a larger build using `FetchContent`.  To support
30# that case, additional variables may be defined by the parent
31# project, ideally in the "extra" find package redirect file:
32# https://cmake.org/cmake/help/latest/module/FetchContent.html#integrating-with-find-package
33#
34# The following variables are available:
35#   HAVE_SSL_SET0_WBIO: `SSL_set0_wbio` present in OpenSSL/wolfSSL
36#   HAVE_OPENSSL_SRP: `SSL_CTX_set_srp_username` present in OpenSSL/wolfSSL
37#   HAVE_GNUTLS_SRP: `gnutls_srp_verifier` present in GnuTLS
38#   HAVE_SSL_CTX_SET_QUIC_METHOD: `SSL_CTX_set_quic_method` present in OpenSSL/wolfSSL
39#   HAVE_QUICHE_CONN_SET_QLOG_FD: `quiche_conn_set_qlog_fd` present in QUICHE
40#
41# For each of the above variables, if the variable is DEFINED (either
42# to ON or OFF), the symbol detection will be skipped.  If the
43# variable is NOT DEFINED, the symbol detection will be performed.
44
45cmake_minimum_required(VERSION 3.7...3.16 FATAL_ERROR)
46message(STATUS "Using CMake version ${CMAKE_VERSION}")
47
48set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake;${CMAKE_MODULE_PATH}")
49include(Utilities)
50include(Macros)
51include(CMakeDependentOption)
52include(CheckCCompilerFlag)
53
54project(CURL C)
55
56file(STRINGS ${CURL_SOURCE_DIR}/include/curl/curlver.h CURL_VERSION_H_CONTENTS REGEX "#define LIBCURL_VERSION( |_NUM )")
57string(REGEX MATCH "#define LIBCURL_VERSION \"[^\"]*"
58  CURL_VERSION ${CURL_VERSION_H_CONTENTS})
59string(REGEX REPLACE "[^\"]+\"" "" CURL_VERSION ${CURL_VERSION})
60string(REGEX MATCH "#define LIBCURL_VERSION_NUM 0x[0-9a-fA-F]+"
61  CURL_VERSION_NUM ${CURL_VERSION_H_CONTENTS})
62string(REGEX REPLACE "[^0]+0x" "" CURL_VERSION_NUM ${CURL_VERSION_NUM})
63
64
65# Setup package meta-data
66# SET(PACKAGE "curl")
67message(STATUS "curl version=[${CURL_VERSION}]")
68# SET(PACKAGE_TARNAME "curl")
69# SET(PACKAGE_NAME "curl")
70# SET(PACKAGE_VERSION "-")
71# SET(PACKAGE_STRING "curl-")
72# SET(PACKAGE_BUGREPORT "a suitable curl mailing list => https://curl.se/mail/")
73set(OPERATING_SYSTEM "${CMAKE_SYSTEM_NAME}")
74if(CMAKE_C_COMPILER_TARGET)
75  set(OS "\"${CMAKE_C_COMPILER_TARGET}\"")
76else()
77  set(OS "\"${CMAKE_SYSTEM_NAME}\"")
78endif()
79
80include_directories(${CURL_SOURCE_DIR}/include)
81
82set(CMAKE_UNITY_BUILD_BATCH_SIZE 0)
83
84option(CURL_WERROR "Turn compiler warnings into errors" OFF)
85option(PICKY_COMPILER "Enable picky compiler options" ON)
86option(BUILD_CURL_EXE "Set to ON to build curl executable." ON)
87option(BUILD_SHARED_LIBS "Build shared libraries" ON)
88option(BUILD_STATIC_LIBS "Build static libraries" OFF)
89option(BUILD_STATIC_CURL "Build curl executable with static libcurl" OFF)
90option(ENABLE_ARES "Set to ON to enable c-ares support" OFF)
91option(CURL_DISABLE_INSTALL "Set to ON to disable installation targets" OFF)
92
93if(WIN32)
94  option(CURL_STATIC_CRT "Set to ON to build libcurl with static CRT on Windows (/MT)." OFF)
95  option(ENABLE_UNICODE "Set to ON to use the Unicode version of the Windows API functions" OFF)
96  set(CURL_TARGET_WINDOWS_VERSION "" CACHE STRING "Minimum target Windows version as hex string")
97  if(CURL_TARGET_WINDOWS_VERSION)
98    add_definitions(-D_WIN32_WINNT=${CURL_TARGET_WINDOWS_VERSION})
99    list(APPEND CMAKE_REQUIRED_DEFINITIONS -D_WIN32_WINNT=${CURL_TARGET_WINDOWS_VERSION})
100    set(CURL_TEST_DEFINES "${CURL_TEST_DEFINES} -D_WIN32_WINNT=${CURL_TARGET_WINDOWS_VERSION}")
101  endif()
102  if(ENABLE_UNICODE)
103    add_definitions(-DUNICODE -D_UNICODE)
104    if(MINGW)
105      add_compile_options(-municode)
106    endif()
107  endif()
108endif()
109option(CURL_LTO "Turn on compiler Link Time Optimizations" OFF)
110
111cmake_dependent_option(ENABLE_THREADED_RESOLVER "Set to ON to enable threaded DNS lookup"
112        ON "NOT ENABLE_ARES"
113        OFF)
114
115option(ENABLE_DEBUG "Set to ON to enable curl debug features" OFF)
116option(ENABLE_CURLDEBUG "Set to ON to build with TrackMemory feature enabled" OFF)
117
118include(PickyWarnings)
119
120if(ENABLE_DEBUG)
121  # DEBUGBUILD will be defined only for Debug builds
122  set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS $<$<CONFIG:Debug>:DEBUGBUILD>)
123  set(ENABLE_CURLDEBUG ON)
124endif()
125
126if(ENABLE_CURLDEBUG)
127  set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS CURLDEBUG)
128endif()
129
130# For debug libs and exes, add "-d" postfix
131if(NOT DEFINED CMAKE_DEBUG_POSTFIX)
132  set(CMAKE_DEBUG_POSTFIX "-d")
133endif()
134
135set(LIB_STATIC "libcurl_static")
136set(LIB_SHARED "libcurl_shared")
137
138if(NOT BUILD_SHARED_LIBS AND NOT BUILD_STATIC_LIBS)
139  set(BUILD_STATIC_LIBS ON)
140endif()
141if(NOT BUILD_STATIC_CURL AND NOT BUILD_SHARED_LIBS)
142  set(BUILD_STATIC_CURL ON)
143elseif(BUILD_STATIC_CURL AND NOT BUILD_STATIC_LIBS)
144  set(BUILD_STATIC_CURL OFF)
145endif()
146
147# lib flavour selected for curl tool
148if(BUILD_STATIC_CURL)
149  set(LIB_SELECTED_FOR_EXE ${LIB_STATIC})
150else()
151  set(LIB_SELECTED_FOR_EXE ${LIB_SHARED})
152endif()
153
154# lib flavour selected for example and test programs.
155if(BUILD_SHARED_LIBS)
156  set(LIB_SELECTED ${LIB_SHARED})
157else()
158  set(LIB_SELECTED ${LIB_STATIC})
159endif()
160
161# initialize CURL_LIBS
162set(CURL_LIBS "")
163
164if(ENABLE_ARES)
165  set(USE_ARES 1)
166  find_package(CARES REQUIRED)
167  list(APPEND CURL_LIBS ${CARES_LIBRARY})
168endif()
169
170include(CurlSymbolHiding)
171
172option(CURL_ENABLE_EXPORT_TARGET "to enable cmake export target" ON)
173mark_as_advanced(CURL_ENABLE_EXPORT_TARGET)
174
175option(CURL_DISABLE_ALTSVC "disables alt-svc support" OFF)
176mark_as_advanced(CURL_DISABLE_ALTSVC)
177option(CURL_DISABLE_SRP "disables TLS-SRP support" OFF)
178mark_as_advanced(CURL_DISABLE_SRP)
179option(CURL_DISABLE_COOKIES "disables cookies support" OFF)
180mark_as_advanced(CURL_DISABLE_COOKIES)
181option(CURL_DISABLE_BASIC_AUTH "disables Basic authentication" OFF)
182mark_as_advanced(CURL_DISABLE_BASIC_AUTH)
183option(CURL_DISABLE_BEARER_AUTH "disables Bearer authentication" OFF)
184mark_as_advanced(CURL_DISABLE_BEARER_AUTH)
185option(CURL_DISABLE_DIGEST_AUTH "disables Digest authentication" OFF)
186mark_as_advanced(CURL_DISABLE_DIGEST_AUTH)
187option(CURL_DISABLE_KERBEROS_AUTH "disables Kerberos authentication" OFF)
188mark_as_advanced(CURL_DISABLE_KERBEROS_AUTH)
189option(CURL_DISABLE_NEGOTIATE_AUTH "disables negotiate authentication" OFF)
190mark_as_advanced(CURL_DISABLE_NEGOTIATE_AUTH)
191option(CURL_DISABLE_AWS "disables AWS-SIG4" OFF)
192mark_as_advanced(CURL_DISABLE_AWS)
193option(CURL_DISABLE_DICT "disables DICT" OFF)
194mark_as_advanced(CURL_DISABLE_DICT)
195option(CURL_DISABLE_DOH "disables DNS-over-HTTPS" OFF)
196mark_as_advanced(CURL_DISABLE_DOH)
197option(CURL_DISABLE_FILE "disables FILE" OFF)
198mark_as_advanced(CURL_DISABLE_FILE)
199cmake_dependent_option(CURL_DISABLE_FORM_API "disables form api" OFF
200                       "NOT CURL_DISABLE_MIME" ON)
201mark_as_advanced(CURL_DISABLE_FORM_API)
202option(CURL_DISABLE_FTP "disables FTP" OFF)
203mark_as_advanced(CURL_DISABLE_FTP)
204option(CURL_DISABLE_GETOPTIONS "disables curl_easy_options API for existing options to curl_easy_setopt" OFF)
205mark_as_advanced(CURL_DISABLE_GETOPTIONS)
206option(CURL_DISABLE_GOPHER "disables Gopher" OFF)
207mark_as_advanced(CURL_DISABLE_GOPHER)
208option(CURL_DISABLE_HEADERS_API "disables headers-api support" OFF)
209mark_as_advanced(CURL_DISABLE_HEADERS_API)
210option(CURL_DISABLE_HSTS "disables HSTS support" OFF)
211mark_as_advanced(CURL_DISABLE_HSTS)
212option(CURL_DISABLE_HTTP "disables HTTP" OFF)
213mark_as_advanced(CURL_DISABLE_HTTP)
214option(CURL_DISABLE_HTTP_AUTH "disables all HTTP authentication methods" OFF)
215mark_as_advanced(CURL_DISABLE_HTTP_AUTH)
216option(CURL_DISABLE_IMAP "disables IMAP" OFF)
217mark_as_advanced(CURL_DISABLE_IMAP)
218option(CURL_DISABLE_LDAP "disables LDAP" OFF)
219mark_as_advanced(CURL_DISABLE_LDAP)
220option(CURL_DISABLE_LDAPS "disables LDAPS" OFF)
221mark_as_advanced(CURL_DISABLE_LDAPS)
222option(CURL_DISABLE_LIBCURL_OPTION "disables --libcurl option from the curl tool" OFF)
223mark_as_advanced(CURL_DISABLE_LIBCURL_OPTION)
224option(CURL_DISABLE_MIME "disables MIME support" OFF)
225mark_as_advanced(CURL_DISABLE_MIME)
226option(CURL_DISABLE_MQTT "disables MQTT" OFF)
227mark_as_advanced(CURL_DISABLE_BINDLOCAL)
228option(CURL_DISABLE_BINDLOCAL "disables local binding support" OFF)
229mark_as_advanced(CURL_DISABLE_MQTT)
230option(CURL_DISABLE_NETRC "disables netrc parser" OFF)
231mark_as_advanced(CURL_DISABLE_NETRC)
232option(CURL_DISABLE_NTLM "disables NTLM support" OFF)
233mark_as_advanced(CURL_DISABLE_NTLM)
234option(CURL_DISABLE_PARSEDATE "disables date parsing" OFF)
235mark_as_advanced(CURL_DISABLE_PARSEDATE)
236option(CURL_DISABLE_POP3 "disables POP3" OFF)
237mark_as_advanced(CURL_DISABLE_POP3)
238option(CURL_DISABLE_PROGRESS_METER "disables built-in progress meter" OFF)
239mark_as_advanced(CURL_DISABLE_PROGRESS_METER)
240option(CURL_DISABLE_PROXY "disables proxy support" OFF)
241mark_as_advanced(CURL_DISABLE_PROXY)
242option(CURL_DISABLE_RTSP "disables RTSP" OFF)
243mark_as_advanced(CURL_DISABLE_RTSP)
244option(CURL_DISABLE_SHUFFLE_DNS "disables shuffle DNS feature" OFF)
245mark_as_advanced(CURL_DISABLE_SHUFFLE_DNS)
246option(CURL_DISABLE_SMB "disables SMB" OFF)
247mark_as_advanced(CURL_DISABLE_SMB)
248option(CURL_DISABLE_SMTP "disables SMTP" OFF)
249mark_as_advanced(CURL_DISABLE_SMTP)
250option(CURL_DISABLE_SOCKETPAIR "disables use of socketpair for curl_multi_poll" OFF)
251mark_as_advanced(CURL_DISABLE_SOCKETPAIR)
252option(CURL_DISABLE_TELNET "disables Telnet" OFF)
253mark_as_advanced(CURL_DISABLE_TELNET)
254option(CURL_DISABLE_TFTP "disables TFTP" OFF)
255mark_as_advanced(CURL_DISABLE_TFTP)
256option(CURL_DISABLE_VERBOSE_STRINGS "disables verbose strings" OFF)
257mark_as_advanced(CURL_DISABLE_VERBOSE_STRINGS)
258
259# Corresponds to HTTP_ONLY in lib/curl_setup.h
260option(HTTP_ONLY "disables all protocols except HTTP (This overrides all CURL_DISABLE_* options)" OFF)
261mark_as_advanced(HTTP_ONLY)
262
263if(HTTP_ONLY)
264  set(CURL_DISABLE_DICT ON)
265  set(CURL_DISABLE_FILE ON)
266  set(CURL_DISABLE_FTP ON)
267  set(CURL_DISABLE_GOPHER ON)
268  set(CURL_DISABLE_IMAP ON)
269  set(CURL_DISABLE_LDAP ON)
270  set(CURL_DISABLE_LDAPS ON)
271  set(CURL_DISABLE_MQTT ON)
272  set(CURL_DISABLE_POP3 ON)
273  set(CURL_DISABLE_RTSP ON)
274  set(CURL_DISABLE_SMB ON)
275  set(CURL_DISABLE_SMTP ON)
276  set(CURL_DISABLE_TELNET ON)
277  set(CURL_DISABLE_TFTP ON)
278endif()
279
280option(ENABLE_IPV6 "Define if you want to enable IPv6 support" ON)
281mark_as_advanced(ENABLE_IPV6)
282if(ENABLE_IPV6 AND NOT WIN32)
283  include(CheckStructHasMember)
284  check_struct_has_member("struct sockaddr_in6" sin6_addr "netinet/in.h"
285                          HAVE_SOCKADDR_IN6_SIN6_ADDR)
286  check_struct_has_member("struct sockaddr_in6" sin6_scope_id "netinet/in.h"
287                          HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID)
288  if(NOT HAVE_SOCKADDR_IN6_SIN6_ADDR)
289    message(WARNING "struct sockaddr_in6 not available, disabling IPv6 support")
290    # Force the feature off as this name is used as guard macro...
291    set(ENABLE_IPV6 OFF
292        CACHE BOOL "Define if you want to enable IPv6 support" FORCE)
293  endif()
294
295  if(CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND NOT ENABLE_ARES)
296    set(use_core_foundation_and_core_services ON)
297
298    find_library(SYSTEMCONFIGURATION_FRAMEWORK "SystemConfiguration")
299    if(NOT SYSTEMCONFIGURATION_FRAMEWORK)
300      message(FATAL_ERROR "SystemConfiguration framework not found")
301    endif()
302
303    list(APPEND CURL_LIBS "-framework SystemConfiguration")
304  endif()
305endif()
306
307find_package(Perl)
308
309option(BUILD_LIBCURL_DOCS "to build libcurl man pages" ON)
310# curl source release tarballs come with the curl man page pre-built.
311option(ENABLE_CURL_MANUAL "to build the man page for curl and enable its -M/--manual option" OFF)
312
313if(ENABLE_CURL_MANUAL OR BUILD_LIBCURL_DOCS)
314  if(PERL_FOUND)
315    curl_nroff_check()
316    if(NROFF_USEFUL)
317      set(HAVE_MANUAL_TOOLS ON)
318    endif()
319  endif()
320  if(NOT HAVE_MANUAL_TOOLS)
321    message(WARNING "Perl not found, or nroff not useful. Will not build manuals.")
322  endif()
323endif()
324
325if(CURL_STATIC_CRT)
326  set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
327  set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /MT")
328  set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /MTd")
329endif()
330
331# Disable warnings on Borland to avoid changing 3rd party code.
332if(BORLAND)
333  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w-")
334endif()
335
336# If we are on AIX, do the _ALL_SOURCE magic
337if(${CMAKE_SYSTEM_NAME} MATCHES AIX)
338  set(_ALL_SOURCE 1)
339endif()
340
341# If we are on Haiku, make sure that the network library is brought in.
342if(${CMAKE_SYSTEM_NAME} MATCHES Haiku)
343  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -lnetwork")
344endif()
345
346# Include all the necessary files for macros
347include(CMakePushCheckState)
348include(CheckFunctionExists)
349include(CheckIncludeFile)
350include(CheckIncludeFiles)
351include(CheckLibraryExists)
352include(CheckSymbolExists)
353include(CheckTypeSize)
354include(CheckCSourceCompiles)
355
356# On windows preload settings
357if(WIN32)
358  include(${CMAKE_CURRENT_SOURCE_DIR}/CMake/Platforms/WindowsCache.cmake)
359endif()
360
361if(ENABLE_THREADED_RESOLVER)
362  if(WIN32)
363    set(USE_THREADS_WIN32 ON)
364  else()
365    find_package(Threads REQUIRED)
366    set(USE_THREADS_POSIX ${CMAKE_USE_PTHREADS_INIT})
367    set(HAVE_PTHREAD_H ${CMAKE_USE_PTHREADS_INIT})
368    set(CURL_LIBS ${CURL_LIBS} ${CMAKE_THREAD_LIBS_INIT})
369  endif()
370endif()
371
372# Check for all needed libraries
373check_library_exists("socket" "connect" "" HAVE_LIBSOCKET)
374if(HAVE_LIBSOCKET)
375  set(CURL_LIBS "socket;${CURL_LIBS}")
376endif()
377
378check_function_exists(gethostname HAVE_GETHOSTNAME)
379
380if(WIN32)
381  list(APPEND CURL_LIBS "ws2_32" "bcrypt")
382  if(USE_LIBRTMP)
383    list(APPEND CURL_LIBS "winmm")
384  endif()
385endif()
386
387# check SSL libraries
388option(CURL_ENABLE_SSL "Enable SSL support" ON)
389
390if(CURL_DEFAULT_SSL_BACKEND)
391  set(valid_default_ssl_backend FALSE)
392endif()
393
394if(APPLE)
395  cmake_dependent_option(CURL_USE_SECTRANSP "Enable Apple OS native SSL/TLS" OFF CURL_ENABLE_SSL OFF)
396endif()
397if(WIN32)
398  cmake_dependent_option(CURL_USE_SCHANNEL "Enable Windows native SSL/TLS" OFF CURL_ENABLE_SSL OFF)
399  cmake_dependent_option(CURL_WINDOWS_SSPI "Use windows libraries to allow NTLM authentication without OpenSSL" ON
400    CURL_USE_SCHANNEL OFF)
401endif()
402cmake_dependent_option(CURL_USE_MBEDTLS "Enable mbedTLS for SSL/TLS" OFF CURL_ENABLE_SSL OFF)
403cmake_dependent_option(CURL_USE_BEARSSL "Enable BearSSL for SSL/TLS" OFF CURL_ENABLE_SSL OFF)
404cmake_dependent_option(CURL_USE_WOLFSSL "Enable wolfSSL for SSL/TLS" OFF CURL_ENABLE_SSL OFF)
405cmake_dependent_option(CURL_USE_GNUTLS "Enable GnuTLS for SSL/TLS" OFF CURL_ENABLE_SSL OFF)
406
407set(openssl_default ON)
408if(WIN32 OR CURL_USE_SECTRANSP OR CURL_USE_SCHANNEL OR CURL_USE_MBEDTLS OR CURL_USE_WOLFSSL)
409  set(openssl_default OFF)
410endif()
411cmake_dependent_option(CURL_USE_OPENSSL "Enable OpenSSL for SSL/TLS" ${openssl_default} CURL_ENABLE_SSL OFF)
412option(CURL_DISABLE_OPENSSL_AUTO_LOAD_CONFIG "Disable automatic loading of OpenSSL configuration" OFF)
413
414count_true(enabled_ssl_options_count
415  CURL_USE_SCHANNEL
416  CURL_USE_SECTRANSP
417  CURL_USE_OPENSSL
418  CURL_USE_MBEDTLS
419  CURL_USE_BEARSSL
420  CURL_USE_WOLFSSL
421)
422if(enabled_ssl_options_count GREATER "1")
423  set(CURL_WITH_MULTI_SSL ON)
424endif()
425
426if(CURL_USE_SCHANNEL)
427  set(SSL_ENABLED ON)
428  set(USE_SCHANNEL ON) # Windows native SSL/TLS support
429  set(USE_WINDOWS_SSPI ON) # CURL_USE_SCHANNEL implies CURL_WINDOWS_SSPI
430
431  if(CURL_DEFAULT_SSL_BACKEND AND CURL_DEFAULT_SSL_BACKEND STREQUAL "schannel")
432    set(valid_default_ssl_backend TRUE)
433  endif()
434endif()
435if(CURL_WINDOWS_SSPI)
436  set(USE_WINDOWS_SSPI ON)
437endif()
438
439if(CURL_USE_SECTRANSP)
440  set(use_core_foundation_and_core_services ON)
441
442  find_library(SECURITY_FRAMEWORK "Security")
443  if(NOT SECURITY_FRAMEWORK)
444     message(FATAL_ERROR "Security framework not found")
445  endif()
446
447  set(SSL_ENABLED ON)
448  set(USE_SECTRANSP ON)
449  list(APPEND CURL_LIBS "-framework Security")
450
451  if(CURL_DEFAULT_SSL_BACKEND AND CURL_DEFAULT_SSL_BACKEND STREQUAL "secure-transport")
452    set(valid_default_ssl_backend TRUE)
453  endif()
454endif()
455
456if(use_core_foundation_and_core_services)
457  find_library(COREFOUNDATION_FRAMEWORK "CoreFoundation")
458  find_library(CORESERVICES_FRAMEWORK "CoreServices")
459
460  if(NOT COREFOUNDATION_FRAMEWORK)
461      message(FATAL_ERROR "CoreFoundation framework not found")
462  endif()
463  if(NOT CORESERVICES_FRAMEWORK)
464      message(FATAL_ERROR "CoreServices framework not found")
465  endif()
466
467  list(APPEND CURL_LIBS "-framework CoreFoundation -framework CoreServices")
468endif()
469
470if(CURL_USE_OPENSSL)
471  find_package(OpenSSL REQUIRED)
472  set(SSL_ENABLED ON)
473  set(USE_OPENSSL ON)
474
475  # Depend on OpenSSL via imported targets if supported by the running
476  # version of CMake.  This allows our dependents to get our dependencies
477  # transitively.
478  if(NOT CMAKE_VERSION VERSION_LESS 3.4)
479    list(APPEND CURL_LIBS OpenSSL::SSL OpenSSL::Crypto)
480  else()
481    list(APPEND CURL_LIBS ${OPENSSL_LIBRARIES})
482    include_directories(${OPENSSL_INCLUDE_DIR})
483  endif()
484
485  if(CURL_DEFAULT_SSL_BACKEND AND CURL_DEFAULT_SSL_BACKEND STREQUAL "openssl")
486    set(valid_default_ssl_backend TRUE)
487  endif()
488
489  set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
490  if(NOT DEFINED HAVE_BORINGSSL)
491    check_symbol_exists(OPENSSL_IS_BORINGSSL "openssl/base.h" HAVE_BORINGSSL)
492  endif()
493  if(NOT DEFINED HAVE_AWSLC)
494    check_symbol_exists(OPENSSL_IS_AWSLC "openssl/base.h" HAVE_AWSLC)
495  endif()
496endif()
497
498if(CURL_USE_MBEDTLS)
499  find_package(MbedTLS REQUIRED)
500  set(SSL_ENABLED ON)
501  set(USE_MBEDTLS ON)
502  list(APPEND CURL_LIBS ${MBEDTLS_LIBRARIES})
503  include_directories(${MBEDTLS_INCLUDE_DIRS})
504
505  if(CURL_DEFAULT_SSL_BACKEND AND CURL_DEFAULT_SSL_BACKEND STREQUAL "mbedtls")
506    set(valid_default_ssl_backend TRUE)
507  endif()
508endif()
509
510if(CURL_USE_BEARSSL)
511  find_package(BearSSL REQUIRED)
512  set(SSL_ENABLED ON)
513  set(USE_BEARSSL ON)
514  list(APPEND CURL_LIBS ${BEARSSL_LIBRARY})
515  include_directories(${BEARSSL_INCLUDE_DIRS})
516
517  if(CURL_DEFAULT_SSL_BACKEND AND CURL_DEFAULT_SSL_BACKEND STREQUAL "bearssl")
518    set(valid_default_ssl_backend TRUE)
519  endif()
520endif()
521
522if(CURL_USE_WOLFSSL)
523  find_package(WolfSSL REQUIRED)
524  set(SSL_ENABLED ON)
525  set(USE_WOLFSSL ON)
526  list(APPEND CURL_LIBS ${WolfSSL_LIBRARIES})
527  include_directories(${WolfSSL_INCLUDE_DIRS})
528
529  if(CURL_DEFAULT_SSL_BACKEND AND CURL_DEFAULT_SSL_BACKEND STREQUAL "wolfssl")
530    set(valid_default_ssl_backend TRUE)
531  endif()
532endif()
533
534if(CURL_USE_GNUTLS)
535  find_package(GnuTLS REQUIRED)
536  set(SSL_ENABLED ON)
537  set(USE_GNUTLS ON)
538  list(APPEND CURL_LIBS ${GNUTLS_LIBRARIES} "nettle")
539  include_directories(${GNUTLS_INCLUDE_DIRS})
540
541  if(CURL_DEFAULT_SSL_BACKEND AND CURL_DEFAULT_SSL_BACKEND STREQUAL "gnutls")
542    set(valid_default_ssl_backend TRUE)
543  endif()
544
545  if(NOT DEFINED HAVE_GNUTLS_SRP AND NOT CURL_DISABLE_SRP)
546    cmake_push_check_state()
547    set(CMAKE_REQUIRED_INCLUDES ${GNUTLS_INCLUDE_DIRS})
548    set(CMAKE_REQUIRED_LIBRARIES ${GNUTLS_LIBRARIES})
549    check_symbol_exists(gnutls_srp_verifier "gnutls/gnutls.h" HAVE_GNUTLS_SRP)
550    cmake_pop_check_state()
551  endif()
552endif()
553
554if(CURL_DEFAULT_SSL_BACKEND AND NOT valid_default_ssl_backend)
555  message(FATAL_ERROR "CURL_DEFAULT_SSL_BACKEND '${CURL_DEFAULT_SSL_BACKEND}' not enabled.")
556endif()
557
558# Keep ZLIB detection after TLS detection,
559# and before calling openssl_check_symbol_exists().
560
561set(HAVE_LIBZ OFF)
562set(USE_ZLIB OFF)
563optional_dependency(ZLIB)
564if(ZLIB_FOUND)
565  set(HAVE_LIBZ ON)
566  set(USE_ZLIB ON)
567
568  # Depend on ZLIB via imported targets if supported by the running
569  # version of CMake.  This allows our dependents to get our dependencies
570  # transitively.
571  if(NOT CMAKE_VERSION VERSION_LESS 3.4)
572    list(APPEND CURL_LIBS ZLIB::ZLIB)
573  else()
574    list(APPEND CURL_LIBS ${ZLIB_LIBRARIES})
575    include_directories(${ZLIB_INCLUDE_DIRS})
576  endif()
577  list(APPEND CMAKE_REQUIRED_INCLUDES ${ZLIB_INCLUDE_DIRS})
578endif()
579
580option(CURL_BROTLI "Set to ON to enable building curl with brotli support." OFF)
581set(HAVE_BROTLI OFF)
582if(CURL_BROTLI)
583  find_package(Brotli REQUIRED)
584  if(BROTLI_FOUND)
585    set(HAVE_BROTLI ON)
586    set(CURL_LIBS "${BROTLI_LIBRARIES};${CURL_LIBS}")  # For 'ld' linker. Emulate `list(PREPEND ...)` to stay compatible with <v3.15 CMake.
587    list(APPEND CURL_LIBS ${BROTLI_LIBRARIES})
588    include_directories(${BROTLI_INCLUDE_DIRS})
589    list(APPEND CMAKE_REQUIRED_INCLUDES ${BROTLI_INCLUDE_DIRS})
590  endif()
591endif()
592
593option(CURL_ZSTD "Set to ON to enable building curl with zstd support." OFF)
594set(HAVE_ZSTD OFF)
595if(CURL_ZSTD)
596  find_package(Zstd REQUIRED)
597  if(Zstd_FOUND AND NOT Zstd_VERSION VERSION_LESS "1.0.0")
598    set(HAVE_ZSTD ON)
599    list(APPEND CURL_LIBS ${Zstd_LIBRARIES})
600    include_directories(${Zstd_INCLUDE_DIRS})
601  else()
602    message(WARNING "zstd v1.0.0 or newer is required, disabling zstd support.")
603  endif()
604endif()
605
606# Check symbol in OpenSSL-like TLS backends.
607macro(openssl_check_symbol_exists SYMBOL FILES VARIABLE)
608  cmake_push_check_state()
609  if(USE_OPENSSL)
610    set(CMAKE_REQUIRED_INCLUDES   "${OPENSSL_INCLUDE_DIR}")
611    set(CMAKE_REQUIRED_LIBRARIES  "${OPENSSL_LIBRARIES}")
612    if(HAVE_LIBZ)
613      list(APPEND CMAKE_REQUIRED_LIBRARIES "${ZLIB_LIBRARIES}")
614    endif()
615    if(WIN32)
616      list(APPEND CMAKE_REQUIRED_LIBRARIES "ws2_32")
617      list(APPEND CMAKE_REQUIRED_LIBRARIES "bcrypt")  # for OpenSSL/LibreSSL
618    endif()
619  elseif(USE_WOLFSSL)
620    set(CMAKE_REQUIRED_INCLUDES   "${WolfSSL_INCLUDE_DIRS}")
621    set(CMAKE_REQUIRED_LIBRARIES  "${WolfSSL_LIBRARIES}")
622    if(HAVE_LIBZ)
623      list(APPEND CMAKE_REQUIRED_INCLUDES  "${ZLIB_INCLUDE_DIRS}")  # Public wolfSSL headers require zlib headers
624      list(APPEND CMAKE_REQUIRED_LIBRARIES "${ZLIB_LIBRARIES}")
625    endif()
626    if(WIN32)
627      list(APPEND CMAKE_REQUIRED_LIBRARIES "ws2_32" "crypt32")
628    endif()
629    list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_UINTPTR_T)  # to pull in stdint.h (as of wolfSSL v5.5.4)
630  endif()
631  check_symbol_exists("${SYMBOL}" "${FILES}" "${VARIABLE}")
632  cmake_pop_check_state()
633endmacro()
634
635# Ensure that the OpenSSL fork actually supports QUIC.
636macro(openssl_check_quic)
637  if(NOT DEFINED HAVE_SSL_CTX_SET_QUIC_METHOD)
638    if(USE_OPENSSL)
639      openssl_check_symbol_exists(SSL_CTX_set_quic_method "openssl/ssl.h" HAVE_SSL_CTX_SET_QUIC_METHOD)
640    elseif(USE_WOLFSSL)
641      openssl_check_symbol_exists(wolfSSL_set_quic_method "wolfssl/options.h;wolfssl/openssl/ssl.h" HAVE_SSL_CTX_SET_QUIC_METHOD)
642    endif()
643  endif()
644  if(NOT HAVE_SSL_CTX_SET_QUIC_METHOD)
645    message(FATAL_ERROR "QUIC support is missing in OpenSSL fork. Try setting -DOPENSSL_ROOT_DIR")
646  endif()
647endmacro()
648
649if(USE_OPENSSL OR USE_WOLFSSL)
650  if(NOT DEFINED HAVE_SSL_SET0_WBIO)
651    openssl_check_symbol_exists(SSL_set0_wbio "openssl/ssl.h" HAVE_SSL_SET0_WBIO)
652  endif()
653  if(NOT DEFINED HAVE_OPENSSL_SRP AND NOT CURL_DISABLE_SRP)
654    openssl_check_symbol_exists(SSL_CTX_set_srp_username "openssl/ssl.h" HAVE_OPENSSL_SRP)
655  endif()
656endif()
657
658option(USE_NGHTTP2 "Use nghttp2 library" OFF)
659if(USE_NGHTTP2)
660  find_package(NGHTTP2 REQUIRED)
661  include_directories(${NGHTTP2_INCLUDE_DIRS})
662  list(APPEND CURL_LIBS ${NGHTTP2_LIBRARIES})
663endif()
664
665option(USE_NGTCP2 "Use ngtcp2 and nghttp3 libraries for HTTP/3 support" OFF)
666if(USE_NGTCP2)
667  if(USE_OPENSSL OR USE_WOLFSSL)
668    if(USE_WOLFSSL)
669      find_package(NGTCP2 REQUIRED wolfSSL)
670    elseif(HAVE_BORINGSSL OR HAVE_AWSLC)
671      find_package(NGTCP2 REQUIRED BoringSSL)
672    else()
673      find_package(NGTCP2 REQUIRED quictls)
674    endif()
675    openssl_check_quic()
676  elseif(USE_GNUTLS)
677    find_package(NGTCP2 REQUIRED GnuTLS)
678  else()
679    message(FATAL_ERROR "ngtcp2 requires OpenSSL, wolfSSL or GnuTLS")
680  endif()
681  set(USE_NGTCP2 ON)
682  include_directories(${NGTCP2_INCLUDE_DIRS})
683  list(APPEND CURL_LIBS ${NGTCP2_LIBRARIES})
684
685  find_package(NGHTTP3 REQUIRED)
686  set(USE_NGHTTP3 ON)
687  include_directories(${NGHTTP3_INCLUDE_DIRS})
688  list(APPEND CURL_LIBS ${NGHTTP3_LIBRARIES})
689endif()
690
691option(USE_QUICHE "Use quiche library for HTTP/3 support" OFF)
692if(USE_QUICHE)
693  if(USE_NGTCP2)
694    message(FATAL_ERROR "Only one HTTP/3 backend can be selected!")
695  endif()
696  find_package(QUICHE REQUIRED)
697  if(NOT HAVE_BORINGSSL)
698    message(FATAL_ERROR "quiche requires BoringSSL")
699  endif()
700  openssl_check_quic()
701  set(USE_QUICHE ON)
702  include_directories(${QUICHE_INCLUDE_DIRS})
703  list(APPEND CURL_LIBS ${QUICHE_LIBRARIES})
704  if(NOT DEFINED HAVE_QUICHE_CONN_SET_QLOG_FD)
705    cmake_push_check_state()
706    set(CMAKE_REQUIRED_INCLUDES   "${QUICHE_INCLUDE_DIRS}")
707    set(CMAKE_REQUIRED_LIBRARIES  "${QUICHE_LIBRARIES}")
708    check_symbol_exists(quiche_conn_set_qlog_fd "quiche.h" HAVE_QUICHE_CONN_SET_QLOG_FD)
709    cmake_pop_check_state()
710  endif()
711endif()
712
713option(USE_MSH3 "Use msquic library for HTTP/3 support" OFF)
714if(USE_MSH3)
715  if(USE_NGTCP2 OR USE_QUICHE)
716    message(FATAL_ERROR "Only one HTTP/3 backend can be selected!")
717  endif()
718  set(USE_MSH3 ON)
719  include_directories(${MSH3_INCLUDE_DIRS})
720  list(APPEND CURL_LIBS ${MSH3_LIBRARIES})
721endif()
722
723if(CURL_WITH_MULTI_SSL AND (USE_NGTCP2 OR USE_QUICHE OR USE_MSH3))
724  message(FATAL_ERROR "MultiSSL cannot be enabled with HTTP/3 and vice versa.")
725endif()
726
727if(NOT CURL_DISABLE_SRP AND (HAVE_GNUTLS_SRP OR HAVE_OPENSSL_SRP))
728  set(USE_TLS_SRP 1)
729endif()
730
731if(NOT CURL_DISABLE_LDAP)
732  if(WIN32)
733    option(USE_WIN32_LDAP "Use Windows LDAP implementation" ON)
734    if(USE_WIN32_LDAP)
735      list(APPEND CURL_LIBS "wldap32")
736      if(NOT CURL_DISABLE_LDAPS)
737        set(HAVE_LDAP_SSL ON)
738      endif()
739    endif()
740  endif()
741
742  set(CMAKE_LDAP_LIB "ldap" CACHE STRING "Name or full path to ldap library")
743  set(CMAKE_LBER_LIB "lber" CACHE STRING "Name or full path to lber library")
744
745  # Now that we know, we're not using windows LDAP...
746  if(NOT USE_WIN32_LDAP)
747    # Check for LDAP
748    set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_LIBRARIES})
749    check_library_exists("${CMAKE_LDAP_LIB}" "ldap_init" "" HAVE_LIBLDAP)
750    if(HAVE_LIBLDAP)
751      check_library_exists("${CMAKE_LDAP_LIB};${CMAKE_LBER_LIB}" "ber_init" "" HAVE_LIBLBER)
752    else()
753      check_library_exists("${CMAKE_LBER_LIB}" "ber_init" "" HAVE_LIBLBER)
754    endif()
755
756    set(CMAKE_REQUIRED_INCLUDES_BAK ${CMAKE_REQUIRED_INCLUDES})
757    set(CMAKE_LDAP_INCLUDE_DIR "" CACHE STRING "Path to LDAP include directory")
758    if(CMAKE_LDAP_INCLUDE_DIR)
759      list(APPEND CMAKE_REQUIRED_INCLUDES ${CMAKE_LDAP_INCLUDE_DIR})
760    endif()
761    check_include_file_concat("ldap.h"           HAVE_LDAP_H)
762    check_include_file_concat("lber.h"           HAVE_LBER_H)
763
764    if(NOT HAVE_LDAP_H)
765      message(STATUS "LDAP_H not found CURL_DISABLE_LDAP set ON")
766      set(CURL_DISABLE_LDAP ON CACHE BOOL "" FORCE)
767      set(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES_BAK}) #LDAP includes won't be used
768    elseif(NOT HAVE_LIBLDAP)
769      message(STATUS "LDAP library '${CMAKE_LDAP_LIB}' not found CURL_DISABLE_LDAP set ON")
770      set(CURL_DISABLE_LDAP ON CACHE BOOL "" FORCE)
771      set(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES_BAK}) #LDAP includes won't be used
772    else()
773      if(CMAKE_LDAP_INCLUDE_DIR)
774        include_directories(${CMAKE_LDAP_INCLUDE_DIR})
775      endif()
776      set(NEED_LBER_H ON)
777      set(_HEADER_LIST)
778      if(WIN32)
779        list(APPEND _HEADER_LIST "windows.h")
780      endif()
781      if(HAVE_SYS_TYPES_H)
782        list(APPEND _HEADER_LIST "sys/types.h")
783      endif()
784      list(APPEND _HEADER_LIST "ldap.h")
785
786      set(_INCLUDE_STRING "")
787      foreach(_HEADER ${_HEADER_LIST})
788        set(_INCLUDE_STRING "${_INCLUDE_STRING}#include <${_HEADER}>\n")
789      endforeach()
790
791      list(APPEND CMAKE_REQUIRED_DEFINITIONS -DLDAP_DEPRECATED=1)
792      list(APPEND CMAKE_REQUIRED_LIBRARIES ${CMAKE_LDAP_LIB})
793      set(CURL_LIBS "${CMAKE_LDAP_LIB};${CURL_LIBS}")
794      if(HAVE_LIBLBER)
795        list(APPEND CMAKE_REQUIRED_LIBRARIES ${CMAKE_LBER_LIB})
796        set(CURL_LIBS "${CMAKE_LBER_LIB};${CURL_LIBS}")
797      endif()
798
799      check_c_source_compiles("
800        ${_INCLUDE_STRING}
801        int main(int argc, char ** argv)
802        {
803          BerValue *bvp = NULL;
804          BerElement *bep = ber_init(bvp);
805          ber_free(bep, 1);
806          return 0;
807        }" NOT_NEED_LBER_H)
808      if(NOT_NEED_LBER_H)
809        set(NEED_LBER_H OFF)
810      else()
811        set(CURL_TEST_DEFINES "${CURL_TEST_DEFINES} -DNEED_LBER_H")
812      endif()
813
814      check_function_exists(ldap_url_parse HAVE_LDAP_URL_PARSE)
815      check_function_exists(ldap_init_fd HAVE_LDAP_INIT_FD)
816
817      unset(CMAKE_REQUIRED_LIBRARIES)
818
819      check_include_file("ldap_ssl.h" HAVE_LDAP_SSL_H)
820
821      if(HAVE_LDAP_INIT_FD)
822        set(USE_OPENLDAP ON)
823        add_definitions("-DLDAP_DEPRECATED=1")
824      endif()
825      if(NOT CURL_DISABLE_LDAPS)
826        set(HAVE_LDAP_SSL ON)
827      endif()
828    endif()
829  endif()
830endif()
831
832# No ldap, no ldaps.
833if(CURL_DISABLE_LDAP)
834  if(NOT CURL_DISABLE_LDAPS)
835    message(STATUS "LDAP needs to be enabled to support LDAPS")
836    set(CURL_DISABLE_LDAPS ON CACHE BOOL "" FORCE)
837  endif()
838endif()
839
840# Check for idn2
841option(USE_LIBIDN2 "Use libidn2 for IDN support" ON)
842if(USE_LIBIDN2)
843  check_library_exists("idn2" "idn2_lookup_ul" "" HAVE_LIBIDN2)
844  if(HAVE_LIBIDN2)
845    set(CURL_LIBS "idn2;${CURL_LIBS}")
846    check_include_file_concat("idn2.h" HAVE_IDN2_H)
847  endif()
848else()
849  set(HAVE_LIBIDN2 OFF)
850endif()
851
852if(WIN32)
853  option(USE_WIN32_IDN "Use WinIDN for IDN support" OFF)
854  if(USE_WIN32_IDN)
855    list(APPEND CURL_LIBS "normaliz")
856  endif()
857endif()
858
859#libpsl
860option(CURL_USE_LIBPSL "Use libPSL" ON)
861mark_as_advanced(CURL_USE_LIBPSL)
862set(USE_LIBPSL OFF)
863
864if(CURL_USE_LIBPSL)
865  find_package(LibPSL)
866  if(LIBPSL_FOUND)
867    list(APPEND CURL_LIBS ${LIBPSL_LIBRARY})
868    list(APPEND CMAKE_REQUIRED_INCLUDES "${LIBPSL_INCLUDE_DIR}")
869    include_directories("${LIBPSL_INCLUDE_DIR}")
870    set(USE_LIBPSL ON)
871  endif()
872endif()
873
874#libSSH2
875option(CURL_USE_LIBSSH2 "Use libSSH2" ON)
876mark_as_advanced(CURL_USE_LIBSSH2)
877set(USE_LIBSSH2 OFF)
878
879if(CURL_USE_LIBSSH2)
880  find_package(LibSSH2)
881  if(LIBSSH2_FOUND)
882    list(APPEND CURL_LIBS ${LIBSSH2_LIBRARY})
883    list(APPEND CMAKE_REQUIRED_INCLUDES "${LIBSSH2_INCLUDE_DIR}")
884    include_directories("${LIBSSH2_INCLUDE_DIR}")
885    set(USE_LIBSSH2 ON)
886  endif()
887endif()
888
889# libssh
890option(CURL_USE_LIBSSH "Use libSSH" OFF)
891mark_as_advanced(CURL_USE_LIBSSH)
892if(NOT USE_LIBSSH2 AND CURL_USE_LIBSSH)
893  find_package(libssh CONFIG)
894  if(libssh_FOUND)
895    message(STATUS "Found libssh ${libssh_VERSION}")
896    # Use imported target for include and library paths.
897    list(APPEND CURL_LIBS ssh)
898    set(USE_LIBSSH ON)
899  endif()
900endif()
901
902option(CURL_USE_GSSAPI "Use GSSAPI implementation (right now only Heimdal is supported with CMake build)" OFF)
903mark_as_advanced(CURL_USE_GSSAPI)
904
905if(CURL_USE_GSSAPI)
906  find_package(GSS)
907
908  set(HAVE_GSSAPI ${GSS_FOUND})
909  if(GSS_FOUND)
910
911    message(STATUS "Found ${GSS_FLAVOUR} GSSAPI version: \"${GSS_VERSION}\"")
912
913    list(APPEND CMAKE_REQUIRED_INCLUDES ${GSS_INCLUDE_DIR})
914    check_include_file_concat("gssapi/gssapi.h"  HAVE_GSSAPI_GSSAPI_H)
915    check_include_file_concat("gssapi/gssapi_generic.h" HAVE_GSSAPI_GSSAPI_GENERIC_H)
916    check_include_file_concat("gssapi/gssapi_krb5.h" HAVE_GSSAPI_GSSAPI_KRB5_H)
917
918    if(NOT GSS_FLAVOUR STREQUAL "Heimdal")
919      # MIT
920      set(_INCLUDE_LIST "")
921      if(HAVE_GSSAPI_GSSAPI_H)
922        list(APPEND _INCLUDE_LIST "gssapi/gssapi.h")
923      endif()
924      if(HAVE_GSSAPI_GSSAPI_GENERIC_H)
925        list(APPEND _INCLUDE_LIST "gssapi/gssapi_generic.h")
926      endif()
927      if(HAVE_GSSAPI_GSSAPI_KRB5_H)
928        list(APPEND _INCLUDE_LIST "gssapi/gssapi_krb5.h")
929      endif()
930
931      string(REPLACE ";" " " _COMPILER_FLAGS_STR "${GSS_COMPILER_FLAGS}")
932      string(REPLACE ";" " " _LINKER_FLAGS_STR "${GSS_LINKER_FLAGS}")
933
934      foreach(_dir ${GSS_LINK_DIRECTORIES})
935        set(_LINKER_FLAGS_STR "${_LINKER_FLAGS_STR} -L\"${_dir}\"")
936      endforeach()
937
938      if(NOT DEFINED HAVE_GSS_C_NT_HOSTBASED_SERVICE)
939        set(CMAKE_REQUIRED_FLAGS "${_COMPILER_FLAGS_STR} ${_LINKER_FLAGS_STR}")
940        set(CMAKE_REQUIRED_LIBRARIES ${GSS_LIBRARIES})
941        check_symbol_exists("GSS_C_NT_HOSTBASED_SERVICE" ${_INCLUDE_LIST} HAVE_GSS_C_NT_HOSTBASED_SERVICE)
942        unset(CMAKE_REQUIRED_LIBRARIES)
943      endif()
944      if(NOT HAVE_GSS_C_NT_HOSTBASED_SERVICE)
945        set(HAVE_OLD_GSSMIT ON)
946      endif()
947    endif()
948
949    include_directories(${GSS_INCLUDE_DIR})
950    link_directories(${GSS_LINK_DIRECTORIES})
951    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${GSS_COMPILER_FLAGS}")
952    string(REPLACE ";" " " GSS_LINKER_FLAGS "${GSS_LINKER_FLAGS}")
953    set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${GSS_LINKER_FLAGS}")
954    set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${GSS_LINKER_FLAGS}")
955    set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} ${GSS_LINKER_FLAGS}")
956    list(APPEND CURL_LIBS ${GSS_LIBRARIES})
957
958  else()
959    message(WARNING "GSSAPI support has been requested but no supporting libraries found. Skipping.")
960  endif()
961endif()
962
963option(ENABLE_UNIX_SOCKETS "Define if you want Unix domain sockets support" ON)
964if(ENABLE_UNIX_SOCKETS)
965  include(CheckStructHasMember)
966  if(WIN32)
967    set(USE_UNIX_SOCKETS ON)
968  else()
969    check_struct_has_member("struct sockaddr_un" sun_path "sys/un.h" USE_UNIX_SOCKETS)
970  endif()
971else()
972  unset(USE_UNIX_SOCKETS CACHE)
973endif()
974
975
976#
977# CA handling
978#
979set(CURL_CA_BUNDLE "auto" CACHE STRING
980    "Path to the CA bundle. Set 'none' to disable or 'auto' for auto-detection. Defaults to 'auto'.")
981set(CURL_CA_FALLBACK OFF CACHE BOOL
982    "Set ON to use built-in CA store of TLS backend. Defaults to OFF")
983set(CURL_CA_PATH "auto" CACHE STRING
984    "Location of default CA path. Set 'none' to disable or 'auto' for auto-detection. Defaults to 'auto'.")
985
986if("${CURL_CA_BUNDLE}" STREQUAL "")
987  message(FATAL_ERROR "Invalid value of CURL_CA_BUNDLE. Use 'none', 'auto' or file path.")
988elseif("${CURL_CA_BUNDLE}" STREQUAL "none")
989  unset(CURL_CA_BUNDLE CACHE)
990elseif("${CURL_CA_BUNDLE}" STREQUAL "auto")
991  unset(CURL_CA_BUNDLE CACHE)
992  if(NOT CMAKE_CROSSCOMPILING)
993    set(CURL_CA_BUNDLE_AUTODETECT TRUE)
994  endif()
995else()
996  set(CURL_CA_BUNDLE_SET TRUE)
997endif()
998
999if("${CURL_CA_PATH}" STREQUAL "")
1000  message(FATAL_ERROR "Invalid value of CURL_CA_PATH. Use 'none', 'auto' or directory path.")
1001elseif("${CURL_CA_PATH}" STREQUAL "none")
1002  unset(CURL_CA_PATH CACHE)
1003elseif("${CURL_CA_PATH}" STREQUAL "auto")
1004  unset(CURL_CA_PATH CACHE)
1005  if(NOT CMAKE_CROSSCOMPILING)
1006    set(CURL_CA_PATH_AUTODETECT TRUE)
1007  endif()
1008else()
1009  set(CURL_CA_PATH_SET TRUE)
1010endif()
1011
1012if(CURL_CA_BUNDLE_SET AND CURL_CA_PATH_AUTODETECT)
1013  # Skip autodetection of unset CA path because CA bundle is set explicitly
1014elseif(CURL_CA_PATH_SET AND CURL_CA_BUNDLE_AUTODETECT)
1015  # Skip autodetection of unset CA bundle because CA path is set explicitly
1016elseif(CURL_CA_PATH_AUTODETECT OR CURL_CA_BUNDLE_AUTODETECT)
1017  # first try autodetecting a CA bundle, then a CA path
1018
1019  if(CURL_CA_BUNDLE_AUTODETECT)
1020    set(SEARCH_CA_BUNDLE_PATHS
1021        /etc/ssl/certs/ca-certificates.crt
1022        /etc/pki/tls/certs/ca-bundle.crt
1023        /usr/share/ssl/certs/ca-bundle.crt
1024        /usr/local/share/certs/ca-root-nss.crt
1025        /etc/ssl/cert.pem)
1026
1027    foreach(SEARCH_CA_BUNDLE_PATH ${SEARCH_CA_BUNDLE_PATHS})
1028      if(EXISTS "${SEARCH_CA_BUNDLE_PATH}")
1029        message(STATUS "Found CA bundle: ${SEARCH_CA_BUNDLE_PATH}")
1030        set(CURL_CA_BUNDLE "${SEARCH_CA_BUNDLE_PATH}" CACHE STRING
1031            "Path to the CA bundle. Set 'none' to disable or 'auto' for auto-detection. Defaults to 'auto'.")
1032        set(CURL_CA_BUNDLE_SET TRUE CACHE BOOL "Path to the CA bundle has been set")
1033        break()
1034      endif()
1035    endforeach()
1036  endif()
1037
1038  if(CURL_CA_PATH_AUTODETECT AND (NOT CURL_CA_PATH_SET))
1039    if(EXISTS "/etc/ssl/certs")
1040      set(CURL_CA_PATH "/etc/ssl/certs" CACHE STRING
1041          "Location of default CA path. Set 'none' to disable or 'auto' for auto-detection. Defaults to 'auto'.")
1042      set(CURL_CA_PATH_SET TRUE CACHE BOOL "Path to the CA bundle has been set")
1043    endif()
1044  endif()
1045endif()
1046
1047if(CURL_CA_PATH_SET AND
1048   NOT USE_OPENSSL AND
1049   NOT USE_WOLFSSL AND
1050   NOT USE_GNUTLS AND
1051   NOT USE_MBEDTLS)
1052  message(STATUS
1053          "CA path only supported by OpenSSL, wolfSSL, GnuTLS or mbedTLS. "
1054          "Set CURL_CA_PATH=none or enable one of those TLS backends.")
1055endif()
1056
1057# Check for header files
1058if(WIN32)
1059  set(CURL_INCLUDES ${CURL_INCLUDES} "winsock2.h")
1060  set(CURL_INCLUDES ${CURL_INCLUDES} "ws2tcpip.h")
1061  set(CURL_INCLUDES ${CURL_INCLUDES} "windows.h")
1062endif()
1063
1064if(WIN32)
1065  # detect actual value of _WIN32_WINNT and store as HAVE_WIN32_WINNT
1066  curl_internal_test(HAVE_WIN32_WINNT)
1067  if(HAVE_WIN32_WINNT)
1068    string(REGEX MATCH ".*_WIN32_WINNT=0x[0-9a-fA-F]+" OUTPUT "${OUTPUT}")
1069    string(REGEX REPLACE ".*_WIN32_WINNT=" "" OUTPUT "${OUTPUT}")
1070    string(REGEX REPLACE "0x([0-9a-f][0-9a-f][0-9a-f])$" "0x0\\1" OUTPUT "${OUTPUT}")  # pad to 4 digits
1071    string(TOLOWER "${OUTPUT}" HAVE_WIN32_WINNT)
1072    message(STATUS "Found _WIN32_WINNT=${HAVE_WIN32_WINNT}")
1073  endif()
1074  # avoid storing HAVE_WIN32_WINNT in CMake cache
1075  unset(HAVE_WIN32_WINNT CACHE)
1076
1077  if(HAVE_WIN32_WINNT)
1078    if(HAVE_WIN32_WINNT STRLESS "0x0501")
1079      # Windows XP is required for freeaddrinfo, getaddrinfo
1080      message(FATAL_ERROR "Building for Windows XP or newer is required.")
1081    endif()
1082
1083    # pre-fill detection results based on target OS version
1084    if(MINGW OR MSVC)
1085      if(HAVE_WIN32_WINNT STRLESS "0x0600")
1086        set(HAVE_INET_NTOP 0)
1087        set(HAVE_INET_PTON 0)
1088      else()  # Windows Vista or newer
1089        set(HAVE_INET_NTOP 1)
1090        set(HAVE_INET_PTON 1)
1091      endif()
1092      unset(HAVE_INET_NTOP CACHE)
1093      unset(HAVE_INET_PTON CACHE)
1094    endif()
1095  endif()
1096endif()
1097
1098check_include_file_concat("sys/filio.h"      HAVE_SYS_FILIO_H)
1099check_include_file_concat("sys/wait.h"       HAVE_SYS_WAIT_H)
1100check_include_file_concat("sys/ioctl.h"      HAVE_SYS_IOCTL_H)
1101check_include_file_concat("sys/param.h"      HAVE_SYS_PARAM_H)
1102check_include_file_concat("sys/poll.h"       HAVE_SYS_POLL_H)
1103check_include_file_concat("sys/resource.h"   HAVE_SYS_RESOURCE_H)
1104check_include_file_concat("sys/select.h"     HAVE_SYS_SELECT_H)
1105check_include_file_concat("sys/socket.h"     HAVE_SYS_SOCKET_H)
1106check_include_file_concat("sys/sockio.h"     HAVE_SYS_SOCKIO_H)
1107check_include_file_concat("sys/stat.h"       HAVE_SYS_STAT_H)
1108check_include_file_concat("sys/time.h"       HAVE_SYS_TIME_H)
1109check_include_file_concat("sys/types.h"      HAVE_SYS_TYPES_H)
1110check_include_file_concat("sys/un.h"         HAVE_SYS_UN_H)
1111check_include_file_concat("sys/utime.h"      HAVE_SYS_UTIME_H)
1112check_include_file_concat("sys/xattr.h"      HAVE_SYS_XATTR_H)
1113check_include_file_concat("arpa/inet.h"      HAVE_ARPA_INET_H)
1114check_include_file_concat("fcntl.h"          HAVE_FCNTL_H)
1115check_include_file_concat("ifaddrs.h"        HAVE_IFADDRS_H)
1116check_include_file_concat("io.h"             HAVE_IO_H)
1117check_include_file_concat("libgen.h"         HAVE_LIBGEN_H)
1118check_include_file_concat("locale.h"         HAVE_LOCALE_H)
1119check_include_file_concat("net/if.h"         HAVE_NET_IF_H)
1120check_include_file_concat("netdb.h"          HAVE_NETDB_H)
1121check_include_file_concat("netinet/in.h"     HAVE_NETINET_IN_H)
1122check_include_file_concat("netinet/tcp.h"    HAVE_NETINET_TCP_H)
1123check_include_file_concat("netinet/udp.h"    HAVE_NETINET_UDP_H)
1124check_include_file("linux/tcp.h"      HAVE_LINUX_TCP_H)
1125
1126check_include_file_concat("poll.h"           HAVE_POLL_H)
1127check_include_file_concat("pwd.h"            HAVE_PWD_H)
1128check_include_file_concat("stdatomic.h"      HAVE_STDATOMIC_H)
1129check_include_file_concat("stdbool.h"        HAVE_STDBOOL_H)
1130check_include_file_concat("strings.h"        HAVE_STRINGS_H)
1131check_include_file_concat("stropts.h"        HAVE_STROPTS_H)
1132check_include_file_concat("termio.h"         HAVE_TERMIO_H)
1133check_include_file_concat("termios.h"        HAVE_TERMIOS_H)
1134check_include_file_concat("unistd.h"         HAVE_UNISTD_H)
1135check_include_file_concat("utime.h"          HAVE_UTIME_H)
1136
1137check_type_size(size_t  SIZEOF_SIZE_T)
1138check_type_size(ssize_t  SIZEOF_SSIZE_T)
1139check_type_size("long long"  SIZEOF_LONG_LONG)
1140check_type_size("long"  SIZEOF_LONG)
1141check_type_size("int"  SIZEOF_INT)
1142check_type_size("__int64"  SIZEOF___INT64)
1143check_type_size("time_t"  SIZEOF_TIME_T)
1144check_type_size("suseconds_t"  SIZEOF_SUSECONDS_T)
1145if(NOT HAVE_SIZEOF_SSIZE_T)
1146  if(SIZEOF_LONG EQUAL SIZEOF_SIZE_T)
1147    set(ssize_t long)
1148  endif()
1149  if(NOT ssize_t AND SIZEOF___INT64 EQUAL SIZEOF_SIZE_T)
1150    set(ssize_t __int64)
1151  endif()
1152endif()
1153# off_t is sized later, after the HAVE_FILE_OFFSET_BITS test
1154
1155if(SIZEOF_LONG_LONG)
1156  set(HAVE_LONGLONG 1)
1157endif()
1158if(SIZEOF_SUSECONDS_T)
1159  set(HAVE_SUSECONDS_T 1)
1160endif()
1161
1162if(NOT CMAKE_CROSSCOMPILING)
1163  find_file(RANDOM_FILE urandom /dev)
1164  mark_as_advanced(RANDOM_FILE)
1165endif()
1166
1167# Check for some functions that are used
1168if(WIN32)
1169  set(CMAKE_REQUIRED_LIBRARIES ws2_32)
1170elseif(HAVE_LIBSOCKET)
1171  set(CMAKE_REQUIRED_LIBRARIES socket)
1172endif()
1173
1174check_symbol_exists(fnmatch       "${CURL_INCLUDES};fnmatch.h" HAVE_FNMATCH)
1175check_symbol_exists(basename      "${CURL_INCLUDES};string.h" HAVE_BASENAME)
1176check_symbol_exists(socket        "${CURL_INCLUDES}" HAVE_SOCKET)
1177check_symbol_exists(sched_yield   "${CURL_INCLUDES};sched.h" HAVE_SCHED_YIELD)
1178check_symbol_exists(socketpair    "${CURL_INCLUDES}" HAVE_SOCKETPAIR)
1179check_symbol_exists(recv          "${CURL_INCLUDES}" HAVE_RECV)
1180check_symbol_exists(send          "${CURL_INCLUDES}" HAVE_SEND)
1181check_symbol_exists(sendmsg       "${CURL_INCLUDES}" HAVE_SENDMSG)
1182check_symbol_exists(select        "${CURL_INCLUDES}" HAVE_SELECT)
1183check_symbol_exists(strdup        "${CURL_INCLUDES};string.h" HAVE_STRDUP)
1184check_symbol_exists(strtok_r      "${CURL_INCLUDES};string.h" HAVE_STRTOK_R)
1185check_symbol_exists(strcasecmp    "${CURL_INCLUDES};string.h" HAVE_STRCASECMP)
1186check_symbol_exists(stricmp       "${CURL_INCLUDES};string.h" HAVE_STRICMP)
1187check_symbol_exists(strcmpi       "${CURL_INCLUDES};string.h" HAVE_STRCMPI)
1188check_symbol_exists(memrchr       "${CURL_INCLUDES};string.h" HAVE_MEMRCHR)
1189check_symbol_exists(alarm         "${CURL_INCLUDES}" HAVE_ALARM)
1190check_symbol_exists(arc4random    "${CURL_INCLUDES};stdlib.h" HAVE_ARC4RANDOM)
1191check_symbol_exists(fcntl         "${CURL_INCLUDES}" HAVE_FCNTL)
1192check_symbol_exists(getppid       "${CURL_INCLUDES}" HAVE_GETPPID)
1193check_symbol_exists(utimes        "${CURL_INCLUDES}" HAVE_UTIMES)
1194
1195check_symbol_exists(gettimeofday  "${CURL_INCLUDES}" HAVE_GETTIMEOFDAY)
1196check_symbol_exists(closesocket   "${CURL_INCLUDES}" HAVE_CLOSESOCKET)
1197check_symbol_exists(sigsetjmp     "${CURL_INCLUDES};setjmp.h" HAVE_SIGSETJMP)
1198check_symbol_exists(getpass_r     "${CURL_INCLUDES}" HAVE_GETPASS_R)
1199check_symbol_exists(getpwuid      "${CURL_INCLUDES}" HAVE_GETPWUID)
1200check_symbol_exists(getpwuid_r    "${CURL_INCLUDES}" HAVE_GETPWUID_R)
1201check_symbol_exists(geteuid       "${CURL_INCLUDES}" HAVE_GETEUID)
1202check_symbol_exists(utime         "${CURL_INCLUDES}" HAVE_UTIME)
1203check_symbol_exists(gmtime_r      "${CURL_INCLUDES};stdlib.h;time.h" HAVE_GMTIME_R)
1204
1205check_symbol_exists(gethostbyname_r "${CURL_INCLUDES}" HAVE_GETHOSTBYNAME_R)
1206
1207check_symbol_exists(signal         "${CURL_INCLUDES};signal.h" HAVE_SIGNAL)
1208check_symbol_exists(strtoll        "${CURL_INCLUDES};stdlib.h" HAVE_STRTOLL)
1209check_symbol_exists(strerror_r     "${CURL_INCLUDES};stdlib.h;string.h" HAVE_STRERROR_R)
1210check_symbol_exists(sigaction      "signal.h" HAVE_SIGACTION)
1211check_symbol_exists(siginterrupt   "${CURL_INCLUDES};signal.h" HAVE_SIGINTERRUPT)
1212check_symbol_exists(getaddrinfo    "${CURL_INCLUDES};stdlib.h;string.h" HAVE_GETADDRINFO)
1213check_symbol_exists(getifaddrs     "${CURL_INCLUDES};stdlib.h" HAVE_GETIFADDRS)
1214check_symbol_exists(freeaddrinfo   "${CURL_INCLUDES}" HAVE_FREEADDRINFO)
1215check_symbol_exists(pipe           "${CURL_INCLUDES}" HAVE_PIPE)
1216check_symbol_exists(ftruncate      "${CURL_INCLUDES}" HAVE_FTRUNCATE)
1217check_symbol_exists(fseeko         "${CURL_INCLUDES};stdio.h" HAVE_FSEEKO)
1218check_symbol_exists(_fseeki64      "${CURL_INCLUDES};stdio.h" HAVE__FSEEKI64)
1219check_symbol_exists(getpeername    "${CURL_INCLUDES}" HAVE_GETPEERNAME)
1220check_symbol_exists(getsockname    "${CURL_INCLUDES}" HAVE_GETSOCKNAME)
1221check_symbol_exists(if_nametoindex "${CURL_INCLUDES}" HAVE_IF_NAMETOINDEX)
1222check_symbol_exists(getrlimit      "${CURL_INCLUDES}" HAVE_GETRLIMIT)
1223check_symbol_exists(setlocale      "${CURL_INCLUDES}" HAVE_SETLOCALE)
1224check_symbol_exists(setmode        "${CURL_INCLUDES}" HAVE_SETMODE)
1225check_symbol_exists(setrlimit      "${CURL_INCLUDES}" HAVE_SETRLIMIT)
1226
1227if(HAVE_FSEEKO)
1228  set(HAVE_DECL_FSEEKO 1)
1229endif()
1230
1231if(NOT MSVC OR (MSVC_VERSION GREATER_EQUAL 1900))
1232  # earlier MSVC compilers had faulty snprintf implementations
1233  check_symbol_exists(snprintf       "stdio.h" HAVE_SNPRINTF)
1234endif()
1235check_function_exists(mach_absolute_time HAVE_MACH_ABSOLUTE_TIME)
1236check_symbol_exists(inet_ntop      "${CURL_INCLUDES};stdlib.h;string.h" HAVE_INET_NTOP)
1237if(MSVC AND (MSVC_VERSION LESS_EQUAL 1600))
1238  set(HAVE_INET_NTOP OFF)
1239endif()
1240check_symbol_exists(inet_pton      "${CURL_INCLUDES};stdlib.h;string.h" HAVE_INET_PTON)
1241
1242check_symbol_exists(fsetxattr "${CURL_INCLUDES}" HAVE_FSETXATTR)
1243if(HAVE_FSETXATTR)
1244  foreach(CURL_TEST HAVE_FSETXATTR_5 HAVE_FSETXATTR_6)
1245    curl_internal_test(${CURL_TEST})
1246  endforeach()
1247endif()
1248
1249set(CMAKE_EXTRA_INCLUDE_FILES   "sys/socket.h")
1250check_type_size("sa_family_t"   SIZEOF_SA_FAMILY_T)
1251set(HAVE_SA_FAMILY_T            ${HAVE_SIZEOF_SA_FAMILY_T})
1252set(CMAKE_EXTRA_INCLUDE_FILES   "")
1253
1254if(WIN32)
1255  set(CMAKE_EXTRA_INCLUDE_FILES   "winsock2.h")
1256  check_type_size("ADDRESS_FAMILY"    SIZEOF_ADDRESS_FAMILY)
1257  set(HAVE_ADDRESS_FAMILY         ${HAVE_SIZEOF_ADDRESS_FAMILY})
1258  set(CMAKE_EXTRA_INCLUDE_FILES   "")
1259endif()
1260
1261# Do curl specific tests
1262foreach(CURL_TEST
1263    HAVE_FCNTL_O_NONBLOCK
1264    HAVE_IOCTLSOCKET
1265    HAVE_IOCTLSOCKET_CAMEL
1266    HAVE_IOCTLSOCKET_CAMEL_FIONBIO
1267    HAVE_IOCTLSOCKET_FIONBIO
1268    HAVE_IOCTL_FIONBIO
1269    HAVE_IOCTL_SIOCGIFADDR
1270    HAVE_SETSOCKOPT_SO_NONBLOCK
1271    HAVE_O_NONBLOCK
1272    HAVE_GETHOSTBYNAME_R_3
1273    HAVE_GETHOSTBYNAME_R_5
1274    HAVE_GETHOSTBYNAME_R_6
1275    HAVE_GETHOSTBYNAME_R_3_REENTRANT
1276    HAVE_GETHOSTBYNAME_R_5_REENTRANT
1277    HAVE_GETHOSTBYNAME_R_6_REENTRANT
1278    HAVE_IN_ADDR_T
1279    HAVE_BOOL_T
1280    STDC_HEADERS
1281    HAVE_FILE_OFFSET_BITS
1282    HAVE_ATOMIC
1283    )
1284  curl_internal_test(${CURL_TEST})
1285endforeach()
1286
1287if(HAVE_FILE_OFFSET_BITS)
1288  set(_FILE_OFFSET_BITS 64)
1289  set(CMAKE_REQUIRED_FLAGS "-D_FILE_OFFSET_BITS=64")
1290endif()
1291check_type_size("off_t"  SIZEOF_OFF_T)
1292
1293# include this header to get the type
1294set(CMAKE_REQUIRED_INCLUDES "${CURL_SOURCE_DIR}/include")
1295set(CMAKE_EXTRA_INCLUDE_FILES "curl/system.h")
1296check_type_size("curl_off_t"  SIZEOF_CURL_OFF_T)
1297set(CMAKE_EXTRA_INCLUDE_FILES "curl/curl.h")
1298check_type_size("curl_socket_t"  SIZEOF_CURL_SOCKET_T)
1299set(CMAKE_EXTRA_INCLUDE_FILES "")
1300
1301if(NOT WIN32 AND NOT CMAKE_CROSSCOMPILING)
1302  # on not-Windows and not-crosscompiling, check for writable argv[]
1303  include(CheckCSourceRuns)
1304  check_c_source_runs("
1305    int main(int argc, char **argv)
1306    {
1307      (void)argc;
1308      argv[0][0] = ' ';
1309      return (argv[0][0] == ' ')?0:1;
1310    }" HAVE_WRITABLE_ARGV)
1311endif()
1312
1313set(CMAKE_REQUIRED_FLAGS)
1314
1315option(ENABLE_WEBSOCKETS "Set to ON to enable EXPERIMENTAL websockets" OFF)
1316
1317if(ENABLE_WEBSOCKETS)
1318  if(${SIZEOF_CURL_OFF_T} GREATER "4")
1319    set(USE_WEBSOCKETS ON)
1320  else()
1321    message(WARNING "curl_off_t is too small to enable WebSockets")
1322  endif()
1323endif()
1324
1325foreach(CURL_TEST
1326    HAVE_GLIBC_STRERROR_R
1327    HAVE_POSIX_STRERROR_R
1328    )
1329  curl_internal_test(${CURL_TEST})
1330endforeach()
1331
1332# Check for reentrant
1333foreach(CURL_TEST
1334    HAVE_GETHOSTBYNAME_R_3
1335    HAVE_GETHOSTBYNAME_R_5
1336    HAVE_GETHOSTBYNAME_R_6)
1337  if(NOT ${CURL_TEST})
1338    if(${CURL_TEST}_REENTRANT)
1339      set(NEED_REENTRANT 1)
1340    endif()
1341  endif()
1342endforeach()
1343
1344if(NEED_REENTRANT)
1345  foreach(CURL_TEST
1346      HAVE_GETHOSTBYNAME_R_3
1347      HAVE_GETHOSTBYNAME_R_5
1348      HAVE_GETHOSTBYNAME_R_6)
1349    set(${CURL_TEST} 0)
1350    if(${CURL_TEST}_REENTRANT)
1351      set(${CURL_TEST} 1)
1352    endif()
1353  endforeach()
1354endif()
1355
1356if(NOT WIN32)
1357  # Check clock_gettime(CLOCK_MONOTONIC, x) support
1358  curl_internal_test(HAVE_CLOCK_GETTIME_MONOTONIC)
1359endif()
1360
1361# Check compiler support of __builtin_available()
1362curl_internal_test(HAVE_BUILTIN_AVAILABLE)
1363
1364# Some other minor tests
1365
1366if(NOT HAVE_IN_ADDR_T)
1367  set(in_addr_t "unsigned long")
1368endif()
1369
1370# Check for nonblocking
1371set(HAVE_DISABLED_NONBLOCKING 1)
1372if(HAVE_FIONBIO OR
1373    HAVE_IOCTLSOCKET OR
1374    HAVE_IOCTLSOCKET_CASE OR
1375    HAVE_O_NONBLOCK)
1376  set(HAVE_DISABLED_NONBLOCKING)
1377endif()
1378
1379if(CMAKE_COMPILER_IS_GNUCC AND APPLE)
1380  include(CheckCCompilerFlag)
1381  check_c_compiler_flag(-Wno-long-double HAVE_C_FLAG_Wno_long_double)
1382  if(HAVE_C_FLAG_Wno_long_double)
1383    # The Mac version of GCC warns about use of long double.  Disable it.
1384    get_source_file_property(MPRINTF_COMPILE_FLAGS mprintf.c COMPILE_FLAGS)
1385    if(MPRINTF_COMPILE_FLAGS)
1386      set(MPRINTF_COMPILE_FLAGS "${MPRINTF_COMPILE_FLAGS} -Wno-long-double")
1387    else()
1388      set(MPRINTF_COMPILE_FLAGS "-Wno-long-double")
1389    endif()
1390    set_source_files_properties(mprintf.c PROPERTIES
1391      COMPILE_FLAGS ${MPRINTF_COMPILE_FLAGS})
1392  endif()
1393endif()
1394
1395include(CMake/OtherTests.cmake)
1396
1397add_definitions(-DHAVE_CONFIG_H)
1398
1399# For Windows, all compilers used by CMake should support large files
1400if(WIN32)
1401  set(USE_WIN32_LARGE_FILES ON)
1402
1403  # Use the manifest embedded in the Windows Resource
1404  set(CMAKE_RC_FLAGS "${CMAKE_RC_FLAGS} -DCURL_EMBED_MANIFEST")
1405
1406  # We use crypto functions that are not available for UWP apps
1407  if(NOT WINDOWS_STORE)
1408    set(USE_WIN32_CRYPTO ON)
1409  endif()
1410
1411  # Link required libraries for USE_WIN32_CRYPTO or USE_SCHANNEL
1412  if(USE_WIN32_CRYPTO OR USE_SCHANNEL)
1413    list(APPEND CURL_LIBS "advapi32" "crypt32")
1414  endif()
1415endif()
1416
1417if(MSVC)
1418  # Disable default manifest added by CMake
1419  set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /MANIFEST:NO")
1420
1421  add_definitions(-D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE)
1422  if(CMAKE_C_FLAGS MATCHES "/W[0-4]")
1423    string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
1424  else()
1425    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W4")
1426  endif()
1427
1428  # Use multithreaded compilation on VS 2008+
1429  if(MSVC_VERSION GREATER_EQUAL 1500)
1430    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /MP")
1431  endif()
1432endif()
1433
1434if(CURL_WERROR)
1435  if(MSVC_VERSION)
1436    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /WX")
1437  else()
1438    # this assumes clang or gcc style options
1439    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror")
1440  endif()
1441endif()
1442
1443if(CURL_LTO)
1444  if(CMAKE_VERSION VERSION_LESS 3.9)
1445    message(FATAL_ERROR "Requested LTO but your cmake version ${CMAKE_VERSION} is to old. You need at least 3.9")
1446  endif()
1447
1448  cmake_policy(SET CMP0069 NEW)
1449
1450  include(CheckIPOSupported)
1451  check_ipo_supported(RESULT CURL_HAS_LTO OUTPUT CURL_LTO_ERROR LANGUAGES C)
1452  if(CURL_HAS_LTO)
1453    message(STATUS "LTO supported and enabled")
1454  else()
1455    message(FATAL_ERROR "LTO was requested - but compiler doesn't support it\n${CURL_LTO_ERROR}")
1456  endif()
1457endif()
1458
1459
1460# Ugly (but functional) way to include "Makefile.inc" by transforming it (= regenerate it).
1461function(transform_makefile_inc INPUT_FILE OUTPUT_FILE)
1462  file(READ ${INPUT_FILE} MAKEFILE_INC_TEXT)
1463  string(REPLACE "$(top_srcdir)"   "\${CURL_SOURCE_DIR}" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT})
1464  string(REPLACE "$(top_builddir)" "\${CURL_BINARY_DIR}" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT})
1465
1466  string(REGEX REPLACE "\\\\\n" "!π!α!" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT})
1467  string(REGEX REPLACE "([a-zA-Z_][a-zA-Z0-9_]*)[\t ]*=[\t ]*([^\n]*)" "SET(\\1 \\2)" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT})
1468  string(REPLACE "!π!α!" "\n" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT})
1469
1470  string(REGEX REPLACE "\\$\\(([a-zA-Z_][a-zA-Z0-9_]*)\\)" "\${\\1}" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT})    # Replace $() with ${}
1471  string(REGEX REPLACE "@([a-zA-Z_][a-zA-Z0-9_]*)@" "\${\\1}" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT})    # Replace @@ with ${}, even if that may not be read by CMake scripts.
1472  file(WRITE ${OUTPUT_FILE} ${MAKEFILE_INC_TEXT})
1473  set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${INPUT_FILE}")
1474endfunction()
1475
1476include(GNUInstallDirs)
1477
1478set(CURL_INSTALL_CMAKE_DIR ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME})
1479set(TARGETS_EXPORT_NAME "${PROJECT_NAME}Targets")
1480set(generated_dir "${CMAKE_CURRENT_BINARY_DIR}/generated")
1481set(project_config "${generated_dir}/${PROJECT_NAME}Config.cmake")
1482set(version_config "${generated_dir}/${PROJECT_NAME}ConfigVersion.cmake")
1483
1484if(HAVE_MANUAL_TOOLS)
1485  add_subdirectory(docs)
1486endif()
1487
1488add_subdirectory(lib)
1489
1490if(BUILD_CURL_EXE)
1491  add_subdirectory(src)
1492endif()
1493
1494cmake_dependent_option(BUILD_TESTING "Build tests"
1495  ON "PERL_FOUND;NOT CURL_DISABLE_TESTS"
1496  OFF)
1497if(BUILD_TESTING)
1498  add_subdirectory(tests)
1499endif()
1500
1501if(NOT CURL_DISABLE_INSTALL)
1502
1503  # Helper to populate a list (_items) with a label when conditions (the remaining
1504  # args) are satisfied
1505  macro(_add_if label)
1506    # needs to be a macro to allow this indirection
1507    if(${ARGN})
1508      set(_items ${_items} "${label}")
1509    endif()
1510  endmacro()
1511
1512  # NTLM support requires crypto function adaptions from various SSL libs
1513  if(NOT (CURL_DISABLE_NTLM) AND
1514      (USE_OPENSSL OR USE_MBEDTLS OR USE_DARWINSSL OR USE_WIN32_CRYPTO OR USE_GNUTLS))
1515    set(use_curl_ntlm_core ON)
1516  endif()
1517
1518  # Clear list and try to detect available features
1519  set(_items)
1520  _add_if("SSL"           SSL_ENABLED)
1521  _add_if("IPv6"          ENABLE_IPV6)
1522  _add_if("UnixSockets"   USE_UNIX_SOCKETS)
1523  _add_if("libz"          HAVE_LIBZ)
1524  _add_if("brotli"        HAVE_BROTLI)
1525  _add_if("zstd"          HAVE_ZSTD)
1526  _add_if("AsynchDNS"     USE_ARES OR USE_THREADS_POSIX OR USE_THREADS_WIN32)
1527  _add_if("IDN"           HAVE_LIBIDN2 OR USE_WIN32_IDN)
1528  _add_if("Largefile"     (SIZEOF_CURL_OFF_T GREATER 4) AND
1529                          ((SIZEOF_OFF_T GREATER 4) OR USE_WIN32_LARGE_FILES))
1530  _add_if("SSPI"          USE_WINDOWS_SSPI)
1531  _add_if("GSS-API"       HAVE_GSSAPI)
1532  _add_if("alt-svc"       NOT CURL_DISABLE_ALTSVC)
1533  _add_if("HSTS"          NOT CURL_DISABLE_HSTS)
1534  _add_if("SPNEGO"        NOT CURL_DISABLE_NEGOTIATE_AUTH AND
1535                          (HAVE_GSSAPI OR USE_WINDOWS_SSPI))
1536  _add_if("Kerberos"      NOT CURL_DISABLE_KERBEROS_AUTH AND
1537                          (HAVE_GSSAPI OR USE_WINDOWS_SSPI))
1538  _add_if("NTLM"          NOT (CURL_DISABLE_NTLM) AND
1539                          (use_curl_ntlm_core OR USE_WINDOWS_SSPI))
1540  _add_if("NTLM_WB"       NOT (CURL_DISABLE_NTLM) AND
1541                          (use_curl_ntlm_core OR USE_WINDOWS_SSPI) AND
1542                          NOT CURL_DISABLE_HTTP AND NTLM_WB_ENABLED)
1543  _add_if("TLS-SRP"       USE_TLS_SRP)
1544  _add_if("HTTP2"         USE_NGHTTP2)
1545  _add_if("HTTP3"         USE_NGTCP2 OR USE_QUICHE)
1546  _add_if("MultiSSL"      CURL_WITH_MULTI_SSL)
1547  # TODO wolfSSL only support this from v5.0.0 onwards
1548  _add_if("HTTPS-proxy"   SSL_ENABLED AND (USE_OPENSSL OR USE_GNUTLS
1549                          OR USE_SCHANNEL OR USE_RUSTLS OR USE_BEARSSL OR
1550                          USE_MBEDTLS OR USE_SECTRANSP))
1551  _add_if("unicode"       ENABLE_UNICODE)
1552  _add_if("threadsafe"    HAVE_ATOMIC OR
1553                          (USE_THREADS_POSIX AND HAVE_PTHREAD_H) OR
1554                          (WIN32 AND HAVE_WIN32_WINNT GREATER_EQUAL 0x600))
1555  _add_if("PSL"           USE_LIBPSL)
1556  string(REPLACE ";" " " SUPPORT_FEATURES "${_items}")
1557  message(STATUS "Enabled features: ${SUPPORT_FEATURES}")
1558
1559  # Clear list and try to detect available protocols
1560  set(_items)
1561  _add_if("HTTP"          NOT CURL_DISABLE_HTTP)
1562  _add_if("IPFS"          NOT CURL_DISABLE_HTTP)
1563  _add_if("IPNS"          NOT CURL_DISABLE_HTTP)
1564  _add_if("HTTPS"         NOT CURL_DISABLE_HTTP AND SSL_ENABLED)
1565  _add_if("FTP"           NOT CURL_DISABLE_FTP)
1566  _add_if("FTPS"          NOT CURL_DISABLE_FTP AND SSL_ENABLED)
1567  _add_if("FILE"          NOT CURL_DISABLE_FILE)
1568  _add_if("TELNET"        NOT CURL_DISABLE_TELNET)
1569  _add_if("LDAP"          NOT CURL_DISABLE_LDAP)
1570  # CURL_DISABLE_LDAP implies CURL_DISABLE_LDAPS
1571  _add_if("LDAPS"         NOT CURL_DISABLE_LDAPS AND
1572                          ((USE_OPENLDAP AND SSL_ENABLED) OR
1573                          (NOT USE_OPENLDAP AND HAVE_LDAP_SSL)))
1574  _add_if("DICT"          NOT CURL_DISABLE_DICT)
1575  _add_if("TFTP"          NOT CURL_DISABLE_TFTP)
1576  _add_if("GOPHER"        NOT CURL_DISABLE_GOPHER)
1577  _add_if("GOPHERS"       NOT CURL_DISABLE_GOPHER AND SSL_ENABLED)
1578  _add_if("POP3"          NOT CURL_DISABLE_POP3)
1579  _add_if("POP3S"         NOT CURL_DISABLE_POP3 AND SSL_ENABLED)
1580  _add_if("IMAP"          NOT CURL_DISABLE_IMAP)
1581  _add_if("IMAPS"         NOT CURL_DISABLE_IMAP AND SSL_ENABLED)
1582  _add_if("SMB"           NOT CURL_DISABLE_SMB AND
1583                          use_curl_ntlm_core AND (SIZEOF_CURL_OFF_T GREATER 4))
1584  _add_if("SMBS"          NOT CURL_DISABLE_SMB AND SSL_ENABLED AND
1585                          use_curl_ntlm_core AND (SIZEOF_CURL_OFF_T GREATER 4))
1586  _add_if("SMTP"          NOT CURL_DISABLE_SMTP)
1587  _add_if("SMTPS"         NOT CURL_DISABLE_SMTP AND SSL_ENABLED)
1588  _add_if("SCP"           USE_LIBSSH2 OR USE_LIBSSH)
1589  _add_if("SFTP"          USE_LIBSSH2 OR USE_LIBSSH)
1590  _add_if("RTSP"          NOT CURL_DISABLE_RTSP)
1591  _add_if("RTMP"          USE_LIBRTMP)
1592  _add_if("MQTT"          NOT CURL_DISABLE_MQTT)
1593  _add_if("WS"            USE_WEBSOCKETS)
1594  _add_if("WSS"           USE_WEBSOCKETS)
1595  if(_items)
1596    list(SORT _items)
1597  endif()
1598  string(REPLACE ";" " " SUPPORT_PROTOCOLS "${_items}")
1599  message(STATUS "Enabled protocols: ${SUPPORT_PROTOCOLS}")
1600
1601  # Clear list and collect SSL backends
1602  set(_items)
1603  _add_if("Schannel"         SSL_ENABLED AND USE_SCHANNEL)
1604  _add_if("OpenSSL"          SSL_ENABLED AND USE_OPENSSL)
1605  _add_if("Secure Transport" SSL_ENABLED AND USE_SECTRANSP)
1606  _add_if("mbedTLS"          SSL_ENABLED AND USE_MBEDTLS)
1607  _add_if("BearSSL"          SSL_ENABLED AND USE_BEARSSL)
1608  _add_if("wolfSSL"          SSL_ENABLED AND USE_WOLFSSL)
1609  _add_if("GnuTLS"           SSL_ENABLED AND USE_GNUTLS)
1610
1611  if(_items)
1612    list(SORT _items)
1613  endif()
1614  string(REPLACE ";" " " SSL_BACKENDS "${_items}")
1615  message(STATUS "Enabled SSL backends: ${SSL_BACKENDS}")
1616  if(CURL_DEFAULT_SSL_BACKEND)
1617    message(STATUS "Default SSL backend: ${CURL_DEFAULT_SSL_BACKEND}")
1618  endif()
1619
1620  # curl-config needs the following options to be set.
1621  set(CC                      "${CMAKE_C_COMPILER}")
1622  # TODO probably put a -D... options here?
1623  set(CONFIGURE_OPTIONS       "")
1624  set(CURLVERSION             "${CURL_VERSION}")
1625  set(exec_prefix             "\${prefix}")
1626  set(includedir              "\${prefix}/include")
1627  set(LDFLAGS                 "${CMAKE_SHARED_LINKER_FLAGS}")
1628  set(LIBCURL_LIBS            "")
1629  set(libdir                  "${CMAKE_INSTALL_PREFIX}/lib")
1630  foreach(_lib ${CMAKE_C_IMPLICIT_LINK_LIBRARIES} ${CURL_LIBS})
1631    if(TARGET "${_lib}")
1632      set(_libname "${_lib}")
1633      get_target_property(_imported "${_libname}" IMPORTED)
1634      if(NOT _imported)
1635        # Reading the LOCATION property on non-imported target will error out.
1636        # Assume the user won't need this information in the .pc file.
1637        continue()
1638      endif()
1639      get_target_property(_lib "${_libname}" LOCATION)
1640      if(NOT _lib)
1641        message(WARNING "Bad lib in library list: ${_libname}")
1642        continue()
1643      endif()
1644    endif()
1645    if(_lib MATCHES ".*/.*" OR _lib MATCHES "^-")
1646      set(LIBCURL_LIBS          "${LIBCURL_LIBS} ${_lib}")
1647    else()
1648      set(LIBCURL_LIBS          "${LIBCURL_LIBS} -l${_lib}")
1649    endif()
1650  endforeach()
1651  if(BUILD_SHARED_LIBS)
1652    set(ENABLE_SHARED         "yes")
1653    set(LIBCURL_NO_SHARED     "")
1654    set(CPPFLAG_CURL_STATICLIB "")
1655  else()
1656    set(ENABLE_SHARED         "no")
1657    set(LIBCURL_NO_SHARED     "${LIBCURL_LIBS}")
1658    set(CPPFLAG_CURL_STATICLIB "-DCURL_STATICLIB")
1659  endif()
1660  if(BUILD_STATIC_LIBS)
1661    set(ENABLE_STATIC         "yes")
1662  else()
1663    set(ENABLE_STATIC         "no")
1664  endif()
1665  # "a" (Linux) or "lib" (Windows)
1666  string(REPLACE "." "" libext "${CMAKE_STATIC_LIBRARY_SUFFIX}")
1667  set(prefix                  "${CMAKE_INSTALL_PREFIX}")
1668  # Set this to "yes" to append all libraries on which -lcurl is dependent
1669  set(REQUIRE_LIB_DEPS        "no")
1670  # SUPPORT_FEATURES
1671  # SUPPORT_PROTOCOLS
1672  set(VERSIONNUM              "${CURL_VERSION_NUM}")
1673
1674  # Finally generate a "curl-config" matching this config
1675  # Use:
1676  # * ENABLE_SHARED
1677  # * ENABLE_STATIC
1678  configure_file("${CURL_SOURCE_DIR}/curl-config.in"
1679                "${CURL_BINARY_DIR}/curl-config" @ONLY)
1680  install(FILES "${CURL_BINARY_DIR}/curl-config"
1681          DESTINATION ${CMAKE_INSTALL_BINDIR}
1682          PERMISSIONS
1683            OWNER_READ OWNER_WRITE OWNER_EXECUTE
1684            GROUP_READ GROUP_EXECUTE
1685            WORLD_READ WORLD_EXECUTE)
1686
1687  # Finally generate a pkg-config file matching this config
1688  configure_file("${CURL_SOURCE_DIR}/libcurl.pc.in"
1689                "${CURL_BINARY_DIR}/libcurl.pc" @ONLY)
1690  install(FILES "${CURL_BINARY_DIR}/libcurl.pc"
1691          DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
1692
1693  # install headers
1694  install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include/curl"
1695      DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
1696      FILES_MATCHING PATTERN "*.h")
1697
1698  include(CMakePackageConfigHelpers)
1699  write_basic_package_version_file(
1700      "${version_config}"
1701      VERSION ${CURL_VERSION}
1702      COMPATIBILITY SameMajorVersion
1703  )
1704  file(READ "${version_config}" generated_version_config)
1705  file(WRITE "${version_config}"
1706  "if(NOT PACKAGE_FIND_VERSION_RANGE AND PACKAGE_FIND_VERSION_MAJOR STREQUAL \"7\")
1707      # Version 8 satisfies version 7... requirements
1708      set(PACKAGE_FIND_VERSION_MAJOR 8)
1709      set(PACKAGE_FIND_VERSION_COUNT 1)
1710  endif()
1711  ${generated_version_config}"
1712  )
1713
1714  # Use:
1715  # * TARGETS_EXPORT_NAME
1716  # * PROJECT_NAME
1717  configure_package_config_file(CMake/curl-config.cmake.in
1718          "${project_config}"
1719          INSTALL_DESTINATION ${CURL_INSTALL_CMAKE_DIR}
1720  )
1721
1722  if(CURL_ENABLE_EXPORT_TARGET)
1723    install(
1724            EXPORT "${TARGETS_EXPORT_NAME}"
1725            NAMESPACE "${PROJECT_NAME}::"
1726            DESTINATION ${CURL_INSTALL_CMAKE_DIR}
1727    )
1728  endif()
1729
1730  install(
1731          FILES ${version_config} ${project_config}
1732          DESTINATION ${CURL_INSTALL_CMAKE_DIR}
1733  )
1734
1735  # Workaround for MSVS10 to avoid the Dialog Hell
1736  # FIXME: This could be removed with future version of CMake.
1737  if(MSVC_VERSION EQUAL 1600)
1738    set(CURL_SLN_FILENAME "${CMAKE_CURRENT_BINARY_DIR}/CURL.sln")
1739    if(EXISTS "${CURL_SLN_FILENAME}")
1740      file(APPEND "${CURL_SLN_FILENAME}" "\n# This should be regenerated!\n")
1741    endif()
1742  endif()
1743
1744  if(NOT TARGET curl_uninstall)
1745    configure_file(
1746        ${CMAKE_CURRENT_SOURCE_DIR}/CMake/cmake_uninstall.cmake.in
1747        ${CMAKE_CURRENT_BINARY_DIR}/CMake/cmake_uninstall.cmake
1748        IMMEDIATE @ONLY)
1749
1750    add_custom_target(curl_uninstall
1751        COMMAND ${CMAKE_COMMAND} -P
1752        ${CMAKE_CURRENT_BINARY_DIR}/CMake/cmake_uninstall.cmake)
1753  endif()
1754endif()
1755