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
This commit is contained in:
gitlost 2024-10-07 16:04:22 +01:00
parent 34be69d241
commit c1666cf350
3 changed files with 53 additions and 16 deletions

View File

@ -1,5 +1,6 @@
% README.linux 2024-09-29 % README.linux 2024-10-04
% Tested on Ubuntu 20.04.4 LTS, Ubuntu 22.04 LTS and Fedora Linux 40 (Workstation Edition) % 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 1. Prerequisites for building zint
================================== ==================================
@ -45,6 +46,9 @@ or Fedora
sudo dnf install mesa-libGL mesa-libGL-devel 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 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 components beyond the basic setup: Qt UI Tools (for dynamically loading the symbology-specific
tabs), and Qt SVG (for rendering icons). 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 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 sudo apt install libxcb-xinerama0
Launch the tool and install the "Desktop gcc 64-bit" component for either Qt 5.15.2 (preferred) 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: Once Qt is installed you may need to tell CMake where it is:

View File

@ -18,25 +18,44 @@
#include <QtTest/QTest> #include <QtTest/QTest>
#include "../qzint.h" /* Don't use <qzint.h> in case it's been changed */ #include "../qzint.h" /* Don't use <qzint.h> in case it's been changed */
#ifndef ARRAY_SIZE
#define ARRAY_SIZE(x) ((int) (sizeof(x) / sizeof((x)[0]))) #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 #endif
class TestQZint : public QObject class TestQZint : public QObject
{ {
Q_OBJECT 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: public:
TestQZint() : m_skipIfFontUsed(false) TestQZint() : m_skipIfFontUsed(false)
{ {
// Qt5 will trigger "detected memory leaks" if font used (libfontconfig) so skip if ASAN enabled // Qt will trigger "detected memory leaks" if font used (libfontconfig) so skip if ASAN enabled
#if QT_VERSION < 0x60000 #ifdef TESTQZINT_HAVE_ASAN
# if !defined(__has_feature)
# define __has_feature(x) 0
# endif
# if defined(__SANITIZE_ADDRESS__) || __has_feature(address_sanitizer)
m_skipIfFontUsed = true; 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 #endif
} }
@ -414,18 +433,21 @@ private slots:
QTest::addColumn<float>("vectorHeight"); QTest::addColumn<float>("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" << 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" << 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) { 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_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" << 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() 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; Zint::QZint bc;
bool bRet; bool bRet;
@ -1369,7 +1391,11 @@ private slots:
} }
}; };
#ifdef TESTQZINT_GUILESS
QTEST_GUILESS_MAIN(TestQZint)
#else
QTEST_MAIN(TestQZint) QTEST_MAIN(TestQZint)
#endif
#include "test_qzint.moc" #include "test_qzint.moc"
/* vim: set ts=4 sw=4 et : */ /* vim: set ts=4 sw=4 et : */

View File

@ -1,6 +1,6 @@
/*************************************************************************** /***************************************************************************
* Copyright (C) 2008 by BogDan Vatra <bogdan@licentia.eu> * * Copyright (C) 2008 by BogDan Vatra <bogdan@licentia.eu> *
* Copyright (C) 2009-2022 by Robin Stuart <rstuart114@gmail.com> * * Copyright (C) 2009-2024 by Robin Stuart <rstuart114@gmail.com> *
* * * *
* This program is free software: you can redistribute it and/or modify * * 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 * * 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); 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 #if QT_VERSION >= 0x50600 && QT_VERSION < 0x60100
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif #endif