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