4 # Finds the Curl library
6 # This will define the following target:
8 # ${APP_NAME_LC}::Curl - The Curl library
10 if(NOT TARGET ${APP_NAME_LC}::${CMAKE_FIND_PACKAGE_NAME})
11 include(cmake/scripts/common/ModuleHelpers.cmake)
14 find_package(Brotli REQUIRED QUIET)
15 find_package(NGHttp2 REQUIRED QUIET)
16 find_package(OpenSSL REQUIRED QUIET)
18 # Darwin platforms link against toolchain provided zlib regardless
19 # They will fail when searching for static. All other platforms, prefer static
20 # if possible (requires cmake 3.24+ otherwise variable is a no-op)
21 # Windows still uses dynamic lib for zlib for other purposes, dont mix
22 if(NOT CMAKE_SYSTEM_NAME MATCHES "Darwin" AND NOT (WIN32 OR WINDOWS_STORE))
23 set(ZLIB_USE_STATIC_LIBS ON)
25 find_package(Zlib REQUIRED)
26 unset(ZLIB_USE_STATIC_LIBS)
28 set(CURL_VERSION ${${MODULE}_VER})
29 # Curl debug uses postfix -d for all platforms
30 set(CURL_DEBUG_POSTFIX -d)
32 if(WIN32 OR WINDOWS_STORE)
33 set(CURL_C_FLAGS -DNGHTTP2_STATICLIB)
34 set(PLATFORM_LINK_LIBS crypt32.lib)
37 set(patches "${CORE_SOURCE_DIR}/tools/depends/target/${MODULE_LC}/01-win-nghttp2-add-name.patch")
39 generate_patchcommand("${patches}")
41 set(CMAKE_ARGS -DBUILD_CURL_EXE=OFF
42 -DBUILD_SHARED_LIBS=OFF
43 -DBUILD_STATIC_LIBS=ON
44 -DBUILD_LIBCURL_DOCS=OFF
45 -DENABLE_CURL_MANUAL=OFF
46 -DCURL_DISABLE_TESTS=OFF
47 -DCURL_DISABLE_LDAP=ON
48 -DCURL_DISABLE_LDAPS=ON
49 -DCURL_DISABLE_SMB=OFF
51 -DOPENSSL_ROOT_DIR=${DEPENDS_PATH}
55 -DCURL_USE_LIBSSH2=OFF
62 # Link libraries for target interface
63 set(PC_CURL_LINK_LIBRARIES Brotli::Brotli NGHttp2::NGHttp2 OpenSSL::Crypto OpenSSL::SSL ZLIB::ZLIB ${PLATFORM_LINK_LIBS})
65 # Add dependencies to build target
66 add_dependencies(${MODULE_LC} Brotli::Brotli)
67 add_dependencies(${MODULE_LC} NGHttp2::NGHttp2)
68 add_dependencies(${MODULE_LC} OpenSSL::SSL)
69 add_dependencies(${MODULE_LC} OpenSSL::Crypto)
70 add_dependencies(${MODULE_LC} ZLIB::ZLIB)
77 find_package(CURL CONFIG QUIET
78 HINTS ${DEPENDS_PATH}/lib/cmake
79 ${${CORE_PLATFORM_NAME_LC}_SEARCH_CONFIG})
81 # Check for existing Curl. If version >= CURL-VERSION file version, dont build
82 # A corner case, but if a linux/freebsd user WANTS to build internal curl, build anyway
83 if((CURL_VERSION VERSION_LESS ${${MODULE}_VER} AND ENABLE_INTERNAL_CURL) OR
84 ((CORE_SYSTEM_NAME STREQUAL linux OR CORE_SYSTEM_NAME STREQUAL freebsd) AND ENABLE_INTERNAL_CURL))
88 # Maybe need to look explicitly for CURL::libcurl_static/shared?
89 if(NOT TARGET CURL::libcurl)
90 find_package(PkgConfig)
92 # We only rely on pkgconfig for non windows platforms
93 if(PKG_CONFIG_FOUND AND NOT (WIN32 OR WINDOWS_STORE))
94 pkg_check_modules(CURL libcurl QUIET)
96 # First item is the full path of the library file found
97 # pkg_check_modules does not populate a variable of the found library explicitly
98 list(GET CURL_LINK_LIBRARIES 0 CURL_LIBRARY_RELEASE)
100 # Add link libraries for static lib usage
101 if(${CURL_LIBRARY} MATCHES ".+\.a$" AND CURL_LINK_LIBRARIES)
103 list(REMOVE_DUPLICATES CURL_LINK_LIBRARIES)
105 # Remove own library - eg libcurl.a
106 list(FILTER CURL_LINK_LIBRARIES EXCLUDE REGEX ".*curl.*\.a$")
107 set(PC_CURL_LINK_LIBRARIES ${CURL_LINK_LIBRARIES})
110 # pkgconfig sets CURL_INCLUDEDIR, map this to our "standard" variable name
111 set(CURL_INCLUDE_DIR ${CURL_INCLUDEDIR})
113 find_path(CURL_INCLUDE_DIR NAMES curl/curl.h
114 HINTS ${DEPENDS_PATH}/include
115 ${${CORE_PLATFORM_LC}_SEARCH_CONFIG})
116 find_library(CURL_LIBRARY_RELEASE NAMES curl libcurl libcurl_imp
117 HINTS ${DEPENDS_PATH}/lib
118 ${${CORE_PLATFORM_LC}_SEARCH_CONFIG})
121 # CURL::libcurl is an alias. We need to get the actual aias target, as we cant make an
122 # alias of an alias (ie our ${APP_NAME_LC}::Curl cant be an alias of Curl::libcurl)
123 get_target_property(_CURL_ALIASTARGET CURL::libcurl ALIASED_TARGET)
125 # This is for the case where a distro provides a non standard (Debug/Release) config type
126 # eg Debian's config file is CURLConfigTargets-none.cmake
127 # convert this back to either DEBUG/RELEASE or just RELEASE
128 # we only do this because we use find_package_handle_standard_args for config time output
129 # and it isnt capable of handling TARGETS, so we have to extract the info
130 get_target_property(_CURL_CONFIGURATIONS ${_CURL_ALIASTARGET} IMPORTED_CONFIGURATIONS)
131 foreach(_curl_config IN LISTS _CURL_CONFIGURATIONS)
132 # Some non standard config (eg None on Debian)
133 # Just set to RELEASE var so select_library_configurations can continue to work its magic
134 string(TOUPPER ${_curl_config} _curl_config_UPPER)
135 if((NOT ${_curl_config_UPPER} STREQUAL "RELEASE") AND
136 (NOT ${_curl_config_UPPER} STREQUAL "DEBUG"))
137 get_target_property(CURL_LIBRARY_RELEASE ${_CURL_ALIASTARGET} IMPORTED_LOCATION_${_curl_config_UPPER})
139 get_target_property(CURL_LIBRARY_${_curl_config_UPPER} ${_CURL_ALIASTARGET} IMPORTED_LOCATION_${_curl_config_UPPER})
143 get_target_property(CURL_INCLUDE_DIR CURL::libcurl INTERFACE_INCLUDE_DIRECTORIES)
147 include(SelectLibraryConfigurations)
148 select_library_configurations(CURL)
149 unset(CURL_LIBRARIES)
151 include(FindPackageHandleStandardArgs)
152 find_package_handle_standard_args(Curl
153 REQUIRED_VARS CURL_LIBRARY CURL_INCLUDE_DIR
154 VERSION_VAR CURL_VERSION)
157 # cmake target and not building internal
158 if(TARGET CURL::libcurl AND NOT TARGET curl)
159 # CURL::libcurl is an alias. We need to get the actual aias target, as we cant make an
160 # alias of an alias (ie our ${APP_NAME_LC}::Curl cant be an alias of Curl::libcurl)
161 if(NOT _CURL_ALIASTARGET)
162 get_target_property(_CURL_ALIASTARGET CURL::libcurl ALIASED_TARGET)
165 add_library(${APP_NAME_LC}::${CMAKE_FIND_PACKAGE_NAME} ALIAS ${_CURL_ALIASTARGET})
167 add_library(${APP_NAME_LC}::${CMAKE_FIND_PACKAGE_NAME} UNKNOWN IMPORTED)
168 set_target_properties(${APP_NAME_LC}::${CMAKE_FIND_PACKAGE_NAME} PROPERTIES
169 INTERFACE_INCLUDE_DIRECTORIES "${CURL_INCLUDE_DIR}")
171 if(CURL_LIBRARY_RELEASE)
172 set_target_properties(${APP_NAME_LC}::${CMAKE_FIND_PACKAGE_NAME} PROPERTIES
173 IMPORTED_CONFIGURATIONS RELEASE
174 IMPORTED_LOCATION_RELEASE "${CURL_LIBRARY_RELEASE}")
176 if(CURL_LIBRARY_DEBUG)
177 set_target_properties(${APP_NAME_LC}::${CMAKE_FIND_PACKAGE_NAME} PROPERTIES
178 IMPORTED_LOCATION_DEBUG "${CURL_LIBRARY_DEBUG}")
179 set_property(TARGET ${APP_NAME_LC}::${CMAKE_FIND_PACKAGE_NAME} APPEND PROPERTY
180 IMPORTED_CONFIGURATIONS DEBUG)
183 # Add link libraries for static lib usage found from pkg-config
184 if(PC_CURL_LINK_LIBRARIES)
185 set_target_properties(${APP_NAME_LC}::${CMAKE_FIND_PACKAGE_NAME} PROPERTIES
186 INTERFACE_LINK_LIBRARIES "${PC_CURL_LINK_LIBRARIES}")
189 if(WIN32 OR WINDOWS_STORE)
190 set_property(TARGET ${APP_NAME_LC}::${CMAKE_FIND_PACKAGE_NAME} APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS "CURL_STATICLIB")
196 add_dependencies(${APP_NAME_LC}::${CMAKE_FIND_PACKAGE_NAME} curl)
199 # Add internal build target when a Multi Config Generator is used
200 # We cant add a dependency based off a generator expression for targeted build types,
201 # https://gitlab.kitware.com/cmake/cmake/-/issues/19467
202 # therefore if the find heuristics only find the library, we add the internal build
203 # target to the project to allow user to manually trigger for any build type they need
204 # in case only a specific build type is actually available (eg Release found, Debug Required)
205 # This is mainly targeted for windows who required different runtime libs for different
206 # types, and they arent compatible
207 if(_multiconfig_generator)
210 set_target_properties(curl PROPERTIES EXCLUDE_FROM_ALL TRUE)
212 add_dependencies(build_internal_depends curl)
215 if(Curl_FIND_REQUIRED)
216 message(FATAL_ERROR "Curl libraries were not found.")