xref: /curl/lib/CMakeLists.txt (revision b3816f67)
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