From 4c3fe50f0e0febf730da26278212ba80eeb4bf30 Mon Sep 17 00:00:00 2001 From: DonC Date: Wed, 26 Jan 2022 13:11:49 +0100 Subject: [PATCH 01/13] Build: Add missing includes Those seem to have been missing all the time without causing issues. Required for Qt6 compatibility. Co-authored-by: Christian Hoffmann --- src/clientdlg.h | 1 + src/recorder/cwavestream.h | 2 ++ 2 files changed, 3 insertions(+) diff --git a/src/clientdlg.h b/src/clientdlg.h index bbcc604766..21021e1a60 100644 --- a/src/clientdlg.h +++ b/src/clientdlg.h @@ -37,6 +37,7 @@ #include #include #include +#include #if QT_VERSION >= QT_VERSION_CHECK( 5, 6, 0 ) # include #endif diff --git a/src/recorder/cwavestream.h b/src/recorder/cwavestream.h index 708304b8dd..d10e72885f 100644 --- a/src/recorder/cwavestream.h +++ b/src/recorder/cwavestream.h @@ -25,6 +25,8 @@ #pragma once #include +#include +#include namespace recorder { From 4924b7233c011036018d65afb1fbf312b6c92296 Mon Sep 17 00:00:00 2001 From: DonC Date: Wed, 26 Jan 2022 13:16:17 +0100 Subject: [PATCH 02/13] Build: Drop endl usage Standard `endl` can no longer be combined with Qt6 streams. Qt6 suggests using `Qt::endl`. However, the latter is only available as of Qt 5.14. Instead of sprinkling #ifdefs all around or introducing an unreadable ENDL #define with version-specific code, simply use '\n' in place of `endl`. `endl` is also responsible for flushing the stream, but all affected places either flush explicitly anyway or implicitly close the file, so we should be safe against changes in behavior. Co-authored-by: Tony Mountifield Co-authored-by: Peter L Jones Co-authored-by: Christian Hoffmann --- src/recorder/creaperproject.cpp | 48 ++++++++++++++++----------------- src/recorder/jamrecorder.cpp | 6 ++--- src/serverlist.cpp | 2 +- src/serverlogging.cpp | 4 +-- src/util.h | 2 +- 5 files changed, 31 insertions(+), 31 deletions(-) diff --git a/src/recorder/creaperproject.cpp b/src/recorder/creaperproject.cpp index 6c1213dd68..20c722131c 100644 --- a/src/recorder/creaperproject.cpp +++ b/src/recorder/creaperproject.cpp @@ -62,21 +62,21 @@ CReaperItem::CReaperItem ( const QString& name, const STrackItem& trackItem, con QTextStream sOut ( &out ); - sOut << " " << endl; - - sOut << " >"; + sOut << " " << '\n' + + << " >"; sOut.flush(); } @@ -91,14 +91,14 @@ CReaperTrack::CReaperTrack ( QString name, qint32& iid, QList items, { QTextStream sOut ( &out ); - sOut << " > tracks, int fr { QTextStream sOut ( &out ); - sOut << ""; diff --git a/src/recorder/jamrecorder.cpp b/src/recorder/jamrecorder.cpp index 95294ae428..930f21b353 100644 --- a/src/recorder/jamrecorder.cpp +++ b/src/recorder/jamrecorder.cpp @@ -479,7 +479,7 @@ void CJamRecorder::ReaperProjectFromCurrentSession() if ( outf.open ( QFile::WriteOnly ) ) { QTextStream out ( &outf ); - out << CReaperProject ( currentSession->Tracks(), iServerFrameSizeSamples ).toString() << endl; + out << CReaperProject ( currentSession->Tracks(), iServerFrameSizeSamples ).toString() << '\n'; qDebug() << "Session RPP:" << reaperProjectFileName; } else @@ -511,7 +511,7 @@ void CJamRecorder::AudacityLofFromCurrentSession() { QFileInfo fi ( item.fileName ); sOut << "file " << '"' << fi.fileName() << '"'; - sOut << " offset " << secondsAt48K ( item.startFrame, iServerFrameSizeSamples ) << endl; + sOut << " offset " << secondsAt48K ( item.startFrame, iServerFrameSizeSamples ) << '\n'; } } @@ -556,7 +556,7 @@ void CJamRecorder::SessionDirToReaper ( QString& strSessionDirName, int serverFr out << CReaperProject ( CJamSession::TracksFromSessionDir ( fiSessionDir.absoluteFilePath(), serverFrameSizeSamples ), serverFrameSizeSamples ) .toString() - << endl; + << '\n'; qDebug() << "Session RPP:" << reaperProjectFileName; } diff --git a/src/serverlist.cpp b/src/serverlist.cpp index 3f93bc6943..b3c2987688 100644 --- a/src/serverlist.cpp +++ b/src/serverlist.cpp @@ -771,7 +771,7 @@ void CServerListManager::Save() .arg ( ServerList[iIdx].HostAddr.toString() ) .arg ( ServerList[iIdx].LHostAddr.toString() ) .arg ( ServerList[iIdx].strName ) ); - out << ServerList[iIdx].toCSV() << "\n"; + out << ServerList[iIdx].toCSV() << '\n'; } } diff --git a/src/serverlogging.cpp b/src/serverlogging.cpp index 8d5732bf42..c88f951c79 100644 --- a/src/serverlogging.cpp +++ b/src/serverlogging.cpp @@ -70,8 +70,8 @@ void CServerLogging::operator<< ( const QString& sNewStr ) { // append new line in logging file QTextStream out ( &File ); - out << sNewStr << endl; - File.flush(); + out << sNewStr << '\n'; + out.flush(); } } diff --git a/src/util.h b/src/util.h index 4a546781c9..650d93b9b8 100644 --- a/src/util.h +++ b/src/util.h @@ -1213,7 +1213,7 @@ class CTimingMeas for ( int i = 0; i < iNumMeas; i++ ) { // convert ns in ms and store the value - streamFile << i << " " << static_cast ( vElapsedTimes[i] ) / 1000000 << endl; + streamFile << i << " " << static_cast ( vElapsedTimes[i] ) / 1000000 << "\n"; } } } From 1a9f6d635c5816938868291e6d4301a67431bb4b Mon Sep 17 00:00:00 2001 From: DonC Date: Wed, 26 Jan 2022 13:22:25 +0100 Subject: [PATCH 03/13] Build: Drop legacy QVBoxLayout->setMargin usage QVBoxLayout->setMargin() is deprecated even in Qt5. Replace it with setContentsMargins(). Required for Qt6 compatibility. --- src/levelmeter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/levelmeter.cpp b/src/levelmeter.cpp index 9eb126fe94..fccafe44d5 100644 --- a/src/levelmeter.cpp +++ b/src/levelmeter.cpp @@ -34,7 +34,7 @@ CLevelMeter::CLevelMeter ( QWidget* parent ) : QWidget ( parent ), eLevelMeterTy QWidget* pLEDMeter = new QWidget(); QVBoxLayout* pLEDLayout = new QVBoxLayout ( pLEDMeter ); pLEDLayout->setAlignment ( Qt::AlignHCenter ); - pLEDLayout->setMargin ( 0 ); + pLEDLayout->setContentsMargins ( 0, 0, 0, 0 ); pLEDLayout->setSpacing ( 0 ); // create LEDs plus the clip LED From e19b63082765ebddb0c5ee84c83718f9b03ff5a7 Mon Sep 17 00:00:00 2001 From: DonC Date: Wed, 26 Jan 2022 13:26:42 +0100 Subject: [PATCH 04/13] Build: server: Drop unused QtConcurrent include This is likely a leftover from the time where multithreading code was switched from QtConcurrent to Futures. --- src/server.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/server.h b/src/server.h index a90c64b47e..c76aa99147 100644 --- a/src/server.h +++ b/src/server.h @@ -29,7 +29,6 @@ #include #include #include -#include #include #ifdef USE_OPUS_SHARED_LIB # include "opus/opus_custom.h" From e076754a4e513c75da940f3bc1d7c65e7c0dfe22 Mon Sep 17 00:00:00 2001 From: Christian Hoffmann Date: Wed, 26 Jan 2022 13:28:31 +0100 Subject: [PATCH 05/13] Build: Improve eSvrRegStatus debug logging This is required for Qt6 compatibility. The old syntax would have required conversions for Qt6 instead. --- src/util.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util.h b/src/util.h index 650d93b9b8..99851dc2d2 100644 --- a/src/util.h +++ b/src/util.h @@ -648,7 +648,7 @@ inline QString svrRegStatusToString ( ESvrRegStatus eSvrRegStatus ) return QCoreApplication::translate ( "CServerDlg", "Requirements not fulfilled" ); } - return QString ( QCoreApplication::translate ( "CServerDlg", "Unknown value " ) ).append ( eSvrRegStatus ); + return QString ( QCoreApplication::translate ( "CServerDlg", "Unknown value %1" ) ).arg ( eSvrRegStatus ); } // Directory server registration outcome --------------------------------------- From ff1d5f1a816aac516a91be2effd245b462b965cd Mon Sep 17 00:00:00 2001 From: Christian Hoffmann Date: Wed, 26 Jan 2022 13:33:01 +0100 Subject: [PATCH 06/13] Mac: Use native Dock Badge handling This commit replaces the deprecated use of Qt5 macextras by a small ObjC integration into the native methods. The macextras build option and dependency is removed accordingly. This is required for Qt6 compatibility, because Qt6 no longer ships macextras and suggests going the path that this commit goes. To avoid duplicated maintenance, the switch is done indepdendent of the Qt version as the new code should work on Qt5 as well. --- .github/autobuild/mac.sh | 2 +- Jamulus.pro | 8 ++++---- mac/badgelabel.h | 27 +++++++++++++++++++++++++++ mac/badgelabel.mm | 29 +++++++++++++++++++++++++++++ src/clientdlg.cpp | 7 ++----- src/clientdlg.h | 6 ++---- 6 files changed, 65 insertions(+), 14 deletions(-) create mode 100644 mac/badgelabel.h create mode 100644 mac/badgelabel.mm diff --git a/.github/autobuild/mac.sh b/.github/autobuild/mac.sh index a38cc393e7..abf9ccc372 100755 --- a/.github/autobuild/mac.sh +++ b/.github/autobuild/mac.sh @@ -19,7 +19,7 @@ setup() { else echo "Installing Qt..." python3 -m pip install "aqtinstall==${AQTINSTALL_VERSION}" - python3 -m aqt install-qt --outputdir "${QT_DIR}" mac desktop "${QT_VERSION}" --archives qtbase qttools qttranslations qtmacextras + python3 -m aqt install-qt --outputdir "${QT_DIR}" mac desktop "${QT_VERSION}" --archives qtbase qttools qttranslations fi } diff --git a/Jamulus.pro b/Jamulus.pro index a6d8dbc05c..9eea58bff2 100644 --- a/Jamulus.pro +++ b/Jamulus.pro @@ -154,9 +154,8 @@ win32 { RC_FILE = mac/mainicon.icns } - QT += macextras - HEADERS += mac/activity.h - OBJECTIVE_SOURCES += mac/activity.mm + HEADERS += mac/activity.h mac/badgelabel.h + OBJECTIVE_SOURCES += mac/activity.mm mac/badgelabel.mm CONFIG += x86 QMAKE_TARGET_BUNDLE_PREFIX = io.jamulus @@ -185,7 +184,8 @@ win32 { -framework CoreMIDI \ -framework AudioToolbox \ -framework AudioUnit \ - -framework Foundation + -framework Foundation \ + -framework AppKit contains(CONFIG, "jackonmac") { message(Using JACK.) diff --git a/mac/badgelabel.h b/mac/badgelabel.h new file mode 100644 index 0000000000..31c243d1ed --- /dev/null +++ b/mac/badgelabel.h @@ -0,0 +1,27 @@ +/******************************************************************************\ + * Copyright (c) 2022 + * + * Author(s): + * The Jamulus Development Team + * + ****************************************************************************** + * + * 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 the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * +\******************************************************************************/ + +#include + +void SetMacBadgeLabelText ( const QString& text ); diff --git a/mac/badgelabel.mm b/mac/badgelabel.mm new file mode 100644 index 0000000000..d6d0101643 --- /dev/null +++ b/mac/badgelabel.mm @@ -0,0 +1,29 @@ +/******************************************************************************\ + * Copyright (c) 2022 + * + * Author(s): + * The Jamulus Development Team + * + ****************************************************************************** + * + * 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 the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * +\******************************************************************************/ + +#include "badgelabel.h" +#import +#import + +void SetMacBadgeLabelText ( const QString& text ) { [[[NSApplication sharedApplication] dockTile] setBadgeLabel:text.toNSString()]; } diff --git a/src/clientdlg.cpp b/src/clientdlg.cpp index c94c03b707..96a4d8b5a9 100644 --- a/src/clientdlg.cpp +++ b/src/clientdlg.cpp @@ -938,19 +938,16 @@ void CClientDlg::SetMyWindowTitle ( const int iNumClients ) #if defined( Q_OS_MACX ) // for MacOS only we show the number of connected clients as a // badge label text if more than one user is connected - // (only available in Qt5.2) -# if QT_VERSION >= QT_VERSION_CHECK( 5, 2, 0 ) if ( iNumClients > 1 ) { // show the number of connected clients - QtMac::setBadgeLabelText ( QString ( "%1" ).arg ( iNumClients ) ); + SetMacBadgeLabelText ( QString ( "%1" ).arg ( iNumClients ) ); } else { // clear the text (apply an empty string) - QtMac::setBadgeLabelText ( "" ); + SetMacBadgeLabelText ( "" ); } -# endif #endif } diff --git a/src/clientdlg.h b/src/clientdlg.h index 21021e1a60..e7e8ac1e8b 100644 --- a/src/clientdlg.h +++ b/src/clientdlg.h @@ -52,10 +52,8 @@ #include "connectdlg.h" #include "analyzerconsole.h" #include "ui_clientdlgbase.h" -#if defined( __APPLE__ ) || defined( __MACOSX ) -# if QT_VERSION >= QT_VERSION_CHECK( 5, 2, 0 ) -# include -# endif +#if defined( Q_OS_MACX ) +# include "mac/badgelabel.h" #endif /* Definitions ****************************************************************/ From f0dc0f0e7500dd683bea485f52360cdf55a406db Mon Sep 17 00:00:00 2001 From: DonC Date: Wed, 26 Jan 2022 23:51:18 +0100 Subject: [PATCH 07/13] Build: Handle new Qt6 QtConcurrent::run signature QtConcurrent::run() has a different parameter order in Qt6. Required for Qt6 compatibility. Co-authored-by: Christian Hoffmann --- src/connectdlg.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/connectdlg.cpp b/src/connectdlg.cpp index 60e0804bf7..855c7099d3 100644 --- a/src/connectdlg.cpp +++ b/src/connectdlg.cpp @@ -750,7 +750,12 @@ void CConnectDlg::OnTimerPing() bEnableIPv6 ) ) { // if address is valid, send ping message using a new thread +#if QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 ) + QFuture f = QtConcurrent::run ( &CConnectDlg::EmitCLServerListPingMes, this, haServerAddress ); + Q_UNUSED ( f ); +#else QtConcurrent::run ( this, &CConnectDlg::EmitCLServerListPingMes, haServerAddress ); +#endif } } } From e0555ec1526fda250f2827c3800df2c07b376054 Mon Sep 17 00:00:00 2001 From: Christian Hoffmann Date: Sat, 16 Apr 2022 21:47:38 +0200 Subject: [PATCH 08/13] Build: Force cross-platform main() usage on MSVC with Qt6 Qt5 had a special qtmain library which took care of forwarding the MSVC default WinMain() entrypoint to the platform-agnostic main(). Qt6 is still supposed to have that lib under the new name QtEntryPoint. As it does not seem to be effective when building with qmake, we are rather instructing MSVC to use the platform-agnostic main() entrypoint directly. Without this change, building fails. --- Jamulus.pro | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Jamulus.pro b/Jamulus.pro index 9eea58bff2..d42e8af480 100644 --- a/Jamulus.pro +++ b/Jamulus.pro @@ -88,6 +88,14 @@ win32 { advapi32.lib \ winmm.lib \ ws2_32.lib + greaterThan(QT_MAJOR_VERSION, 5) { + # Qt5 had a special qtmain library which took care of forwarding the MSVC default WinMain() entrypoint to + # the platform-agnostic main(). + # Qt6 is still supposed to have that lib under the new name QtEntryPoint. As it does not seem + # to be effective when building with qmake, we are rather instructing MSVC to use the platform-agnostic + # main() entrypoint directly: + QMAKE_LFLAGS += /subsystem:windows /ENTRY:mainCRTStartup + } } contains(CONFIG, "serveronly") { From 8ffcb66203e136740c21fe5ebe4a08b034c2a1cd Mon Sep 17 00:00:00 2001 From: Christian Hoffmann Date: Sun, 6 Feb 2022 18:50:19 +0100 Subject: [PATCH 09/13] Code: Use early returns to avoid deep nesting --- src/clientsettingsdlg.cpp | 29 +++++++++++++++-------------- src/serverdlg.cpp | 9 +++++---- 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/src/clientsettingsdlg.cpp b/src/clientsettingsdlg.cpp index 78f2353b50..8dd5bdc83f 100644 --- a/src/clientsettingsdlg.cpp +++ b/src/clientsettingsdlg.cpp @@ -561,21 +561,22 @@ CClientSettingsDlg::CClientSettingsDlg ( CClient* pNCliP, CClientSettings* pNSet for ( int iCurCntry = static_cast ( QLocale::AnyCountry ); iCurCntry < static_cast ( QLocale::LastCountry ); iCurCntry++ ) { // exclude the "None" entry since it is added after the sorting - if ( static_cast ( iCurCntry ) != QLocale::AnyCountry ) + if ( static_cast ( iCurCntry ) == QLocale::AnyCountry ) { - // get current country enum - QLocale::Country eCountry = static_cast ( iCurCntry ); - - // try to load icon from resource file name - QIcon CurFlagIcon; - CurFlagIcon.addFile ( CLocale::GetCountryFlagIconsResourceReference ( eCountry ) ); - - // only add the entry if a flag is available - if ( !CurFlagIcon.isNull() ) - { - // create a combo box item with text and image - pcbxCountry->addItem ( QIcon ( CurFlagIcon ), QLocale::countryToString ( eCountry ), iCurCntry ); - } + continue; + } + // get current country enum + QLocale::Country eCountry = static_cast ( iCurCntry ); + + // try to load icon from resource file name + QIcon CurFlagIcon; + CurFlagIcon.addFile ( CLocale::GetCountryFlagIconsResourceReference ( eCountry ) ); + + // only add the entry if a flag is available + if ( !CurFlagIcon.isNull() ) + { + // create a combo box item with text and image + pcbxCountry->addItem ( QIcon ( CurFlagIcon ), QLocale::countryToString ( eCountry ), iCurCntry ); } } diff --git a/src/serverdlg.cpp b/src/serverdlg.cpp index f467a2f22b..5b007247b5 100644 --- a/src/serverdlg.cpp +++ b/src/serverdlg.cpp @@ -308,12 +308,13 @@ lvwClients->setMinimumHeight ( 140 ); for ( int iCurCntry = static_cast ( QLocale::AnyCountry ); iCurCntry < static_cast ( QLocale::LastCountry ); iCurCntry++ ) { // add all countries except of the "Default" country - if ( static_cast ( iCurCntry ) != QLocale::AnyCountry ) + if ( static_cast ( iCurCntry ) == QLocale::AnyCountry ) { - // store the country enum index together with the string (this is - // important since we sort the combo box items later on) - cbxLocationCountry->addItem ( QLocale::countryToString ( static_cast ( iCurCntry ) ), iCurCntry ); + continue; } + // store the country enum index together with the string (this is + // important since we sort the combo box items later on) + cbxLocationCountry->addItem ( QLocale::countryToString ( static_cast ( iCurCntry ) ), iCurCntry ); } // sort country combo box items in alphabetical order From 75629c37fe2ee8832383ab443b2ae8f33cd730ff Mon Sep 17 00:00:00 2001 From: Christian Hoffmann Date: Thu, 27 Jan 2022 00:19:57 +0100 Subject: [PATCH 10/13] Build: Add Qt5/6 Locale compatibility layer Jamulus uses the Qt5-internal enum values of Country codes within its protocol. Qt6 changed those assignments. This would lead to different behavior for users based on their Qt version. To avoid that, this commit adds a compatibility layer to translate Qt6 Country codes to their Qt5 equivalent and vice-versa. This affects the protocol traffic and any ini-stored country values for clients and servers. https://doc.qt.io/qt-5/qlocale.html#Country-enum https://doc.qt.io/qt-6/qlocale.html#Country-enum Co-authored-by: Tony Mountifield Co-authored-by: Peter L Jones Co-authored-by: DonC --- src/clientsettingsdlg.cpp | 9 ++++ src/main.cpp | 2 +- src/protocol.cpp | 36 ++++++++----- src/protocol.h | 4 ++ src/serverdlg.cpp | 9 ++++ src/settings.cpp | 8 +-- src/util.cpp | 37 +++++++++++++- src/util.h | 32 +++++++++++- tools/qt5-to-qt6-country-code-table.py | 70 ++++++++++++++++++++++++++ 9 files changed, 188 insertions(+), 19 deletions(-) create mode 100755 tools/qt5-to-qt6-country-code-table.py diff --git a/src/clientsettingsdlg.cpp b/src/clientsettingsdlg.cpp index 8dd5bdc83f..8b2b50b851 100644 --- a/src/clientsettingsdlg.cpp +++ b/src/clientsettingsdlg.cpp @@ -565,6 +565,15 @@ CClientSettingsDlg::CClientSettingsDlg ( CClient* pNCliP, CClientSettings* pNSet { continue; } + + if ( !CLocale::IsCountryCodeSupported ( iCurCntry ) ) + { + // The current Qt version which is the base for the loop may support + // more country codes than our protocol does. Therefore, skip + // the unsupported options to avoid surprises. + continue; + } + // get current country enum QLocale::Country eCountry = static_cast ( iCurCntry ); diff --git a/src/main.cpp b/src/main.cpp index 0bc792376b..4e09bc4f73 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1051,7 +1051,7 @@ QString UsageArguments ( char** argv ) " -L, --licence show an agreement window before users can connect\n" " -m, --htmlstatus enable HTML status file, set file name\n" " -o, --serverinfo registration info for this Server. Format:\n" - " [name];[city];[country as QLocale ID]\n" + " [name];[city];[country as Qt5 QLocale ID]\n" " --serverpublicip public IP address for this Server. Needed when\n" " registering with a server list hosted\n" " behind the same NAT\n" diff --git a/src/protocol.cpp b/src/protocol.cpp index 62504ed15f..f6c518baf4 100644 --- a/src/protocol.cpp +++ b/src/protocol.cpp @@ -1152,7 +1152,7 @@ void CProtocol::CreateConClientListMes ( const CVector& vecChanInf PutValOnStream ( vecData, iPos, static_cast ( vecChanInfo[i].iChanID ), 1 ); // country (2 bytes) - PutValOnStream ( vecData, iPos, static_cast ( vecChanInfo[i].eCountry ), 2 ); + PutCountryOnStream ( vecData, iPos, vecChanInfo[i].eCountry ); // instrument (4 bytes) PutValOnStream ( vecData, iPos, static_cast ( vecChanInfo[i].iInstrument ), 4 ); @@ -1191,7 +1191,7 @@ bool CProtocol::EvaluateConClientListMes ( const CVector& vecData ) const int iChanID = static_cast ( GetValFromStream ( vecData, iPos, 1 ) ); // country (2 bytes) - const QLocale::Country eCountry = static_cast ( GetValFromStream ( vecData, iPos, 2 ) ); + const QLocale::Country eCountry = GetCountryFromStream ( vecData, iPos ); // instrument (4 bytes) const int iInstrument = static_cast ( GetValFromStream ( vecData, iPos, 4 ) ); @@ -1261,7 +1261,7 @@ void CProtocol::CreateChanInfoMes ( const CChannelCoreInfo ChanInfo ) CVector vecData ( iEntrLen ); // country (2 bytes) - PutValOnStream ( vecData, iPos, static_cast ( ChanInfo.eCountry ), 2 ); + PutCountryOnStream ( vecData, iPos, ChanInfo.eCountry ); // instrument (4 bytes) PutValOnStream ( vecData, iPos, static_cast ( ChanInfo.iInstrument ), 4 ); @@ -1291,7 +1291,7 @@ bool CProtocol::EvaluateChanInfoMes ( const CVector& vecData ) } // country (2 bytes) - ChanInfo.eCountry = static_cast ( GetValFromStream ( vecData, iPos, 2 ) ); + ChanInfo.eCountry = GetCountryFromStream ( vecData, iPos ); // instrument (4 bytes) ChanInfo.iInstrument = static_cast ( GetValFromStream ( vecData, iPos, 4 ) ); @@ -1773,7 +1773,7 @@ void CProtocol::CreateCLRegisterServerMes ( const CHostAddress& InetAddr, const PutValOnStream ( vecData, iPos, static_cast ( LInetAddr.iPort ), 2 ); // country (2 bytes) - PutValOnStream ( vecData, iPos, static_cast ( ServerInfo.eCountry ), 2 ); + PutCountryOnStream ( vecData, iPos, ServerInfo.eCountry ); // maximum number of connected clients (1 byte) PutValOnStream ( vecData, iPos, static_cast ( ServerInfo.iMaxNumClients ), 1 ); @@ -1811,7 +1811,7 @@ bool CProtocol::EvaluateCLRegisterServerMes ( const CHostAddress& InetAddr, cons LInetAddr.iPort = static_cast ( GetValFromStream ( vecData, iPos, 2 ) ); // country (2 bytes) - RecServerInfo.eCountry = static_cast ( GetValFromStream ( vecData, iPos, 2 ) ); + RecServerInfo.eCountry = GetCountryFromStream ( vecData, iPos ); // maximum number of connected clients (1 byte) RecServerInfo.iMaxNumClients = static_cast ( GetValFromStream ( vecData, iPos, 1 ) ); @@ -1887,7 +1887,7 @@ void CProtocol::CreateCLRegisterServerExMes ( const CHostAddress& InetAddr, cons PutValOnStream ( vecData, iPos, static_cast ( LInetAddr.iPort ), 2 ); // country (2 bytes) - PutValOnStream ( vecData, iPos, static_cast ( ServerInfo.eCountry ), 2 ); + PutCountryOnStream ( vecData, iPos, ServerInfo.eCountry ); // maximum number of connected clients (1 byte) PutValOnStream ( vecData, iPos, static_cast ( ServerInfo.iMaxNumClients ), 1 ); @@ -1931,7 +1931,7 @@ bool CProtocol::EvaluateCLRegisterServerExMes ( const CHostAddress& InetAddr, co LInetAddr.iPort = static_cast ( GetValFromStream ( vecData, iPos, 2 ) ); // country (2 bytes) - RecServerInfo.eCountry = static_cast ( GetValFromStream ( vecData, iPos, 2 ) ); + RecServerInfo.eCountry = GetCountryFromStream ( vecData, iPos ); // maximum number of connected clients (1 byte) RecServerInfo.iMaxNumClients = static_cast ( GetValFromStream ( vecData, iPos, 1 ) ); @@ -2045,7 +2045,7 @@ void CProtocol::CreateCLServerListMes ( const CHostAddress& InetAddr, const CVec PutValOnStream ( vecData, iPos, static_cast ( vecServerInfo[i].HostAddr.iPort ), 2 ); // country (2 bytes) - PutValOnStream ( vecData, iPos, static_cast ( vecServerInfo[i].eCountry ), 2 ); + PutCountryOnStream ( vecData, iPos, vecServerInfo[i].eCountry ); // maximum number of connected clients (1 byte) PutValOnStream ( vecData, iPos, static_cast ( vecServerInfo[i].iMaxNumClients ), 1 ); @@ -2087,7 +2087,7 @@ bool CProtocol::EvaluateCLServerListMes ( const CHostAddress& InetAddr, const CV const quint16 iPort = static_cast ( GetValFromStream ( vecData, iPos, 2 ) ); // country (2 bytes) - const QLocale::Country eCountry = static_cast ( GetValFromStream ( vecData, iPos, 2 ) ); + const QLocale::Country eCountry = GetCountryFromStream ( vecData, iPos ); // maximum number of connected clients (1 byte) const int iMaxNumClients = static_cast ( GetValFromStream ( vecData, iPos, 1 ) ); @@ -2396,7 +2396,7 @@ void CProtocol::CreateCLConnClientsListMes ( const CHostAddress& InetAddr, const PutValOnStream ( vecData, iPos, static_cast ( vecChanInfo[i].iChanID ), 1 ); // country (2 bytes) - PutValOnStream ( vecData, iPos, static_cast ( vecChanInfo[i].eCountry ), 2 ); + PutCountryOnStream ( vecData, iPos, vecChanInfo[i].eCountry ); // instrument (4 bytes) PutValOnStream ( vecData, iPos, static_cast ( vecChanInfo[i].iInstrument ), 4 ); @@ -2435,7 +2435,7 @@ bool CProtocol::EvaluateCLConnClientsListMes ( const CHostAddress& InetAddr, con const int iChanID = static_cast ( GetValFromStream ( vecData, iPos, 1 ) ); // country (2 bytes) - const QLocale::Country eCountry = static_cast ( GetValFromStream ( vecData, iPos, 2 ) ); + const QLocale::Country eCountry = GetCountryFromStream ( vecData, iPos ); // instrument (4 bytes) const int iInstrument = static_cast ( GetValFromStream ( vecData, iPos, 4 ) ); @@ -2769,6 +2769,12 @@ bool CProtocol::GetStringFromStream ( const CVector& vecIn, int& iPos, return false; // no error } +QLocale::Country CProtocol::GetCountryFromStream ( const CVector& vecIn, int& iPos ) +{ + unsigned short iCountryCode = GetValFromStream ( vecIn, iPos, 2 ); + return CLocale::WireFormatCountryCodeToQtCountry ( iCountryCode ); +} + void CProtocol::GenMessageFrame ( CVector& vecOut, const int iCnt, const int iID, const CVector& vecData ) { int i; @@ -2881,3 +2887,9 @@ void CProtocol::PutStringUTF8OnStream ( CVector& vecIn, int& iPos, cons PutValOnStream ( vecIn, iPos, static_cast ( sStringUTF8[j] ), 1 ); } } + +void CProtocol::PutCountryOnStream ( CVector& vecIn, int& iPos, QLocale::Country eCountry ) +{ + unsigned short iCountryCode = CLocale::QtCountryToWireFormatCountryCode ( eCountry ); + PutValOnStream ( vecIn, iPos, iCountryCode, 2 ); +} diff --git a/src/protocol.h b/src/protocol.h index 334ce0af92..e05db57611 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -217,6 +217,8 @@ void CreateReqChannelLevelListMes(); const QByteArray& sStringUTF8, const int iNumberOfBytsLen = 2 ); // default is 2 bytes length indicator + void PutCountryOnStream ( CVector& vecIn, int& iPos, QLocale::Country eCountry ); + static uint32_t GetValFromStream ( const CVector& vecIn, int& iPos, const int iNumOfBytes ); bool GetStringFromStream ( const CVector& vecIn, @@ -225,6 +227,8 @@ void CreateReqChannelLevelListMes(); QString& strOut, const int iNumberOfBytsLen = 2 ); // default is 2 bytes length indicator + static QLocale::Country GetCountryFromStream ( const CVector& vecIn, int& iPos ); + void SendMessage(); void CreateAndSendMessage ( const int iID, const CVector& vecData ); diff --git a/src/serverdlg.cpp b/src/serverdlg.cpp index 5b007247b5..704343f793 100644 --- a/src/serverdlg.cpp +++ b/src/serverdlg.cpp @@ -312,6 +312,15 @@ lvwClients->setMinimumHeight ( 140 ); { continue; } + + if ( !CLocale::IsCountryCodeSupported ( iCurCntry ) ) + { + // The current Qt version which is the base for the loop may support + // more country codes than our protocol does. Therefore, skip + // the unsupported options to avoid surprises. + continue; + } + // store the country enum index together with the string (this is // important since we sort the combo box items later on) cbxLocationCountry->addItem ( QLocale::countryToString ( static_cast ( iCurCntry ) ), iCurCntry ); diff --git a/src/settings.cpp b/src/settings.cpp index ab9b038dfd..1fb14d115e 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -296,7 +296,7 @@ void CClientSettings::ReadSettingsFromXML ( const QDomDocument& IniXMLDocument, // country if ( GetNumericIniSet ( IniXMLDocument, "client", "country", 0, static_cast ( QLocale::LastCountry ), iValue ) ) { - pClient->ChannelInfo.eCountry = static_cast ( iValue ); + pClient->ChannelInfo.eCountry = CLocale::WireFormatCountryCodeToQtCountry ( iValue ); } else { @@ -636,7 +636,7 @@ void CClientSettings::WriteSettingsToXML ( QDomDocument& IniXMLDocument ) SetNumericIniSet ( IniXMLDocument, "client", "instrument", pClient->ChannelInfo.iInstrument ); // country - SetNumericIniSet ( IniXMLDocument, "client", "country", static_cast ( pClient->ChannelInfo.eCountry ) ); + SetNumericIniSet ( IniXMLDocument, "client", "country", CLocale::QtCountryToWireFormatCountryCode ( pClient->ChannelInfo.eCountry ) ); // city PutIniSetting ( IniXMLDocument, "client", "city_base64", ToBase64 ( pClient->ChannelInfo.strCity ) ); @@ -784,7 +784,7 @@ void CServerSettings::ReadSettingsFromXML ( const QDomDocument& IniXMLDocument, // country if ( GetNumericIniSet ( IniXMLDocument, "server", "country", 0, static_cast ( QLocale::LastCountry ), iValue ) ) { - pServer->SetServerCountry ( static_cast ( iValue ) ); + pServer->SetServerCountry ( CLocale::WireFormatCountryCodeToQtCountry ( iValue ) ); } } @@ -921,7 +921,7 @@ void CServerSettings::WriteSettingsToXML ( QDomDocument& IniXMLDocument ) PutIniSetting ( IniXMLDocument, "server", "city", pServer->GetServerCity() ); // country - SetNumericIniSet ( IniXMLDocument, "server", "country", static_cast ( pServer->GetServerCountry() ) ); + SetNumericIniSet ( IniXMLDocument, "server", "country", CLocale::QtCountryToWireFormatCountryCode ( pServer->GetServerCountry() ) ); // norecord flag SetFlagIniSet ( IniXMLDocument, "server", "norecord", pServer->GetDisableRecording() ); diff --git a/src/util.cpp b/src/util.cpp index d2f7d6f78b..4f7d6e1122 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -1202,7 +1202,42 @@ CInstPictures::EInstCategory CInstPictures::GetCategory ( const int iInstrument } // Locale management class ----------------------------------------------------- -QString CLocale::GetCountryFlagIconsResourceReference ( const QLocale::Country eCountry ) +QLocale::Country CLocale::WireFormatCountryCodeToQtCountry ( unsigned short iCountryCode ) +{ +#if QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 ) + // The Jamulus protocol wire format gives us Qt5 country IDs. + // Qt6 changed those IDs, so we have to convert back: + return (QLocale::Country) wireFormatToQt6Table[iCountryCode]; +#else + return (QLocale::Country) iCountryCode; +#endif +} + +unsigned short CLocale::QtCountryToWireFormatCountryCode ( const QLocale::Country eCountry ) +{ +#if QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 ) + // The Jamulus protocol wire format expects Qt5 country IDs. + // Qt6 changed those IDs, so we have to convert back: + return qt6CountryToWireFormat[(unsigned short) eCountry]; +#else + return (unsigned short) eCountry; +#endif +} + +bool CLocale::IsCountryCodeSupported ( unsigned short iCountryCode ) +{ +#if QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 ) + // On newer Qt versions there might be codes which do not have a Qt5 equivalent. + // We have no way to support those sanely right now. + return qt6CountryToWireFormat[iCountryCode] != -1; +#else + // All Qt5 codes are supported. + Q_UNUSED ( iCountryCode ); + return true; +#endif +} + +QString CLocale::GetCountryFlagIconsResourceReference ( const QLocale::Country eCountry /* Qt-native value */ ) { QString strReturn = ""; diff --git a/src/util.h b/src/util.h index 99851dc2d2..49a8bca0bd 100644 --- a/src/util.h +++ b/src/util.h @@ -813,10 +813,40 @@ class CInstPictures class CLocale { public: - static QString GetCountryFlagIconsResourceReference ( const QLocale::Country eCountry ); + static QString GetCountryFlagIconsResourceReference ( const QLocale::Country eCountry /* Always a Qt5 (!) code */ ); static QMap GetAvailableTranslations(); static QPair FindSysLangTransFileName ( const QMap& TranslMap ); static void LoadTranslation ( const QString strLanguage, QCoreApplication* pApp ); + static QLocale::Country WireFormatCountryCodeToQtCountry ( unsigned short iCountryCode ); + static unsigned short QtCountryToWireFormatCountryCode ( const QLocale::Country eCountry ); + static bool IsCountryCodeSupported ( unsigned short iCountryCode ); +#if QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 ) + // ./tools/qt5-to-qt6-country-code-table.py generates these lists: + constexpr int const static wireFormatToQt6Table[] = { + 0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, + 29, 30, 31, 32, 33, 35, 36, 37, 38, 39, 40, 41, 43, 45, 46, 48, 49, 50, 51, 53, 54, 55, 57, 56, 58, 59, 118, + 60, 61, 63, 64, 65, 67, 68, 69, 232, 70, 71, 72, 73, 74, 75, 77, 80, 81, 82, 83, 84, 100, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 102, 101, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 116, 117, 119, + 120, 122, 123, 124, 125, 174, 218, 127, 128, 129, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, + 148, 149, 150, 151, 152, 153, 154, 155, 156, 158, 159, 160, 161, 162, 163, 164, 165, 62, 166, 167, 168, 170, 169, 171, 172, 173, 175, + 176, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 197, 198, 201, 202, 203, 204, 205, 206, 208, + 209, 210, 212, 213, 214, 215, 216, 217, 220, 221, 196, 200, 222, 223, 224, 76, 225, 226, 227, 228, 229, 230, 231, 233, 234, 235, 236, + 238, 239, 240, 241, 242, 243, 244, 245, 246, 248, 247, 250, 251, 252, 253, 254, 255, 34, 249, 256, 257, 259, 42, 260, 261, 52, 157, + 207, 195, 199, 130, 14, 2, 66, 47, 115, 121, 237, 219, 44, 211, 126, 79, 177, 258, 78, + }; + constexpr int const static qt6CountryToWireFormat[] = { + 0, 1, 248, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 247, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 233, 32, 33, 34, 35, 36, 37, 38, 238, 39, 255, 40, 41, 250, 42, 43, 44, 45, 241, 46, + 47, 48, 50, 49, 51, 52, 54, 55, 152, 56, 57, 58, 249, 59, 60, 61, 63, 64, 65, 66, 67, 68, 204, 69, 261, 258, 70, + 71, 72, 73, 74, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 75, 92, 91, 93, 94, 95, 96, 97, + 98, 99, 100, 101, 102, 103, 104, 251, 105, 106, 53, 107, 108, 252, 109, 110, 111, 112, 257, 115, 116, 117, 246, 118, 119, 120, 121, + 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 242, 144, 145, 146, 147, + 148, 149, 150, 151, 153, 154, 155, 157, 156, 158, 159, 160, 113, 161, 162, 259, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, + 174, 175, 176, 177, 178, 179, 244, 199, 180, 181, 245, 200, 182, 183, 184, 185, 186, 187, 243, 188, 189, 190, 256, 191, 192, 193, 194, + 195, 196, 114, 254, 197, 198, 201, 202, 203, 205, 206, 207, 208, 209, 210, 211, 62, 212, 213, 214, 215, 253, 216, 217, 218, 219, 220, + 221, 222, 223, 224, 226, 225, 234, 227, 228, 229, 230, 231, 232, 235, 236, 260, 237, 239, 240, + }; +#endif }; // Info of a channel ----------------------------------------------------------- diff --git a/tools/qt5-to-qt6-country-code-table.py b/tools/qt5-to-qt6-country-code-table.py new file mode 100755 index 0000000000..4d54bf9a01 --- /dev/null +++ b/tools/qt5-to-qt6-country-code-table.py @@ -0,0 +1,70 @@ +#!/usr/bin/env python3 +""" +Jamulus uses Qt5 QLocale::Country codes in its protocol. +Qt6 changed those codes in an incompatible way. +To make >=Qt6 clients compatible with the Jamulus protocol in the wild, +we need to translate between those codes. +This script generates two translation tables from Qt5 + Qt6 header files: +A table to translate from Qt5 to Qt6 and an inverse table. +""" +import re + +# verify that the following actually points to Qt5 on your system! +qt5_include = '/usr/include/qt/QtCore/qlocale.h' +qt6_include = '/usr/include/qt6/QtCore/qlocale.h' + + +def parse_enum_from_header(header): + name_to_val = {} + val_to_name = {} + with open(header) as f: + s = f.read() + matches = re.search(r'enum Country[^\n]+\{([^}]+)\}', s) + assignments = matches.group(1) + + assign_pattern = re.compile(r'^\s*(\S+)(?:\s+.*)?\s+=\s+([^\s,]+),?$') + for assignment in assignments.split('\n'): + if assignment.startswith('#') or not assignment.strip(): + continue + matches = assign_pattern.match(assignment) + if not matches: + raise Exception("unable to match line: %r" % assignment) + name = matches.group(1) + val = matches.group(2) + if val.isnumeric(): + val = int(val) + if val not in val_to_name: + val_to_name[val] = name + name_to_val[name] = val + elif val in name_to_val: + # resolve aliases: + name_to_val[name] = name_to_val[val] + else: + raise("Unhandled case") + return name_to_val, val_to_name + + +def make_struct(name, table): + ret = '' + highest_key = max([int(x) for x in table.keys()]) + ret += 'constexpr int const static %s[] = {' % (name,) + for key in range(highest_key+1): + ret += '%d' % table.get(key, -1) # fill gaps with -1 + ret += ', ' + ret += '};' + return ret + + +qt5_name_to_val, qt5_val_to_name = parse_enum_from_header(qt5_include) +qt6_name_to_val, qt6_val_to_name = parse_enum_from_header(qt6_include) + +qt5_to_qt6 = {} +qt6_to_qt5 = {} +# We need to support all Qt5 codes, so we work by value: +for qt5_val, name in qt5_val_to_name.items(): + qt6_val = qt6_name_to_val[name] + qt5_to_qt6[qt5_val] = qt6_val + qt6_to_qt5[qt6_val] = qt5_val + +print(make_struct('wireFormatToQt6Table', qt5_to_qt6)) +print(make_struct('qt6CountryToWireFormat', qt6_to_qt5)) From 3c335ab5bdef62b1bb5e664eab35ff2bb29fa3ea Mon Sep 17 00:00:00 2001 From: Christian Hoffmann Date: Sat, 19 Mar 2022 18:52:51 +0100 Subject: [PATCH 11/13] Build: Remove unused qt{mac,win}extras dependencies Required for Qt6 compatibility as they are no longer there. --- .github/autobuild/ios.sh | 2 +- .github/autobuild/windows.ps1 | 2 +- Jamulus.pro | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/autobuild/ios.sh b/.github/autobuild/ios.sh index 011379fe5f..2f9d6d29b1 100755 --- a/.github/autobuild/ios.sh +++ b/.github/autobuild/ios.sh @@ -19,7 +19,7 @@ setup() { else echo "Installing Qt" python3 -m pip install "aqtinstall==${AQTINSTALL_VERSION}" - python3 -m aqt install-qt --outputdir "${QT_DIR}" mac ios "${QT_VERSION}" --archives qtbase qttools qttranslations qtmacextras + python3 -m aqt install-qt --outputdir "${QT_DIR}" mac ios "${QT_VERSION}" --archives qtbase qttools qttranslations fi } diff --git a/.github/autobuild/windows.ps1 b/.github/autobuild/windows.ps1 index ace3808658..19c9993c8d 100644 --- a/.github/autobuild/windows.ps1 +++ b/.github/autobuild/windows.ps1 @@ -42,7 +42,7 @@ Function Install-Qt "desktop", "$QtVersion", "$QtArch", - "--archives", "qtbase", "qttools", "qttranslations", "qtwinextras" + "--archives", "qtbase", "qttools", "qttranslations" ) aqt install-qt @Args if ( !$? ) diff --git a/Jamulus.pro b/Jamulus.pro index d42e8af480..7d89bbfbdd 100644 --- a/Jamulus.pro +++ b/Jamulus.pro @@ -216,7 +216,6 @@ win32 { } else:ios { QMAKE_INFO_PLIST = ios/Info.plist - QT += macextras OBJECTIVE_SOURCES += ios/ios_app_delegate.mm HEADERS += ios/ios_app_delegate.h HEADERS += ios/sound.h From deb9db11fec7a782aa5236675cf35db9bb4212ee Mon Sep 17 00:00:00 2001 From: Christian Hoffmann Date: Sat, 19 Mar 2022 23:29:13 +0100 Subject: [PATCH 12/13] iOS: Add Qt6 qmake installation workaround to fix build --- .github/autobuild/ios.sh | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/autobuild/ios.sh b/.github/autobuild/ios.sh index 2f9d6d29b1..a9f7ace3eb 100755 --- a/.github/autobuild/ios.sh +++ b/.github/autobuild/ios.sh @@ -2,7 +2,7 @@ set -eu QT_DIR=/usr/local/opt/qt -AQTINSTALL_VERSION=2.0.6 +AQTINSTALL_VERSION=2.1.0 if [[ ! ${QT_VERSION:-} =~ [0-9]+\.[0-9]+\..* ]]; then echo "Environment variable QT_VERSION must be set to a valid Qt version" @@ -19,7 +19,14 @@ setup() { else echo "Installing Qt" python3 -m pip install "aqtinstall==${AQTINSTALL_VERSION}" + # Install actual ios Qt: python3 -m aqt install-qt --outputdir "${QT_DIR}" mac ios "${QT_VERSION}" --archives qtbase qttools qttranslations + if [[ ! "${QT_VERSION}" =~ 5\..* ]]; then + # Starting with Qt6, ios' qtbase install does no longer include a real qmake binary. + # Instead, it is a script which invokes the mac desktop qmake. + # As of aqtinstall 2.1.0 / 04/2022, desktop qtbase has to be installed manually: + python3 -m aqt install-qt --outputdir "${QT_DIR}" mac desktop "${QT_VERSION}" --archives qtbase + fi fi } From 0b2ad5f7f455a14486991062cd383184681cfe1c Mon Sep 17 00:00:00 2001 From: Christian Hoffmann Date: Sun, 20 Mar 2022 00:54:43 +0100 Subject: [PATCH 13/13] iOS: Add additional options to disable IPA signing to fix build on Qt6 --- ios/deploy_ios.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ios/deploy_ios.sh b/ios/deploy_ios.sh index 4344761480..0555fd9e2b 100755 --- a/ios/deploy_ios.sh +++ b/ios/deploy_ios.sh @@ -5,7 +5,7 @@ set -eu # Create Xcode file and build qmake -spec macx-xcode Jamulus.pro -/usr/bin/xcodebuild -project Jamulus.xcodeproj -scheme Jamulus -configuration Release clean archive -archivePath "build/Jamulus.xcarchive" CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO +/usr/bin/xcodebuild -project Jamulus.xcodeproj -scheme Jamulus -configuration Release clean archive -archivePath "build/Jamulus.xcarchive" CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO CODE_SIGN_ENTITLEMENTS="" # Generate ipa by copying the .app file from the xcarchive directory mkdir build/Payload