From 030e62a663ecf1d92e6eab160fd18fd332a1c43d Mon Sep 17 00:00:00 2001 From: fuzzard Date: Sun, 28 Apr 2024 16:38:56 +1000 Subject: [cmake][modules] FindCurl enable building internal --- CMakeLists.txt | 1 + cmake/modules/FindCurl.cmake | 215 ++++++++++++++++++--- .../scripts/0_package.target-win10-arm.list | 1 - .../scripts/0_package.target-win10-win32.list | 1 - .../scripts/0_package.target-win10-x64.list | 1 - .../scripts/0_package.target-win32.list | 1 - .../scripts/0_package.target-x64.list | 1 - tools/depends/target/Makefile | 1 - .../target/curl/01-win-nghttp2-add-name.patch | 11 ++ tools/depends/target/curl/CURL-VERSION | 1 + 10 files changed, 200 insertions(+), 34 deletions(-) create mode 100644 tools/depends/target/curl/01-win-nghttp2-add-name.patch diff --git a/CMakeLists.txt b/CMakeLists.txt index 01acbbf3f2..1b4348f7a7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -89,6 +89,7 @@ option(ENABLE_INTERNAL_FFMPEG "Enable internal ffmpeg?" OFF) # These are built for all platforms not using system libs or disabled by user dependent_option(ENABLE_INTERNAL_CEC "Enable internal libcec?") +dependent_option(ENABLE_INTERNAL_CURL "Enable internal libcurl?") dependent_option(ENABLE_INTERNAL_FLATBUFFERS "Enable internal flatbuffers?") dependent_option(ENABLE_INTERNAL_FMT "Enable internal fmt?") dependent_option(ENABLE_INTERNAL_NFS "Enable internal libnfs?") diff --git a/cmake/modules/FindCurl.cmake b/cmake/modules/FindCurl.cmake index 33df48c625..3872b9c64a 100644 --- a/cmake/modules/FindCurl.cmake +++ b/cmake/modules/FindCurl.cmake @@ -8,53 +8,212 @@ # Curl::Curl - The Curl library if(NOT TARGET Curl::Curl) - find_package(PkgConfig) + include(cmake/scripts/common/ModuleHelpers.cmake) - # We only rely on pkgconfig for non windows platforms - if(PKG_CONFIG_FOUND AND NOT (WIN32 OR WINDOWS_STORE)) - pkg_check_modules(CURL libcurl QUIET) + macro(buildCurl) - # First item is the full path of the library file found - # pkg_check_modules does not populate a variable of the found library explicitly - list(GET CURL_LINK_LIBRARIES 0 CURL_LIBRARY) + find_package(NGHttp2 REQUIRED QUIET) + find_package(OpenSSL REQUIRED QUIET) + find_package(Brotli REQUIRED QUIET) + + # Darwin platforms link against toolchain provided zlib regardless + # They will fail when searching for static. All other platforms, prefer static + # if possible (requires cmake 3.24+ otherwise variable is a no-op) + # Windows still uses dynamic lib for zlib for other purposes, dont mix + if(NOT CMAKE_SYSTEM_NAME MATCHES "Darwin" AND NOT (WIN32 OR WINDOWS_STORE)) + set(ZLIB_USE_STATIC_LIBS ON) + endif() + find_package(ZLIB REQUIRED) + unset(ZLIB_USE_STATIC_LIBS) + + set(CURL_VERSION ${${MODULE}_VER}) + # Curl debug uses postfix -d for all platforms + set(CURL_DEBUG_POSTFIX -d) + + if(WIN32 OR WINDOWS_STORE) + set(CURL_C_FLAGS -DNGHTTP2_STATICLIB) + set(PLATFORM_LINK_LIBS crypt32.lib) + endif() + + set(patches "${CORE_SOURCE_DIR}/tools/depends/target/${MODULE_LC}/01-win-nghttp2-add-name.patch") + + generate_patchcommand("${patches}") + + set(CMAKE_ARGS -DBUILD_CURL_EXE=OFF + -DBUILD_SHARED_LIBS=OFF + -DBUILD_STATIC_LIBS=ON + -DBUILD_LIBCURL_DOCS=OFF + -DENABLE_CURL_MANUAL=OFF + -DCURL_DISABLE_TESTS=OFF + -DCURL_DISABLE_LDAP=ON + -DCURL_DISABLE_LDAPS=ON + -DCURL_DISABLE_SMB=OFF + -DCURL_USE_OPENSSL=ON + -DOPENSSL_ROOT_DIR=${DEPENDS_PATH} + -DCURL_BROTLI=ON + -DUSE_NGHTTP2=ON + -DUSE_LIBIDN2=OFF + -DCURL_USE_LIBSSH2=OFF + -DCURL_USE_GSSAPI=OFF + -DCURL_CA_FALLBACK=ON + ${OPTIONAL_ARGS}) + + BUILD_DEP_TARGET() + + # Link libraries for target interface + set(PC_CURL_LINK_LIBRARIES Brotli::Brotli OpenSSL::Crypto OpenSSL::SSL NGHttp2::NGHttp2 ZLIB::ZLIB ${PLATFORM_LINK_LIBS}) + + # Add dependencies to build target + add_dependencies(${MODULE_LC} NGHttp2::NGHttp2) + add_dependencies(${MODULE_LC} OpenSSL::SSL) + add_dependencies(${MODULE_LC} OpenSSL::Crypto) + add_dependencies(${MODULE_LC} ZLIB::ZLIB) + add_dependencies(${MODULE_LC} Brotli::Brotli) + endmacro() + + set(MODULE_LC curl) + + SETUP_BUILD_VARS() + + find_package(CURL CONFIG QUIET + HINTS ${DEPENDS_PATH}/lib/cmake + ${${CORE_PLATFORM_NAME_LC}_SEARCH_CONFIG}) + + # Check for existing Curl. If version >= CURL-VERSION file version, dont build + # A corner case, but if a linux/freebsd user WANTS to build internal curl, build anyway + if((CURL_VERSION VERSION_LESS ${${MODULE}_VER} AND ENABLE_INTERNAL_CURL) OR + ((CORE_SYSTEM_NAME STREQUAL linux OR CORE_SYSTEM_NAME STREQUAL freebsd) AND ENABLE_INTERNAL_CURL)) + + buildCurl() else() + # Maybe need to look explicitly for CURL::libcurl_static/shared? + if(NOT TARGET CURL::libcurl) + find_package(PkgConfig) - find_path(CURL_INCLUDEDIR NAMES curl/curl.h - HINTS ${DEPENDS_PATH}/include - ${${CORE_PLATFORM_LC}_SEARCH_CONFIG} - NO_CACHE) - find_library(CURL_LIBRARY NAMES curl libcurl libcurl_imp - HINTS ${DEPENDS_PATH}/lib - ${${CORE_PLATFORM_LC}_SEARCH_CONFIG} - NO_CACHE) + # We only rely on pkgconfig for non windows platforms + if(PKG_CONFIG_FOUND AND NOT (WIN32 OR WINDOWS_STORE)) + pkg_check_modules(CURL libcurl QUIET) + + # First item is the full path of the library file found + # pkg_check_modules does not populate a variable of the found library explicitly + list(GET CURL_LINK_LIBRARIES 0 CURL_LIBRARY_RELEASE) + + # Add link libraries for static lib usage + if(${CURL_LIBRARY} MATCHES ".+\.a$" AND CURL_LINK_LIBRARIES) + # Remove duplicates + list(REMOVE_DUPLICATES CURL_LINK_LIBRARIES) + + # Remove own library - eg libcurl.a + list(FILTER CURL_LINK_LIBRARIES EXCLUDE REGEX ".*curl.*\.a$") + set(PC_CURL_LINK_LIBRARIES ${CURL_LINK_LIBRARIES}) + endif() + + # pkgconfig sets CURL_INCLUDEDIR, map this to our "standard" variable name + set(CURL_INCLUDE_DIR ${CURL_INCLUDEDIR}) + else() + find_path(CURL_INCLUDE_DIR NAMES curl/curl.h + HINTS ${DEPENDS_PATH}/include + ${${CORE_PLATFORM_LC}_SEARCH_CONFIG}) + find_library(CURL_LIBRARY_RELEASE NAMES curl libcurl libcurl_imp + HINTS ${DEPENDS_PATH}/lib + ${${CORE_PLATFORM_LC}_SEARCH_CONFIG}) + endif() + else() + # CURL::libcurl is an alias. We need to get the actual aias target, as we cant make an + # alias of an alias (ie our Curl::Curl cant be an alias of Curl::libcurl) + get_target_property(_CURL_ALIASTARGET CURL::libcurl ALIASED_TARGET) + + # This is for the case where a distro provides a non standard (Debug/Release) config type + # eg Debian's config file is CURLConfigTargets-none.cmake + # convert this back to either DEBUG/RELEASE or just RELEASE + # we only do this because we use find_package_handle_standard_args for config time output + # and it isnt capable of handling TARGETS, so we have to extract the info + get_target_property(_CURL_CONFIGURATIONS ${_CURL_ALIASTARGET} IMPORTED_CONFIGURATIONS) + foreach(_curl_config IN LISTS _CURL_CONFIGURATIONS) + # Some non standard config (eg None on Debian) + # Just set to RELEASE var so select_library_configurations can continue to work its magic + string(TOUPPER ${_curl_config} _curl_config_UPPER) + if((NOT ${_curl_config_UPPER} STREQUAL "RELEASE") AND + (NOT ${_curl_config_UPPER} STREQUAL "DEBUG")) + get_target_property(CURL_LIBRARY_RELEASE ${_CURL_ALIASTARGET} IMPORTED_LOCATION_${_curl_config_UPPER}) + else() + get_target_property(CURL_LIBRARY_${_curl_config_UPPER} ${_CURL_ALIASTARGET} IMPORTED_LOCATION_${_curl_config_UPPER}) + endif() + endforeach() + + get_target_property(CURL_INCLUDE_DIR CURL::libcurl INTERFACE_INCLUDE_DIRECTORIES) + endif() endif() + include(SelectLibraryConfigurations) + select_library_configurations(CURL) + unset(CURL_LIBRARIES) + include(FindPackageHandleStandardArgs) find_package_handle_standard_args(Curl - REQUIRED_VARS CURL_LIBRARY CURL_INCLUDEDIR + REQUIRED_VARS CURL_LIBRARY CURL_INCLUDE_DIR VERSION_VAR CURL_VERSION) if(CURL_FOUND) - if(NOT TARGET Curl::Curl) + # cmake target and not building internal + if(TARGET CURL::libcurl AND NOT TARGET curl) + # CURL::libcurl is an alias. We need to get the actual aias target, as we cant make an + # alias of an alias (ie our Curl::Curl cant be an alias of Curl::libcurl) + if(NOT _CURL_ALIASTARGET) + get_target_property(_CURL_ALIASTARGET CURL::libcurl ALIASED_TARGET) + endif() + + add_library(Curl::Curl ALIAS ${_CURL_ALIASTARGET}) + else() add_library(Curl::Curl UNKNOWN IMPORTED) set_target_properties(Curl::Curl PROPERTIES - IMPORTED_LOCATION "${CURL_LIBRARY}" - INTERFACE_INCLUDE_DIRECTORIES "${CURL_INCLUDEDIR}") - - # Add link libraries for static lib usage - if(${CURL_LIBRARY} MATCHES ".+\.a$" AND CURL_LINK_LIBRARIES) - # Remove duplicates - list(REMOVE_DUPLICATES CURL_LINK_LIBRARIES) + INTERFACE_INCLUDE_DIRECTORIES "${CURL_INCLUDE_DIR}") - # Remove own library - eg libcurl.a - list(FILTER CURL_LINK_LIBRARIES EXCLUDE REGEX ".*curl.*\.a$") + if(CURL_LIBRARY_RELEASE) + set_target_properties(Curl::Curl PROPERTIES + IMPORTED_CONFIGURATIONS RELEASE + IMPORTED_LOCATION_RELEASE "${CURL_LIBRARY_RELEASE}") + endif() + if(CURL_LIBRARY_DEBUG) + set_target_properties(Curl::Curl PROPERTIES + IMPORTED_CONFIGURATIONS DEBUG + IMPORTED_LOCATION_DEBUG "${CURL_LIBRARY_DEBUG}") + endif() + # Add link libraries for static lib usage found from pkg-config + if(PC_CURL_LINK_LIBRARIES) set_target_properties(Curl::Curl PROPERTIES - INTERFACE_LINK_LIBRARIES "${CURL_LINK_LIBRARIES}") + INTERFACE_LINK_LIBRARIES "${PC_CURL_LINK_LIBRARIES}") + endif() + + if(WIN32 OR WINDOWS_STORE) + set_property(TARGET Curl::Curl APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS "CURL_STATICLIB") endif() - set_property(GLOBAL APPEND PROPERTY INTERNAL_DEPS_PROP Curl::Curl) endif() + + if(TARGET curl) + add_dependencies(Curl::Curl curl) + endif() + + # Add internal build target when a Multi Config Generator is used + # We cant add a dependency based off a generator expression for targeted build types, + # https://gitlab.kitware.com/cmake/cmake/-/issues/19467 + # therefore if the find heuristics only find the library, we add the internal build + # target to the project to allow user to manually trigger for any build type they need + # in case only a specific build type is actually available (eg Release found, Debug Required) + # This is mainly targeted for windows who required different runtime libs for different + # types, and they arent compatible + if(_multiconfig_generator) + if(NOT TARGET curl) + buildCurl() + set_target_properties(curl PROPERTIES EXCLUDE_FROM_ALL TRUE) + endif() + add_dependencies(build_internal_depends curl) + endif() + + set_property(GLOBAL APPEND PROPERTY INTERNAL_DEPS_PROP Curl::Curl) + else() if(Curl_FIND_REQUIRED) message(FATAL_ERROR "Curl libraries were not found.") diff --git a/project/BuildDependencies/scripts/0_package.target-win10-arm.list b/project/BuildDependencies/scripts/0_package.target-win10-arm.list index 27ecc0202a..04b5887b2a 100644 --- a/project/BuildDependencies/scripts/0_package.target-win10-arm.list +++ b/project/BuildDependencies/scripts/0_package.target-win10-arm.list @@ -7,7 +7,6 @@ ; -> ... ;PLEASE KEEP THIS LIST IN ALPHABETICAL ORDER! brotli-1.0.7-win10-arm-v141-20200105.7z -curl-7.67.0-win10-arm-v141-20200105.7z dav1d-1.4.1-win10-arm-v142-20240331.7z freetype-2.10.1-win10-arm-v141-20200105.7z fstrcmp-0.7-win10-arm-v141-20200105.7z diff --git a/project/BuildDependencies/scripts/0_package.target-win10-win32.list b/project/BuildDependencies/scripts/0_package.target-win10-win32.list index 777c6a4614..bf72fde0c8 100644 --- a/project/BuildDependencies/scripts/0_package.target-win10-win32.list +++ b/project/BuildDependencies/scripts/0_package.target-win10-win32.list @@ -7,7 +7,6 @@ ; -> ... ;PLEASE KEEP THIS LIST IN ALPHABETICAL ORDER! brotli-1.0.7-win10-win32-v141-20200105.7z -curl-7.67.0-win10-win32-v141-20200105.7z dav1d-1.4.1-win10-win32-v142-20240331.7z freetype-2.10.1-win10-win32-v141-20200105.7z fstrcmp-0.7-win10-win32-v141-20200105.7z diff --git a/project/BuildDependencies/scripts/0_package.target-win10-x64.list b/project/BuildDependencies/scripts/0_package.target-win10-x64.list index b893723c10..51312322d8 100644 --- a/project/BuildDependencies/scripts/0_package.target-win10-x64.list +++ b/project/BuildDependencies/scripts/0_package.target-win10-x64.list @@ -7,7 +7,6 @@ ; -> ... ;PLEASE KEEP THIS LIST IN ALPHABETICAL ORDER! brotli-1.0.7-win10-x64-v141-20200105.7z -curl-7.67.0-win10-x64-v141-20200105.7z dav1d-1.4.1-win10-x64-v142-20240331.7z freetype-2.10.1-win10-x64-v141-20200105.7z fstrcmp-0.7-win10-x64-v141-20200105.7z diff --git a/project/BuildDependencies/scripts/0_package.target-win32.list b/project/BuildDependencies/scripts/0_package.target-win32.list index 632650ec9a..9ac7f69e62 100644 --- a/project/BuildDependencies/scripts/0_package.target-win32.list +++ b/project/BuildDependencies/scripts/0_package.target-win32.list @@ -7,7 +7,6 @@ ; -> ... ;PLEASE KEEP THIS LIST IN ALPHABETICAL ORDER! brotli-1.0.7-win32-v141-20200105.7z -curl-7.67.0-win32-v141-20200105.7z dav1d-1.4.1-win32-v142-20240331.7z detours-64ec13-win32-v141-20200105.7z dnssd-878.260.1-win32-v141-20200105.7z diff --git a/project/BuildDependencies/scripts/0_package.target-x64.list b/project/BuildDependencies/scripts/0_package.target-x64.list index 2dd353c9cd..e396e54eb6 100644 --- a/project/BuildDependencies/scripts/0_package.target-x64.list +++ b/project/BuildDependencies/scripts/0_package.target-x64.list @@ -7,7 +7,6 @@ ; -> ... ;PLEASE KEEP THIS LIST IN ALPHABETICAL ORDER! brotli-1.0.7-x64-v141-20200105.7z -curl-7.67.0-x64-v141-20200105.7z dav1d-1.4.1-x64-v142-20240331.7z detours-64ec13-x64-v141-20200105.7z dnssd-878.260.1-x64-v141-20200105.7z diff --git a/tools/depends/target/Makefile b/tools/depends/target/Makefile index 11cdbb533b..e47e8bff26 100644 --- a/tools/depends/target/Makefile +++ b/tools/depends/target/Makefile @@ -8,7 +8,6 @@ endif DEPENDS = \ brotli \ bzip2 \ - curl \ dav1d \ expat \ ffmpeg \ diff --git a/tools/depends/target/curl/01-win-nghttp2-add-name.patch b/tools/depends/target/curl/01-win-nghttp2-add-name.patch new file mode 100644 index 0000000000..e07843010a --- /dev/null +++ b/tools/depends/target/curl/01-win-nghttp2-add-name.patch @@ -0,0 +1,11 @@ +--- a/CMake/FindNGHTTP2.cmake ++++ b/CMake/FindNGHTTP2.cmake +@@ -25,7 +25,7 @@ + + find_path(NGHTTP2_INCLUDE_DIR "nghttp2/nghttp2.h") + +-find_library(NGHTTP2_LIBRARY NAMES nghttp2) ++find_library(NGHTTP2_LIBRARY NAMES nghttp2 nghttp2_static) + + find_package_handle_standard_args(NGHTTP2 + FOUND_VAR diff --git a/tools/depends/target/curl/CURL-VERSION b/tools/depends/target/curl/CURL-VERSION index 017b222e75..f9a42c2939 100644 --- a/tools/depends/target/curl/CURL-VERSION +++ b/tools/depends/target/curl/CURL-VERSION @@ -3,3 +3,4 @@ VERSION=8.7.1 ARCHIVE=$(LIBNAME)-$(VERSION).tar.xz SHA512=5bbde9d5648e9226f5490fa951690aaf159149345f3a315df2ba58b2468f3e59ca32e8a49734338afc861803a4f81caac6d642a4699b72c6310ebfb1f618aad2 BYPRODUCT=libcurl.a +BYPRODUCT_WIN=libcurl.lib -- cgit v1.2.3