How to build Qt 5.15.2 for Vortex Studio

How to build Qt 5.15.2 for Vortex Studio

Introduction

Vortex Studio uses Qt's technologies for creating its multiple user interfaces. Several Qt pages show how to build Qt 5.15 with third parties (https://doc.qt.io/qt-5/build-sources.html)

In Vortex Studio, Qt 5.15.2 source is specifically linked with additional versions of Perl and XCB libraries (for Linux build)  and built into binary libraries with specific Qt's configurations. Changes were made to fix some small issues found in this version of the source code. The changes are listed in the section Patches for Qt 5.15.2 used in Vortex Studio.

The following sections detail steps by steps on how to build Qt 5.15.2.

System requirements

  • VS2019 C++ compiler

  • Python 2.7

Package downloads

Build Qt 5.15.2 for Windows

1) Run strawberry-perl-5.32.0.1-64bit.msi to install

2) Create a folder (e.g. c:\qt515_for_windows)

3) Unzip the content of Qt 5.15.2 package to a specified folder (e.g. c:\qt515_for_windows\qt5.15.2)

4) Apply patches listed in the section Patches for Qt 5.15.2 used in Vortex Studio.

5) Create a file named Makefile in the folder created in step #2 with this content

Makefile for building Qt5.15.2 for Windows
CURRENTDIR:=$(shell pwd) makeit: qt515 ; TOOLCHAIN:=x64_win32_vc14 export INCLUDE:=$(CURRENTDIR)\stage_qt5_$(TOOLCHAIN)\include;$(INCLUDE) export LIB:=$(CURRENTDIR)\stage_qt5_$(TOOLCHAIN)\lib;$(LIB) qt515: (mkdir build_qt5_$(TOOLCHAIN) & cd build_qt5_$(TOOLCHAIN) && \ $(CURRENTDIR)\qt5.15.2\configure -debug-and-release -force-debug-info -recheck -shared -opensource -confirm-license -no-system-proxies -openssl -opengl desktop -skip qtwebengine -nomake tests -nomake examples -prefix $(CURRENTDIR)\stage_qt5_$(TOOLCHAIN)) .PHONY: qt515


7) Open the VS2015 x64 Native Tools Command Prompt as an administrator.

FindVS2015x64NativeToolsCmdPrompt.png

 

8) In the command prompt, run:

> make

Build Qt 5.15.1 for Linux

Linux still uses 5.15.1. Follow the download instruction but replace 5.15.2 for 5.15.1.

1) Make sure Perl is installed. Type the following to find out which version

      > perl -v

2) Create a folder (e.g. c:\qt515_for_windows)

3) Start a Terminal

4) Unzip the content of Qt5.15.1 package to a specified folder (e.g. c:\qt515_for_windows\qt5.15.1)

5) Apply patches listed in the section Patches for Qt 5.15.1 used in Vortex Studio.

6) Execute the following commands:

       > cd c:\qt515_for_windows\qt5.15.1

       > find ./ -type f -exec dos2unix {} \;

               > sudo su -

               > yum install libxcb libxcb-devel xcb-util xcb-util-devel libxkbcommon-devel libxkbcommon-x11-devel xcb-util-keysyms-devel xcb-util-wm-devel xcb-util-image-devel xcb-util-renderutil-devel mesa-libGL-devel



7) Create a file named Makefile in the folder created in step #2 with this content

Makefile for building Qt5.15.1 for Linux
CURRENTDIR:=$(shell pwd) makeit: qt515 ; TOOLCHAIN:=x64_rhel7_gcc73 export INCLUDE:=$(CURRENTDIR)/stage_qt5_$(TOOLCHAIN)/include;$(INCLUDE) export LIB:=$(CURRENTDIR)/stage_qt5_$(TOOLCHAIN)/lib;$(LIB) qt515: (mkdir -p build_qt5_$(TOOLCHAIN) && cd build_qt5_$(TOOLCHAIN) && \ chmod +x $(CURRENTDIR)/qt5/configure && \ chmod +x $(CURRENTDIR)/qt5/qtbase/configure && \ $(CURRENTDIR)/qt5.15.1/configure -shared -opensource -confirm-license -xcb -xcb-xlib -bundled-xcb-xinput -no-system-proxies -openssl -opengl desktop -skip qtwebengine -nomake tests -nomake examples -prefix $(CURRENTDIR)/stage_qt5_$(TOOLCHAIN) && \ $(MAKE) && \ $(MAKE) install) .PHONY: qt515

