From 5bdfc849afa55a1497954153787aecefe41f074a Mon Sep 17 00:00:00 2001 From: Vladyslav Baranovskyi Date: Fri, 25 Oct 2024 22:43:06 +0300 Subject: [PATCH 1/6] Removed windows specific CMakeLists.txt for building curl, moved build logic to the link function --- 3rdParty/curl/CMakeLists.txt | 59 ++++++++++++++++-------- 3rdParty/curl/ext/CMakeLists.txt | 5 +- 3rdParty/curl/ext_windows/CMakeLists.txt | 45 ------------------ 3 files changed, 42 insertions(+), 67 deletions(-) delete mode 100644 3rdParty/curl/ext_windows/CMakeLists.txt diff --git a/3rdParty/curl/CMakeLists.txt b/3rdParty/curl/CMakeLists.txt index e9623fb..ba2e61b 100644 --- a/3rdParty/curl/CMakeLists.txt +++ b/3rdParty/curl/CMakeLists.txt @@ -1,27 +1,27 @@ include(Utils) +include(FetchContent) + +set(CURL_REPO https://github.com/curl/curl.git) +set(CURL_GIT_TAG curl-8_8_0) set(CURL_DEPS_INSTALL ${CMAKE_BINARY_DIR}/deps_curl) find_package(CURL QUIET) if (NOT ${CURL_FOUND}) - file(MAKE_DIRECTORY ${CURL_DEPS_INSTALL}) - if (WIN32) - set(EXT_DIR ext_windows) - else () - set(EXT_DIR ext) - endif () - execute_process( - COMMAND ${CMAKE_COMMAND} -G ${CMAKE_GENERATOR} -DTOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE} ${CMAKE_CURRENT_SOURCE_DIR}/${EXT_DIR} -DCURL_REPO=${CURL_REPO} -DOPENSSL_REPO=${OPENSSL_REPO} -DPLATFORM=${PLATFORM} - WORKING_DIRECTORY ${CURL_DEPS_INSTALL} - ) - execute_process( - COMMAND ${CMAKE_COMMAND} --build ${CURL_DEPS_INSTALL} --config Release - RESULT_VARIABLE build_result - ) - if (NOT ${build_result} EQUAL "0") - message(FATAL_ERROR "Failed to build curl!") - endif() + if (NOT WIN32) + execute_process( + COMMAND ${CMAKE_COMMAND} -G ${CMAKE_GENERATOR} -DTOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE} ${CMAKE_CURRENT_SOURCE_DIR}/ext -DCURL_REPO=${CURL_REPO} -DCURL_GIT_TAG=${CURL_GIT_TAG} -DOPENSSL_REPO=${OPENSSL_REPO} -DPLATFORM=${PLATFORM} + WORKING_DIRECTORY ${CURL_DEPS_INSTALL} + ) + execute_process( + COMMAND ${CMAKE_COMMAND} --build ${CURL_DEPS_INSTALL} --config Release + RESULT_VARIABLE build_result + ) + if (NOT ${build_result} EQUAL "0") + message(FATAL_ERROR "Failed to build curl!") + endif() - list(APPEND CMAKE_PREFIX_PATH ${CURL_DEPS_INSTALL}/INSTALL) + list(APPEND CMAKE_PREFIX_PATH ${CURL_DEPS_INSTALL}/INSTALL) + endif () else () message("Using system curl") set(USING_SYSTEM_CURL ON PARENT_SCOPE) @@ -38,12 +38,31 @@ function(LinkCurl TARGET) if (APPLE) target_link_libraries(${TARGET} PUBLIC curl) elseif (WIN32) - target_link_libraries(${TARGET} PUBLIC ${OPENSSL_SSL_LIBRARY} ${OPENSSL_CRYPTO_LIBRARY}) + set(CURL_USE_SCHANNEL ON CACHE BOOL "USE SCHANNEL") + FetchContent_Declare( + curl + # In function you cannot access the variables defined outside, so hardcoding for now. + GIT_REPOSITORY https://github.com/curl/curl.git + GIT_TAG curl-8_8_0 + GIT_SHALLOW TRUE + CMAKE_ARGS + -DCMAKE_BUILD_TYPE=Release + -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_BINARY_DIR}/INSTALL + -DUSE_NGHTTP2=OFF + -DBUILD_STATIC_LIBS=ON + -DBUILD_SHARED_LIBS=OFF + OVERRIDE_FIND_PACKAGE + ) + FetchContent_MakeAvailable(curl) + find_package(curl REQUIRED) + target_link_libraries(${TARGET} PUBLIC CURL::libcurl) else () target_link_libraries(${TARGET} PUBLIC crypto ssl curl) endif () else () - target_include_directories(${TARGET} PUBLIC ${CURL_INCLUDE_DIR}) + if (CURL_INCLUDE_DIR) + target_include_directories(${TARGET} PUBLIC ${CURL_INCLUDE_DIR}) + endif () target_link_libraries(${TARGET} PUBLIC CURL::libcurl) endif () target_compile_definitions(${TARGET} PRIVATE HAS_CURL) diff --git a/3rdParty/curl/ext/CMakeLists.txt b/3rdParty/curl/ext/CMakeLists.txt index e69f1aa..279e0b3 100644 --- a/3rdParty/curl/ext/CMakeLists.txt +++ b/3rdParty/curl/ext/CMakeLists.txt @@ -6,6 +6,9 @@ include(FetchContent) if (NOT DEFINED CURL_REPO OR CURL_REPO STREQUAL "") set(CURL_REPO https://github.com/curl/curl.git) endif () +if (NOT DEFINED CURL_GIT_TAG OR CURL_GIT_TAG STREQUAL "") + set(CURL_GIT_TAG curl-8_8_0) +endif () if (NOT DEFINED OPENSSL_REPO OR OPENSSL_REPO STREQUAL "") set(OPENSSL_REPO https://github.com/openssl/openssl.git) endif () @@ -29,8 +32,6 @@ else () set(OPENSSL_MAKE_COMMAND make) endif () -set(CURL_GIT_TAG curl-8_8_0) - function(InstallOpenSSL) ExternalProject_Add( OpenSSL diff --git a/3rdParty/curl/ext_windows/CMakeLists.txt b/3rdParty/curl/ext_windows/CMakeLists.txt deleted file mode 100644 index 1247e9a..0000000 --- a/3rdParty/curl/ext_windows/CMakeLists.txt +++ /dev/null @@ -1,45 +0,0 @@ -cmake_minimum_required(VERSION 3.16) -project(build_curl) -include(FetchContent) - -if (NOT DEFINED CURL_MIRROR_LINK) - set(CURL_MIRROR_LINK https://curl.se/download/curl-8.8.0.tar.gz) -endif () -if (NOT DEFINED LIBRESSL_MIRROR_LINK) - set(LIBRESSL_MIRROR_LINK https://ftp.openbsd.org/pub/OpenBSD/LibreSSL/libressl-3.9.2.tar.gz) -endif () - -set(LIBRESSL_TESTS OFF CACHE BOOL "" FORCE) -FetchContent_Declare( - libressl - URL ${LIBRESSL_MIRROR_LINK} - CMAKE_ARGS - -DCMAKE_BUILD_TYPE=Release - -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_BINARY_DIR}/INSTALL -) -FetchContent_MakeAvailable(libressl) - -set(BUILD_SHARED_LIBS OFF CACHE BOOL "Build shared libraries" FORCE) -set(BUILD_STATIC_LIBS ON CACHE BOOL "Build static libraries" FORCE) -set(BUILD_STATIC_CURL ON CACHE BOOL "Build curl executable with static libcurl" FORCE) -set(CURL_DISABLE_TESTS ON CACHE BOOL "Do no build tests" FORCE) - -set(CURL_USE_LIBRESSL ON CACHE BOOL "Use LibreSSL instead of OpenSSL" FORCE) -set(OPENSSL_ROOT_DIR ${libressl_SOURCE_DIR} CACHE PATH "Path to LibreSSL root directory" FORCE) -if (WIN32) - set(OPENSSL_CRYPTO_LIBRARY ${libressl_BINARY_DIR}/crypto/release/crypto.lib CACHE FILEPATH "Path to LibreSSL crypto library" FORCE) - set(OPENSSL_SSL_LIBRARY ${libressl_BINARY_DIR}/ssl/release/ssl.lib CACHE FILEPATH "Path to LibreSSL SSL library" FORCE) -else () - set(OPENSSL_CRYPTO_LIBRARY ${libressl_BINARY_DIR}/crypto/libcrypto.a CACHE FILEPATH "Path to LibreSSL crypto library" FORCE) - set(OPENSSL_SSL_LIBRARY ${libressl_BINARY_DIR}/ssl/libssl.a CACHE FILEPATH "Path to LibreSSL SSL library" FORCE) -endif () -set(OPENSSL_INCLUDE_DIR ${libressl_SOURCE_DIR}/include CACHE PATH "Path to LibreSSL include directory" FORCE) - -FetchContent_Declare( - curl - URL ${CURL_MIRROR_LINK} - CMAKE_ARGS - -DCMAKE_BUILD_TYPE=Release - -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_BINARY_DIR}/INSTALL -) -FetchContent_MakeAvailable(curl) \ No newline at end of file From 79b7deed7f849930748e4d36460ec08fce556f19 Mon Sep 17 00:00:00 2001 From: Vladyslav Baranovskyi Date: Fri, 25 Oct 2024 22:43:37 +0300 Subject: [PATCH 2/6] Removed ifdefs around curl in WebResourceLoader --- openVulkanoCpp/Host/WebResourceLoader.cpp | 19 ++++--------------- openVulkanoCpp/Host/WebResourceLoader.hpp | 1 + 2 files changed, 5 insertions(+), 15 deletions(-) diff --git a/openVulkanoCpp/Host/WebResourceLoader.cpp b/openVulkanoCpp/Host/WebResourceLoader.cpp index 578f8d4..08e63bc 100644 --- a/openVulkanoCpp/Host/WebResourceLoader.cpp +++ b/openVulkanoCpp/Host/WebResourceLoader.cpp @@ -12,16 +12,10 @@ #include #include -#if __has_include("curl/curl.h") - #include -#else - #pragma message ("Missing curl.h even though HAS_CURL is set") - #undef HAS_CURL -#endif +#include namespace OpenVulkano { -#ifdef HAS_CURL namespace { size_t CurlDownloader(void* contents, size_t size, size_t memBlockCount, void* userData) @@ -32,7 +26,6 @@ namespace OpenVulkano return totalSize; } } -#endif bool WebResourceLoader::IsUrl(const std::string& str) { @@ -43,16 +36,12 @@ namespace OpenVulkano { m_cacheDirectory = AppFolders::GetAppCacheDir() / "resources"; std::filesystem::create_directories(m_cacheDirectory); -#ifdef HAS_CURL curl_global_init(CURL_GLOBAL_DEFAULT); -#endif } WebResourceLoader::~WebResourceLoader() { -#ifdef HAS_CURL curl_global_cleanup(); -#endif } std::filesystem::path WebResourceLoader::GetCacheFilePath(const std::string& url) @@ -66,7 +55,6 @@ namespace OpenVulkano Array WebResourceLoader::DownloadResource(const std::string& url) { std::vector buffer; -#ifdef HAS_CURL CURL* curl = curl_easy_init(); if (curl) { @@ -81,8 +69,9 @@ namespace OpenVulkano CURLcode result = curl_easy_perform(curl); if (result != CURLE_OK) { + std::string error = curl_easy_strerror(result); + Logger::APP->error("Failed to download resource: '" + url + "' - " + error); curl_easy_cleanup(curl); - Logger::APP->error("Failed to download resource: '" + url + "' - " + curl_easy_strerror(result)); return Array(); } curl_easy_cleanup(curl); @@ -91,7 +80,7 @@ namespace OpenVulkano std::filesystem::path cacheFilePath = GetCacheFilePath(url); std::ofstream file(cacheFilePath, std::ios::binary); file.write(buffer.data(), buffer.size()); -#endif + return Array(buffer); } diff --git a/openVulkanoCpp/Host/WebResourceLoader.hpp b/openVulkanoCpp/Host/WebResourceLoader.hpp index 5159e85..a4a87af 100644 --- a/openVulkanoCpp/Host/WebResourceLoader.hpp +++ b/openVulkanoCpp/Host/WebResourceLoader.hpp @@ -14,6 +14,7 @@ namespace OpenVulkano { class WebResourceLoader : public ResourceLoader { + protected: std::filesystem::path m_cacheDirectory; std::filesystem::path GetCacheFilePath(const std::string& url); From 8fc563706f2a13aab147ea529f91d289cf5ca373 Mon Sep 17 00:00:00 2001 From: Vladyslav Baranovskyi Date: Fri, 25 Oct 2024 22:43:57 +0300 Subject: [PATCH 3/6] Tests for WebResourceLoader --- tests/Host/WebResourceLoader.cpp | 137 +++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 tests/Host/WebResourceLoader.cpp diff --git a/tests/Host/WebResourceLoader.cpp b/tests/Host/WebResourceLoader.cpp new file mode 100644 index 0000000..04c4a87 --- /dev/null +++ b/tests/Host/WebResourceLoader.cpp @@ -0,0 +1,137 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +#include + +#include "Host/WebResourceLoader.hpp" + +#include +#include +#include + +#include "curl/curl.h" + +using namespace OpenVulkano; + +class TestWebResourceLoader : public WebResourceLoader +{ +public: + std::filesystem::path GetCacheFilePath(const std::string& url) + { + return WebResourceLoader::GetCacheFilePath(url); + } + + Array DownloadResource(const std::string& url) + { + return WebResourceLoader::DownloadResource(url); + } + + std::filesystem::path GetCacheDir() + { + return m_cacheDirectory; + } +}; + +TEST_CASE("CURL SSL support", "[WebResourceLoader]") +{ + curl_version_info_data* vinfo = curl_version_info(CURLVERSION_NOW); + REQUIRE(vinfo->features & CURL_VERSION_SSL); +} + +TEST_CASE("Constructor/Destructor", "[WebResourceLoader]") +{ + TestWebResourceLoader loader; + + REQUIRE(std::filesystem::exists(loader.GetCacheDir())); +} + +TEST_CASE("IsUrl", "[WebResourceLoader]") +{ + REQUIRE(WebResourceLoader::IsUrl("http://example.com")); + REQUIRE(WebResourceLoader::IsUrl("https://example.com")); + REQUIRE(WebResourceLoader::IsUrl("ftp://example.com")); + REQUIRE_FALSE(WebResourceLoader::IsUrl("file://example.com")); + REQUIRE_FALSE(WebResourceLoader::IsUrl("example.com")); +} + +TEST_CASE("GetCacheFilePath", "[WebResourceLoader]") +{ + TestWebResourceLoader loader; + + std::string url = "http://example.com/resource"; + std::filesystem::path cachePath = loader.GetCacheFilePath(url); + + size_t expectedHash = std::hash {}(url); + std::string expectedHashStr = std::to_string(expectedHash); + + REQUIRE(cachePath.filename().string() == expectedHashStr); + REQUIRE(cachePath.parent_path().filename().string() == "resources"); +} + +TEST_CASE("DownloadResource from non-ssl uri", "[WebResourceLoader]") +{ + TestWebResourceLoader loader; + std::string url = "http://neverssl.com"; + Array resourceData = loader.DownloadResource(url); + REQUIRE(!resourceData.Empty()); + std::filesystem::path cachePath = loader.GetCacheFilePath(url); + REQUIRE(std::filesystem::exists(cachePath)); + std::filesystem::remove(cachePath); +} + +TEST_CASE("DownloadResource with curl", "[WebResourceLoader]") +{ + TestWebResourceLoader loader; + std::string url = "https://example.com/resource"; + Array resourceData = loader.DownloadResource(url); + REQUIRE(!resourceData.Empty()); + std::filesystem::path cachePath = loader.GetCacheFilePath(url); + REQUIRE(std::filesystem::exists(cachePath)); + std::filesystem::remove(cachePath); +} + +TEST_CASE("DownloadResource without curl", "[WebResourceLoader]") +{ + TestWebResourceLoader loader; + std::string url = "https://example.com/resource"; + Array resourceData = loader.DownloadResource(url); + + REQUIRE(!resourceData.Empty()); +} + +TEST_CASE("GetResource", "[WebResourceLoader]") +{ + TestWebResourceLoader loader; + + std::string url = "https://example.com/resource"; + + { + std::filesystem::path cachePath = loader.GetCacheFilePath(url); + std::ofstream file(cachePath, std::ios::binary); + std::string mockContent = "Mock cached content"; + file.write(mockContent.c_str(), mockContent.size()); + file.close(); + + Array resource = loader.GetResource(url); + + REQUIRE(!resource.Empty()); + REQUIRE(std::memcmp(resource.Data(), mockContent.c_str(), mockContent.size()) == 0); + + std::filesystem::remove(cachePath); + } + + { + std::filesystem::path cachePath = loader.GetCacheFilePath(url); + std::filesystem::remove(cachePath); + + Array resource = loader.GetResource(url); + + REQUIRE(!resource.Empty()); + REQUIRE(std::filesystem::exists(cachePath)); + + std::filesystem::remove(cachePath); + } +} \ No newline at end of file From 994f43ac72643711e5829546061b8d02b75f86f0 Mon Sep 17 00:00:00 2001 From: Vladyslav Baranovskyi Date: Sat, 26 Oct 2024 18:56:16 +0300 Subject: [PATCH 4/6] Fix building on linux --- 3rdParty/curl/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/3rdParty/curl/CMakeLists.txt b/3rdParty/curl/CMakeLists.txt index ba2e61b..dd92c8b 100644 --- a/3rdParty/curl/CMakeLists.txt +++ b/3rdParty/curl/CMakeLists.txt @@ -8,6 +8,7 @@ set(CURL_DEPS_INSTALL ${CMAKE_BINARY_DIR}/deps_curl) find_package(CURL QUIET) if (NOT ${CURL_FOUND}) if (NOT WIN32) + file(MAKE_DIRECTORY ${CURL_DEPS_INSTALL}) execute_process( COMMAND ${CMAKE_COMMAND} -G ${CMAKE_GENERATOR} -DTOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE} ${CMAKE_CURRENT_SOURCE_DIR}/ext -DCURL_REPO=${CURL_REPO} -DCURL_GIT_TAG=${CURL_GIT_TAG} -DOPENSSL_REPO=${OPENSSL_REPO} -DPLATFORM=${PLATFORM} WORKING_DIRECTORY ${CURL_DEPS_INSTALL} From b6a1769765cc3fad8544f2841edaea4512b6087c Mon Sep 17 00:00:00 2001 From: Vladyslav Baranovskyi Date: Mon, 28 Oct 2024 12:12:26 +0200 Subject: [PATCH 5/6] Added preprocessor gates around curl code --- openVulkanoCpp/Host/WebResourceLoader.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/openVulkanoCpp/Host/WebResourceLoader.cpp b/openVulkanoCpp/Host/WebResourceLoader.cpp index 08e63bc..2fc1735 100644 --- a/openVulkanoCpp/Host/WebResourceLoader.cpp +++ b/openVulkanoCpp/Host/WebResourceLoader.cpp @@ -12,10 +12,16 @@ #include #include -#include +#if __has_include("curl/curl.h") + #include +#else + #pragma message ("Missing curl.h even though HAS_CURL is set") + #undef HAS_CURL +#endif namespace OpenVulkano { +#ifdef HAS_CURL namespace { size_t CurlDownloader(void* contents, size_t size, size_t memBlockCount, void* userData) @@ -26,6 +32,7 @@ namespace OpenVulkano return totalSize; } } +#endif bool WebResourceLoader::IsUrl(const std::string& str) { @@ -36,12 +43,16 @@ namespace OpenVulkano { m_cacheDirectory = AppFolders::GetAppCacheDir() / "resources"; std::filesystem::create_directories(m_cacheDirectory); +#ifdef HAS_CURL curl_global_init(CURL_GLOBAL_DEFAULT); +#endif } WebResourceLoader::~WebResourceLoader() { +#ifdef HAS_CURL curl_global_cleanup(); +#endif } std::filesystem::path WebResourceLoader::GetCacheFilePath(const std::string& url) @@ -55,6 +66,7 @@ namespace OpenVulkano Array WebResourceLoader::DownloadResource(const std::string& url) { std::vector buffer; +#ifdef HAS_CURL CURL* curl = curl_easy_init(); if (curl) { @@ -80,6 +92,7 @@ namespace OpenVulkano std::filesystem::path cacheFilePath = GetCacheFilePath(url); std::ofstream file(cacheFilePath, std::ios::binary); file.write(buffer.data(), buffer.size()); +#endif return Array(buffer); } From a07cbe0fa8bea7d157aac4bb69e5088699fdf0ab Mon Sep 17 00:00:00 2001 From: Vladyslav Baranovskyi Date: Mon, 28 Oct 2024 12:23:29 +0200 Subject: [PATCH 6/6] Removed extra spaces... --- openVulkanoCpp/Host/WebResourceLoader.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/openVulkanoCpp/Host/WebResourceLoader.cpp b/openVulkanoCpp/Host/WebResourceLoader.cpp index 2fc1735..2ee8997 100644 --- a/openVulkanoCpp/Host/WebResourceLoader.cpp +++ b/openVulkanoCpp/Host/WebResourceLoader.cpp @@ -13,10 +13,10 @@ #include #if __has_include("curl/curl.h") - #include -#else - #pragma message ("Missing curl.h even though HAS_CURL is set") - #undef HAS_CURL + #include +#else + #pragma message ("Missing curl.h even though HAS_CURL is set") + #undef HAS_CURL #endif namespace OpenVulkano