From 3c9b96231130adef17f74a82089fa6542c0623f9 Mon Sep 17 00:00:00 2001 From: Martin Valgur Date: Mon, 9 Sep 2024 23:31:50 +0300 Subject: [PATCH] qcoro: update to v0.10.0, add workaround for MSVC ABI issue --- recipes/qcoro/all/conandata.yml | 6 +- recipes/qcoro/all/conanfile.py | 119 +++++++++++------- recipes/qcoro/all/test_package/CMakeLists.txt | 13 +- .../qcoro/all/test_package/test_package.cpp | 35 +----- recipes/qcoro/config.yml | 2 +- 5 files changed, 90 insertions(+), 85 deletions(-) diff --git a/recipes/qcoro/all/conandata.yml b/recipes/qcoro/all/conandata.yml index f303943d3a6a1..b13849c689481 100644 --- a/recipes/qcoro/all/conandata.yml +++ b/recipes/qcoro/all/conandata.yml @@ -1,4 +1,4 @@ sources: - "0.4.0": - url: "https://github.com/danvratil/qcoro/archive/refs/tags/v0.4.0.tar.gz" - sha256: "0e68b3f0ce7bf521ffbdd731464d2d60d8d7a39a749b551ed26855a1707d86d1" + "0.10.0": + url: "https://github.com/danvratil/qcoro/archive/refs/tags/v0.10.0.tar.gz" + sha256: "b7c8f00273ad27d85814bf4ec93eb6922c75656800a61d11854d36355a4a1aec" diff --git a/recipes/qcoro/all/conanfile.py b/recipes/qcoro/all/conanfile.py index 839a2fe9be89e..4f9eb0be94dcb 100644 --- a/recipes/qcoro/all/conanfile.py +++ b/recipes/qcoro/all/conanfile.py @@ -6,7 +6,7 @@ from conan.tools.build import check_min_cppstd from conan.tools.cmake import CMake, CMakeDeps, CMakeToolchain, cmake_layout from conan.tools.env import VirtualBuildEnv, VirtualRunEnv -from conan.tools.files import apply_conandata_patches, copy, get, rm +from conan.tools.files import copy, get, rm, replace_in_file, rmdir from conan.tools.scm import Version required_conan_version = ">=1.56.0 <2 || >=2.0.6" @@ -55,7 +55,7 @@ def layout(self): cmake_layout(self, src_folder="src") def requirements(self): - self.requires("qt/6.6.0", transitive_headers=True, transitive_libs=True) + self.requires("qt/[>=6.6.0 <7]", transitive_headers=True, transitive_libs=True) def validate(self): if self.settings.compiler.cppstd: @@ -64,7 +64,7 @@ def validate(self): # Special check for clang that can only be linked to libc++ if self.settings.compiler == "clang" and self.settings.compiler.libcxx != "libc++": raise ConanInvalidConfiguration( - "qcoro requires some C++20 features, which are available in libc++ for clang compiler." + "qcoro requires some C++20 features, which are only available in libc++ for clang compiler." ) compiler_version = str(self.settings.compiler.version) @@ -82,70 +82,99 @@ def build_requirements(self): def source(self): get(self, **self.conan_data["sources"][self.version], strip_root=True) + @property + def _with_qml(self): + return self.dependencies["qt"].options.get_safe("qtdeclarative", False) + + @property + def _with_dbus(self): + return self.dependencies["qt"].options.get_safe("with_dbus", False) + + @property + def _with_quick(self): + return (self.dependencies["qt"].options.get_safe("gui", False) and + self.dependencies["qt"].options.get_safe("qtshadertools", False)) + + @property + def _with_websockets(self): + return self.dependencies["qt"].options.get_safe("qtwebsockets", False) + def generate(self): - venv = VirtualBuildEnv(self) - venv.generate() - # Required for Qt's moc - venv = VirtualRunEnv(self) - venv.generate(scope="build") + VirtualBuildEnv(self).generate() + # Required for Qt's moc and qtpaths + VirtualRunEnv(self).generate(scope="build") tc = CMakeToolchain(self) tc.variables["QCORO_BUILD_EXAMPLES"] = False tc.variables["QCORO_ENABLE_ASAN"] = self.options.asan tc.variables["BUILD_TESTING"] = False - tc.variables["QCORO_WITH_QTDBUS"] = self.dependencies["qt"].options.with_dbus + tc.variables["USE_QT_VERSION"] = self.dependencies["qt"].ref.version.major + tc.variables["QCORO_WITH_QML"] = self._with_qml + tc.variables["QCORO_WITH_QTDBUS"] = self._with_qml + tc.variables["QCORO_WITH_QTQUICK"] = self._with_quick + tc.variables["QCORO_WITH_QTWEBSOCKETS"] = self._with_websockets tc.generate() tc = CMakeDeps(self) tc.generate() + def _patch_sources(self): + replace_in_file(self, os.path.join(self.source_folder, "cmake", "ECMQueryQt.cmake"), + "get_target_property(_qtpaths_executable Qt6::qtpaths LOCATION)", + "set(_qtpaths_executable qtpaths)") + def build(self): - apply_conandata_patches(self) + self._patch_sources() cmake = CMake(self) cmake.configure() cmake.build() def package(self): copy(self, "*", - dst=os.path.join(self.package_folder, "licenses"), - src=os.path.join(self.source_folder, "LICENSES")) + src=os.path.join(self.source_folder, "LICENSES"), + dst=os.path.join(self.package_folder, "licenses")) cmake = CMake(self) cmake.install() + rmdir(self, os.path.join(self.package_folder, "mkspecs")) for mask in ["Find*.cmake", "*Config*.cmake", "*-config.cmake", "*Targets*.cmake"]: rm(self, mask, self.package_folder, recursive=True) def package_info(self): - self.cpp_info.set_property("cmake_file_name", "QCoro6") - - self.cpp_info.builddirs.append(os.path.join("lib", "cmake", "QCoro6Coro")) - macros_cmake_path = os.path.join("lib", "cmake", "QCoro6Coro", "QCoroMacros.cmake") - self.cpp_info.set_property("cmake_build_modules", [macros_cmake_path]) - - self.cpp_info.components["qcoro-core"].set_property("cmake_target_name", "QCoro::Core") - self.cpp_info.components["qcoro-core"].libs = ["QCoro6Core"] - self.cpp_info.components["qcoro-core"].includedirs.append(os.path.join("include", "qcoro6", "qcoro")) - self.cpp_info.components["qcoro-core"].requires = ["qt::qtCore"] - - self.cpp_info.components["qcoro-network"].set_property("cmake_target_name", "QCoro::Network") - self.cpp_info.components["qcoro-network"].libs = ["QCoro6Network"] - self.cpp_info.components["qcoro-network"].requires = ["qt::qtNetwork"] + qt_major = self.dependencies["qt"].ref.version.major + name = f"QCoro{qt_major}" + self.cpp_info.set_property("cmake_file_name", name) + self.cpp_info.set_property("cmake_target_name", f"{name}::{name}") + + def _add_module(module_name, requires=None, interface=False): + component = self.cpp_info.components[module_name.lower()] + component.set_property("cmake_target_name", f"{name}::{module_name}") + if not interface: + component.libs = [f"{name}{module_name}"] + component.includedirs.append(os.path.join("include", f"qcoro{qt_major}", "qcoro")) + component.requires = requires or [] + # TODO: Legacy, to be removed on Conan 2.0 + component.names["cmake_find_package"] = module_name + component.names["cmake_find_package_multi"] = module_name + + _add_module("Coro", interface=True) + _add_module("Core", requires=["coro", "qt::qtCore"]) + _add_module("Network", requires=["coro", "core", "qt::qtCore", "qt::qtNetwork"]) if is_apple_os(self): - self.cpp_info.components["qcoro-network"].frameworks = ["CFNetwork"] - - if self.dependencies["qt"].options.with_dbus: - self.cpp_info.components["qcoro-dbus"].set_property("cmake_target_name", "QCoro::DBus") - self.cpp_info.components["qcoro-dbus"].libs = ["QCoroDBus"] - self.cpp_info.components["qcoro-core"].requires = ["qt::qtDBus"] + self.cpp_info.components["network"].frameworks = ["CFNetwork"] + _add_module("Test", requires=["qt::qtTest"], interface=True) + if self._with_dbus: + _add_module("DBus", requires=["coro", "core", "qt::qtCore", "qt::qtDBus"]) + if self._with_qml: + _add_module("Qml", requires=["coro", "qt::qtCore", "qt::qtQml"]) + if self._with_quick: + _add_module("Quick", requires=["coro", "core", "qt::qtCore", "qt::qtGui", "qt::qtQuick"]) + if self._with_websockets: + _add_module("WebSockets", requires=["coro", "core", "qt::qtCore", "qt::qtNetwork", "qt::qtWebSockets"]) + + self.cpp_info.builddirs.append(os.path.join("lib", "cmake", f"{name}Coro")) + macros_cmake_path = os.path.join("lib", "cmake", f"{name}Coro", "QCoroMacros.cmake") + self.cpp_info.set_property("cmake_build_modules", [macros_cmake_path]) # TODO: Legacy, to be removed on Conan 2.0 - self.cpp_info.filenames["cmake_find_package"] = "QCoro6" - self.cpp_info.filenames["cmake_find_package_multi"] = "QCoro6" - self.cpp_info.names["cmake_find_package"] = "QCoro" - self.cpp_info.names["cmake_find_package_multi"] = "QCoro" - self.cpp_info.components["qcoro-core"].names["cmake_find_package"] = "Core" - self.cpp_info.components["qcoro-core"].names["cmake_find_package_multi"] = "Core" - self.cpp_info.components["qcoro-network"].names["cmake_find_package"] = "Network" - self.cpp_info.components["qcoro-network"].names["cmake_find_package_multi"] = "Network" - if self.dependencies["qt"].options.with_dbus: - self.cpp_info.components["qcoro-dbus"].names["cmake_find_package"] = "DBus" - self.cpp_info.components["qcoro-dbus"].names["cmake_find_package_multi"] = "DBus" - self.cpp_info.components["qcoro-core"].build_modules["cmake_find_package"].append(macros_cmake_path) - self.cpp_info.components["qcoro-core"].build_modules["cmake_find_package_multi"].append(macros_cmake_path) + self.cpp_info.names["cmake_find_package"] = name + self.cpp_info.names["cmake_find_package_multi"] = name + self.cpp_info.components["core"].build_modules["cmake_find_package"].append(macros_cmake_path) + self.cpp_info.components["core"].build_modules["cmake_find_package_multi"].append(macros_cmake_path) diff --git a/recipes/qcoro/all/test_package/CMakeLists.txt b/recipes/qcoro/all/test_package/CMakeLists.txt index bf9b43951f200..11a0e1206f90e 100644 --- a/recipes/qcoro/all/test_package/CMakeLists.txt +++ b/recipes/qcoro/all/test_package/CMakeLists.txt @@ -4,8 +4,13 @@ project(test_package CXX) find_package(QCoro6 REQUIRED COMPONENTS Core) qcoro_enable_coroutines() +if(MSVC) + # Qt6Core.lib(qlocale_win.cpp.obj) : error LNK2038: mismatch detected for '_COROUTINE_ABI': value '1' doesn't match value '2' in test_package.obj + # https://stackoverflow.com/questions/70348706/error-lnk2038-mismatch-detected-for-coroutine-abi-value-2-doesnt-match-v + # https://devblogs.microsoft.com/oldnewthing/20230111-00/?p=107694 + add_compile_definitions(_ALLOW_COROUTINE_ABI_MISMATCH) +endif() + add_executable(${PROJECT_NAME} test_package.cpp) -target_link_libraries(${PROJECT_NAME} QCoro::Core - Qt6::Core - Qt6::Concurrent) -set_target_properties(${PROJECT_NAME} PROPERTIES CXX_STANDARD 20) +target_link_libraries(${PROJECT_NAME} QCoro6::Core Qt6::Concurrent) +target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_20) diff --git a/recipes/qcoro/all/test_package/test_package.cpp b/recipes/qcoro/all/test_package/test_package.cpp index a01824f987d94..b321834a7f016 100644 --- a/recipes/qcoro/all/test_package/test_package.cpp +++ b/recipes/qcoro/all/test_package/test_package.cpp @@ -1,41 +1,12 @@ -// SPDX-FileCopyrightText: 2021 Daniel Vrátil -// -// SPDX-License-Identifier: MIT - -#include "qcorofuture.h" - -#include -#include +#include #include -#include -#include - QCoro::Task<> startTask() { const auto data = co_await QtConcurrent::run([]() { - QVector data; - std::random_device rd{}; - std::mt19937 gen{rd()}; - data.reserve(10'000'000); - for (int i = 0; i < 10'000'000; ++i) { - data.push_back(gen()); - } - return data; + return 0; }); - - std::cout << "Generated " << data.size() << " random numbers" << std::endl; - - const auto sum = co_await QtConcurrent::filteredReduced( - data, [](const auto &) { return true; }, - [](std::uint64_t &interm, std::uint64_t val) { interm += val; }, - QtConcurrent::UnorderedReduce); - - std::cout << "Calculated result: " << sum << std::endl; - qApp->quit(); } int main(int argc, char **argv) { - QCoreApplication app(argc, argv); - QTimer::singleShot(0, startTask); - return app.exec(); + return 0; } diff --git a/recipes/qcoro/config.yml b/recipes/qcoro/config.yml index af29e78bd9b25..1b582dcf6716b 100644 --- a/recipes/qcoro/config.yml +++ b/recipes/qcoro/config.yml @@ -1,3 +1,3 @@ versions: - "0.4.0": + "0.10.0": folder: all