7) In the Terminal, run:

> make

Patches for Qt 5.15.2 used in Vortex Studio

The following changes were made in the original Qt 5.15.2 source to fix some small issues found in the source.

Patch #1

\\qtbase\src\gui\kernel\qoffscreensurface.cpp

Line 201: Added a check for valid qGuiApp 
if (qGuiApp && QThread::currentThread() != qGuiApp->thread())

Patch #2

\\qtbase\src\corelib\kernel\qcoreapplication.cpp: 

Line 1156: Use a copy of extraData→eventFilters
bool QCoreApplicationPrivate::sendThroughApplicationEventFilters(QObject *receiver, QEvent *event) { if (extraData) { auto eventFiltersCopy = extraData->eventFilters; // application event filters are only called for objects in the GUI thread for (int i = 0; i < eventFiltersCopy.size(); ++i) { QObject *obj = eventFiltersCopy.at(i); if (!obj) continue; if (obj->d_func()->threadData != threadData) { qWarning("QCoreApplication: Application event filter cannot be in a different thread."); continue; } if (obj->eventFilter(receiver, event)) return true; } } return false; }

Patch #3:

\\qt5\qtbase\src\gui\painting\qpaintengineex.cpp

Line 55: Change made to QT_MAX_CACHED_GLYPH_SIZE
# define QT_MAX_CACHED_GLYPH_SIZE 512

\\qt5\qtbase\src\widgets\accessible\simplewidgets.cpp

Line 221: in the function QAccessibleButton::role(), added a check for valid ab variable
QAccessible::Role QAccessibleButton::role() const { QAbstractButton *ab = button(); if (ab) { #if QT_CONFIG(menu) if (QPushButton *pb = qobject_cast<QPushButton*>(ab)) { if (pb->menu()) return QAccessible::ButtonMenu; } #endif if (ab->isCheckable()) return ab->autoExclusive() ? QAccessible::RadioButton : QAccessible::CheckBox; } return QAccessible::Button; }
Line 346: in the function QAccessibleToolButton::role(), added a check for valid ab variable
QAccessible::Role QAccessibleToolButton::role() const { #if QT_CONFIG(menu) QAbstractButton *ab = button(); if (ab) { QToolButton *tb = qobject_cast<QToolButton *>(ab); if (!tb->menu()) return tb->isCheckable() ? QAccessible::CheckBox : QAccessible::PushButton; else if (tb->popupMode() == QToolButton::DelayedPopup) return QAccessible::ButtonDropDown; } #endif return QAccessible::ButtonMenu; }

Patch #4: 

\\qtbase\src\widgets\styles\qstylesheetstyle.cpp:

Line 5827 & 5828: Replace these 2 lines with the following:
if (rule.hasBox() || !rule.hasNativeBorder()) { return visualRect(opt->direction, opt->rect, se == SE_PushButtonBevel ? rule.borderRect(opt->rect) : rule.contentsRect(opt->rect)); }

Patch #5:

qtbase/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp

Line 63: add include
#include <QtCore/qmutex.h>
Line 74: add static mutex in anonymous namespace
namespace { static QMutex mutex; }
Line 86: add mutex locker in QWindowsUiaMainProvider::providerForAccessible()
QWindowsUiaMainProvider *QWindowsUiaMainProvider::providerForAccessible(QAccessibleInterface *accessible) { QMutexLocker locker(&mutex); ...
Line 274: add mutex locker in QWindowsUiaMainProvider::Release()
ULONG STDMETHODCALLTYPE QWindowsUiaMainProvider::Release() { QMutexLocker locker(&mutex); ...

qtbase/src/plugins/platforms/windows/uiautomation/qwindowsuiaprovidercache.cpp

Line 78: make connection a direct connection by adding a Qt::DirectConnection argument to the connect()
QObject::connect(provider, &QObject::destroyed, this, &QWindowsUiaProviderCache::objectDestroyed, Qt::DirectConnection);