From c1666cf35052a6e8993eac30a4240517d2b16475 Mon Sep 17 00:00:00 2001 From: gitlost Date: Mon, 7 Oct 2024 16:04:22 +0100 Subject: [PATCH] GUI: use X11 (xcb) as platform instead of Wayland on Linux to avoid various weird behaviours tests: disable GUI-dependent tests (`TestQZint::renderTest()`) if ZINT_SANITIZE and on Linux for later versions of Qt (5 and 6) to avoid ASAN "detected memory leaks" errors on exit --- README.linux | 12 ++++++--- backend_qt/tests/test_qzint.cpp | 48 +++++++++++++++++++++++++-------- frontend_qt/main.cpp | 9 ++++++- 3 files changed, 53 insertions(+), 16 deletions(-) diff --git a/README.linux b/README.linux index ea36e12d..9f438206 100644 --- a/README.linux +++ b/README.linux @@ -1,5 +1,6 @@ -% README.linux 2024-09-29 -% Tested on Ubuntu 20.04.4 LTS, Ubuntu 22.04 LTS and Fedora Linux 40 (Workstation Edition) +% README.linux 2024-10-04 +% Tested on Ubuntu 20.04.4 LTS, Ubuntu 22.04 LTS, Ubuntu 24.04 LTS and +% Fedora Linux 40 (Workstation Edition) 1. Prerequisites for building zint ================================== @@ -45,6 +46,9 @@ or Fedora sudo dnf install mesa-libGL mesa-libGL-devel +zint-qt has issues running on Wayland so sets X11 as the Qt platform (via the environment variable +"QT_QPA_PLATFORM=xcb") on startup unless already set. + 2.1. Using Qt packages ---------------------- @@ -53,7 +57,7 @@ what their ever-changing names and contents are isn't. A complication is that zi components beyond the basic setup: Qt UI Tools (for dynamically loading the symbology-specific tabs), and Qt SVG (for rendering icons). -E.g. on Ubuntu 22.04 +E.g. on Ubuntu 22.04 or 24.04 sudo apt install qtbase5-dev qttools5-dev qttools5-dev-tools libqt5svg5-dev @@ -84,7 +88,7 @@ On Ubuntu/Debian you may need to install xinerama to run the tool: sudo apt install libxcb-xinerama0 Launch the tool and install the "Desktop gcc 64-bit" component for either Qt 5.15.2 (preferred) -or Qt 6 (>= 6.1, 6.2.4 preferably, and not >= 6.3 which are incompatible). +or Qt 6 (>= 6.1). Once Qt is installed you may need to tell CMake where it is: diff --git a/backend_qt/tests/test_qzint.cpp b/backend_qt/tests/test_qzint.cpp index 12bc917d..b1766c16 100644 --- a/backend_qt/tests/test_qzint.cpp +++ b/backend_qt/tests/test_qzint.cpp @@ -18,25 +18,44 @@ #include #include "../qzint.h" /* Don't use in case it's been changed */ -#ifndef ARRAY_SIZE #define ARRAY_SIZE(x) ((int) (sizeof(x) / sizeof((x)[0]))) + +// Whether using ZINT_SANITIZE +#if !defined(__has_feature) +# define __has_feature(x) 0 +#endif +#if defined(__SANITIZE_ADDRESS__) || __has_feature(address_sanitizer) +# define TESTQZINT_HAVE_ASAN #endif class TestQZint : public QObject { Q_OBJECT +// This avoids WaylandClient memory leaks for Qt5 > 5.15.2 (taken from "frontend_qt/main.cpp") +#if defined(__linux__) && QT_VERSION > 0x50F02 +public: + static void initMain() + { + /* Not compatible with Wayland for some reason(s) so use X11 unless overridden */ + if (qEnvironmentVariableIsEmpty("QT_QPA_PLATFORM")) { + qputenv("QT_QPA_PLATFORM", QByteArrayLiteral("xcb")); + } + } +#endif + public: TestQZint() : m_skipIfFontUsed(false) { - // Qt5 will trigger "detected memory leaks" if font used (libfontconfig) so skip if ASAN enabled -#if QT_VERSION < 0x60000 -# if !defined(__has_feature) -# define __has_feature(x) 0 -# endif -# if defined(__SANITIZE_ADDRESS__) || __has_feature(address_sanitizer) + // Qt will trigger "detected memory leaks" if font used (libfontconfig) so skip if ASAN enabled +#ifdef TESTQZINT_HAVE_ASAN m_skipIfFontUsed = true; -# endif +#endif + // Unfortunately Qt5 > 5.15.13 & Qt6 > 6.4.2 have further libfontconfig leaks which this doesn't address... + // ...only option found so far is to use `QTEST_GUILESS_MAIN()` and skip `renderTest()` completely +#if defined(__linux__) && ((QT_VERSION > 0x50F0D && QT_VERSION < 0x60000) || QT_VERSION > 0x60402) \ + && defined(TESTQZINT_HAVE_ASAN) +#define TESTQZINT_GUILESS #endif } @@ -414,18 +433,21 @@ private slots: QTest::addColumn("vectorHeight"); QTest::newRow("BARCODE_CODE128") << BARCODE_CODE128 << "1234" << 0.0f << 0 << "" << 57 << 1 << 50.0f << 114.0f << 100.0f; - QTest::newRow("BARCODE_CODE128") << BARCODE_CODE128 << "1234" << 2.0f << 0 << "" << 57 << 1 << 50.0f << 228.0f << 200.0f; + QTest::newRow("BARCODE_CODE128 Scale 2") << BARCODE_CODE128 << "1234" << 2.0f << 0 << "" << 57 << 1 << 50.0f << 228.0f << 200.0f; QTest::newRow("BARCODE_QRCODE") << BARCODE_QRCODE << "1234" << 0.0f << 0 << "" << 21 << 21 << 21.0f << 42.0f << 42.0f; - QTest::newRow("BARCODE_QRCODE") << BARCODE_QRCODE << "1234" << 1.5f << 0 << "" << 21 << 21 << 21.0f << 63.0f << 63.0f; + QTest::newRow("BARCODE_QRCODE Scale 1.5") << BARCODE_QRCODE << "1234" << 1.5f << 0 << "" << 21 << 21 << 21.0f << 63.0f << 63.0f; if (!m_skipIfFontUsed) { QTest::newRow("BARCODE_QRCODE no text") << BARCODE_QRCODE << "" << 0.0f << ZINT_ERROR_INVALID_DATA << "Error 778: No input data (segment 0 empty)" << 0 << 0 << 0.0f << 0.0f << 0.0f; } QTest::newRow("BARCODE_MAXICODE") << BARCODE_MAXICODE << "1234" << 0.0f << 0 << "" << 30 << 33 << 28.578f << 60.0f << 57.7334f; - QTest::newRow("BARCODE_MAXICODE") << BARCODE_MAXICODE << "1234" << 2.0f << 0 << "" << 30 << 33 << 28.578f << 120.0f << 115.467f; + QTest::newRow("BARCODE_MAXICODE Scale 2") << BARCODE_MAXICODE << "1234" << 2.0f << 0 << "" << 30 << 33 << 28.578f << 120.0f << 115.467f; } void renderTest() { +#ifdef TESTQZINT_GUILESS + QSKIP("disabled on Linux for Qt5 > 5.15.13 & Qt6 > 6.4.2 due to memory leaks (ZINT_SANITIZE)"); +#endif Zint::QZint bc; bool bRet; @@ -1369,7 +1391,11 @@ private slots: } }; +#ifdef TESTQZINT_GUILESS +QTEST_GUILESS_MAIN(TestQZint) +#else QTEST_MAIN(TestQZint) +#endif #include "test_qzint.moc" /* vim: set ts=4 sw=4 et : */ diff --git a/frontend_qt/main.cpp b/frontend_qt/main.cpp index 2edfe6bf..45df9003 100644 --- a/frontend_qt/main.cpp +++ b/frontend_qt/main.cpp @@ -1,6 +1,6 @@ /*************************************************************************** * Copyright (C) 2008 by BogDan Vatra * - * Copyright (C) 2009-2022 by Robin Stuart * + * Copyright (C) 2009-2024 by Robin Stuart * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * @@ -21,6 +21,13 @@ int main(int argc, char *argv[]) { Q_INIT_RESOURCE(resources); +#if defined(__linux__) && QT_VERSION > 0x50F02 + /* Not compatible with Wayland for some reason(s) so use X11 unless overridden */ + if (qEnvironmentVariableIsEmpty("QT_QPA_PLATFORM")) { + qputenv("QT_QPA_PLATFORM", QByteArrayLiteral("xcb")); + } +#endif + #if QT_VERSION >= 0x50600 && QT_VERSION < 0x60100 QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling); #endif