# =================================================================== # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # =================================================================== # =================================================================== # The following variables can be set to locate dependencies that # are not installed in standard paths. These variables are used # by the find_package() modules. # # APR_ROOT - Path to APR's install area # APRUtil_ROOT - Path to APR-Util's install area # OPENSSL_ROOT_DIR - Path to OpenSSL's install area # ZLIB_ROOT - Path to zlib's install area # Brotli_ROOT - Path to Brotli's install area # GSSAPI_ROOT - Path to GSSAPI's install area # Unbound_ROOT - Path to libunbound's install area # =================================================================== cmake_minimum_required(VERSION 3.12) # Enable CMP0092 if supported: MSVC warning flags are not in # CMAKE__FLAGS by default. if(POLICY CMP0092) cmake_policy(SET CMP0092 NEW) endif() set(SERF_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}") set(CMAKE_MODULE_PATH "${SERF_SOURCE_DIR}/build") include(SerfVersion) project("Serf" VERSION ${SERF_VERSION} LANGUAGES C) message(WARNING "Serf's CMake build is considered EXPERIMENTAL. " "Some features are not supported and the build " "has not been tested on many supported platforms.") # Optional dependency options option(USE_BROTLI "Use the Brotli decoding library if available" ON) option(USE_GSSAPI "Use GSSAPI authentication if available" ON) option(USE_UNBOUND "Use the Unbound async resolver if available" ON) # Build options option(DEBUG "Enable debugging info and strict compile warnings" OFF) option(DOT_CLANGD "Generate a .clangd file at the root of the source tree" OFF) option(SKIP_SHARED "Disable building shared Serf libraries" OFF) option(SKIP_STATIC "Disable building static Serf libraries" OFF) option(DISABLE_LOGGING "Disable the logging framework at compile time" OFF) option(SKIP_TESTS "Disable building the unit tests and utilities" OFF) option(ENABLE_SLOW_TESTS "Enable long-running unit tests" OFF) # Platform-specific build options option(APR_STATIC "Windows: Link with static APR/-Util libraries" OFF) option(EXPAT "Windows: optional path to Expat's install area for APR_STATIC" "") option(RELATIVE_RPATH "macOS: Use @rpath in installed shared library" OFF) option(USE_HOMEBREW "macOS: Use dependencies from Homebrew" OFF) option(USE_MACPORTS "macOS: Use dependencies from MacPorts" OFF) if(SKIP_SHARED AND SKIP_STATIC) message(FATAL_ERROR "You have disabled both shared and static library builds.") endif() if(USE_HOMEBREW AND USE_MACPORTS) message(FATAL_ERROR "You requested both Homebrew and McPorts dependencies.") endif() # Initialize the build type if it was not set on the command line. if(NOT CMAKE_BUILD_TYPE) if(DEBUG) set(CMAKE_BUILD_TYPE Debug CACHE STRING "Default to debug build." FORCE) set(SERF_MAINTAINER_MODE TRUE) else() set(CMAKE_BUILD_TYPE Release CACHE STRING "Default to release build." FORCE) endif() endif() include(GNUInstallDirs) include(SerfFindPkgConfig) include(SerfPlatform) # On the Mac: Use dependencies from Homebrew or MacPorts if(USE_HOMEBREW OR USE_MACPORTS) if(SERF_DARWIN) include(SerfMacOS) serf_macos_find_packages() else() if(USE_HOMEBREW) message(WARNING "option USE_HOMEBREW is not implemented on this platform") endif() if(USE_MACPORTS) message(WARNING "option USE_MACPORTS is not implemented on this platform") endif() endif(SERF_DARWIN) endif(USE_HOMEBREW OR USE_MACPORTS) # Install directories if(NOT SERF_WINDOWS) set(SERF_INCLUDE_SUBDIR "serf-${SERF_MAJOR_VERSION}") set(SERF_INSTALL_HEADERS "${CMAKE_INSTALL_INCLUDEDIR}/${SERF_INCLUDE_SUBDIR}") else() set(SERF_INSTALL_HEADERS "${CMAKE_INSTALL_INCLUDEDIR}") endif() set(SERF_INSTALL_LIBRARIES "${CMAKE_INSTALL_LIBDIR}") set(SERF_INSTALL_RUNTIME "${CMAKE_INSTALL_BINDIR}") set(SERF_INSTALL_PKGCONFIG "${CMAKE_INSTALL_LIBDIR}/pkgconfig") # Public headers list(APPEND HEADERS "serf.h" "serf_bucket_types.h" "serf_bucket_util.h" ) # List of symbols that should not be exported from the shared library. list(APPEND EXPORTS_BLACKLIST "serf_connection_switch_protocol" "serf_http_protocol_create" "serf_https_protocol_create" "serf_http_request_queue" ) # Serf library source files list(APPEND SOURCES "src/config_store.c" "src/context.c" "src/error_callbacks.c" "src/deprecated.c" "src/incoming.c" "src/inet_pton.c" "src/init_once.c" "src/logging.c" "src/outgoing.c" "src/outgoing_request.c" "src/pump.c" "src/resolve.c" "src/ssltunnel.c" "src/syntax.c" "auth/auth.c" "auth/auth_basic.c" "auth/auth_digest.c" "auth/auth_spnego.c" "auth/auth_spnego_gss.c" "auth/auth_spnego_sspi.c" "auth/auth_user_defined.c" "buckets/aggregate_buckets.c" "buckets/allocator.c" "buckets/barrier_buckets.c" "buckets/brotli_buckets.c" "buckets/buckets.c" "buckets/bwtp_buckets.c" "buckets/chunk_buckets.c" "buckets/copy_buckets.c" "buckets/dechunk_buckets.c" "buckets/deflate_buckets.c" "buckets/event_buckets.c" "buckets/fcgi_buckets.c" "buckets/file_buckets.c" "buckets/headers_buckets.c" "buckets/hpack_buckets.c" "buckets/http2_frame_buckets.c" "buckets/iovec_buckets.c" "buckets/limit_buckets.c" "buckets/log_wrapper_buckets.c" "buckets/mmap_buckets.c" "buckets/prefix_buckets.c" "buckets/request_buckets.c" "buckets/response_body_buckets.c" "buckets/response_buckets.c" "buckets/simple_buckets.c" "buckets/socket_buckets.c" "buckets/split_buckets.c" "buckets/ssl_buckets.c" "protocols/fcgi_protocol.c" "protocols/fcgi_stream.c" "protocols/http2_protocol.c" "protocols/http2_stream.c" ) # Generate lists of symbols to export from shared libraries. if(SERF_WINDOWS) set(export_symbols_ext_ "def") set(export_symbols_gen_ SerfWindowsGenDef) set(export_symbols_ldflag "${CMAKE_LINK_DEF_FILE_FLAG}") elseif(SERF_DARWIN) set(export_symbols_ext_ "exp") set(export_symbols_gen_ SerfMachGenExp) set(export_symbols_ldflag "-Wl,-exported_symbols_list,") elseif(SERF_ELF_TARGET) set(export_symbols_ext_ "map") set(export_symbols_gen_ SerfElfGenMap) set(export_symbols_ldflag "-Wl,--version-script,") endif() if(DEFINED export_symbols_gen_) set(SERF_EXPORT_SYMBOLS "${CMAKE_CURRENT_BINARY_DIR}/libserf-${SERF_MAJOR_VERSION}.${export_symbols_ext_}") add_custom_command( OUTPUT "${SERF_EXPORT_SYMBOLS}" DEPENDS ${HEADERS} COMMAND ${CMAKE_COMMAND} -DCMAKE_SYSTEM_NAME="${CMAKE_SYSTEM_NAME}" -DCMAKE_MODULE_PATH="${CMAKE_MODULE_PATH}" -DSERF_EXPORT_BLACKLIST="${EXPORTS_BLACKLIST}" -DSERF_EXPORT_HEADERS="${HEADERS}" -DSERF_EXPORT_SYMBOLS="${SERF_EXPORT_SYMBOLS}" -P "build/${export_symbols_gen_}.cmake" WORKING_DIRECTORY "${SERF_SOURCE_DIR}" ) add_custom_target(serf_export_symbols DEPENDS "${SERF_EXPORT_SYMBOLS}") endif() if(SERF_WINDOWS) set(SHARED_SOURCES "serf.rc") # Static OpenSSL, APR and APR-Util need additional libraries that are not # linked by default by CMake. These will be ignored by the linker if they're # not actually used. set(SERF_STANDARD_LIBRARIES "crypt32.lib" "mswsock.lib" "rpcrt4.lib" "secur32.lib" "ws2_32.lib" ) list(APPEND SERF_C_DEFINES "SERF_HAVE_SSPI") endif() # Process build options for dependency search if(EXPAT) if(SERF_WINDOWS) set(PC_EXPAT_INCLUDE_DIRS "${EXPAT}/include") set(PC_EXPAT_LIBRARY_DIRS "${EXPAT}/lib") else(SERF_WINDOWS) message(WARNING "option EXPAT is not implemented on this platform") endif(SERF_WINDOWS) endif(EXPAT) # Find required dependencies find_package(APR REQUIRED) find_package(APRUtil REQUIRED) SerfFindPkgConfig(OpenSSL_SSL OPENSSL_ROOT_DIR libssl OpenSSL::SSL) SerfFindPkgConfig(OpenSSL_Crypto OPENSSL_ROOT_DIR libcrypto OpenSSL::Crypto) if(NOT (OpenSSL_SSL_FOUND AND OpenSSL_Crypto_FOUND)) find_package(OpenSSL REQUIRED) if(OpenSSL_FOUND) set(OPENSSL_PC_LIBS ${OPENSSL_LIBRARIES}) endif() else() set(OpenSSL_FOUND TRUE) set(OPENSSL_VERSION ${OPENSSL_SSL_VERSION}) set(OPENSSL_INCLUDE_DIR ${OPENSSL_SSL_INCLUDE_DIR}) set(OPENSSL_PC_REQUIRES ${OPENSSL_SSL_PC_REQUIRES} ${OPENSSL_CRYPTO_PC_REQUIRES}) set(OPENSSL_LIBRARIES ${OPENSSL_SSL_LIBRARY} ${OPENSSL_CRYPTO_LIBRARY}) endif() SerfFindPkgConfig(ZLIB ZLIB_ROOT zlib ZLIB::ZLIB) if(NOT ZLIB_FOUND) find_package(ZLIB REQUIRED) set(ZLIB_PC_LIBS ${ZLIB_LIBRARIES}) endif() # We do not want or need OpenSSL's compatibility macros. list(APPEND SERF_C_DEFINES "OPENSSL_NO_DEPRECATED") # Hide OpenSSL's _fp() API. list(APPEND SERF_C_DEFINES "OPENSSL_NO_STDIO") # Find optional dependencies if(USE_BROTLI) SerfFindPkgConfig(Brotli_Decode Brotli_ROOT libbrotlidec Brotli::Decode) if(NOT Brotli_Decode_FOUND) find_package(Brotli) if(Brotli_FOUND) set(BROTLI_PC_LIBS ${BROTLI_DECODE_LIBRARY}) endif() else() set(Brotli_FOUND TRUE) set(BROTLI_VERSION ${BROTLI_DECODE_VERSION}) set(BROTLI_INCLUDE_DIR ${BROTLI_DECODE_INCLUDE_DIR}) set(BROTLI_PC_REQUIRES ${BROTLI_DECODE_PC_REQUIRES}) endif() endif() if(NOT SERF_WINDOWS) if(USE_GSSAPI) SerfFindPkgConfig(GSSAPI GSSAPI_ROOT krb5-gssapi KRB5::GSSAPI) if(NOT GSSAPI_FOUND) find_package(GSSAPI) if(GSSAPI_FOUND) set(GSSAPI_PC_LIBS ${GSSAPI_LIBRARIES}) endif() endif() endif() else() # We use SSPI on Windows and there's no Kerberos/GSSAPI port there. set(GSSAPI_FOUND FALSE) if(DEFINED GSSAPI_ROOT) message(WARNING "option GSSAPI_ROOT is not implemented on this platform") endif() endif() if(USE_UNBOUND) SerfFindPkgConfig(Unbound Unbound_ROOT libunbound Unbound::Unbound) if(NOT Unbound_FOUND) find_package(Unbound) if(Unbound_FOUND) set(UNBOUND_PC_LIBS "${UNBOUND_LIBRARY}") endif() endif() endif() # Calculate the set of private and public targets if(APR_STATIC) if(SERF_WINDOWS) list(APPEND SERF_PUBLIC_TARGETS APR::APR_static) if(NOT APR_CONTAINS_APRUTIL) list(APPEND SERF_PUBLIC_TARGETS APR::APRUtil_static) endif() else(SERF_WINDOWS) message(WARNING "option APR_STATIC is not implemented on this platform") endif(SERF_WINDOWS) else(APR_STATIC) list(APPEND SERF_PUBLIC_TARGETS APR::APR) if(NOT APR_CONTAINS_APRUTIL) list(APPEND SERF_PUBLIC_TARGETS APR::APRUtil) endif() endif(APR_STATIC) list(APPEND SERF_PRIVATE_TARGETS OpenSSL::SSL OpenSSL::Crypto ZLIB::ZLIB) if(Brotli_FOUND) list(APPEND SERF_PRIVATE_TARGETS Brotli::Decode) endif() if(GSSAPI_FOUND) list(APPEND SERF_C_DEFINES "SERF_HAVE_GSSAPI") list(APPEND SERF_PRIVATE_TARGETS KRB5::GSSAPI) endif() if(Unbound_FOUND) list(APPEND SERF_C_DEFINES "SERF_HAVE_ASYNC_RESOLVER=1") list(APPEND SERF_C_DEFINES "SERF_HAVE_UNBOUND=1") list(APPEND SERF_PRIVATE_TARGETS Unbound::Unbound) endif() # Feature tests include(SerfChecks) CheckNotFunction("BIO_set_init" "NULL, 0" "SERF_NO_SSL_BIO_WRAPPERS" "openssl/bio.h" "${OPENSSL_INCLUDE_DIR}" ${OPENSSL_LIBRARIES} ${SERF_STANDARD_LIBRARIES}) CheckNotFunction("X509_STORE_get0_param" "NULL" "SERF_NO_SSL_X509_STORE_WRAPPERS" "openssl/x509.h" "${OPENSSL_INCLUDE_DIR}" ${OPENSSL_LIBRARIES} ${SERF_STANDARD_LIBRARIES}) CheckNotFunction("X509_get0_notBefore" "NULL" "SERF_NO_SSL_X509_GET0_NOTBEFORE" "openssl/x509.h" "${OPENSSL_INCLUDE_DIR}" ${OPENSSL_LIBRARIES} ${SERF_STANDARD_LIBRARIES}) CheckNotFunction("X509_get0_notAfter" "NULL" "SERF_NO_SSL_X509_GET0_NOTAFTER" "openssl/x509.h" "${OPENSSL_INCLUDE_DIR}" ${OPENSSL_LIBRARIES} ${SERF_STANDARD_LIBRARIES}) CheckNotFunction("X509_STORE_CTX_get0_chain" "NULL" "SERF_NO_SSL_X509_GET0_CHAIN" "openssl/x509.h" "${OPENSSL_INCLUDE_DIR}" ${OPENSSL_LIBRARIES} ${SERF_STANDARD_LIBRARIES}) CheckNotFunction("ASN1_STRING_get0_data" "NULL" "SERF_NO_SSL_ASN1_STRING_GET0_DATA" "openssl/asn1.h" "${OPENSSL_INCLUDE_DIR}" ${OPENSSL_LIBRARIES} ${SERF_STANDARD_LIBRARIES}) CheckFunction("X509_check_certificate_times" "NULL, NULL, NULL" "SERF_HAVE_SSL_X509_CHECK_CERTIFICATE_TIMES" "openssl/x509.h" "${OPENSSL_INCLUDE_DIR}" ${OPENSSL_LIBRARIES} ${SERF_STANDARD_LIBRARIES}) CheckFunction("OSSL_STORE_open_ex" "NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL" "SERF_HAVE_OSSL_STORE_OPEN_EX" "openssl/store.h" "${OPENSSL_INCLUDE_DIR}" ${OPENSSL_LIBRARIES} ${SERF_STANDARD_LIBRARIES}) CheckFunction("CRYPTO_set_locking_callback" "NULL" "SERF_HAVE_SSL_LOCKING_CALLBACKS" "openssl/crypto.h" "${OPENSSL_INCLUDE_DIR}" ${OPENSSL_LIBRARIES} ${SERF_STANDARD_LIBRARIES}) CheckFunction("SSL_set_alpn_protos" "NULL, NULL, 0" "SERF_HAVE_OPENSSL_ALPN" "openssl/ssl.h" "${OPENSSL_INCLUDE_DIR}" ${OPENSSL_LIBRARIES} ${SERF_STANDARD_LIBRARIES}) CheckFunction("OpenSSL_version_num" "" "SERF_HAVE_OPENSSL_VERSION_NUM" "openssl/ssl.h" "${OPENSSL_INCLUDE_DIR}" ${OPENSSL_LIBRARIES} ${SERF_STANDARD_LIBRARIES}) CheckFunction("OPENSSL_malloc_init" "" "SERF_HAVE_OPENSSL_MALLOC_INIT" "openssl/ssl.h" "${OPENSSL_INCLUDE_DIR}" ${OPENSSL_LIBRARIES} ${SERF_STANDARD_LIBRARIES}) CheckFunction("SSL_library_init" "" "SERF_HAVE_OPENSSL_SSL_LIBRARY_INIT" "openssl/ssl.h" "${OPENSSL_INCLUDE_DIR}" ${OPENSSL_LIBRARIES} ${SERF_STANDARD_LIBRARIES}) CheckHeader("stdbool.h" "HAVE_STDBOOL_H=1") CheckHeader("unistd.h" "HAVE_UNISTD_H=1") CheckType("OSSL_HANDSHAKE_STATE" "openssl/ssl.h" "SERF_HAVE_OSSL_HANDSHAKE_STATE" ${OPENSSL_INCLUDE_DIR}) if(Brotli_FOUND) CheckType("BrotliDecoderResult" "brotli/decode.h" "SERF_HAVE_BROTLI_DECODER_RESULT" ${BROTLI_INCLUDE_DIR}) # Check for the function only if the type check succeeded. if("SERF_HAVE_BROTLI_DECODER_RESULT" IN_LIST SERF_C_DEFINES) CheckFunction("BrotliDecoderTakeOutput" "NULL, NULL" "SERF_HAVE_BROTLI" "brotli/decode.h" ${BROTLI_INCLUDE_DIR} ${BROTLI_DECODE_LIBRARY} ${SERF_STANDARD_LIBRARIES}) endif() endif() if(CMAKE_COMPILER_IS_GNUCC OR (CMAKE_C_COMPILER_ID MATCHES "Clang")) set(CC_LIKE_GNUC TRUE) endif() # Process other build options if(DEBUG) list(APPEND SERF_C_DEFINES "DEBUG" "_DEBUG") endif() if(DISABLE_LOGGING) list(APPEND SERF_C_DEFINES "SERF_DISABLE_LOGGING") endif() if(ENABLE_SLOW_TESTS) list(APPEND SERF_C_DEFINES "SERF_TEST_DEFLATE_4GBPLUS_BUCKETS") endif() # Set common compiler flags set(CMAKE_C_STANDARD 90) # Use C90. MockHTTP overrides this. set(CMAKE_C_EXTENSIONS OFF) set(CMAKE_C_STANDARD_REQUIRED TRUE) if(NOT MSVC) if(CC_LIKE_GNUC) list(APPEND SERF_C_WARNINGS "-Wall") list(APPEND SERF_C_WARNINGS "-Wdeclaration-after-statement") list(APPEND SERF_C_WARNINGS "-Wmissing-prototypes") list(APPEND SERF_C_WARNINGS "-Wshadow") string(APPEND CMAKE_C_FLAGS_DEBUG " -O0") if(SERF_MAINTAINER_MODE) # This is for clang, which happily accepts unknow warning options. CheckCFlag(SERF_C_WARNINGS "-Werror=unknown-warning-option") # Additional warning flags for more pedantic checks CheckCFlag(SERF_C_WARNINGS "-Wimplicit-function-declaration") CheckCFlag(SERF_C_WARNINGS "-Wmissing-variable-declarations") CheckCFlag(SERF_C_WARNINGS "-Wunreachable-code") CheckCFlag(SERF_C_WARNINGS "-Wshorten-64-to-32") CheckCFlag(SERF_C_WARNINGS "-Wno-system-headers") CheckCFlag(SERF_C_WARNINGS "-Wextra-tokens") CheckCFlag(SERF_C_WARNINGS "-Wnewline-eof") endif() endif() else() # Warning level 4, no unused argument warnings list(APPEND SERF_C_WARNINGS "/W4" "/wd4100") # Conditional expression is constant list(APPEND SERF_C_WARNINGS "/wd4127") # Assignment within conditional expression list(APPEND SERF_C_WARNINGS "/wd4706") # 'function' undefined; assuming extern returning int list(APPEND SERF_C_WARNINGS "/we4013") list(APPEND SERF_C_DEFINES "WIN32" "WIN32_LEAN_AND_MEAN" "NOUSER" "NOGDI" "NONLS" "NOCRYPT" "_CRT_SECURE_NO_WARNINGS" "_CRT_NONSTDC_NO_WARNINGS" ) if(SERF_WIN64) list(APPEND SERF_C_DEFINES "WIN64") endif() set(CMAKE_IMPORT_LIBRARY_PREFIX "${SERF_INSTALL_LIBRARIES}") set(CMAKE_SHARED_LIBRARY_PREFIX "${SERF_INSTALL_LIBRARIES}") endif(NOT MSVC) # Define all targets if(NOT SKIP_SHARED) add_library(serf_shared SHARED ${SOURCES} ${SHARED_SOURCES}) target_compile_options(serf_shared PUBLIC ${APR_CFLAGS} PRIVATE ${SERF_C_WARNINGS}) target_compile_definitions(serf_shared PRIVATE ${SERF_C_DEFINES}) target_include_directories(serf_shared PUBLIC ${SERF_SOURCE_DIR}) target_link_libraries(serf_shared PRIVATE ${SERF_PRIVATE_TARGETS} ${SERF_STANDARD_LIBRARIES} PUBLIC ${SERF_PUBLIC_TARGETS}) set_target_properties(serf_shared PROPERTIES VERSION ${SERF_VERSION} SOVERSION ${SERF_SOVERSION}) if(DEFINED SERF_EXPORT_SYMBOLS) add_dependencies(serf_shared serf_export_symbols) set_target_properties(serf_shared PROPERTIES LINK_FLAGS "${export_symbols_ldflag}${SERF_EXPORT_SYMBOLS}") endif() if(SERF_DARWIN AND NOT RELATIVE_RPATH) set_target_properties(serf_shared PROPERTIES INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/${SERF_INSTALL_LIBRARIES}") endif() list(APPEND SERF_TARGETS serf_shared) if(SERF_WINDOWS) install(FILES $ CONFIGURATIONS Debug RelWithDebinfo DESTINATION "${SERF_INSTALL_RUNTIME}") endif() endif() if(NOT SKIP_STATIC) add_library(serf_static STATIC ${SOURCES}) target_compile_options(serf_static PUBLIC ${APR_CFLAGS} PRIVATE ${SERF_C_WARNINGS}) target_compile_definitions(serf_static PRIVATE ${SERF_C_DEFINES}) target_include_directories(serf_static PUBLIC ${SERF_SOURCE_DIR}) target_link_libraries(serf_static ${SERF_PRIVATE_TARGETS} ${SERF_PUBLIC_TARGETS} ${SERF_STANDARD_LIBRARIES}) list(APPEND SERF_TARGETS serf_static) endif() set_target_properties(${SERF_TARGETS} PROPERTIES OUTPUT_NAME "serf-${SERF_MAJOR_VERSION}") # Generate the .clangd file if(DOT_CLANGD) include(SerfGenClangd) endif() # Install targets install(TARGETS ${SERF_TARGETS} ARCHIVE DESTINATION "${SERF_INSTALL_LIBRARIES}" LIBRARY DESTINATION "${SERF_INSTALL_LIBRARIES}" RUNTIME DESTINATION "${SERF_INSTALL_RUNTIME}") install(FILES ${HEADERS} DESTINATION "${SERF_INSTALL_HEADERS}") # Generate the pkg-config module file. set(SERF_PC_FILE "serf-${SERF_MAJOR_VERSION}.pc") # Use a separate variable scope for the substitutions in serf.pc.in. function(make_pkgconfig) # Use a relative prefix to create a relocatable PC file. if(SERF_WINDOWS) file(RELATIVE_PATH relfragment "X:\\${SERF_INSTALL_PKGCONFIG}" "X:\\") else() file(RELATIVE_PATH relfragment "/${SERF_INSTALL_PKGCONFIG}" "/") endif() file(TO_CMAKE_PATH "\${pcfiledir}/${relfragment}" relprefix) set(PREFIX ${relprefix}) set(INCLUDE_SUBDIR ${SERF_INCLUDE_SUBDIR}) set(LIBDIR \${prefix}/${SERF_INSTALL_LIBRARIES}) set(VERSION ${SERF_VERSION}) set(MAJOR ${SERF_MAJOR_VERSION}) set(REQUIRES ${OPENSSL_PC_REQUIRES} ${ZLIB_PC_REQUIRES} ${BROTLI_PC_REQUIRES} ${GSSAPI_PC_REQUIRES} ${UNBOUND_PC_REQUIRES} ) set(CFLAGS ${APR_CFLAGS} ) set(LIBS ${APR_LDFLAGS} ${APR_LIBRARIES} ${APR_EXTRALIBS} ${APRUTIL_LDFLAGS} ${APRUTIL_LIBRARIES} ${APRUTIL_EXTRALIBS} ${OPENSSL_PC_LIBS} ${ZLIB_PC_LIBS} ${BROTLI_PC_LIBS} ${GSSAPI_PC_LIBS} ${UNBOUND_PC_LIBS} ${SERF_STANDARD_LIBRARIES} ) list(REMOVE_DUPLICATES REQUIRES) list(JOIN REQUIRES " " REQUIRES) list(REMOVE_DUPLICATES CFLAGS) list(JOIN CFLAGS " " CFLAGS) list(REMOVE_DUPLICATES LIBS) list(JOIN LIBS " " LIBS) configure_file("build/serf.pc.in" "${SERF_PC_FILE}" @ONLY) endfunction() make_pkgconfig() install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${SERF_PC_FILE}" DESTINATION "${SERF_INSTALL_PKGCONFIG}") if(NOT SKIP_TESTS) if(SKIP_STATIC) message(WARNING "The tests depend on the Serf static library") message(STATUS "Skipping tests; to silence this message, either remove") message(STATUS "the SKIP_STATIC option or add the SKIP_TESTS option.") set(SKIP_TESTS TRUE) else() enable_testing() add_subdirectory(test) endif() endif() # Summary set(_build_shared OFF) set(_build_static OFF) set(_build_tests OFF) set(_gen_dot_clangd OFF) set(_have_brotli OFF) set(_have_gssapi OFF) set(_have_sspi OFF) set(_have_unbound OFF) if(NOT SKIP_SHARED) set(_build_shared ON) endif() if(NOT SKIP_STATIC) set(_build_static ON) endif() if(NOT SKIP_TESTS) set(_build_tests ON) if(ENABLE_SLOW_TESTS) set(_build_tests "ON, slow tests enabled") endif() endif() if(DOT_CLANGD) set(_gen_dot_clangd ON) endif() if(APR_HAS_THREADS) set(_apr_version "${APR_VERSION}") else() set(_apr_version "${APR_VERSION} [no threads]") endif() if("SERF_HAVE_BROTLI" IN_LIST SERF_C_DEFINES) set(_have_brotli ON) if(NOT SERF_WINDOWS) set(_brotli_version ${BROTLI_VERSION}) else() # On Windows, vcpkg doesn't install the 'brotli' binary which we use to # find the version, and it isn't published in the headers. *shrug* if("${BROTLI_VERSION}" STREQUAL "") set(_brotli_version "N/A") endif() endif() endif() if("SERF_HAVE_GSSAPI" IN_LIST SERF_C_DEFINES) set(_have_gssapi ON) endif() if("SERF_HAVE_SSPI" IN_LIST SERF_C_DEFINES) set(_have_sspi ON) endif() if ("SERF_HAVE_UNBOUND=1" IN_LIST SERF_C_DEFINES) set(_have_unbound ON) endif() # Check if we're linking with LibreSSL file(STRINGS "${OPENSSL_INCLUDE_DIR}/openssl/opensslv.h" _libressl_text REGEX "^ *# *define +LIBRESSL_VERSION_TEXT +\".+$") if(NOT (_libressl_text STREQUAL "")) string(REGEX REPLACE "^[^\"]+\"([^\"]+)\".*$" "\\1" _libressl_text ${_libressl_text}) set(_openssl_version ${_libressl_text}) else() set(_openssl_version ${OPENSSL_VERSION}) endif() message(STATUS "Summary:") message(STATUS " Version ................... : ${SERF_VERSION}") message(STATUS " Build:") message(STATUS " platform: ............... : ${SERF_PLATFORM}") message(STATUS " target: ................. : ${SERF_TARGET}") message(STATUS " generator: .............. : ${CMAKE_GENERATOR}") message(STATUS " build type .............. : ${CMAKE_BUILD_TYPE}") message(STATUS " shared libraries ........ : ${_build_shared}") message(STATUS " static libraries ........ : ${_build_static}") message(STATUS " tests ................... : ${_build_tests}") message(STATUS " generate .clangd ........ : ${_gen_dot_clangd}") message(STATUS " Options:") message(STATUS " Brotli .................. : ${_have_brotli}") message(STATUS " GSSAPI .................. : ${_have_gssapi}") message(STATUS " SSPI .................... : ${_have_sspi}") message(STATUS " Unbound ................. : ${_have_unbound}") message(STATUS " Dependencies:") message(STATUS " APR ..................... : ${_apr_version}") if(APR_VERSION VERSION_LESS 2.0.0) message(STATUS " APR-Util ................ : ${APRUTIL_VERSION}") endif() message(STATUS " OpenSSL ................. : ${_openssl_version}") message(STATUS " Zlib .................... : ${ZLIB_VERSION}") if(_have_brotli) message(STATUS " Brotli .................. : ${_brotli_version}") endif() if(_have_gssapi) message(STATUS " GSSAPI .................. : ${GSSAPI_VERSION}") endif() if(_have_unbound) message(STATUS " Unbound ................. : ${UNBOUND_VERSION}") endif() message(STATUS " Install:") message(STATUS " prefix: ................. : ${CMAKE_INSTALL_PREFIX}") message(STATUS " headers: ................ : ${SERF_INSTALL_HEADERS}") message(STATUS " libraries: .............. : ${SERF_INSTALL_LIBRARIES}") if(SERF_WINDOWS) message(STATUS " dynamic libraries: ...... : ${SERF_INSTALL_RUNTIME}") endif() message(STATUS " pkg-config file: ........ : ${SERF_INSTALL_PKGCONFIG}")