cmake: support building static and shared libcurl in one go
This patch adds the ability to build a static and shared libcurl library in a single build session. It also adds an option to select which one to use when building the curl executable. New build options: - `BUILD_STATIC_LIBS`. Default: `OFF`. Enabled automatically if `BUILD_SHARED_LIBS` is `OFF`. - `BUILD_STATIC_CURL`. Default: `OFF`. Requires `BUILD_STATIC_LIBS` enabled. Enabled automatically if building static libcurl only. - `STATIC_LIB_SUFFIX`. Default: empty. - `IMPORT_LIB_SUFFIX`. Default: `_imp` if implib filename would collide with static lib name (typically with MSVC) in Windows builds. Otherwise empty. Also: - Stop setting the `CURL_STATICLIB` macro via `curl_config.h`, and pass it directly to the compiler. This also allows to delete a condition from `tests/server/CMakeLists.txt`. - Complete a TODO by following the logic used in autotools (also for `LIBCURL_NO_SHARED`), and set `-DCURL_STATICLIB` in `Cflags:` of `libcurl.pc` for _static-only_ curl builds. - Convert an existing CI test to build both shared and static libcurl. Closes #11505
This commit is contained in:
Родитель
40c63290e3
Коммит
1199308dbc
|
@ -180,7 +180,7 @@ jobs:
|
|||
generate: -DOPENSSL_ROOT_DIR=/usr/local/opt/libressl -DCURL_DISABLE_LDAP=ON -DCURL_DISABLE_LDAPS=ON -DCMAKE_UNITY_BUILD=ON
|
||||
- name: libssh2
|
||||
install: nghttp2 openssl libssh2
|
||||
generate: -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl -DCURL_USE_LIBSSH2=ON
|
||||
generate: -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl -DCURL_USE_LIBSSH2=ON -DBUILD_SHARED_LIBS=ON -DBUILD_STATIC_LIBS=ON
|
||||
steps:
|
||||
- run: echo libtool autoconf automake pkg-config ${{ matrix.build.install }} | xargs -Ix -n1 echo brew '"x"' > /tmp/Brewfile
|
||||
name: 'brew bundle'
|
||||
|
|
|
@ -33,3 +33,6 @@ endif()
|
|||
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/@TARGETS_EXPORT_NAME@.cmake")
|
||||
check_required_components("@PROJECT_NAME@")
|
||||
|
||||
# Alias for either shared or static library
|
||||
add_library(curl::libcurl ALIAS curl::@LIB_SELECTED@)
|
||||
|
|
|
@ -103,6 +103,8 @@ option(CURL_WERROR "Turn compiler warnings into errors" OFF)
|
|||
option(PICKY_COMPILER "Enable picky compiler options" ON)
|
||||
option(BUILD_CURL_EXE "Set to ON to build curl executable." ON)
|
||||
option(BUILD_SHARED_LIBS "Build shared libraries" ON)
|
||||
option(BUILD_STATIC_LIBS "Build shared libraries" OFF)
|
||||
option(BUILD_STATIC_CURL "Build curl executable with static libcurl" OFF)
|
||||
option(ENABLE_ARES "Set to ON to enable c-ares support" OFF)
|
||||
if(WIN32)
|
||||
option(CURL_STATIC_CRT "Set to ON to build libcurl with static CRT on Windows (/MT)." OFF)
|
||||
|
@ -146,6 +148,32 @@ if(NOT DEFINED CMAKE_DEBUG_POSTFIX)
|
|||
set(CMAKE_DEBUG_POSTFIX "-d")
|
||||
endif()
|
||||
|
||||
set(LIB_STATIC "libcurl_static")
|
||||
set(LIB_SHARED "libcurl_shared")
|
||||
|
||||
if(NOT BUILD_SHARED_LIBS AND NOT BUILD_STATIC_LIBS)
|
||||
set(BUILD_STATIC_LIBS ON)
|
||||
endif()
|
||||
if(NOT BUILD_STATIC_CURL AND NOT BUILD_SHARED_LIBS)
|
||||
set(BUILD_STATIC_CURL ON)
|
||||
elseif(BUILD_STATIC_CURL AND NOT BUILD_STATIC_LIBS)
|
||||
set(BUILD_STATIC_CURL OFF)
|
||||
endif()
|
||||
|
||||
# lib flavour selected for curl tool
|
||||
if(BUILD_STATIC_CURL)
|
||||
set(LIB_SELECTED_FOR_EXE ${LIB_STATIC})
|
||||
else()
|
||||
set(LIB_SELECTED_FOR_EXE ${LIB_SHARED})
|
||||
endif()
|
||||
|
||||
# lib flavour selected for example and test programs.
|
||||
if(BUILD_SHARED_LIBS)
|
||||
set(LIB_SELECTED ${LIB_SHARED})
|
||||
else()
|
||||
set(LIB_SELECTED ${LIB_STATIC})
|
||||
endif()
|
||||
|
||||
# initialize CURL_LIBS
|
||||
set(CURL_LIBS "")
|
||||
|
||||
|
@ -1539,8 +1567,6 @@ message(STATUS "Enabled SSL backends: ${SSL_BACKENDS}")
|
|||
set(CC "${CMAKE_C_COMPILER}")
|
||||
# TODO probably put a -D... options here?
|
||||
set(CONFIGURE_OPTIONS "")
|
||||
# TODO when to set "-DCURL_STATICLIB" for CPPFLAG_CURL_STATICLIB?
|
||||
set(CPPFLAG_CURL_STATICLIB "")
|
||||
set(CURLVERSION "${CURL_VERSION}")
|
||||
set(exec_prefix "\${prefix}")
|
||||
set(includedir "\${prefix}/include")
|
||||
|
@ -1570,12 +1596,17 @@ foreach(_lib ${CMAKE_C_IMPLICIT_LINK_LIBRARIES} ${CURL_LIBS})
|
|||
endforeach()
|
||||
if(BUILD_SHARED_LIBS)
|
||||
set(ENABLE_SHARED "yes")
|
||||
set(ENABLE_STATIC "no")
|
||||
set(LIBCURL_NO_SHARED "")
|
||||
set(CPPFLAG_CURL_STATICLIB "")
|
||||
else()
|
||||
set(ENABLE_SHARED "no")
|
||||
set(ENABLE_STATIC "yes")
|
||||
set(LIBCURL_NO_SHARED "${LIBCURL_LIBS}")
|
||||
set(CPPFLAG_CURL_STATICLIB "-DCURL_STATICLIB")
|
||||
endif()
|
||||
if(BUILD_STATIC_LIBS)
|
||||
set(ENABLE_STATIC "yes")
|
||||
else()
|
||||
set(ENABLE_STATIC "no")
|
||||
endif()
|
||||
# "a" (Linux) or "lib" (Windows)
|
||||
string(REPLACE "." "" libext "${CMAKE_STATIC_LIBRARY_SUFFIX}")
|
||||
|
|
|
@ -25,14 +25,6 @@ set(LIB_NAME libcurl)
|
|||
set(LIBCURL_OUTPUT_NAME libcurl CACHE STRING "Basename of the curl library")
|
||||
add_definitions(-DBUILDING_LIBCURL)
|
||||
|
||||
if(BUILD_SHARED_LIBS)
|
||||
set(CURL_STATICLIB NO)
|
||||
else()
|
||||
set(CURL_STATICLIB YES)
|
||||
endif()
|
||||
|
||||
# Use:
|
||||
# * CURL_STATICLIB
|
||||
configure_file(curl_config.h.cmake
|
||||
${CMAKE_CURRENT_BINARY_DIR}/curl_config.h)
|
||||
|
||||
|
@ -43,10 +35,6 @@ list(APPEND HHEADERS
|
|||
${CMAKE_CURRENT_BINARY_DIR}/curl_config.h
|
||||
)
|
||||
|
||||
if(WIN32 AND NOT CURL_STATICLIB)
|
||||
list(APPEND CSOURCES libcurl.rc)
|
||||
endif()
|
||||
|
||||
# The rest of the build
|
||||
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR}/../include)
|
||||
|
@ -59,11 +47,6 @@ if(USE_ARES)
|
|||
include_directories(${CARES_INCLUDE_DIR})
|
||||
endif()
|
||||
|
||||
add_library(
|
||||
${LIB_NAME}
|
||||
${HHEADERS} ${CSOURCES}
|
||||
)
|
||||
|
||||
add_library(
|
||||
curlu # special libcurlu library just for unittests
|
||||
STATIC
|
||||
|
@ -72,32 +55,16 @@ add_library(
|
|||
)
|
||||
target_compile_definitions(curlu PUBLIC UNITTESTS CURL_STATICLIB)
|
||||
|
||||
add_library(
|
||||
${PROJECT_NAME}::${LIB_NAME}
|
||||
ALIAS ${LIB_NAME}
|
||||
)
|
||||
|
||||
if(ENABLE_CURLDEBUG)
|
||||
# We must compile memdebug.c separately to avoid memdebug.h redefinitions
|
||||
# being applied to memdebug.c itself.
|
||||
set_source_files_properties(memdebug.c PROPERTIES SKIP_UNITY_BUILD_INCLUSION ON)
|
||||
endif()
|
||||
|
||||
if(NOT BUILD_SHARED_LIBS)
|
||||
set_target_properties(${LIB_NAME} PROPERTIES INTERFACE_COMPILE_DEFINITIONS CURL_STATICLIB)
|
||||
endif()
|
||||
|
||||
target_link_libraries(${LIB_NAME} PRIVATE ${CURL_LIBS})
|
||||
target_link_libraries(curlu PRIVATE ${CURL_LIBS})
|
||||
|
||||
transform_makefile_inc("Makefile.soname" "${CMAKE_CURRENT_BINARY_DIR}/Makefile.soname.cmake")
|
||||
include(${CMAKE_CURRENT_BINARY_DIR}/Makefile.soname.cmake)
|
||||
|
||||
set_target_properties(${LIB_NAME} PROPERTIES
|
||||
COMPILE_DEFINITIONS BUILDING_LIBCURL
|
||||
OUTPUT_NAME ${LIBCURL_OUTPUT_NAME}
|
||||
)
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "AIX" OR
|
||||
CMAKE_SYSTEM_NAME STREQUAL "Linux" OR
|
||||
CMAKE_SYSTEM_NAME STREQUAL "Darwin" OR
|
||||
|
@ -114,39 +81,11 @@ if(CMAKE_SYSTEM_NAME STREQUAL "AIX" OR
|
|||
|
||||
math(EXPR CMAKESONAME "${VERSIONCHANGE} - ${VERSIONDEL}")
|
||||
set(CMAKEVERSION "${CMAKESONAME}.${VERSIONDEL}.${VERSIONADD}")
|
||||
|
||||
set_target_properties(${LIB_NAME} PROPERTIES
|
||||
VERSION ${CMAKEVERSION}
|
||||
SOVERSION ${CMAKESONAME}
|
||||
)
|
||||
|
||||
else()
|
||||
unset(CMAKESONAME)
|
||||
endif()
|
||||
|
||||
|
||||
if(HIDES_CURL_PRIVATE_SYMBOLS)
|
||||
set_property(TARGET ${LIB_NAME} APPEND PROPERTY COMPILE_DEFINITIONS "CURL_HIDDEN_SYMBOLS")
|
||||
set_property(TARGET ${LIB_NAME} APPEND PROPERTY COMPILE_FLAGS ${CURL_CFLAG_SYMBOLS_HIDE})
|
||||
endif()
|
||||
|
||||
# Remove the "lib" prefix since the library is already named "libcurl".
|
||||
set_target_properties(${LIB_NAME} PROPERTIES PREFIX "")
|
||||
set_target_properties(${LIB_NAME} PROPERTIES IMPORT_PREFIX "")
|
||||
|
||||
if(CURL_HAS_LTO)
|
||||
set_target_properties(${LIB_NAME} PROPERTIES
|
||||
INTERPROCEDURAL_OPTIMIZATION_RELEASE TRUE
|
||||
INTERPROCEDURAL_OPTIMIZATION_RELWITHDEBINFO TRUE)
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
if(BUILD_SHARED_LIBS)
|
||||
if(MSVC)
|
||||
# Add "_imp" as a suffix before the extension to avoid conflicting with
|
||||
# the statically linked "libcurl.lib"
|
||||
set_target_properties(${LIB_NAME} PROPERTIES IMPORT_SUFFIX "_imp.lib")
|
||||
endif()
|
||||
endif()
|
||||
elseif(NOT CMAKE_CROSSCOMPILING)
|
||||
if(NOT WIN32 AND NOT CMAKE_CROSSCOMPILING)
|
||||
# on not-Windows and not-crosscompiling, check for writable argv[]
|
||||
include(CheckCSourceRuns)
|
||||
check_c_source_runs("
|
||||
|
@ -159,19 +98,104 @@ int main(int argc, char **argv)
|
|||
HAVE_WRITABLE_ARGV)
|
||||
endif()
|
||||
|
||||
target_include_directories(${LIB_NAME} INTERFACE
|
||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
|
||||
$<BUILD_INTERFACE:${CURL_SOURCE_DIR}/include>)
|
||||
## Library definition
|
||||
|
||||
# Add "_imp" as a suffix before the extension to avoid conflicting with
|
||||
# the statically linked "libcurl.lib" (typically with MSVC)
|
||||
if(WIN32 AND
|
||||
NOT IMPORT_LIB_SUFFIX AND
|
||||
CMAKE_STATIC_LIBRARY_SUFFIX STREQUAL CMAKE_IMPORT_LIBRARY_SUFFIX)
|
||||
set(IMPORT_LIB_SUFFIX "_imp")
|
||||
endif()
|
||||
|
||||
# we want it to be called libcurl on all platforms
|
||||
if(BUILD_STATIC_LIBS)
|
||||
list(APPEND libcurl_export ${LIB_STATIC})
|
||||
add_library(${LIB_STATIC} STATIC ${HHEADERS} ${CSOURCES})
|
||||
add_library(${PROJECT_NAME}::${LIB_STATIC} ALIAS ${LIB_STATIC})
|
||||
target_link_libraries(${LIB_STATIC} PRIVATE ${CURL_LIBS})
|
||||
# Remove the "lib" prefix since the library is already named "libcurl".
|
||||
set_target_properties(${LIB_STATIC} PROPERTIES
|
||||
PREFIX "" OUTPUT_NAME "${LIBCURL_OUTPUT_NAME}"
|
||||
SUFFIX "${STATIC_LIB_SUFFIX}${CMAKE_STATIC_LIBRARY_SUFFIX}"
|
||||
COMPILE_DEFINITIONS "BUILDING_LIBCURL"
|
||||
INTERFACE_COMPILE_DEFINITIONS "CURL_STATICLIB")
|
||||
if(HIDES_CURL_PRIVATE_SYMBOLS)
|
||||
set_target_properties(${LIB_STATIC} PROPERTIES
|
||||
COMPILE_DEFINITIONS "CURL_HIDDEN_SYMBOLS"
|
||||
COMPILE_FLAGS "${CURL_CFLAG_SYMBOLS_HIDE}")
|
||||
endif()
|
||||
if(CURL_HAS_LTO)
|
||||
set_target_properties(${LIB_STATIC} PROPERTIES
|
||||
INTERPROCEDURAL_OPTIMIZATION_RELEASE TRUE
|
||||
INTERPROCEDURAL_OPTIMIZATION_RELWITHDEBINFO TRUE)
|
||||
endif()
|
||||
if(CMAKEVERSION AND CMAKESONAME)
|
||||
set_target_properties(${LIB_STATIC} PROPERTIES
|
||||
VERSION ${CMAKEVERSION} SOVERSION ${CMAKESONAME})
|
||||
endif()
|
||||
|
||||
target_include_directories(${LIB_STATIC} INTERFACE
|
||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
|
||||
$<BUILD_INTERFACE:${CURL_SOURCE_DIR}/include>)
|
||||
endif()
|
||||
|
||||
if(BUILD_SHARED_LIBS)
|
||||
list(APPEND libcurl_export ${LIB_SHARED})
|
||||
add_library(${LIB_SHARED} SHARED ${HHEADERS} ${CSOURCES})
|
||||
add_library(${PROJECT_NAME}::${LIB_SHARED} ALIAS ${LIB_SHARED})
|
||||
if(WIN32)
|
||||
set_property(TARGET ${LIB_SHARED} APPEND PROPERTY SOURCES libcurl.rc)
|
||||
endif()
|
||||
target_link_libraries(${LIB_SHARED} PRIVATE ${CURL_LIBS})
|
||||
# Remove the "lib" prefix since the library is already named "libcurl".
|
||||
set_target_properties(${LIB_SHARED} PROPERTIES
|
||||
PREFIX "" OUTPUT_NAME "${LIBCURL_OUTPUT_NAME}"
|
||||
IMPORT_PREFIX "" IMPORT_SUFFIX "${IMPORT_LIB_SUFFIX}${CMAKE_IMPORT_LIBRARY_SUFFIX}"
|
||||
COMPILE_DEFINITIONS "BUILDING_LIBCURL"
|
||||
POSITION_INDEPENDENT_CODE ON)
|
||||
if(HIDES_CURL_PRIVATE_SYMBOLS)
|
||||
set_target_properties(${LIB_SHARED} PROPERTIES
|
||||
COMPILE_DEFINITIONS "CURL_HIDDEN_SYMBOLS"
|
||||
COMPILE_FLAGS "${CURL_CFLAG_SYMBOLS_HIDE}")
|
||||
endif()
|
||||
if(CURL_HAS_LTO)
|
||||
set_target_properties(${LIB_SHARED} PROPERTIES
|
||||
INTERPROCEDURAL_OPTIMIZATION_RELEASE TRUE
|
||||
INTERPROCEDURAL_OPTIMIZATION_RELWITHDEBINFO TRUE)
|
||||
endif()
|
||||
if(CMAKEVERSION AND CMAKESONAME)
|
||||
set_target_properties(${LIB_SHARED} PROPERTIES
|
||||
VERSION ${CMAKEVERSION} SOVERSION ${CMAKESONAME})
|
||||
endif()
|
||||
|
||||
target_include_directories(${LIB_SHARED} INTERFACE
|
||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
|
||||
$<BUILD_INTERFACE:${CURL_SOURCE_DIR}/include>)
|
||||
endif()
|
||||
|
||||
add_library(${LIB_NAME} ALIAS ${LIB_SELECTED})
|
||||
add_library(${PROJECT_NAME}::${LIB_NAME} ALIAS ${LIB_SELECTED})
|
||||
|
||||
if(CURL_ENABLE_EXPORT_TARGET)
|
||||
install(TARGETS ${LIB_NAME}
|
||||
EXPORT ${TARGETS_EXPORT_NAME}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
)
|
||||
if(BUILD_STATIC_LIBS)
|
||||
install(TARGETS ${LIB_STATIC}
|
||||
EXPORT ${TARGETS_EXPORT_NAME}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
)
|
||||
endif()
|
||||
if(BUILD_SHARED_LIBS)
|
||||
install(TARGETS ${LIB_SHARED}
|
||||
EXPORT ${TARGETS_EXPORT_NAME}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
)
|
||||
endif()
|
||||
|
||||
export(TARGETS ${LIB_NAME}
|
||||
export(TARGETS ${libcurl_export}
|
||||
FILE ${PROJECT_BINARY_DIR}/libcurl-target.cmake
|
||||
NAMESPACE ${PROJECT_NAME}::
|
||||
)
|
||||
|
|
|
@ -132,9 +132,6 @@
|
|||
/* Use Windows LDAP implementation */
|
||||
#cmakedefine USE_WIN32_LDAP 1
|
||||
|
||||
/* when not building a shared library */
|
||||
#cmakedefine CURL_STATICLIB 1
|
||||
|
||||
/* your Entropy Gathering Daemon socket pathname */
|
||||
#cmakedefine EGD_SOCKET ${EGD_SOCKET}
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@ if(WIN32)
|
|||
endif()
|
||||
|
||||
# CURL_CFILES, CURLX_CFILES, CURL_HFILES come from Makefile.inc
|
||||
if(NOT BUILD_SHARED_LIBS)
|
||||
if(BUILD_STATIC_CURL)
|
||||
set(CURLX_CFILES ../lib/dynbuf.c)
|
||||
endif()
|
||||
|
||||
|
@ -107,7 +107,7 @@ include_directories(
|
|||
)
|
||||
|
||||
#Build curl executable
|
||||
target_link_libraries(${EXE_NAME} libcurl ${CURL_LIBS})
|
||||
target_link_libraries(${EXE_NAME} ${LIB_SELECTED_FOR_EXE} ${CURL_LIBS})
|
||||
|
||||
################################################################################
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ set(TARGET_LABEL_PREFIX "Test ")
|
|||
|
||||
function(setup_test TEST_NAME) # ARGN are the files in the test
|
||||
|
||||
if(NOT BUILD_SHARED_LIBS)
|
||||
if(LIB_SELECTED STREQUAL LIB_STATIC)
|
||||
# These are part of the libcurl static lib. Do not compile/link them again.
|
||||
list(REMOVE_ITEM ARGN ${WARNLESS} ${MULTIBYTE} ${TIMEDIFF})
|
||||
endif()
|
||||
|
@ -44,7 +44,7 @@ function(setup_test TEST_NAME) # ARGN are the files in the test
|
|||
include_directories(${CARES_INCLUDE_DIR})
|
||||
endif()
|
||||
|
||||
target_link_libraries(${TEST_NAME} libcurl ${CURL_LIBS})
|
||||
target_link_libraries(${TEST_NAME} ${LIB_SELECTED} ${CURL_LIBS})
|
||||
|
||||
set_target_properties(${TEST_NAME}
|
||||
PROPERTIES COMPILE_DEFINITIONS ${UPPER_TEST_NAME})
|
||||
|
|
|
@ -50,10 +50,8 @@ function(SETUP_EXECUTABLE TEST_NAME) # ARGN are the files in the test
|
|||
# to build the servers. In order to achieve proper linkage of these
|
||||
# files on Win32 targets it is necessary to build the test servers
|
||||
# with CURL_STATICLIB defined, independently of how libcurl is built.
|
||||
if(BUILD_SHARED_LIBS)
|
||||
set_target_properties(${TEST_NAME} PROPERTIES
|
||||
COMPILE_DEFINITIONS CURL_STATICLIB) # ${UPPER_TEST_NAME}
|
||||
endif()
|
||||
set_target_properties(${TEST_NAME} PROPERTIES
|
||||
COMPILE_DEFINITIONS CURL_STATICLIB) # ${UPPER_TEST_NAME}
|
||||
set_target_properties(${TEST_NAME} PROPERTIES
|
||||
PROJECT_LABEL "${TARGET_LABEL_PREFIX}${TEST_NAME}")
|
||||
endfunction()
|
||||
|
|
Загрузка…
Ссылка в новой задаче