From 39c60290871daad481820f27c4f3eddea00b07a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20Cl=C3=A9ro?= Date: Sat, 15 Mar 2025 11:36:08 +0100 Subject: [PATCH 1/3] Update to Qt6 --- .github/workflows/linux.yml | 10 +- .github/workflows/macos.yml | 10 +- .github/workflows/windows.yml | 10 +- CHANGELOG.md | 6 ++ CMakeLists.txt | 25 ++++- CMakePresets.json | 110 +++++++++++++++++---- README.md | 8 +- cmake/DeployQt.cmake | 32 ------ cmake/config.cmake.in | 8 ++ examples/multiple/CMakeLists.txt | 16 +-- examples/single/CMakeLists.txt | 16 +-- src/CMakeLists.txt | 102 ++++++++++++------- src/source/oclero/LocalEndpoint.cpp | 49 ++++----- src/source/oclero/QtAppInstanceManager.cpp | 4 +- tests/CMakeLists.txt | 19 ++-- 15 files changed, 271 insertions(+), 154 deletions(-) delete mode 100644 cmake/DeployQt.cmake create mode 100644 cmake/config.cmake.in diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 03793e6..cd9848d 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -5,7 +5,6 @@ on: branches: - master - dev - - setup-ci pull_request: branches: - master @@ -20,17 +19,18 @@ jobs: uses: actions/checkout@v4 - name: Install Qt - uses: jurplel/install-qt-action@v3 + uses: jurplel/install-qt-action@v4 with: - version: "5.15.2" + version: "6.8.2" host: linux target: desktop + arch: linux_gcc_64 - name: Configure CMake - run: cmake --preset linux + run: cmake --preset linux -DCMAKE_INSTALL_PREFIX=${{github.workspace}}/install - name: Build library - run: cmake --build --preset linux + run: cmake --build --preset linux --target install - name: Build tests run: cmake --build --preset linux-test diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 7d4945b..dd0e92f 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -5,7 +5,6 @@ on: branches: - master - dev - - setup-ci pull_request: branches: - master @@ -20,17 +19,18 @@ jobs: uses: actions/checkout@v4 - name: Install Qt - uses: jurplel/install-qt-action@v3 + uses: jurplel/install-qt-action@v4 with: - version: "5.15.2" + version: "6.8.2" host: mac target: desktop + arch: clang_64 - name: Configure CMake - run: cmake --preset macos -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED=OFF -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY="-" + run: cmake --preset macos -DCMAKE_INSTALL_PREFIX=${{github.workspace}}/install - name: Build library - run: cmake --build --preset macos + run: cmake --build --preset macos --target install - name: Build tests run: cmake --build --preset macos-test diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 26b61af..f4390ed 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -5,7 +5,6 @@ on: branches: - master - dev - - setup-ci pull_request: branches: - master @@ -20,17 +19,18 @@ jobs: uses: actions/checkout@v4 - name: Install Qt - uses: jurplel/install-qt-action@v3 + uses: jurplel/install-qt-action@v4 with: - version: "5.15.2" + version: "6.8.2" host: windows target: desktop + arch: win64_msvc2022_64 - name: Configure CMake - run: cmake --preset windows + run: cmake --preset windows -DCMAKE_INSTALL_PREFIX=${{github.workspace}}/install - name: Build library - run: cmake --build --preset windows + run: cmake --build --preset windows --target install - name: Build tests run: cmake --build --preset windows-test diff --git a/CHANGELOG.md b/CHANGELOG.md index 49d7426..9bb7d70 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## v1.3.0 + +- Switch to Qt6. +- Switch to Ninja for macOS builds. +- Add `QTAPPINSTANCEMANAGER_TESTS` and `QTAPPINSTANCEMANAGER_EXAMPLES` options to enable tests and examples. + ## v1.2.1 - Recommend FetchContent instead of submodule. diff --git a/CMakeLists.txt b/CMakeLists.txt index 2f33f50..0aaf95b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,13 +1,18 @@ cmake_minimum_required(VERSION 3.21.0) + +# Enable parallel build (not enabled by default on Windows). +set(CMAKE_BUILD_PARALLEL_LEVEL $ENV{NUMBER_OF_PROCESSORS}) + enable_testing() set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") -include(DeployQt) # Set project information. project("QtAppInstanceManager" LANGUAGES CXX - VERSION 1.2.1.0 + VERSION 1.3.0.0 + DESCRIPTION "A tool to communicate between the instances of your Qt application." + HOMEPAGE_URL "https://github.com/oclero/QtAppInstanceManager" ) set(PROJECT_NAMESPACE "oclero") @@ -16,15 +21,25 @@ set(CMAKE_CXX_EXTENSIONS OFF) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set_property(GLOBAL PROPERTY USE_FOLDERS ON) +if(NOT CMAKE_OSX_DEPLOYMENT_TARGET) + set(CMAKE_OSX_DEPLOYMENT_TARGET "13.6") +endif() +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake") + +# Find Qt. +find_package(Qt6 REQUIRED COMPONENTS Core Network) +qt_standard_project_setup() # The library. add_subdirectory(src) -if(${CMAKE_PROJECT_NAME} STREQUAL ${PROJECT_NAME}) - # Tests. +# Tests. +if(QTAPPINSTANCEMANAGER_TESTS) add_subdirectory(tests) +endif() - # Examples. +# Examples. +if(QTAPPINSTANCEMANAGER_EXAMPLES) add_subdirectory(examples/single) add_subdirectory(examples/multiple) endif() diff --git a/CMakePresets.json b/CMakePresets.json index 28dba6a..447a464 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -1,5 +1,5 @@ { - "version": 3, + "version": 6, "cmakeMinimumRequired": { "major": 3, "minor": 21, @@ -9,11 +9,13 @@ { "name": "macos", "displayName": "macOS", - "description": "Xcode project for macOS", - "generator": "Xcode", + "description": "Ninja Build for macOS", + "generator": "Ninja", "binaryDir": "${sourceDir}/_build", "cacheVariables": { - "Qt5_DIR": "/opt/homebrew/opt/qt/lib/cmake/Qt5" + "CMAKE_PREFIX_PATH": "/opt/homebrew/opt/qt/lib/cmake/Qt6", + "QTAPPINSTANCEMANAGER_TESTS": true, + "QTAPPINSTANCEMANAGER_EXAMPLES": true }, "condition": { "type": "equals", @@ -28,7 +30,9 @@ "generator": "Visual Studio 17 2022", "binaryDir": "${sourceDir}/_build", "cacheVariables": { - "Qt5_DIR": "C:/Qt/5.15.2/msvc2019_64/lib/cmake/Qt5" + "CMAKE_PREFIX_PATH": "C:/Qt/6.8.0/msvc2022_64", + "QTAPPINSTANCEMANAGER_TESTS": true, + "QTAPPINSTANCEMANAGER_EXAMPLES": true }, "condition": { "type": "equals", @@ -39,9 +43,13 @@ { "name": "linux", "displayName": "Linux", - "description": "Makefile for Linux", - "generator": "Unix Makefiles", + "description": "Ninja Build for Linux", + "generator": "Ninja", "binaryDir": "${sourceDir}/_build", + "cacheVariables": { + "QTAPPINSTANCEMANAGER_TESTS": true, + "QTAPPINSTANCEMANAGER_EXAMPLES": true + }, "condition": { "type": "equals", "lhs": "${hostSystemName}", @@ -54,8 +62,10 @@ "name": "macos", "displayName": "macOS", "configurePreset": "macos", - "description": "Release build with Xcode for macOS", - "targets": ["QtAppInstanceManager"], + "description": "Release build for macOS", + "targets": [ + "QtAppInstanceManager" + ], "configuration": "Release", "condition": { "type": "equals", @@ -67,8 +77,10 @@ "name": "macos-test", "displayName": "Tests for macOS", "configurePreset": "macos", - "description": "Tests release build with Xcode for macOS", - "targets": ["QtAppInstanceManagerTests"], + "description": "Tests release build for macOS", + "targets": [ + "QtAppInstanceManagerTests" + ], "configuration": "Release", "condition": { "type": "equals", @@ -80,8 +92,10 @@ "name": "windows", "displayName": "Windows", "configurePreset": "windows", - "description": "Release build with Visual Studio for Windows", - "targets": ["QtAppInstanceManager"], + "description": "Release build for Windows", + "targets": [ + "QtAppInstanceManager" + ], "configuration": "Release", "condition": { "type": "equals", @@ -93,8 +107,10 @@ "name": "windows-test", "displayName": "Tests for Windows", "configurePreset": "windows", - "description": "Tests release build with Visual Studio for Windows", - "targets": ["QtAppInstanceManagerTests"], + "description": "Tests release build for Windows", + "targets": [ + "QtAppInstanceManagerTests" + ], "configuration": "Release", "condition": { "type": "equals", @@ -107,7 +123,9 @@ "displayName": "Linux", "configurePreset": "linux", "description": "Release build for Linux", - "targets": ["QtAppInstanceManager"], + "targets": [ + "QtAppInstanceManager" + ], "configuration": "Release", "condition": { "type": "equals", @@ -120,7 +138,9 @@ "displayName": "Tests for Linux", "configurePreset": "linux", "description": "Tests release build for Linux", - "targets": ["QtAppInstanceManagerTests"], + "targets": [ + "QtAppInstanceManagerTests" + ], "configuration": "Release", "condition": { "type": "equals", @@ -184,5 +204,61 @@ "rhs": "Windows" } } + ], + "workflowPresets": [ + { + "name": "macos", + "displayName": "macOS", + "steps": [ + { + "type": "configure", + "name": "macos" + }, + { + "type": "build", + "name": "macos-test" + }, + { + "type": "test", + "name": "macos" + } + ] + }, + { + "name": "windows", + "displayName": "Windows", + "steps": [ + { + "type": "configure", + "name": "windows" + }, + { + "type": "build", + "name": "windows-test" + }, + { + "type": "test", + "name": "windows" + } + ] + }, + { + "name": "linux", + "displayName": "Linux", + "steps": [ + { + "type": "configure", + "name": "linux" + }, + { + "type": "build", + "name": "linux-test" + }, + { + "type": "test", + "name": "linux" + } + ] + } ] } diff --git a/README.md b/README.md index a2be2e2..4924f4d 100644 --- a/README.md +++ b/README.md @@ -7,9 +7,9 @@ [![License: MIT](https://img.shields.io/badge/license-MIT-green)](https://mit-license.org/) [![CMake version](https://img.shields.io/badge/CMake-3.21+-064F8C?logo=cmake)](https://www.qt.io) [![C++ version](https://img.shields.io/badge/C++-17-00599C?logo=++)](https://www.qt.io) -[![Qt version](https://img.shields.io/badge/Qt-5.15.2+-41CD52?logo=qt)](https://www.qt.io) +[![Qt version](https://img.shields.io/badge/Qt-6.6.0+-41CD52?logo=qt)](https://www.qt.io) -**QtAppInstanceManager** is a tool to control how many instances of your Qt5 application are running at the same time, and to send messages between instances. It uses a local socket under the hood. You may then build upon this foundation any messaging system or protocol, such as JSON-RPC for instance (NB: not provided because out of the scope of this library). +**QtAppInstanceManager** is a tool to control how many instances of your Qt application are running at the same time, and to send messages between instances. It uses a local socket under the hood. You may then build upon this foundation any messaging system or protocol, such as JSON-RPC for instance (NB: not provided because out of the scope of this library). It is intended to be a replacement for `QtSingleApplication`, the deprecated Qt4 official project. @@ -33,11 +33,11 @@ Also, it differs from [itay-grudev's SingleApplication](https://github.com/itay- - Platform: Windows, MacOS, Linux. - [CMake 3.21+](https://cmake.org/download/) -- [Qt 5.15+](https://www.qt.io/download-qt-installer) +- [Qt 6.6+](https://www.qt.io/download-qt-installer) ## Usage -1. Add the library as a dependency with CMake FetchContent. +1. Add the library as a dependency in your CMakeLists.txt, for example with FetchContent. ```cmake include(FetchContent) diff --git a/cmake/DeployQt.cmake b/cmake/DeployQt.cmake deleted file mode 100644 index e0ac639..0000000 --- a/cmake/DeployQt.cmake +++ /dev/null @@ -1,32 +0,0 @@ -# Deploys Qt libraries besides the target executable. -function(target_deploy_qt TARGET_NAME) - if(WIN32) - set(DEPLOYQT_NAME "windeployqt") - elseif(APPLE) - get_target_property(TARGET_IS_BUNDLE ${TARGET_NAME} MACOSX_BUNDLE) - if(${TARGET_IS_BUNDLE}) - set(DEPLOYQT_NAME "macdeployqt") - else() - set(DEPLOYQT_NAME "") - endif() - else() - set(DEPLOYQT_NAME "") - endif() - - if (DEPLOYQT_NAME) - get_target_property(QMAKE_LOCATION Qt5::qmake IMPORTED_LOCATION) - get_filename_component(QT_BINARY_DIR ${QMAKE_LOCATION} DIRECTORY) - find_program(DEPLOYQT_EXE "${DEPLOYQT_NAME}" HINTS "${QT_BINARY_DIR}" REQUIRED) - set(QTDEPLOY_TARGET_NAME Qt5::deploy) - add_executable(${QTDEPLOY_TARGET_NAME} IMPORTED) - set_property(TARGET ${QTDEPLOY_TARGET_NAME} PROPERTY IMPORTED_LOCATION ${DEPLOYQT_EXE}) - - # Deploy Qt dependencies to help launch individual instances. - if(TARGET ${QTDEPLOY_TARGET_NAME}) - add_custom_command(TARGET ${TARGET_NAME} POST_BUILD - COMMAND ${CMAKE_COMMAND} -E echo "Deploying Qt..." - COMMAND ${QTDEPLOY_TARGET_NAME} --verbose 0 --no-patchqt --no-compiler-runtime --no-webkit2 --no-system-d3d-compiler --no-translations --no-angle --no-opengl-sw --dir "$" "$" - ) - endif() - endif() -endfunction() diff --git a/cmake/config.cmake.in b/cmake/config.cmake.in new file mode 100644 index 0000000..9425122 --- /dev/null +++ b/cmake/config.cmake.in @@ -0,0 +1,8 @@ +@PACKAGE_INIT@ + +include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake") +include(CMakeFindDependencyMacro) + +find_dependency(Qt6 REQUIRED COMPONENTS Core Widgets Svg) + +check_required_components(@PROJECT_NAME@) diff --git a/examples/multiple/CMakeLists.txt b/examples/multiple/CMakeLists.txt index e523fcc..fecd626 100644 --- a/examples/multiple/CMakeLists.txt +++ b/examples/multiple/CMakeLists.txt @@ -1,14 +1,18 @@ -find_package(Qt5 REQUIRED Core) +find_package(Qt6 REQUIRED COMPONENTS Core) add_executable(MultipleInstanceExample) -target_sources(MultipleInstanceExample PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp) -target_link_libraries(MultipleInstanceExample PRIVATE oclero::QtAppInstanceManager Qt5::Core) +target_sources(MultipleInstanceExample + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp +) +target_link_libraries(MultipleInstanceExample + PRIVATE + ${PROJECT_NAMESPACE}::${PROJECT_NAME} + Qt::Core +) set_target_properties(MultipleInstanceExample PROPERTIES INTERNAL_CONSOLE ON EXCLUDE_FROM_ALL ON FOLDER examples ) - -############# Minimal example ends here ############# -target_deploy_qt(MultipleInstanceExample) diff --git a/examples/single/CMakeLists.txt b/examples/single/CMakeLists.txt index 491fdc5..a971c63 100644 --- a/examples/single/CMakeLists.txt +++ b/examples/single/CMakeLists.txt @@ -1,14 +1,18 @@ -find_package(Qt5 REQUIRED Core) +find_package(Qt6 REQUIRED COMPONENTS Core) add_executable(SingleInstanceExample) -target_sources(SingleInstanceExample PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp) -target_link_libraries(SingleInstanceExample PRIVATE oclero::QtAppInstanceManager Qt5::Core) +target_sources(SingleInstanceExample + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp +) +target_link_libraries(SingleInstanceExample + PRIVATE + ${PROJECT_NAMESPACE}::${PROJECT_NAME} + Qt::Core +) set_target_properties(SingleInstanceExample PROPERTIES INTERNAL_CONSOLE ON EXCLUDE_FROM_ALL ON FOLDER examples ) - -############# Minimal example ends here ############# -target_deploy_qt(SingleInstanceExample) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8482dad..26b57cf 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,11 +1,3 @@ -set(LIB_TARGET_NAME ${PROJECT_NAME}) - -find_package(Qt5 - REQUIRED - Core - Network -) - set(HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/include/oclero/QtAppInstanceManager.hpp ) @@ -16,53 +8,97 @@ set(SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/source/oclero/LocalEndpoint.hpp ) -# Configure target. -add_library(${LIB_TARGET_NAME} STATIC) -add_library(${PROJECT_NAMESPACE}::${LIB_TARGET_NAME} ALIAS ${LIB_TARGET_NAME}) - -target_sources(${LIB_TARGET_NAME} - PRIVATE - ${HEADERS} - ${SOURCES} +# Create target. +qt_add_library(${PROJECT_NAME} STATIC + ${HEADERS} + ${SOURCES} ) +add_library(${PROJECT_NAMESPACE}::${PROJECT_NAME} ALIAS ${PROJECT_NAME}) + +include(CMakePackageConfigHelpers) -target_include_directories(${LIB_TARGET_NAME} +target_include_directories(${PROJECT_NAME} PUBLIC $ PRIVATE $ ) -target_link_libraries(${LIB_TARGET_NAME} +target_link_libraries(${PROJECT_NAME} PRIVATE - Qt5::Core - Qt5::Network + Qt::Core + Qt::Network ) -set_target_properties(${LIB_TARGET_NAME} +set_target_properties(${PROJECT_NAME} PROPERTIES - AUTOMOC ON - AUTORCC ON - OUTPUT_NAME ${LIB_TARGET_NAME} - PROJECT_LABEL ${LIB_TARGET_NAME} + OUTPUT_NAME ${PROJECT_NAME} + PROJECT_LABEL ${PROJECT_NAME} FOLDER src SOVERSION ${PROJECT_VERSION_MAJOR} VERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} - PUBLIC_HEADER ${HEADERS} DEBUG_POSTFIX _debug + CMAKE_AUTORCC ON + CMAKE_AUTOMOC ON + CMAKE_AUTOUIC ON ) -target_compile_features(${LIB_TARGET_NAME} PUBLIC cxx_std_17) - -target_compile_options(${LIB_TARGET_NAME} PRIVATE $<$:/MP>) +target_compile_options(${PROJECT_NAME} + PRIVATE + $<$:/MP /WX /W4> + $<$>:-Wall -Wextra -Werror> +) # Create source groups. -source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES - ${HEADERS} - ${SOURCES} +source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} + FILES + ${HEADERS} + ${SOURCES} ) # Select correct startup project in Visual Studio. if(WIN32) - set_property(DIRECTORY PROPERTY VS_STARTUP_PROJECT ${LIB_TARGET_NAME}) + set_property(DIRECTORY PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME}) endif() + +# Install target +configure_package_config_file( + "${CMAKE_CURRENT_SOURCE_DIR}/../cmake/config.cmake.in" + "${CMAKE_BINARY_DIR}/cmake/${PROJECT_NAME}Config.cmake" + INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}" +) + +write_basic_package_version_file( + "${CMAKE_BINARY_DIR}/cmake/${PROJECT_NAME}ConfigVersion.cmake" + VERSION "${PROJECT_VERSION}" + COMPATIBILITY AnyNewerVersion +) + +install(TARGETS ${PROJECT_NAME} + EXPORT "${PROJECT_NAME}Targets" + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" + ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" + INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" +) + +install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include/" + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/" +) + +install(EXPORT "${PROJECT_NAME}Targets" + FILE "${PROJECT_NAME}Targets.cmake" + NAMESPACE ${PROJECT_NAME}:: + DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}" +) + +install(FILES + "${CMAKE_BINARY_DIR}/cmake/${PROJECT_NAME}Config.cmake" + "${CMAKE_BINARY_DIR}/cmake/${PROJECT_NAME}ConfigVersion.cmake" + DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}" +) + +export(EXPORT "${PROJECT_NAME}Targets" + FILE "${CMAKE_BINARY_DIR}/cmake/${PROJECT_NAME}Targets.cmake" + NAMESPACE ${PROJECT_NAME}:: +) diff --git a/src/source/oclero/LocalEndpoint.cpp b/src/source/oclero/LocalEndpoint.cpp index bffcd94..101646c 100644 --- a/src/source/oclero/LocalEndpoint.cpp +++ b/src/source/oclero/LocalEndpoint.cpp @@ -172,8 +172,7 @@ struct LocalEndpoint::Impl { return; const auto id = socket->socketDescriptor(); - auto& it = - serverClients.emplace_back(SocketConnectionInfo{ socket, static_cast(id) }); + serverClients.emplace_back(SocketConnectionInfo{ socket, static_cast(id) }); QObject::connect(socket, &QLocalSocket::destroyed, &owner, [this, socket]() { #if LOGCAT_LOCALENDPOINT @@ -182,17 +181,22 @@ struct LocalEndpoint::Impl { removeClient(socket); }); -#pragma warning(push) -#pragma warning(disable : 26812) // Warning about Qt not using enum class - QObject::connect( - socket, &QLocalSocket::errorOccurred, &owner, [this](QLocalSocket::LocalSocketError const errorCode) { +#if defined(_MSC_VER) +# pragma warning(push) +# pragma warning(disable : 26812) // Warning about Qt not using enum class +#endif + + QObject::connect(socket, &QLocalSocket::errorOccurred, &owner, [](QLocalSocket::LocalSocketError const errorCode) { #if LOGCAT_LOCALENDPOINT - qCDebug(LOGCAT_LOCALENDPOINT) << "[Server] Client error occurred:" << errorCode; + qCDebug(LOGCAT_LOCALENDPOINT) << "[Server] Client error occurred:" << errorCode; #else Q_UNUSED(errorCode); #endif - }); -#pragma warning(pop) + }); + +#if defined(_MSC_VER) +# pragma warning(pop) +#endif QObject::connect(socket, &QLocalSocket::disconnected, &owner, [this, socket]() { #if LOGCAT_LOCALENDPOINT @@ -249,7 +253,7 @@ struct LocalEndpoint::Impl { readClientHandshake(socketInfo); sendHandshakeToClient(socketInfo); // There is some bytes left to read: it should be the header. - if (socketInfo.socket->bytesAvailable() >= sizeof(SocketConnectionInfo::bodySize)) { + if (socketInfo.socket->bytesAvailable() >= static_cast(sizeof(SocketConnectionInfo::bodySize))) { readClientMessageHeader(socketInfo); } break; @@ -267,7 +271,7 @@ struct LocalEndpoint::Impl { void readClientHandshake(SocketConnectionInfo& socketInfo) const { socketInfo.pid = {}; - if (socketInfo.socket->bytesAvailable() < static_cast(sizeof(SocketConnectionInfo::pid))) { + if (socketInfo.socket->bytesAvailable() < static_cast(sizeof(SocketConnectionInfo::pid))) { return; } @@ -306,13 +310,14 @@ struct LocalEndpoint::Impl { socketInfo.step = Step::Body; // There is some bytes left to read: it should be the body. - if (socketInfo.socket->bytesAvailable() >= bodySize) { + if (socketInfo.socket->bytesAvailable() >= static_cast(bodySize)) { readClientMessageBody(socketInfo); } } void readClientMessageBody(SocketConnectionInfo& socketInfo) const { - if (socketInfo.socket->bytesAvailable() < socketInfo.bodySize || socketInfo.step != Step::Body) { + if (socketInfo.socket->bytesAvailable() < static_cast(socketInfo.bodySize) + || socketInfo.step != Step::Body) { // Wait for more bytes to be written. return; } @@ -382,15 +387,14 @@ struct LocalEndpoint::Impl { #if LOGCAT_LOCALENDPOINT qCDebug(LOGCAT_LOCALENDPOINT) << "[Client] Disconnecting from server"; #endif - client->disconnectFromServer(); - + const auto disconnectResult = client->waitForDisconnected(1000); if (client->state() != QLocalSocket::UnconnectedState) { - const auto disconnectResult = client->waitForDisconnected(1000); - #if LOGCAT_LOCALENDPOINT if (client->state() != QLocalSocket::UnconnectedState || !disconnectResult) { qCDebug(LOGCAT_LOCALENDPOINT) << "[Client] Error: can't disconnect from server. Code:" << client->error(); } +#else + Q_UNUSED(disconnectResult); #endif } } @@ -447,7 +451,7 @@ struct LocalEndpoint::Impl { case Step::Handshake: readServerHandshake(); // There is some bytes left to read: it should be the header. - if (clientSocketInfo.socket->bytesAvailable() >= sizeof(SocketConnectionInfo::bodySize)) { + if (clientSocketInfo.socket->bytesAvailable() >= static_cast(sizeof(SocketConnectionInfo::bodySize))) { readServerMessageHeader(); } break; @@ -464,7 +468,7 @@ struct LocalEndpoint::Impl { void readServerHandshake() { clientSocketInfo.id = 0u; - if (clientSocketInfo.socket->bytesAvailable() < (quint64) sizeof(SocketConnectionInfo::id)) { + if (clientSocketInfo.socket->bytesAvailable() < static_cast(sizeof(SocketConnectionInfo::id))) { return; } @@ -490,7 +494,7 @@ struct LocalEndpoint::Impl { void readServerMessageHeader() { clientSocketInfo.bodySize = {}; - if (client->bytesAvailable() < (quint64) sizeof(SocketConnectionInfo::bodySize)) { + if (client->bytesAvailable() < static_cast(sizeof(SocketConnectionInfo::bodySize))) { return; } @@ -506,13 +510,14 @@ struct LocalEndpoint::Impl { clientSocketInfo.bodySize = bodySize; // There is some bytes left to read: it should be the body. - if (client->bytesAvailable() >= bodySize) { + if (client->bytesAvailable() >= static_cast(bodySize)) { readServerMessageBody(); } } void readServerMessageBody() { - if (client->bytesAvailable() < clientSocketInfo.bodySize || clientSocketInfo.step != Step::Body) { + if (client->bytesAvailable() < static_cast(clientSocketInfo.bodySize) + || clientSocketInfo.step != Step::Body) { // Wait for more bytes to be written. return; } diff --git a/src/source/oclero/QtAppInstanceManager.cpp b/src/source/oclero/QtAppInstanceManager.cpp index 97f936c..60cf65f 100644 --- a/src/source/oclero/QtAppInstanceManager.cpp +++ b/src/source/oclero/QtAppInstanceManager.cpp @@ -50,14 +50,14 @@ QtAppInstanceManager::QtAppInstanceManager(QObject* parent) : QtAppInstanceManager(Mode::MultipleInstances, parent) {} QtAppInstanceManager::QtAppInstanceManager(Mode mode, QObject* parent) - : QtAppInstanceManager(Mode::MultipleInstances, AppExitMode::Auto, parent) {} + : QtAppInstanceManager(mode, AppExitMode::Auto, parent) {} QtAppInstanceManager::QtAppInstanceManager(Mode mode, AppExitMode appExitMode, QObject* parent) : QObject(parent) , _impl(new Impl(*this)) { _impl->mode = mode; _impl->appExitMode = appExitMode; - QTimer::singleShot(0, [this]() { + QTimer::singleShot(0, this, [this]() { _impl->quitIfRequired(); }); } diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 827f6f7..ab23a04 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,16 +1,12 @@ set(TESTS_TARGET_NAME ${PROJECT_NAME}Tests) -find_package(Qt5 - REQUIRED - Core - Test -) +find_package(Qt6 REQUIRED COMPONENTS Core Test) add_executable(${TESTS_TARGET_NAME}) set_target_properties(${TESTS_TARGET_NAME} PROPERTIES - AUTOMOC ON - AUTORCC ON + CMAKE_AUTOMOC ON + CMAKE_AUTORCC ON INTERNAL_CONSOLE ON EXCLUDE_FROM_ALL ON FOLDER tests @@ -31,13 +27,12 @@ target_include_directories(${TESTS_TARGET_NAME} target_link_libraries(${TESTS_TARGET_NAME} PRIVATE ${PROJECT_NAMESPACE}::${PROJECT_NAME} - Qt5::Core - Qt5::Test + Qt::Core + Qt::Test ) add_test(NAME ${TESTS_TARGET_NAME} COMMAND $ - WORKING_DIRECTORY $) + WORKING_DIRECTORY $ +) source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${TESTS_SOURCES}) - -target_deploy_qt(${TESTS_TARGET_NAME}) From 7f72b9105c16e9d0c532cd5b5af65814c7d5cb99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20Cl=C3=A9ro?= Date: Sat, 15 Mar 2025 11:46:28 +0100 Subject: [PATCH 2/3] Install Ninja on CI --- .github/workflows/macos.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index dd0e92f..80de5b1 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -18,6 +18,9 @@ jobs: - name: Check Out uses: actions/checkout@v4 + - name: Install Ninja + run: brew install ninja + - name: Install Qt uses: jurplel/install-qt-action@v4 with: From 3c0ea3607afe74ed33297e59bde0dd0564a93122 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20Cl=C3=A9ro?= Date: Sat, 15 Mar 2025 11:50:09 +0100 Subject: [PATCH 3/3] No need for semicolon with this macro --- src/source/oclero/LocalEndpoint.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/source/oclero/LocalEndpoint.cpp b/src/source/oclero/LocalEndpoint.cpp index 101646c..1040ea8 100644 --- a/src/source/oclero/LocalEndpoint.cpp +++ b/src/source/oclero/LocalEndpoint.cpp @@ -394,7 +394,7 @@ struct LocalEndpoint::Impl { qCDebug(LOGCAT_LOCALENDPOINT) << "[Client] Error: can't disconnect from server. Code:" << client->error(); } #else - Q_UNUSED(disconnectResult); + Q_UNUSED(disconnectResult) #endif } }