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########################################################################### 24set(LIB_NAME "libcurl") 25set(LIBCURL_OUTPUT_NAME "libcurl" CACHE STRING "Basename of the curl library") 26add_definitions("-DBUILDING_LIBCURL") 27 28configure_file("curl_config.h.cmake" "${CMAKE_CURRENT_BINARY_DIR}/curl_config.h") 29 30# Get 'CSOURCES', 'HHEADERS' variables 31transform_makefile_inc("Makefile.inc" "${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake") 32include("${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake") 33 34# DllMain is added later for DLL builds only. 35list(REMOVE_ITEM CSOURCES "dllmain.c") 36 37list(APPEND HHEADERS "${CMAKE_CURRENT_BINARY_DIR}/curl_config.h") 38 39# The rest of the build 40 41include_directories( 42 "${PROJECT_BINARY_DIR}/lib" # for "curl_config.h" 43 "${PROJECT_SOURCE_DIR}/lib" # for "curl_setup.h" 44) 45if(USE_ARES) 46 include_directories(SYSTEM ${CARES_INCLUDE_DIRS}) 47endif() 48 49if(CURL_BUILD_TESTING) 50 add_library( 51 curlu # special libcurlu library just for unittests 52 STATIC 53 EXCLUDE_FROM_ALL 54 ${HHEADERS} ${CSOURCES} 55 ) 56 target_compile_definitions(curlu PUBLIC "UNITTESTS" "CURL_STATICLIB") 57 target_link_libraries(curlu PRIVATE ${CURL_LIBS}) 58endif() 59 60if(ENABLE_CURLDEBUG) 61 # We must compile these sources separately to avoid memdebug.h redefinitions 62 # applying to them. 63 set_source_files_properties("memdebug.c" "curl_multibyte.c" PROPERTIES SKIP_UNITY_BUILD_INCLUSION ON) 64endif() 65 66## Library definition 67 68# Add "_imp" as a suffix before the extension to avoid conflicting with 69# the statically linked "libcurl.lib" (typically with MSVC) 70if(WIN32 AND 71 NOT IMPORT_LIB_SUFFIX AND 72 CMAKE_STATIC_LIBRARY_SUFFIX STREQUAL CMAKE_IMPORT_LIBRARY_SUFFIX) 73 set(IMPORT_LIB_SUFFIX "_imp") 74endif() 75 76# Whether to do a single compilation pass for libcurl sources and reuse these 77# objects to generate both static and shared target. 78if(NOT DEFINED SHARE_LIB_OBJECT) 79 # Enable it by default on platforms where PIC is the default for both shared 80 # and static and there is a way to tell the linker which libcurl symbols it 81 # should export (vs. marking these symbols exportable at compile-time). 82 if(WIN32) 83 set(SHARE_LIB_OBJECT ON) 84 else() 85 # On other platforms, make it an option disabled by default 86 set(SHARE_LIB_OBJECT OFF) 87 endif() 88endif() 89 90if(SHARE_LIB_OBJECT) 91 set(LIB_OBJECT "libcurl_object") 92 add_library(${LIB_OBJECT} OBJECT ${HHEADERS} ${CSOURCES}) 93 if(WIN32) 94 # Define CURL_STATICLIB always, to disable __declspec(dllexport) for 95 # exported libcurl symbols. We handle exports via libcurl.def instead. 96 # Except with symbol hiding disabled or debug mode enabled, when we export 97 # _all_ symbols from libcurl DLL, without using libcurl.def. 98 set_property(TARGET ${LIB_OBJECT} APPEND PROPERTY COMPILE_DEFINITIONS "CURL_STATICLIB") 99 endif() 100 target_link_libraries(${LIB_OBJECT} PRIVATE ${CURL_LIBS}) 101 set_target_properties(${LIB_OBJECT} PROPERTIES 102 POSITION_INDEPENDENT_CODE ON) 103 if(CURL_HIDES_PRIVATE_SYMBOLS) 104 set_property(TARGET ${LIB_OBJECT} APPEND PROPERTY COMPILE_FLAGS "${CURL_CFLAG_SYMBOLS_HIDE}") 105 set_property(TARGET ${LIB_OBJECT} APPEND PROPERTY COMPILE_DEFINITIONS "CURL_HIDDEN_SYMBOLS") 106 endif() 107 if(CURL_HAS_LTO) 108 set_target_properties(${LIB_OBJECT} PROPERTIES 109 INTERPROCEDURAL_OPTIMIZATION_RELEASE TRUE 110 INTERPROCEDURAL_OPTIMIZATION_RELWITHDEBINFO TRUE) 111 endif() 112 113 target_include_directories(${LIB_OBJECT} INTERFACE 114 "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>" 115 "$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>") 116 117 set(LIB_SOURCE $<TARGET_OBJECTS:${LIB_OBJECT}>) 118else() 119 set(LIB_SOURCE ${HHEADERS} ${CSOURCES}) 120endif() 121 122# We want it to be called libcurl on all platforms 123if(BUILD_STATIC_LIBS) 124 list(APPEND libcurl_export ${LIB_STATIC}) 125 add_library(${LIB_STATIC} STATIC ${LIB_SOURCE}) 126 add_library(${PROJECT_NAME}::${LIB_STATIC} ALIAS ${LIB_STATIC}) 127 if(WIN32) 128 set_property(TARGET ${LIB_OBJECT} APPEND PROPERTY COMPILE_DEFINITIONS "CURL_STATICLIB") 129 endif() 130 target_link_libraries(${LIB_STATIC} PRIVATE ${CURL_LIBS}) 131 # Remove the "lib" prefix since the library is already named "libcurl". 132 set_target_properties(${LIB_STATIC} PROPERTIES 133 PREFIX "" OUTPUT_NAME "${LIBCURL_OUTPUT_NAME}" 134 SUFFIX "${STATIC_LIB_SUFFIX}${CMAKE_STATIC_LIBRARY_SUFFIX}" 135 INTERFACE_COMPILE_DEFINITIONS "CURL_STATICLIB") 136 if(CURL_HIDES_PRIVATE_SYMBOLS) 137 set_property(TARGET ${LIB_STATIC} APPEND PROPERTY COMPILE_FLAGS "${CURL_CFLAG_SYMBOLS_HIDE}") 138 set_property(TARGET ${LIB_STATIC} APPEND PROPERTY COMPILE_DEFINITIONS "CURL_HIDDEN_SYMBOLS") 139 endif() 140 if(CURL_HAS_LTO) 141 set_target_properties(${LIB_STATIC} PROPERTIES 142 INTERPROCEDURAL_OPTIMIZATION_RELEASE TRUE 143 INTERPROCEDURAL_OPTIMIZATION_RELWITHDEBINFO TRUE) 144 endif() 145 146 target_include_directories(${LIB_STATIC} INTERFACE 147 "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>" 148 "$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>") 149endif() 150 151if(BUILD_SHARED_LIBS) 152 list(APPEND libcurl_export ${LIB_SHARED}) 153 add_library(${LIB_SHARED} SHARED ${LIB_SOURCE}) 154 add_library(${PROJECT_NAME}::${LIB_SHARED} ALIAS ${LIB_SHARED}) 155 if(WIN32 OR CYGWIN) 156 if(CYGWIN) 157 # For Cygwin always compile dllmain.c as a separate unit since it 158 # includes windows.h, which should not be included in other units. 159 set_source_files_properties("dllmain.c" PROPERTIES SKIP_UNITY_BUILD_INCLUSION ON) 160 endif() 161 set_property(TARGET ${LIB_SHARED} APPEND PROPERTY SOURCES "dllmain.c") 162 endif() 163 if(WIN32) 164 set_property(TARGET ${LIB_SHARED} APPEND PROPERTY SOURCES "libcurl.rc") 165 if(CURL_HIDES_PRIVATE_SYMBOLS) 166 set_property(TARGET ${LIB_SHARED} APPEND PROPERTY SOURCES "${PROJECT_SOURCE_DIR}/lib/libcurl.def") 167 endif() 168 endif() 169 target_link_libraries(${LIB_SHARED} PRIVATE ${CURL_LIBS}) 170 # Remove the "lib" prefix since the library is already named "libcurl". 171 set_target_properties(${LIB_SHARED} PROPERTIES 172 PREFIX "" OUTPUT_NAME "${LIBCURL_OUTPUT_NAME}" 173 IMPORT_PREFIX "" IMPORT_SUFFIX "${IMPORT_LIB_SUFFIX}${CMAKE_IMPORT_LIBRARY_SUFFIX}" 174 POSITION_INDEPENDENT_CODE ON) 175 if(CURL_HIDES_PRIVATE_SYMBOLS) 176 set_property(TARGET ${LIB_SHARED} APPEND PROPERTY COMPILE_FLAGS "${CURL_CFLAG_SYMBOLS_HIDE}") 177 set_property(TARGET ${LIB_SHARED} APPEND PROPERTY COMPILE_DEFINITIONS "CURL_HIDDEN_SYMBOLS") 178 endif() 179 if(CURL_HAS_LTO) 180 set_target_properties(${LIB_SHARED} PROPERTIES 181 INTERPROCEDURAL_OPTIMIZATION_RELEASE TRUE 182 INTERPROCEDURAL_OPTIMIZATION_RELWITHDEBINFO TRUE) 183 endif() 184 185 target_include_directories(${LIB_SHARED} INTERFACE 186 "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>" 187 "$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>") 188 189 if(CMAKE_DLL_NAME_WITH_SOVERSION OR 190 CYGWIN OR 191 APPLE OR 192 CMAKE_SYSTEM_NAME STREQUAL "AIX" OR 193 CMAKE_SYSTEM_NAME STREQUAL "Linux" OR 194 CMAKE_SYSTEM_NAME STREQUAL "SunOS" OR 195 CMAKE_SYSTEM_NAME STREQUAL "Haiku" OR 196 CMAKE_SYSTEM_NAME STREQUAL "GNU/kFreeBSD" OR 197 # FreeBSD comes with the a.out and ELF flavours but a.out was supported 198 # up to v3.x and ELF from v3.x. I cannot imagine someone running CMake 199 # on those ancient systems. 200 CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") 201 set(_soversion_default TRUE) 202 else() 203 set(_soversion_default FALSE) 204 endif() 205 206 option(CURL_LIBCURL_SOVERSION "Enable libcurl SOVERSION" ${_soversion_default}) 207 option(CURL_LIBCURL_VERSIONED_SYMBOLS "Enable libcurl versioned symbols" OFF) 208 209 if(CURL_LIBCURL_SOVERSION OR CURL_LIBCURL_VERSIONED_SYMBOLS) 210 # Get 'VERSIONCHANGE', 'VERSIONADD', 'VERSIONDEL', 'VERSIONINFO' variables 211 transform_makefile_inc("Makefile.soname" "${CMAKE_CURRENT_BINARY_DIR}/Makefile.soname.cmake") 212 include("${CMAKE_CURRENT_BINARY_DIR}/Makefile.soname.cmake") 213 214 math(EXPR _cmakesoname "${VERSIONCHANGE} - ${VERSIONDEL}") 215 set(_cmakeversion "${_cmakesoname}.${VERSIONDEL}.${VERSIONADD}") 216 endif() 217 218 if(CURL_LIBCURL_SOVERSION) 219 set_target_properties(${LIB_SHARED} PROPERTIES 220 VERSION "${_cmakeversion}" SOVERSION "${_cmakesoname}") 221 endif() 222 223 ## Versioned symbols 224 225 if(CURL_LIBCURL_VERSIONED_SYMBOLS) 226 if(NOT DEFINED CURL_LIBCURL_VERSIONED_SYMBOLS_PREFIX) 227 # Default to prefixes used by autotools 228 if(CURL_WITH_MULTI_SSL) 229 set(CURL_LIBCURL_VERSIONED_SYMBOLS_PREFIX "MULTISSL_") 230 elseif(CURL_USE_OPENSSL) 231 set(CURL_LIBCURL_VERSIONED_SYMBOLS_PREFIX "OPENSSL_") 232 elseif(CURL_USE_MBEDTLS) 233 set(CURL_LIBCURL_VERSIONED_SYMBOLS_PREFIX "MBEDTLS_") 234 elseif(CURL_USE_BEARSSL) 235 set(CURL_LIBCURL_VERSIONED_SYMBOLS_PREFIX "BEARSSL_") 236 elseif(CURL_USE_WOLFSSL) 237 set(CURL_LIBCURL_VERSIONED_SYMBOLS_PREFIX "WOLFSSL_") 238 elseif(CURL_USE_GNUTLS) 239 set(CURL_LIBCURL_VERSIONED_SYMBOLS_PREFIX "GNUTLS_") 240 elseif(CURL_USE_RUSTLS) 241 set(CURL_LIBCURL_VERSIONED_SYMBOLS_PREFIX "RUSTLS_") 242 endif() 243 endif() 244 # Generate version script for the linker, for versioned symbols. 245 # Consumed variables: 246 # CURL_LIBCURL_VERSIONED_SYMBOLS_PREFIX 247 # CURL_LIBCURL_VERSIONED_SYMBOLS_SONAME 248 set(CURL_LIBCURL_VERSIONED_SYMBOLS_SONAME ${_cmakesoname}) 249 configure_file( 250 "${CMAKE_CURRENT_SOURCE_DIR}/libcurl.vers.in" 251 "${CMAKE_CURRENT_BINARY_DIR}/libcurl.vers" @ONLY) 252 include(CMakePushCheckState) 253 include(CheckCSourceCompiles) 254 cmake_push_check_state() 255 set(CMAKE_REQUIRED_LINK_OPTIONS "-Wl,--version-script=${CMAKE_CURRENT_BINARY_DIR}/libcurl.vers") 256 check_c_source_compiles("int main(void) { return 0; }" HAVE_VERSIONED_SYMBOLS) 257 if(HAVE_VERSIONED_SYMBOLS) 258 # Superseded by LINK_OPTIONS in CMake 3.13 and later. 259 set_target_properties(${LIB_SHARED} PROPERTIES LINK_FLAGS "${CMAKE_REQUIRED_LINK_OPTIONS}") 260 else() 261 message(WARNING "Versioned symbols requested, but not supported by the toolchain.") 262 endif() 263 cmake_pop_check_state() 264 endif() 265endif() 266 267add_library(${LIB_NAME} ALIAS ${LIB_SELECTED}) 268add_library(${PROJECT_NAME}::${LIB_NAME} ALIAS ${LIB_SELECTED}) 269 270if(CURL_ENABLE_EXPORT_TARGET) 271 if(BUILD_STATIC_LIBS) 272 install(TARGETS ${LIB_STATIC} 273 EXPORT ${TARGETS_EXPORT_NAME} 274 ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} 275 LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} 276 RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} 277 ) 278 endif() 279 if(BUILD_SHARED_LIBS) 280 install(TARGETS ${LIB_SHARED} 281 EXPORT ${TARGETS_EXPORT_NAME} 282 ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} 283 LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} 284 RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} 285 ) 286 endif() 287 288 export(TARGETS ${libcurl_export} 289 FILE "${PROJECT_BINARY_DIR}/libcurl-target.cmake" 290 NAMESPACE ${PROJECT_NAME}:: 291 ) 292endif() 293