From f7dc6042cbff1b9638bc916872c1aaff86de0c0d Mon Sep 17 00:00:00 2001 From: Vitaly Fanaskov Date: Fri, 7 Dec 2018 16:59:30 +0100 Subject: Remove dead code Task-number: QTBUG-44131 Change-Id: Ic092f2be5855840d6467560159c12f3c5aa36344 Reviewed-by: Christian Ehrlicher Reviewed-by: Lars Knoll --- .../dialogs/qmessagebox/tst_qmessagebox.cpp | 134 --------------------- 1 file changed, 134 deletions(-) diff --git a/tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp b/tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp index eeda17074b..76314564f1 100644 --- a/tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp +++ b/tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp @@ -38,49 +38,6 @@ #include #include -#define CONVENIENCE_FUNC_SYMS(func) \ - { \ - int x1 = QMessageBox::func(0, "Foo", "Bar"); \ - int x3 = QMessageBox::func(0, "Foo", "Bar", "Save"); \ - int x6 = QMessageBox::func(0, "Foo", "Bar", "Save", "Save As"); \ - int x7 = QMessageBox::func(0, "Foo", "Bar", "Save", "Save As", "Dont Save"); \ - int x8 = QMessageBox::func(0, "Foo", "Bar", "Save", "Save As", "Dont Save", 1); \ - int x9 = QMessageBox::func(0, "Foo", "Bar", "Save", "Save As", "Dont Save", 1, 2); \ - int x10 = QMessageBox::func(0, "Foo", "Bar", QMessageBox::YesAll, QMessageBox::Yes); \ - int x11 = QMessageBox::func(0, "Foo", "Bar", QMessageBox::YesAll, QMessageBox::Yes, \ - QMessageBox::No); \ - qDebug("%d %d %d %d %d %d %d %d", x1, x3, x6, x7, x8, x9, x10, x11); \ - { \ - int x4 = QMessageBox::func(0, "Foo", "Bar", (int)QMessageBox::Yes, (int)QMessageBox::No); \ - int x5 = QMessageBox::func(0, "Foo", "Bar", QMessageBox::Yes, (int)QMessageBox::No); \ - int x6 = QMessageBox::func(0, "Foo", "Bar", QMessageBox::Yes | QMessageBox::Default, (int)QMessageBox::No); \ - int x7 = QMessageBox::func(0, "Foo", "Bar", (int)QMessageBox::Yes, QMessageBox::No); \ - int x8 = QMessageBox::func(0, "Foo", "Bar", QMessageBox::Yes, QMessageBox::No); \ - int x9 = QMessageBox::func(0, "Foo", "Bar", QMessageBox::Yes | QMessageBox::Default, QMessageBox::No); \ - int x10 = QMessageBox::func(0, "Foo", "Bar", (int)QMessageBox::Yes, (int)QMessageBox::No, (int)QMessageBox::Ok); \ - int x11 = QMessageBox::func(0, "Foo", "Bar", QMessageBox::Yes, (int)QMessageBox::No, (int)QMessageBox::Ok); \ - int x12 = QMessageBox::func(0, "Foo", "Bar", QMessageBox::Yes | QMessageBox::Default, (int)QMessageBox::No, (int)QMessageBox::Ok); \ - int x13 = QMessageBox::func(0, "Foo", "Bar", (int)QMessageBox::Yes, QMessageBox::No, (int)QMessageBox::Ok); \ - int x14 = QMessageBox::func(0, "Foo", "Bar", QMessageBox::Yes, QMessageBox::No, (int)QMessageBox::Ok); \ - int x15 = QMessageBox::func(0, "Foo", "Bar", QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, (int)QMessageBox::Ok); \ - int x16 = QMessageBox::func(0, "Foo", "Bar", (int)QMessageBox::Yes, (int)QMessageBox::No, QMessageBox::Ok); \ - int x17 = QMessageBox::func(0, "Foo", "Bar", QMessageBox::Yes, (int)QMessageBox::No, QMessageBox::Ok); \ - int x18 = QMessageBox::func(0, "Foo", "Bar", QMessageBox::Yes | QMessageBox::Default, (int)QMessageBox::No, QMessageBox::Ok); \ - int x19 = QMessageBox::func(0, "Foo", "Bar", (int)QMessageBox::Yes, QMessageBox::No, QMessageBox::Ok); \ - int x20 = QMessageBox::func(0, "Foo", "Bar", QMessageBox::Yes, QMessageBox::No, QMessageBox::Ok); \ - int x21 = QMessageBox::func(0, "Foo", "Bar", QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Ok); \ - qDebug("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d", x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21); \ - } \ - } - -#define CONVENIENCE_FUNC_SYMS_EXTRA(func) \ - { \ - int x1 = QMessageBox::func(0, "Foo", "Bar", (int)QMessageBox::Yes); \ - int x2 = QMessageBox::func(0, "Foo", "Bar", QMessageBox::Yes); \ - int x3 = QMessageBox::func(0, "Foo", "Bar", QMessageBox::Yes | QMessageBox::Default); \ - qDebug("%d %d %d", x1, x2, x3); \ - } - class tst_QMessageBox : public QObject { Q_OBJECT @@ -103,7 +60,6 @@ private slots: void staticSourceCompat(); void instanceSourceCompat(); - void testSymbols(); void incorrectDefaultButton(); void updateSize(); @@ -509,96 +465,6 @@ void tst_QMessageBox::instanceSourceCompat() #endif } -void tst_QMessageBox::testSymbols() -{ - return; - - QMessageBox::Icon icon; - icon = QMessageBox::NoIcon; - icon = QMessageBox::Information; - icon = QMessageBox::Warning; - icon = QMessageBox::Critical; - icon = QMessageBox::Question; - - QMessageBox mb1; - QMessageBox mb2(0); - QMessageBox mb3(&mb1); - QMessageBox mb3b("title", "text", QMessageBox::Critical, int(QMessageBox::Yes), - int(QMessageBox::No), int(QMessageBox::Cancel), &mb1, Qt::Dialog); - - QMessageBox::Button button = QMessageBox::NoButton; - button = QMessageBox::Ok; - button = QMessageBox::Cancel; - button = QMessageBox::Yes; - button = QMessageBox::No; - button = QMessageBox::Abort; - button = QMessageBox::Retry; - button = QMessageBox::Ignore; - button = QMessageBox::YesAll; - button = QMessageBox::NoAll; - button = QMessageBox::ButtonMask; - button = QMessageBox::Default; - button = QMessageBox::Escape; - button = QMessageBox::FlagMask; - QVERIFY(button); - - const QString text = QStringLiteral("Foo"); - mb1.setText(text); - QCOMPARE(mb1.text(), text); - - icon = mb1.icon(); - QCOMPARE(icon, QMessageBox::NoIcon); - mb1.setIcon(QMessageBox::Question); - QCOMPARE(mb1.icon(), QMessageBox::Question); - - QPixmap iconPixmap = mb1.iconPixmap(); - mb1.setIconPixmap(iconPixmap); - QCOMPARE(mb1.icon(), QMessageBox::NoIcon); - - QCOMPARE(mb1.buttonText(QMessageBox::Ok), QLatin1String("OK")); - QCOMPARE(mb1.buttonText(QMessageBox::Cancel), QString()); - QCOMPARE(mb1.buttonText(QMessageBox::Ok | QMessageBox::Default), QString()); - - const QString button1 = QStringLiteral("Bar"); - mb2.setButtonText(QMessageBox::Cancel, QStringLiteral("Foo")); - mb2.setButtonText(QMessageBox::Ok, button1); - mb2.setButtonText(QMessageBox::Ok | QMessageBox::Default, QStringLiteral("Baz")); - - QCOMPARE(mb2.buttonText(QMessageBox::Cancel), QString()); - QCOMPARE(mb2.buttonText(QMessageBox::Ok), button1); - - QVERIFY(mb3b.buttonText(QMessageBox::Yes).endsWith("Yes")); - QCOMPARE(mb3b.buttonText(QMessageBox::YesAll), QString()); - QCOMPARE(mb3b.buttonText(QMessageBox::Ok), QString()); - - const QString button2 = QStringLiteral("Blah"); - mb3b.setButtonText(QMessageBox::Yes, button2); - mb3b.setButtonText(QMessageBox::YesAll, QStringLiteral("Zoo")); - mb3b.setButtonText(QMessageBox::Ok, QStringLiteral("Zoo")); - - QCOMPARE(mb3b.buttonText(QMessageBox::Yes), button2); - QCOMPARE(mb3b.buttonText(QMessageBox::YesAll), QString()); - QCOMPARE(mb3b.buttonText(QMessageBox::Ok), QString()); - - QCOMPARE(mb1.textFormat(), Qt::AutoText); - mb1.setTextFormat(Qt::PlainText); - QCOMPARE(mb1.textFormat(), Qt::PlainText); - - CONVENIENCE_FUNC_SYMS(information); - CONVENIENCE_FUNC_SYMS_EXTRA(information); - CONVENIENCE_FUNC_SYMS(question); - CONVENIENCE_FUNC_SYMS_EXTRA(question); - CONVENIENCE_FUNC_SYMS(warning); - CONVENIENCE_FUNC_SYMS(critical); - - QSize sizeHint = mb1.sizeHint(); - QVERIFY(sizeHint.width() > 20 && sizeHint.height() > 20); - - QMessageBox::about(&mb1, "title", "text"); - QMessageBox::aboutQt(&mb1); - QMessageBox::aboutQt(&mb1, "title"); -} - void tst_QMessageBox::detailsText() { QMessageBox box; -- cgit v1.2.3 From 8c2ca29045498be5fd74b8a4df633e7edae211c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tony=20Saraj=C3=A4rvi?= Date: Thu, 15 Nov 2018 09:51:25 +0200 Subject: Revert "Blacklist tst_QTimer::basic_chrono on macOS" Incorrectly blacklisted. This reverts commit 40a7c57ba990dfd58814a4a9dc69948991458cd4. Task-number: QTBUG-61013 Change-Id: I7d9dc4a4b1c8d7ff77ab75c61027b908ffb74552 Reviewed-by: Liang Qi --- tests/auto/corelib/kernel/qtimer/BLACKLIST | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/auto/corelib/kernel/qtimer/BLACKLIST b/tests/auto/corelib/kernel/qtimer/BLACKLIST index b355bc22c2..e5136624d8 100644 --- a/tests/auto/corelib/kernel/qtimer/BLACKLIST +++ b/tests/auto/corelib/kernel/qtimer/BLACKLIST @@ -1,5 +1,3 @@ [remainingTime] windows osx -[basic_chrono] -osx ci -- cgit v1.2.3 From 1075f10184e52ecb08e9b91ae8da25d12f17a9ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Sat, 22 Dec 2018 20:08:27 +0100 Subject: macOS: Optimize detection of dark mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I579527c54f8453c1e4f57bab7eebfc576b6ad365 Reviewed-by: Morten Johan Sørvig --- src/corelib/kernel/qcore_mac_objc.mm | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/corelib/kernel/qcore_mac_objc.mm b/src/corelib/kernel/qcore_mac_objc.mm index 7b78ef11be..bc23e821fd 100644 --- a/src/corelib/kernel/qcore_mac_objc.mm +++ b/src/corelib/kernel/qcore_mac_objc.mm @@ -170,8 +170,11 @@ QDebug operator<<(QDebug debug, const QMacAutoReleasePool *pool) bool qt_mac_applicationIsInDarkMode() { #if QT_MACOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_14) - if (__builtin_available(macOS 10.14, *)) - return [NSApp.effectiveAppearance.name hasSuffix:@"DarkAqua"]; + if (__builtin_available(macOS 10.14, *)) { + auto appearance = [NSApp.effectiveAppearance bestMatchFromAppearancesWithNames: + @[ NSAppearanceNameAqua, NSAppearanceNameDarkAqua ]]; + return [appearance isEqualToString:NSAppearanceNameDarkAqua]; + } #endif return false; } -- cgit v1.2.3 From 1fb41a38692a4f675a9a336d92d806e12eeb0de9 Mon Sep 17 00:00:00 2001 From: Ville Voutilainen Date: Fri, 4 Jan 2019 09:35:40 +0200 Subject: Fix qbswap calls for Big Endian targets Task-number: QTBUG-71945 Change-Id: I5356f8e32d00ea591b1f65cdd4111276fcf876ac Reviewed-by: Simon Hausmann Reviewed-by: Khem Raj --- src/corelib/global/qendian.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/corelib/global/qendian.h b/src/corelib/global/qendian.h index f2e5833468..615f523888 100644 --- a/src/corelib/global/qendian.h +++ b/src/corelib/global/qendian.h @@ -204,9 +204,9 @@ template inline Q_DECL_CONSTEXPR T qToBigEndian(T source) template inline Q_DECL_CONSTEXPR T qFromBigEndian(T source) { return source; } template inline Q_DECL_CONSTEXPR T qToLittleEndian(T source) -{ return qbswap(source); } +{ return qbswap(source); } template inline Q_DECL_CONSTEXPR T qFromLittleEndian(T source) -{ return qbswap(source); } +{ return qbswap(source); } template inline void qToBigEndian(T src, void *dest) { qToUnaligned(src, dest); } template inline void qToLittleEndian(T src, void *dest) -- cgit v1.2.3 From 012f7bb622add41ffc79c0d1eb62043c840be7db Mon Sep 17 00:00:00 2001 From: Sona Kurazyan Date: Fri, 4 Jan 2019 10:45:59 +0100 Subject: Copy backend configuration while setting dtls config When setting dtls configuration, we should also copy backendConfig, otherwise this setting will be ignored. Change-Id: I4df53e8e6d8c2bd0eb7dddb9928b7883c401d60a Reviewed-by: Timur Pocheptsov --- src/network/ssl/qdtls.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/network/ssl/qdtls.cpp b/src/network/ssl/qdtls.cpp index bbb22aa527..3185bfa124 100644 --- a/src/network/ssl/qdtls.cpp +++ b/src/network/ssl/qdtls.cpp @@ -370,6 +370,7 @@ void QDtlsBasePrivate::setConfiguration(const QSslConfiguration &configuration) dtlsConfiguration.nextProtocolNegotiationStatus = configuration.nextProtocolNegotiationStatus(); dtlsConfiguration.dtlsCookieEnabled = configuration.dtlsCookieVerificationEnabled(); dtlsConfiguration.allowRootCertOnDemandLoading = configuration.d->allowRootCertOnDemandLoading; + dtlsConfiguration.backendConfig = configuration.backendConfiguration(); clearDtlsError(); } -- cgit v1.2.3 From 2f4eea5b9cce7b438eeb9016c52a67937d536793 Mon Sep 17 00:00:00 2001 From: Volker Krause Date: Sat, 5 Jan 2019 12:50:18 +0100 Subject: Also integrate Android AAR libraries This works in the same way as JARs are currently provided by dependencies, and becomes necessary when needing e.g. the Android support/compat libs for implementing the Java side of a library. While this is not relevant (yet?) for Qt itself, we hit this with KDE's notification framework. Change-Id: Ia87d1a048a493f7bc311abf5761f33d1943cfbe9 Reviewed-by: BogDan Vatra --- src/android/templates/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/android/templates/build.gradle b/src/android/templates/build.gradle index fcd8ae345d..989d0792cf 100644 --- a/src/android/templates/build.gradle +++ b/src/android/templates/build.gradle @@ -17,7 +17,7 @@ repositories { apply plugin: 'com.android.application' dependencies { - implementation fileTree(dir: 'libs', include: ['*.jar']) + implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar']) } android { -- cgit v1.2.3 From fff59911a353b3fcf74369d8459ac79ce350a54d Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 14 Dec 2018 20:13:44 +0100 Subject: qmake: add QMAKE_EXPORTED_VARIABLES because QMAKE_EXTRA_VARIABLES sometimes just ain't enough. Change-Id: I739e5b6510e4701ca0a86834e4f9a978d7ef1cf4 Reviewed-by: Joerg Bornemann --- qmake/generators/makefile.cpp | 19 +++++++++++++++++++ qmake/generators/makefile.h | 1 + qmake/generators/unix/unixmake2.cpp | 2 ++ qmake/generators/win32/winmakefile.cpp | 2 ++ 4 files changed, 24 insertions(+) diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp index 8b36b64d1d..99455e7cb5 100644 --- a/qmake/generators/makefile.cpp +++ b/qmake/generators/makefile.cpp @@ -2212,6 +2212,25 @@ MakefileGenerator::writeExtraVariables(QTextStream &t) } } +// This is a more powerful alternative to the above function. +// It's meant to be internal, as one can make quite a mess with it. +void +MakefileGenerator::writeExportedVariables(QTextStream &t) +{ + const auto &vars = project->values("QMAKE_EXPORTED_VARIABLES"); + if (vars.isEmpty()) + return; + for (const auto &exp : vars) { + const ProString &name = project->first(ProKey(exp + ".name")); + const ProString &value = project->first(ProKey(exp + ".value")); + if (!value.isEmpty()) + t << name << " = " << value << endl; + else + t << name << " =\n"; + } + t << endl; +} + bool MakefileGenerator::writeDummyMakefile(QTextStream &t) { diff --git a/qmake/generators/makefile.h b/qmake/generators/makefile.h index b5c150e1cb..0c30e74a1d 100644 --- a/qmake/generators/makefile.h +++ b/qmake/generators/makefile.h @@ -79,6 +79,7 @@ protected: void writeHeader(QTextStream &t); void writeSubDirs(QTextStream &t); void writeMakeQmake(QTextStream &t, bool noDummyQmakeAll = false); + void writeExportedVariables(QTextStream &t); void writeExtraVariables(QTextStream &t); void writeExtraTargets(QTextStream &t); void writeExtraCompilerTargets(QTextStream &t); diff --git a/qmake/generators/unix/unixmake2.cpp b/qmake/generators/unix/unixmake2.cpp index d3abedb50b..4b33713a75 100644 --- a/qmake/generators/unix/unixmake2.cpp +++ b/qmake/generators/unix/unixmake2.cpp @@ -180,6 +180,8 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) ProStringList &bundledFiles = project->values("QMAKE_BUNDLED_FILES"); + writeExportedVariables(t); + t << "####### Compiler, tools and options\n\n"; t << "CC = " << var("QMAKE_CC") << endl; t << "CXX = " << var("QMAKE_CXX") << endl; diff --git a/qmake/generators/win32/winmakefile.cpp b/qmake/generators/win32/winmakefile.cpp index e0d03ccc1c..91215c94b1 100644 --- a/qmake/generators/win32/winmakefile.cpp +++ b/qmake/generators/win32/winmakefile.cpp @@ -520,6 +520,8 @@ void Win32MakefileGenerator::writeIncPart(QTextStream &t) void Win32MakefileGenerator::writeStandardParts(QTextStream &t) { + writeExportedVariables(t); + t << "####### Compiler, tools and options\n\n"; t << "CC = " << var("QMAKE_CC") << endl; t << "CXX = " << var("QMAKE_CXX") << endl; -- cgit v1.2.3 From f89ac0101ad4a6cb5339a3bfe132aad897eafc9d Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 14 Dec 2018 21:12:11 +0100 Subject: qmake: add $$read_registry() function Change-Id: I7f9f17e0f44c273e4754d1decc92a8594cad8658 Reviewed-by: Simon Hausmann --- qmake/Makefile.unix | 6 +- qmake/Makefile.unix.win32 | 2 +- qmake/doc/src/qmake-manual.qdoc | 11 +++ qmake/generators/win32/registry.cpp | 158 --------------------------------- qmake/generators/win32/registry_p.h | 73 --------------- qmake/library/qmakebuiltins.cpp | 40 ++++++++- qmake/library/registry.cpp | 158 +++++++++++++++++++++++++++++++++ qmake/library/registry_p.h | 73 +++++++++++++++ tests/auto/tools/qmakelib/qmakelib.pro | 2 + 9 files changed, 287 insertions(+), 236 deletions(-) delete mode 100644 qmake/generators/win32/registry.cpp delete mode 100644 qmake/generators/win32/registry_p.h create mode 100644 qmake/library/registry.cpp create mode 100644 qmake/library/registry_p.h diff --git a/qmake/Makefile.unix b/qmake/Makefile.unix index 9e0b51ba55..0f69b6b487 100644 --- a/qmake/Makefile.unix +++ b/qmake/Makefile.unix @@ -192,6 +192,9 @@ qmakeevaluator.o: $(QMKLIBSRC)/qmakeevaluator.cpp qmakebuiltins.o: $(QMKLIBSRC)/qmakebuiltins.cpp $(CXX) -c -o $@ $(CXXFLAGS) $< +registry.o: $(QMKLIBSRC)/registry.cpp + $(CXX) -c -o $@ $(CXXFLAGS) $< + project.o: $(QMKSRC)/project.cpp $(CXX) -c -o $@ $(CXXFLAGS) $< @@ -225,9 +228,6 @@ unixmake.o: $(QMKSRC)/generators/unix/unixmake.cpp unixmake2.o: $(QMKSRC)/generators/unix/unixmake2.cpp $(CXX) -c -o $@ $(CXXFLAGS) $< -registry.o: $(QMKSRC)/generators/win32/registry.cpp - $(CXX) -c -o $@ $(CXXFLAGS) $< - winmakefile.o: $(QMKSRC)/generators/win32/winmakefile.cpp $(CXX) -c -o $@ $(CXXFLAGS) $< diff --git a/qmake/Makefile.unix.win32 b/qmake/Makefile.unix.win32 index 48efd6f030..faf09ac11e 100644 --- a/qmake/Makefile.unix.win32 +++ b/qmake/Makefile.unix.win32 @@ -18,4 +18,4 @@ QTSRCS = \ $(SOURCE_PATH)/src/corelib/io/qsettings_win.cpp \ $(SOURCE_PATH)/src/corelib/tools/qlocale_win.cpp \ $(SOURCE_PATH)/src/corelib/plugin/qsystemlibrary.cpp \ - $(SOURCE_PATH)/qmake/generators/win32/registry.cpp + $(SOURCE_PATH)/qmake/library/registry.cpp diff --git a/qmake/doc/src/qmake-manual.qdoc b/qmake/doc/src/qmake-manual.qdoc index 97744e7460..fb8bad32a2 100644 --- a/qmake/doc/src/qmake-manual.qdoc +++ b/qmake/doc/src/qmake-manual.qdoc @@ -3258,6 +3258,17 @@ Returns the \c string with every special regular expression character escaped with a backslash. This function is a wrapper around QRegExp::escape. + \section2 read_registry(tree, key[, flag]) + + Returns the value of registry key \c key inside the tree \c tree. + + Only the trees \c HKEY_CURRENT_USER (\c HKCU) and \c HKEY_LOCAL_MACHINE + (\c HKLM) are supported. + + The \c flag may be \c WOW64_32KEY (\c 32) or \c WOW64_64KEY (\c 64). + + \note This function is available only on Windows hosts. + \section2 relative_path(filePath[, base]) Returns the path to \c filePath relative to \c base. diff --git a/qmake/generators/win32/registry.cpp b/qmake/generators/win32/registry.cpp deleted file mode 100644 index 3391ab9512..0000000000 --- a/qmake/generators/win32/registry.cpp +++ /dev/null @@ -1,158 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the qmake application of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include "registry_p.h" - -QT_BEGIN_NAMESPACE - -#ifdef Q_OS_WIN32 -/* - Returns the path part of a registry key. - e.g. - For a key - "Software\\Microsoft\\VisualStudio\\8.0\\Setup\\VC\\ProductDir" - it returns - "Software\\Microsoft\\VisualStudio\\8.0\\Setup\\VC\\" -*/ -static QString keyPath(const QString &rKey) -{ - int idx = rKey.lastIndexOf(QLatin1Char('\\')); - if (idx == -1) - return QString(); - return rKey.left(idx + 1); -} - -/* - Returns the name part of a registry key. - e.g. - For a key - "Software\\Microsoft\\VisualStudio\\8.0\\Setup\\VC\\ProductDir" - it returns - "ProductDir" -*/ -static QString keyName(const QString &rKey) -{ - int idx = rKey.lastIndexOf(QLatin1Char('\\')); - if (idx == -1) - return rKey; - - QString res(rKey.mid(idx + 1)); - if (res == QLatin1String("Default") || res == QLatin1String(".")) - res = QString(); - return res; -} -#endif - -QString qt_readRegistryKey(HKEY parentHandle, const QString &rSubkey, unsigned long options) -{ - QString result; - -#ifdef Q_OS_WIN32 - QString rSubkeyName = keyName(rSubkey); - QString rSubkeyPath = keyPath(rSubkey); - - HKEY handle = nullptr; - LONG res = RegOpenKeyEx(parentHandle, (wchar_t*)rSubkeyPath.utf16(), 0, - KEY_READ | options, &handle); - - if (res != ERROR_SUCCESS) - return QString(); - - // get the size and type of the value - DWORD dataType; - DWORD dataSize; - res = RegQueryValueEx(handle, (wchar_t*)rSubkeyName.utf16(), nullptr, &dataType, nullptr, &dataSize); - if (res != ERROR_SUCCESS) { - RegCloseKey(handle); - return QString(); - } - - // get the value - QByteArray data(dataSize, 0); - res = RegQueryValueEx(handle, (wchar_t*)rSubkeyName.utf16(), nullptr, nullptr, - reinterpret_cast(data.data()), &dataSize); - if (res != ERROR_SUCCESS) { - RegCloseKey(handle); - return QString(); - } - - switch (dataType) { - case REG_EXPAND_SZ: - case REG_SZ: { - result = QString::fromWCharArray(((const wchar_t *)data.constData())); - break; - } - - case REG_MULTI_SZ: { - QStringList l; - int i = 0; - for (;;) { - QString s = QString::fromWCharArray((const wchar_t *)data.constData() + i); - i += s.length() + 1; - - if (s.isEmpty()) - break; - l.append(s); - } - result = l.join(QLatin1String(", ")); - break; - } - - case REG_NONE: - case REG_BINARY: { - result = QString::fromWCharArray((const wchar_t *)data.constData(), data.size() / 2); - break; - } - - case REG_DWORD_BIG_ENDIAN: - case REG_DWORD: { - Q_ASSERT(data.size() == sizeof(int)); - int i; - memcpy((char*)&i, data.constData(), sizeof(int)); - result = QString::number(i); - break; - } - - default: - qWarning("QSettings: unknown data %u type in windows registry", quint32(dataType)); - break; - } - - RegCloseKey(handle); -#else - Q_UNUSED(parentHandle); - Q_UNUSED(rSubkey) - Q_UNUSED(options); -#endif - - return result; -} - -QT_END_NAMESPACE - diff --git a/qmake/generators/win32/registry_p.h b/qmake/generators/win32/registry_p.h deleted file mode 100644 index f9e8bba016..0000000000 --- a/qmake/generators/win32/registry_p.h +++ /dev/null @@ -1,73 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the qmake application of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QT_WINDOWS_REGISTRY_H -#define QT_WINDOWS_REGISTRY_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include - -#ifdef Q_OS_WIN32 - #include -#else - typedef void* HKEY; -#endif - -#include - -QT_BEGIN_NAMESPACE - -/** - * Read a value from the Windows registry. - * - * If the key is not found, or the registry cannot be accessed (for example - * if this code is compiled for a platform other than Windows), a null - * string is returned. - * - * 32-bit code reads from the registry's 32 bit view (Wow6432Node), - * 64 bit code reads from the 64 bit view. - * Pass KEY_WOW64_32KEY to access the 32 bit view regardless of the - * application's architecture, KEY_WOW64_64KEY respectively. - */ -QString qt_readRegistryKey(HKEY parentHandle, const QString &rSubkey, - unsigned long options = 0); - -QT_END_NAMESPACE - -#endif // QT_WINDOWS_REGISTRY_H - diff --git a/qmake/library/qmakebuiltins.cpp b/qmake/library/qmakebuiltins.cpp index f81bec158b..dd7766c8e0 100644 --- a/qmake/library/qmakebuiltins.cpp +++ b/qmake/library/qmakebuiltins.cpp @@ -52,6 +52,9 @@ # include #endif #include +#ifdef Q_OS_WIN +# include +#endif #include @@ -93,7 +96,7 @@ enum ExpandFunc { E_UPPER, E_LOWER, E_TITLE, E_FILES, E_PROMPT, E_RE_ESCAPE, E_VAL_ESCAPE, E_REPLACE, E_SORT_DEPENDS, E_RESOLVE_DEPENDS, E_ENUMERATE_VARS, E_SHADOWED, E_ABSOLUTE_PATH, E_RELATIVE_PATH, E_CLEAN_PATH, - E_SYSTEM_PATH, E_SHELL_PATH, E_SYSTEM_QUOTE, E_SHELL_QUOTE, E_GETENV + E_SYSTEM_PATH, E_SHELL_PATH, E_SYSTEM_QUOTE, E_SHELL_QUOTE, E_GETENV, E_READ_REGISTRY }; enum TestFunc { @@ -190,6 +193,7 @@ void QMakeEvaluator::initFunctionStatics() { "system_quote", E_SYSTEM_QUOTE, -1, 1, "arg" }, { "shell_quote", E_SHELL_QUOTE, -1, 1, "arg" }, { "getenv", E_GETENV, 1, 1, "arg" }, + { "read_registry", E_READ_REGISTRY, 2, 3, "tree, key, [wow64]" }, }; statics.expands.reserve((int)(sizeof(expandInits)/sizeof(expandInits[0]))); for (unsigned i = 0; i < sizeof(expandInits)/sizeof(expandInits[0]); ++i) @@ -1214,6 +1218,40 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinExpand( ret << ProString(m_option->getEnv(u1.str())); break; } +#ifdef Q_OS_WIN + case E_READ_REGISTRY: { + HKEY tree; + const auto par = args.at(0); + if (!par.compare(QLatin1String("HKCU"), Qt::CaseInsensitive) + || !par.compare(QLatin1String("HKEY_CURRENT_USER"), Qt::CaseInsensitive)) { + tree = HKEY_CURRENT_USER; + } else if (!par.compare(QLatin1String("HKLM"), Qt::CaseInsensitive) + || !par.compare(QLatin1String("HKEY_LOCAL_MACHINE"), Qt::CaseInsensitive)) { + tree = HKEY_LOCAL_MACHINE; + } else { + evalError(fL1S("read_registry(): invalid or unsupported registry tree %1.") + .arg(par.toQStringView())); + goto allfail; + } + int flags = 0; + if (args.count() > 2) { + const auto opt = args.at(2); + if (opt == "32" + || !opt.compare(QLatin1String("wow64_32key"), Qt::CaseInsensitive)) { + flags = KEY_WOW64_32KEY; + } else if (opt == "64" + || !opt.compare(QLatin1String("wow64_64key"), Qt::CaseInsensitive)) { + flags = KEY_WOW64_64KEY; + } else { + evalError(fL1S("read_registry(): invalid option %1.") + .arg(opt.toQStringView())); + goto allfail; + } + } + ret << ProString(qt_readRegistryKey(tree, args.at(1).toQString(m_tmp1), flags)); + break; + } +#endif default: evalError(fL1S("Function '%1' is not implemented.").arg(func.toQStringView())); break; diff --git a/qmake/library/registry.cpp b/qmake/library/registry.cpp new file mode 100644 index 0000000000..3391ab9512 --- /dev/null +++ b/qmake/library/registry.cpp @@ -0,0 +1,158 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the qmake application of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include "registry_p.h" + +QT_BEGIN_NAMESPACE + +#ifdef Q_OS_WIN32 +/* + Returns the path part of a registry key. + e.g. + For a key + "Software\\Microsoft\\VisualStudio\\8.0\\Setup\\VC\\ProductDir" + it returns + "Software\\Microsoft\\VisualStudio\\8.0\\Setup\\VC\\" +*/ +static QString keyPath(const QString &rKey) +{ + int idx = rKey.lastIndexOf(QLatin1Char('\\')); + if (idx == -1) + return QString(); + return rKey.left(idx + 1); +} + +/* + Returns the name part of a registry key. + e.g. + For a key + "Software\\Microsoft\\VisualStudio\\8.0\\Setup\\VC\\ProductDir" + it returns + "ProductDir" +*/ +static QString keyName(const QString &rKey) +{ + int idx = rKey.lastIndexOf(QLatin1Char('\\')); + if (idx == -1) + return rKey; + + QString res(rKey.mid(idx + 1)); + if (res == QLatin1String("Default") || res == QLatin1String(".")) + res = QString(); + return res; +} +#endif + +QString qt_readRegistryKey(HKEY parentHandle, const QString &rSubkey, unsigned long options) +{ + QString result; + +#ifdef Q_OS_WIN32 + QString rSubkeyName = keyName(rSubkey); + QString rSubkeyPath = keyPath(rSubkey); + + HKEY handle = nullptr; + LONG res = RegOpenKeyEx(parentHandle, (wchar_t*)rSubkeyPath.utf16(), 0, + KEY_READ | options, &handle); + + if (res != ERROR_SUCCESS) + return QString(); + + // get the size and type of the value + DWORD dataType; + DWORD dataSize; + res = RegQueryValueEx(handle, (wchar_t*)rSubkeyName.utf16(), nullptr, &dataType, nullptr, &dataSize); + if (res != ERROR_SUCCESS) { + RegCloseKey(handle); + return QString(); + } + + // get the value + QByteArray data(dataSize, 0); + res = RegQueryValueEx(handle, (wchar_t*)rSubkeyName.utf16(), nullptr, nullptr, + reinterpret_cast(data.data()), &dataSize); + if (res != ERROR_SUCCESS) { + RegCloseKey(handle); + return QString(); + } + + switch (dataType) { + case REG_EXPAND_SZ: + case REG_SZ: { + result = QString::fromWCharArray(((const wchar_t *)data.constData())); + break; + } + + case REG_MULTI_SZ: { + QStringList l; + int i = 0; + for (;;) { + QString s = QString::fromWCharArray((const wchar_t *)data.constData() + i); + i += s.length() + 1; + + if (s.isEmpty()) + break; + l.append(s); + } + result = l.join(QLatin1String(", ")); + break; + } + + case REG_NONE: + case REG_BINARY: { + result = QString::fromWCharArray((const wchar_t *)data.constData(), data.size() / 2); + break; + } + + case REG_DWORD_BIG_ENDIAN: + case REG_DWORD: { + Q_ASSERT(data.size() == sizeof(int)); + int i; + memcpy((char*)&i, data.constData(), sizeof(int)); + result = QString::number(i); + break; + } + + default: + qWarning("QSettings: unknown data %u type in windows registry", quint32(dataType)); + break; + } + + RegCloseKey(handle); +#else + Q_UNUSED(parentHandle); + Q_UNUSED(rSubkey) + Q_UNUSED(options); +#endif + + return result; +} + +QT_END_NAMESPACE + diff --git a/qmake/library/registry_p.h b/qmake/library/registry_p.h new file mode 100644 index 0000000000..f9e8bba016 --- /dev/null +++ b/qmake/library/registry_p.h @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the qmake application of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT_WINDOWS_REGISTRY_H +#define QT_WINDOWS_REGISTRY_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include + +#ifdef Q_OS_WIN32 + #include +#else + typedef void* HKEY; +#endif + +#include + +QT_BEGIN_NAMESPACE + +/** + * Read a value from the Windows registry. + * + * If the key is not found, or the registry cannot be accessed (for example + * if this code is compiled for a platform other than Windows), a null + * string is returned. + * + * 32-bit code reads from the registry's 32 bit view (Wow6432Node), + * 64 bit code reads from the 64 bit view. + * Pass KEY_WOW64_32KEY to access the 32 bit view regardless of the + * application's architecture, KEY_WOW64_64KEY respectively. + */ +QString qt_readRegistryKey(HKEY parentHandle, const QString &rSubkey, + unsigned long options = 0); + +QT_END_NAMESPACE + +#endif // QT_WINDOWS_REGISTRY_H + diff --git a/tests/auto/tools/qmakelib/qmakelib.pro b/tests/auto/tools/qmakelib/qmakelib.pro index 140bece708..29f17f6a14 100644 --- a/tests/auto/tools/qmakelib/qmakelib.pro +++ b/tests/auto/tools/qmakelib/qmakelib.pro @@ -1,6 +1,7 @@ CONFIG += testcase TARGET = tst_qmakelib QT = core testlib +win32: LIBS += -ladvapi32 INCLUDEPATH += ../../../../qmake/library VPATH += ../../../../qmake/library @@ -13,6 +14,7 @@ SOURCES += \ parsertest.cpp \ evaltest.cpp \ ioutils.cpp \ + registry.cpp \ proitems.cpp \ qmakevfs.cpp \ qmakeparser.cpp \ -- cgit v1.2.3 From ef14c3dc1a6106673969bc55967c434761d33629 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 17 Dec 2018 21:16:27 +0100 Subject: qmake: reshuffle toolchain.prf swap the order of compiler version detection and default path detection. this keeps a subsequent commit smaller, which introduces a dependency between the two. Change-Id: I2d4cbee1fd3555411c18833bbee0201c994a9942 Reviewed-by: Joerg Bornemann --- mkspecs/features/toolchain.prf | 209 +++++++++++++++++++++-------------------- 1 file changed, 106 insertions(+), 103 deletions(-) diff --git a/mkspecs/features/toolchain.prf b/mkspecs/features/toolchain.prf index 1a76e50b49..734a7fbf86 100644 --- a/mkspecs/features/toolchain.prf +++ b/mkspecs/features/toolchain.prf @@ -1,14 +1,3 @@ - -defineReplace(qtMakeExpand) { - out = "$$1" - for(ever) { - m = $$replace(out, ".*\\$\\(EXPORT_([^)]+)\\).*", \\1) - equals(m, $$out): \ - return($$out) - out = $$replace(out, "\\$\\(EXPORT_$$m\\)", $$eval($$m)) - } -} - defineTest(qtCompilerError) { !cross_compile: \ what = @@ -30,6 +19,112 @@ cross_compile:host_build: \ else: \ target_prefix = QMAKE_CXX +# +# Determine and cache the compiler version +# + +defineReplace(qtVariablesFromMSVC) { + ret = $$system("$$1 -nologo -E $$2 $$system_quote($$PWD/data/macros.cpp) 2>NUL", lines, ec) + !equals(ec, 0): qtCompilerError($$1, $$ret) + return($$ret) +} + +defineReplace(qtVariablesFromGCC) { + ret = $$system("$$1 -E $$system_quote($$PWD/data/macros.cpp) \ + 2>$$QMAKE_SYSTEM_NULL_DEVICE", lines, ec) + !equals(ec, 0): qtCompilerError($$1, $$ret) + return($$ret) +} + +isEmpty($${target_prefix}.COMPILER_MACROS) { + msvc { + clang_cl { + # We need to obtain the cl.exe version first + vars = $$qtVariablesFromMSVC(cl) + for (v, vars) { + isEmpty(v)|contains(v, $${LITERAL_HASH}.*): next() + eval($$v) + } + isEmpty(QMAKE_MSC_FULL_VER): error("Could not determine the Visual Studio version") + + QMAKE_CFLAGS_MSVC_COMPAT = $$replace(QMAKE_MSC_FULL_VER, "(..)(..)(.*)", \ + "-fms-compatibility-version=\\1.\\2.\\3") + cache($${target_prefix}.QMAKE_CFLAGS_MSVC_COMPAT, set stash, QMAKE_CFLAGS_MSVC_COMPAT) + $${target_prefix}.COMPILER_MACROS += QMAKE_CFLAGS_MSVC_COMPAT + vars = $$qtVariablesFromMSVC($$QMAKE_CXX, $$QMAKE_CFLAGS_MSVC_COMPAT) + } else { + vars = $$qtVariablesFromMSVC($$QMAKE_CXX) + } + } else: gcc|ghs { + vars = $$qtVariablesFromGCC($$QMAKE_CXX) + } + for (v, vars) { + !contains(v, "[A-Z_]+ = .*"): next() + # Set both for the outer scope ... + eval($$v) + v ~= s/ .*// + isEmpty($$v): error("Compiler produced empty value for $${v}.") + # ... and save QMAKE_(HOST_)?CXX. in the cache. + cache($${target_prefix}.$$v, set stash, $$v) + $${target_prefix}.COMPILER_MACROS += $$v + } + cache($${target_prefix}.COMPILER_MACROS, set stash) +} else { + # load from the cache + for (i, $${target_prefix}.COMPILER_MACROS): \ + $$i = $$eval($${target_prefix}.$$i) +} + +# Populate QMAKE_COMPILER_DEFINES and some compatibility variables. +# The $$format_number() calls strip leading zeros to avoid misinterpretation as octal. +QMAKE_COMPILER_DEFINES += __cplusplus=$$QT_COMPILER_STDCXX +!isEmpty(QMAKE_MSC_VER): \ + QMAKE_COMPILER_DEFINES += _MSC_VER=$$QMAKE_MSC_VER _MSC_FULL_VER=$$QMAKE_MSC_FULL_VER +!isEmpty(QMAKE_ICC_VER): \ + QMAKE_COMPILER_DEFINES += __INTEL_COMPILER=$$QMAKE_ICC_VER __INTEL_COMPILER_UPDATE=$$QMAKE_ICC_UPDATE_VER +!isEmpty(QMAKE_APPLE_CC): \ + QMAKE_COMPILER_DEFINES += __APPLE_CC__=$$QMAKE_APPLE_CC +!isEmpty(QMAKE_APPLE_CLANG_MAJOR_VERSION): \ + QMAKE_COMPILER_DEFINES += __clang__ \ + __clang_major__=$$QMAKE_APPLE_CLANG_MAJOR_VERSION \ + __clang_minor__=$$QMAKE_APPLE_CLANG_MINOR_VERSION \ + __clang_patchlevel__=$$QMAKE_APPLE_CLANG_PATCH_VERSION +!isEmpty(QMAKE_CLANG_MAJOR_VERSION): \ + QMAKE_COMPILER_DEFINES += __clang__ \ + __clang_major__=$$QMAKE_CLANG_MAJOR_VERSION \ + __clang_minor__=$$QMAKE_CLANG_MINOR_VERSION \ + __clang_patchlevel__=$$QMAKE_CLANG_PATCH_VERSION +!isEmpty(QMAKE_GCC_MAJOR_VERSION): \ + QMAKE_COMPILER_DEFINES += \ + __GNUC__=$$QMAKE_GCC_MAJOR_VERSION \ + __GNUC_MINOR__=$$QMAKE_GCC_MINOR_VERSION \ + __GNUC_PATCHLEVEL__=$$QMAKE_GCC_PATCH_VERSION +!isEmpty(QMAKE_GHS_VERSION): \ + QMAKE_COMPILER_DEFINES += __ghs__ __GHS_VERSION_NUMBER=$$QMAKE_GHS_VERSION + +QMAKE_CFLAGS += $$QMAKE_CFLAGS_MSVC_COMPAT +QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_MSVC_COMPAT + +clang_cl|intel_icl { + include(../common/msvc-based-version.conf) +} else: msvc { + include(../common/msvc-version.conf) +} + +# +# Determine and cache the default search paths +# + +defineReplace(qtMakeExpand) { + out = "$$1" + for(ever) { + m = $$replace(out, ".*\\$\\(EXPORT_([^)]+)\\).*", \\1) + equals(m, $$out): \ + return($$out) + out = $$replace(out, "\\$\\(EXPORT_$$m\\)", $$eval($$m)) + } +} + isEmpty($${target_prefix}.INCDIRS) { # # Get default include and library paths from compiler @@ -193,96 +288,4 @@ isEmpty($${target_prefix}.INCDIRS) { QMAKE_DEFAULT_LIBDIRS = $$eval($${target_prefix}.LIBDIRS) } -# -# Determine and cache the compiler version -# - -defineReplace(qtVariablesFromMSVC) { - ret = $$system("$$1 -nologo -E $$2 $$system_quote($$PWD/data/macros.cpp) 2>NUL", lines, ec) - !equals(ec, 0): qtCompilerError($$1, $$ret) - return($$ret) -} - -defineReplace(qtVariablesFromGCC) { - ret = $$system("$$1 -E $$system_quote($$PWD/data/macros.cpp) \ - 2>$$QMAKE_SYSTEM_NULL_DEVICE", lines, ec) - !equals(ec, 0): qtCompilerError($$1, $$ret) - return($$ret) -} - -isEmpty($${target_prefix}.COMPILER_MACROS) { - msvc { - clang_cl { - # We need to obtain the cl.exe version first - vars = $$qtVariablesFromMSVC(cl) - for (v, vars) { - isEmpty(v)|contains(v, $${LITERAL_HASH}.*): next() - eval($$v) - } - isEmpty(QMAKE_MSC_FULL_VER): error("Could not determine the Visual Studio version") - - QMAKE_CFLAGS_MSVC_COMPAT = $$replace(QMAKE_MSC_FULL_VER, "(..)(..)(.*)", \ - "-fms-compatibility-version=\\1.\\2.\\3") - cache($${target_prefix}.QMAKE_CFLAGS_MSVC_COMPAT, set stash, QMAKE_CFLAGS_MSVC_COMPAT) - $${target_prefix}.COMPILER_MACROS += QMAKE_CFLAGS_MSVC_COMPAT - vars = $$qtVariablesFromMSVC($$QMAKE_CXX, $$QMAKE_CFLAGS_MSVC_COMPAT) - } else { - vars = $$qtVariablesFromMSVC($$QMAKE_CXX) - } - } else: gcc|ghs { - vars = $$qtVariablesFromGCC($$QMAKE_CXX) - } - for (v, vars) { - !contains(v, "[A-Z_]+ = .*"): next() - # Set both for the outer scope ... - eval($$v) - v ~= s/ .*// - isEmpty($$v): error("Compiler produced empty value for $${v}.") - # ... and save QMAKE_(HOST_)?CXX. in the cache. - cache($${target_prefix}.$$v, set stash, $$v) - $${target_prefix}.COMPILER_MACROS += $$v - } - cache($${target_prefix}.COMPILER_MACROS, set stash) -} else { - # load from the cache - for (i, $${target_prefix}.COMPILER_MACROS): \ - $$i = $$eval($${target_prefix}.$$i) -} - unset(target_prefix) - -# Populate QMAKE_COMPILER_DEFINES and some compatibility variables. -# The $$format_number() calls strip leading zeros to avoid misinterpretation as octal. -QMAKE_COMPILER_DEFINES += __cplusplus=$$QT_COMPILER_STDCXX -!isEmpty(QMAKE_MSC_VER): \ - QMAKE_COMPILER_DEFINES += _MSC_VER=$$QMAKE_MSC_VER _MSC_FULL_VER=$$QMAKE_MSC_FULL_VER -!isEmpty(QMAKE_ICC_VER): \ - QMAKE_COMPILER_DEFINES += __INTEL_COMPILER=$$QMAKE_ICC_VER __INTEL_COMPILER_UPDATE=$$QMAKE_ICC_UPDATE_VER -!isEmpty(QMAKE_APPLE_CC): \ - QMAKE_COMPILER_DEFINES += __APPLE_CC__=$$QMAKE_APPLE_CC -!isEmpty(QMAKE_APPLE_CLANG_MAJOR_VERSION): \ - QMAKE_COMPILER_DEFINES += __clang__ \ - __clang_major__=$$QMAKE_APPLE_CLANG_MAJOR_VERSION \ - __clang_minor__=$$QMAKE_APPLE_CLANG_MINOR_VERSION \ - __clang_patchlevel__=$$QMAKE_APPLE_CLANG_PATCH_VERSION -!isEmpty(QMAKE_CLANG_MAJOR_VERSION): \ - QMAKE_COMPILER_DEFINES += __clang__ \ - __clang_major__=$$QMAKE_CLANG_MAJOR_VERSION \ - __clang_minor__=$$QMAKE_CLANG_MINOR_VERSION \ - __clang_patchlevel__=$$QMAKE_CLANG_PATCH_VERSION -!isEmpty(QMAKE_GCC_MAJOR_VERSION): \ - QMAKE_COMPILER_DEFINES += \ - __GNUC__=$$QMAKE_GCC_MAJOR_VERSION \ - __GNUC_MINOR__=$$QMAKE_GCC_MINOR_VERSION \ - __GNUC_PATCHLEVEL__=$$QMAKE_GCC_PATCH_VERSION -!isEmpty(QMAKE_GHS_VERSION): \ - QMAKE_COMPILER_DEFINES += __ghs__ __GHS_VERSION_NUMBER=$$QMAKE_GHS_VERSION - -QMAKE_CFLAGS += $$QMAKE_CFLAGS_MSVC_COMPAT -QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_MSVC_COMPAT - -clang_cl|intel_icl { - include(../common/msvc-based-version.conf) -} else: msvc { - include(../common/msvc-version.conf) -} -- cgit v1.2.3 From 45e4dfb449fb15632e5144cf671e38943fa1455f Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 17 Dec 2018 20:57:18 +0100 Subject: qmake: rewrite msvc/nmake cross-build environment setup rather than reproducing vcvarsall.bat's functionality as hard-wired code in the nmake generator, just invoke the actual script from toolchain.prf. this is much easier, more future proof, and - critically - makes the detected variables available to configure's new library & header search facilities. [ChangeLog][Important Behavior Changes][qmake][WinRT] Cross-builds will now ignore pre-set values of %INCLUDE% and %LIB% when building target executables. If necessary, use configure's -I and -L switches when building Qt, and pass QMAKE_INCDIR and QMAKE_LIBDIR on qmake's command line when building own projects. Change-Id: I36f53e8880d6523f3f6f7a44d40d87d04bd06854 Reviewed-by: Thomas Miller Reviewed-by: Oliver Wolff --- mkspecs/features/data/dumpvcvars.bat | 44 ++++++++ mkspecs/features/toolchain.prf | 146 ++++++++++++++++++++++-- mkspecs/winrt-arm-msvc2015/qmake.conf | 1 - mkspecs/winrt-arm-msvc2017/qmake.conf | 1 - mkspecs/winrt-x64-msvc2015/qmake.conf | 1 - mkspecs/winrt-x64-msvc2017/qmake.conf | 1 - mkspecs/winrt-x86-msvc2015/qmake.conf | 1 - mkspecs/winrt-x86-msvc2017/qmake.conf | 1 - qmake/generators/win32/msvc_nmake.cpp | 201 ---------------------------------- 9 files changed, 181 insertions(+), 216 deletions(-) create mode 100644 mkspecs/features/data/dumpvcvars.bat diff --git a/mkspecs/features/data/dumpvcvars.bat b/mkspecs/features/data/dumpvcvars.bat new file mode 100644 index 0000000000..4721da2e39 --- /dev/null +++ b/mkspecs/features/data/dumpvcvars.bat @@ -0,0 +1,44 @@ +::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: +:: +:: Copyright (C) 2018 The Qt Company Ltd. +:: Contact: https://www.qt.io/licensing/ +:: +:: This file is part of the tools applications of the Qt Toolkit. +:: +:: $QT_BEGIN_LICENSE:GPL-EXCEPT$ +:: Commercial License Usage +:: Licensees holding valid commercial Qt licenses may use this file in +:: accordance with the commercial license agreement provided with the +:: Software or, alternatively, in accordance with the terms contained in +:: a written agreement between you and The Qt Company. For licensing terms +:: and conditions see https://www.qt.io/terms-conditions. For further +:: information use the contact form at https://www.qt.io/contact-us. +:: +:: GNU General Public License Usage +:: Alternatively, this file may be used under the terms of the GNU +:: General Public License version 3 as published by the Free Software +:: Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +:: included in the packaging of this file. Please review the following +:: information to ensure the GNU General Public License requirements will +:: be met: https://www.gnu.org/licenses/gpl-3.0.html. +:: +:: $QT_END_LICENSE$ +:: +::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + +@echo off + +REM We clear INCLUDE and LIB, because we want to obtain pristine values. +REM PATH cannot be cleared, because then the script does not even run, +REM and it would be counterproductive anyway (see toolchain.prf). +set INCLUDE= +set LIB= + +call %* || exit 1 +REM VS2015 does not set errorlevel in case of failure. +if "%INCLUDE%" == "" exit 1 + +echo =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+= +echo %INCLUDE% +echo %LIB% +echo %PATH% diff --git a/mkspecs/features/toolchain.prf b/mkspecs/features/toolchain.prf index 734a7fbf86..2a7cbabc54 100644 --- a/mkspecs/features/toolchain.prf +++ b/mkspecs/features/toolchain.prf @@ -1,3 +1,13 @@ +defineTest(qtToolchainError) { + msg = \ + $$1 \ + "===================" \ + $$2 \ + "===================" \ + $$3 + error($$join(msg, $$escape_expand(\\n))) +} + defineTest(qtCompilerError) { !cross_compile: \ what = @@ -5,13 +15,8 @@ defineTest(qtCompilerError) { what = " host" else: \ what = " target" - msg = \ - "Cannot run$$what compiler '$$1'. Output:" \ - "===================" \ - $$2 \ - "===================" \ - "Maybe you forgot to setup the environment?" - error($$join(msg, $$escape_expand(\\n))) + qtToolchainError("Cannot run$$what compiler '$$1'. Output:", $$2, \ + "Maybe you forgot to setup the environment?") } cross_compile:host_build: \ @@ -125,6 +130,36 @@ defineReplace(qtMakeExpand) { } } +defineReplace(qtSplitPathList) { + paths = $$split(1, $$QMAKE_DIRLIST_SEP) + ret = + for (p, paths): \ + ret += $$clean_path($$p) + return($$ret) +} + +defineReplace(qtNmakePathList) { + paths = + for (p, 1): \ + paths += $$shell_path($$p) + paths ~= s,$${LITERAL_HASH},^$${LITERAL_HASH},g + paths ~= s,\\$,\$\$,g + return($$join(paths, $$QMAKE_DIRLIST_SEP)) +} + +msvc { + arch = $$lower($$VCPROJ_ARCH) + equals(arch, x64): \ # may be "win32" or undefined + arch = amd64 + else: !equals(arch, arm):!equals(arch, arm64): \ # may be "win32" or undefined + arch = x86 + # Consider only WinRT and ARM64 desktop builds to be cross-builds - + # the host is assumed to be Intel and capable of running the target + # executables (so building for x64 on x86 will break). + winrt|equals(arch, arm64): \ + CONFIG += msvc_cross +} + isEmpty($${target_prefix}.INCDIRS) { # # Get default include and library paths from compiler @@ -264,9 +299,89 @@ isEmpty($${target_prefix}.INCDIRS) { } } } + } else: msvc_cross { + # Use a batch file, because %VAR% in the system() call expands to + # the pre-script-call value, and !VAR! cannot be enabled outside + # a batch file without invoking another shell instance. + cmd = $$system_quote($$system_path($$PWD/data/dumpvcvars.bat)) + + hostArch = $$QMAKE_HOST.arch + equals(hostArch, x86_64): \ + hostArch = amd64 + !equals(arch, $$hostArch): \ + arch = $${hostArch}_$$arch + + isEmpty(MSVC_VER): \ + error("Mkspec does not specify MSVC_VER. Cannot continue.") + versionAtLeast(MSVC_VER, 15.0) { + dir = $$(VSINSTALLDIR) + isEmpty(dir): \ + dir = $$read_registry(HKLM, \ + "Software\\Microsoft\\VisualStudio\\SxS\\VS7\\$$MSVC_VER", 32) + isEmpty(dir): \ + error("Failed to find the Visual Studio installation directory.") + cmd += $$system_quote($$dir\\VC\\Auxiliary\\Build\\vcvarsall.bat) $$arch + } else { + dir = $$(VCINSTALLDIR) + isEmpty(dir): \ + dir = $$read_registry(HKLM, \ + "Software\\Microsoft\\VisualStudio\\$$MSVC_VER\\Setup\\VC\\ProductDir", 32) + isEmpty(dir): \ + error("Failed to find the Visual C installation directory.") + cmd += $$system_quote($$dir\\vcvarsall.bat) $$arch + } + winrt: cmd += store + + isEmpty(WINSDK_VER): \ + error("Mkspec does not specify WINSDK_VER. Cannot continue.") + # We prefer the environment variable, because that may work around + # a broken registry entry after uninstalling a newer SDK. + # However, we do that only if the major+minor SDK version matches + # the one requested by the mkspec, as we might be building for a + # newer target than the host. + winsdk_ver = $$(WindowsSDKVersion) + !isEmpty(winsdk_ver) { + winsdk_ver ~= s,\\\\$,, # Work around SDK breakage. + !equals(WINSDK_VER, $$replace(winsdk_ver, ^(\\d+\\.\\d+).*$, \\1)): \ + winsdk_ver = + } + !isEmpty(winsdk_ver) { + cmd += $$winsdk_ver + } else { + winsdk_ver = $$read_registry(HKLM, \ + "Software\\Microsoft\\Microsoft SDKs\\Windows\\v$$WINSDK_VER\\ProductVersion", 32) + isEmpty(winsdk_ver): \ + error("Windows SDK $$WINSDK_VER requested by mkspec is not installed. Cannot continue.") + cmd += $${winsdk_ver}.0 + } + + output = $$system("$$cmd 2>&1", lines, ec) + !equals(ec, 0): \ + qtToolchainError("SDK setup script failed. Output:", $$output, \ + "Command was: $$cmd") + lines = $$output + for(ever) { + isEmpty(lines): \ + break() + line = $$take_first(lines) + equals(line, "=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+="): \ + break() + } + !count(lines, 3): \ + qtToolchainError("SDK setup script returned unexpected output:", $$output, \ + "Command was: $$cmd") + + # These contain only paths for the target. + QMAKE_DEFAULT_INCDIRS = $$qtSplitPathList($$member(lines, 0)) + QMAKE_DEFAULT_LIBDIRS = $$qtSplitPathList($$member(lines, 1)) + # PATH is inherently for the host, and paths that are not shadowed + # by vcvarsall.bat are assumed to contain only tools that work for + # both host and target builds. + QMAKE_DEFAULT_PATH = $$qtSplitPathList($$member(lines, 2)) + # We de-duplicate, because the script just prepends to the paths for + # the host, some of which are identical to the ones for the target. + QMAKE_DEFAULT_PATH = $$unique(QMAKE_DEFAULT_PATH) } else: msvc { - # This doesn't differentiate between host and target, - # but neither do the compilers. LIB = $$getenv("LIB") QMAKE_DEFAULT_LIBDIRS = $$split(LIB, $$QMAKE_DIRLIST_SEP) INCLUDE = $$getenv("INCLUDE") @@ -283,9 +398,22 @@ isEmpty($${target_prefix}.INCDIRS) { cache($${target_prefix}.INCDIRS, set stash, QMAKE_DEFAULT_INCDIRS) !isEmpty(QMAKE_DEFAULT_LIBDIRS): \ cache($${target_prefix}.LIBDIRS, set stash, QMAKE_DEFAULT_LIBDIRS) + !isEmpty(QMAKE_DEFAULT_PATH): \ + cache($${target_prefix}.PATH, set stash, QMAKE_DEFAULT_PATH) } else { QMAKE_DEFAULT_INCDIRS = $$eval($${target_prefix}.INCDIRS) QMAKE_DEFAULT_LIBDIRS = $$eval($${target_prefix}.LIBDIRS) + QMAKE_DEFAULT_PATH = $$eval($${target_prefix}.PATH) +} + +msvc_cross { + qmake_inc_exp.name = INCLUDE + qmake_inc_exp.value = $$qtNmakePathList($$QMAKE_DEFAULT_INCDIRS) + qmake_lib_exp.name = LIB + qmake_lib_exp.value = $$qtNmakePathList($$QMAKE_DEFAULT_LIBDIRS) + qmake_path_exp.name = PATH + qmake_path_exp.value = $$qtNmakePathList($$QMAKE_DEFAULT_PATH) + QMAKE_EXPORTED_VARIABLES += qmake_inc_exp qmake_lib_exp qmake_path_exp } unset(target_prefix) diff --git a/mkspecs/winrt-arm-msvc2015/qmake.conf b/mkspecs/winrt-arm-msvc2015/qmake.conf index 8bca6f4af8..bc113d4954 100644 --- a/mkspecs/winrt-arm-msvc2015/qmake.conf +++ b/mkspecs/winrt-arm-msvc2015/qmake.conf @@ -15,6 +15,5 @@ QMAKE_LIBS += windowscodecs.lib WindowsApp.lib runtimeobject.lib One VCPROJ_ARCH = ARM WINSDK_VER = 10.0 -WINTARGET_VER = winv10.0 WINRT_MANIFEST = $$PWD/../common/winrt_winphone/manifests/10.0/AppxManifest.xml.in WINRT_MANIFEST.architecture = arm diff --git a/mkspecs/winrt-arm-msvc2017/qmake.conf b/mkspecs/winrt-arm-msvc2017/qmake.conf index bf571d620c..1160d5766d 100644 --- a/mkspecs/winrt-arm-msvc2017/qmake.conf +++ b/mkspecs/winrt-arm-msvc2017/qmake.conf @@ -15,6 +15,5 @@ QMAKE_LIBS += windowscodecs.lib WindowsApp.lib runtimeobject.lib One VCPROJ_ARCH = ARM WINSDK_VER = 10.0 -WINTARGET_VER = winv10.0 WINRT_MANIFEST = $$PWD/../common/winrt_winphone/manifests/10.0/AppxManifest.xml.in WINRT_MANIFEST.architecture = arm diff --git a/mkspecs/winrt-x64-msvc2015/qmake.conf b/mkspecs/winrt-x64-msvc2015/qmake.conf index d503399e3c..d1d1eb6513 100644 --- a/mkspecs/winrt-x64-msvc2015/qmake.conf +++ b/mkspecs/winrt-x64-msvc2015/qmake.conf @@ -15,6 +15,5 @@ QMAKE_LIBS += windowscodecs.lib WindowsApp.lib runtimeobject.lib One VCPROJ_ARCH = x64 WINSDK_VER = 10.0 -WINTARGET_VER = winv10.0 WINRT_MANIFEST = $$PWD/../common/winrt_winphone/manifests/10.0/AppxManifest.xml.in WINRT_MANIFEST.architecture = x64 diff --git a/mkspecs/winrt-x64-msvc2017/qmake.conf b/mkspecs/winrt-x64-msvc2017/qmake.conf index cb2209fa23..dce896bd47 100644 --- a/mkspecs/winrt-x64-msvc2017/qmake.conf +++ b/mkspecs/winrt-x64-msvc2017/qmake.conf @@ -15,6 +15,5 @@ QMAKE_LIBS += windowscodecs.lib WindowsApp.lib runtimeobject.lib One VCPROJ_ARCH = x64 WINSDK_VER = 10.0 -WINTARGET_VER = winv10.0 WINRT_MANIFEST = $$PWD/../common/winrt_winphone/manifests/10.0/AppxManifest.xml.in WINRT_MANIFEST.architecture = x64 diff --git a/mkspecs/winrt-x86-msvc2015/qmake.conf b/mkspecs/winrt-x86-msvc2015/qmake.conf index 37ce0e5525..06f059b600 100644 --- a/mkspecs/winrt-x86-msvc2015/qmake.conf +++ b/mkspecs/winrt-x86-msvc2015/qmake.conf @@ -14,6 +14,5 @@ QMAKE_LFLAGS += /SAFESEH /MACHINE:X86 /NODEFAULTLIB:kernel32.lib QMAKE_LIBS += windowscodecs.lib WindowsApp.lib runtimeobject.lib OneCore.lib VCPROJ_ARCH = Win32 WINSDK_VER = 10.0 -WINTARGET_VER = winv10.0 WINRT_MANIFEST = $$PWD/../common/winrt_winphone/manifests/10.0/AppxManifest.xml.in WINRT_MANIFEST.architecture = x86 diff --git a/mkspecs/winrt-x86-msvc2017/qmake.conf b/mkspecs/winrt-x86-msvc2017/qmake.conf index 3c9506bbad..94fb68f6c0 100644 --- a/mkspecs/winrt-x86-msvc2017/qmake.conf +++ b/mkspecs/winrt-x86-msvc2017/qmake.conf @@ -14,6 +14,5 @@ QMAKE_LFLAGS += /SAFESEH /MACHINE:X86 /NODEFAULTLIB:kernel32.lib QMAKE_LIBS += windowscodecs.lib WindowsApp.lib runtimeobject.lib OneCore.lib VCPROJ_ARCH = Win32 WINSDK_VER = 10.0 -WINTARGET_VER = winv10.0 WINRT_MANIFEST = $$PWD/../common/winrt_winphone/manifests/10.0/AppxManifest.xml.in WINRT_MANIFEST.architecture = x86 diff --git a/qmake/generators/win32/msvc_nmake.cpp b/qmake/generators/win32/msvc_nmake.cpp index 548d2e8575..aa3d389b67 100644 --- a/qmake/generators/win32/msvc_nmake.cpp +++ b/qmake/generators/win32/msvc_nmake.cpp @@ -34,23 +34,10 @@ #include #include -#include - #include QT_BEGIN_NAMESPACE -static QString nmakePathList(const QStringList &list) -{ - QStringList pathList; - pathList.reserve(list.size()); - for (const QString &path : list) - pathList.append(QDir::cleanPath(path)); - - return QDir::toNativeSeparators(pathList.join(QLatin1Char(';'))) - .replace('#', QLatin1String("^#")).replace('$', QLatin1String("$$")); -} - NmakeMakefileGenerator::NmakeMakefileGenerator() : usePCH(false), usePCHC(false) { @@ -70,194 +57,6 @@ NmakeMakefileGenerator::writeMakefile(QTextStream &t) if(Option::mkfile::do_stub_makefile) return MakefileGenerator::writeStubMakefile(t); #endif - if (!project->isHostBuild()) { - const QString msvcVer = project->first("MSVC_VER").toQString(); - if (msvcVer.isEmpty()) { - fprintf(stderr, "Mkspec does not specify MSVC_VER. Cannot continue.\n"); - return false; - } - - bool winrtBuild = false; - bool crossPlatformDesktopBuild = false; - QString arch = project->first("VCPROJ_ARCH").toQString().toLower(); - if (project->isActiveConfig(QStringLiteral("winrt"))) { - winrtBuild = true; - - // Only add explicit support for arm64 cross-platform desktop builds. - } else if ((arch == QLatin1String("arm64")) && (msvcVer == QStringLiteral("15.0"))) { - crossPlatformDesktopBuild = true; - } - - if (winrtBuild || crossPlatformDesktopBuild) { - QString compiler; - QString compilerArch; - const ProStringList hostArch = project->values("QMAKE_TARGET.arch"); - if (msvcVer == QStringLiteral("15.0")) { - if (hostArch.contains("x86_64")) - compiler = QStringLiteral("HostX64/"); - else - compiler = QStringLiteral("HostX86/"); - if (arch == QLatin1String("arm")) { - compiler += QStringLiteral("arm"); - compilerArch = QStringLiteral("arm"); - } else if (arch == QLatin1String("x64")) { - compiler += QStringLiteral("x64"); - compilerArch = QStringLiteral("amd64"); - } else if (arch == QLatin1String("arm64")) { - compiler += QStringLiteral("arm64"); - compilerArch = QStringLiteral("arm64"); - } else { - arch = QStringLiteral("x86"); - compiler += QStringLiteral("x86"); - } - } else { - if (arch == QLatin1String("arm")) { - compiler = QStringLiteral("x86_arm"); - compilerArch = QStringLiteral("arm"); - } else if (arch == QLatin1String("x64")) { - const ProStringList hostArch = project->values("QMAKE_TARGET.arch"); - if (hostArch.contains("x86_64")) - compiler = QStringLiteral("amd64"); - else - compiler = QStringLiteral("x86_amd64"); - compilerArch = QStringLiteral("amd64"); - } else { - arch = QStringLiteral("x86"); - } - } - - const QString winsdkVer = project->first("WINSDK_VER").toQString(); - if (winsdkVer.isEmpty()) { - fprintf(stderr, "Mkspec does not specify WINSDK_VER. Cannot continue.\n"); - return false; - } - const QString targetVer = project->first("WINTARGET_VER").toQString(); - if (targetVer.isEmpty() && winrtBuild) { - fprintf(stderr, "Mkspec does not specify WINTARGET_VER. Cannot continue.\n"); - return false; - } - -#ifdef Q_OS_WIN - QString regKey; - if (msvcVer == QStringLiteral("15.0")) - regKey = QStringLiteral("Software\\Microsoft\\VisualStudio\\SxS\\VS7\\") + msvcVer; - else - regKey = QStringLiteral("Software\\Microsoft\\VisualStudio\\") + msvcVer + ("\\Setup\\VC\\ProductDir"); - const QString vcInstallDir = qt_readRegistryKey(HKEY_LOCAL_MACHINE, regKey, KEY_WOW64_32KEY); - if (vcInstallDir.isEmpty()) { - fprintf(stderr, "Failed to find the Visual Studio installation directory.\n"); - return false; - } - - const QString windowsPath = "Software\\Microsoft\\Microsoft SDKs\\Windows\\v"; - - regKey = windowsPath + winsdkVer + QStringLiteral("\\InstallationFolder"); - const QString kitDir = qt_readRegistryKey(HKEY_LOCAL_MACHINE, regKey, KEY_WOW64_32KEY); - if (kitDir.isEmpty()) { - fprintf(stderr, "Failed to find the Windows Kit installation directory.\n"); - return false; - } -#else - const QString vcInstallDir = "/fake/vc_install_dir"; - const QString kitDir = "/fake/sdk_install_dir"; -#endif // Q_OS_WIN - QStringList incDirs; - QStringList libDirs; - QStringList binDirs; - if (msvcVer == QStringLiteral("15.0")) { - const QString toolsInstallDir = qgetenv("VCToolsInstallDir"); - if (toolsInstallDir.isEmpty()) { - fprintf(stderr, "Failed to access tools installation dir.\n"); - return false; - } - - binDirs << toolsInstallDir + QStringLiteral("bin/") + compiler; - if (arch == QStringLiteral("x64")) - binDirs << toolsInstallDir + QStringLiteral("bin/HostX86/X86"); - binDirs << kitDir + QStringLiteral("bin/x86"); - binDirs << vcInstallDir + QStringLiteral("Common7/Tools"); - binDirs << vcInstallDir + QStringLiteral("Common7/ide"); - binDirs << vcInstallDir + QStringLiteral("MSBuild/15.0/bin"); - - incDirs << toolsInstallDir + QStringLiteral("include"); - incDirs << vcInstallDir + QStringLiteral("VC/Auxiliary/VS/include"); - - const QString crtVersion = qgetenv("UCRTVersion"); - if (crtVersion.isEmpty()) { - fprintf(stderr, "Failed to access CRT version.\n"); - return false; - } - const QString crtInclude = kitDir + QStringLiteral("Include/") + crtVersion; - const QString crtLib = kitDir + QStringLiteral("Lib/") + crtVersion; - incDirs << crtInclude + QStringLiteral("/ucrt"); - incDirs << crtInclude + QStringLiteral("/um"); - incDirs << crtInclude + QStringLiteral("/shared"); - incDirs << crtInclude + QStringLiteral("/winrt"); - - if (winrtBuild) { - libDirs << toolsInstallDir + QStringLiteral("lib/") + arch + QStringLiteral("/store"); - } else { - // Desktop projects may require the atl headers and libs. - incDirs << toolsInstallDir + QStringLiteral("atlmfc/include"); - libDirs << toolsInstallDir + QStringLiteral("atlmfc/lib/") + compilerArch; - libDirs << toolsInstallDir + QStringLiteral("lib/") + arch; - } - - libDirs << vcInstallDir + QStringLiteral("VC/Auxiliary/VS/lib/") + arch; - - libDirs << crtLib + QStringLiteral("/ucrt/") + arch; - libDirs << crtLib + QStringLiteral("/um/") + arch; - } else if (msvcVer == QStringLiteral("14.0")) { - binDirs << vcInstallDir + QStringLiteral("bin/") + compiler; - binDirs << vcInstallDir + QStringLiteral("bin/"); // Maybe remove for x86 again? - binDirs << kitDir + QStringLiteral("bin/") + (arch == QStringLiteral("arm") ? QStringLiteral("x86") : arch); - binDirs << vcInstallDir + QStringLiteral("../Common7/Tools/bin"); - binDirs << vcInstallDir + QStringLiteral("../Common7/Tools"); - binDirs << vcInstallDir + QStringLiteral("../Common7/ide"); - binDirs << kitDir + QStringLiteral("Windows Performance Toolkit/"); - - incDirs << vcInstallDir + QStringLiteral("include"); - incDirs << vcInstallDir + QStringLiteral("atlmfc/include"); - - const QString crtVersion = qgetenv("UCRTVersion"); - if (crtVersion.isEmpty()) { - fprintf(stderr, "Failed to access CRT version.\n"); - return false; - } - const QString crtInclude = kitDir + QStringLiteral("Include/") + crtVersion; - const QString crtLib = kitDir + QStringLiteral("Lib/") + crtVersion; - incDirs << crtInclude + QStringLiteral("/ucrt"); - incDirs << crtInclude + QStringLiteral("/um"); - incDirs << crtInclude + QStringLiteral("/shared"); - incDirs << crtInclude + QStringLiteral("/winrt"); - - libDirs << vcInstallDir + QStringLiteral("lib/store/") + compilerArch; - libDirs << vcInstallDir + QStringLiteral("atlmfc/lib") + compilerArch; - - libDirs << crtLib + QStringLiteral("/ucrt/") + arch; - libDirs << crtLib + QStringLiteral("/um/") + arch; - } else { - incDirs << vcInstallDir + QStringLiteral("/include"); - libDirs << vcInstallDir + QStringLiteral("/lib/store/") + compilerArch - << vcInstallDir + QStringLiteral("/lib/") + compilerArch; - binDirs << vcInstallDir + QStringLiteral("/bin/") + compiler - << vcInstallDir + QStringLiteral("/../Common7/IDE"); - libDirs << kitDir + QStringLiteral("/Lib/") + targetVer + ("/um/") + arch; - incDirs << kitDir + QStringLiteral("/include/um") - << kitDir + QStringLiteral("/include/shared") - << kitDir + QStringLiteral("/include/winrt"); - } - - binDirs << vcInstallDir + QStringLiteral("/bin"); - - // Inherit PATH - binDirs << QString::fromLocal8Bit(qgetenv("PATH")).split(QLatin1Char(';')); - - t << "\nINCLUDE = " << nmakePathList(incDirs); - t << "\nLIB = " << nmakePathList(libDirs); - t << "\nPATH = " << nmakePathList(binDirs) << '\n'; - } - } writeNmakeParts(t); return MakefileGenerator::writeMakefile(t); } -- cgit v1.2.3 From ecdccce8e468784e050b65052da193bb40e2d9b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Nowacki?= Date: Fri, 4 Jan 2019 13:48:56 +0100 Subject: Fix warnings about uninitialized variables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit qtbase/src/corelib/kernel/qmetatype.cpp: In static member function ‘static void QMetaType::destroy(int, void*)’: qtbase/src/corelib/kernel/qmetatype.cpp:2599:27: error: ‘info.QMetaType::m_destructor’ may be used uninitialized in this function [-Werror=maybe-uninitialized] if (m_typedDestructor && !m_destructor) ~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~ qtbase/src/corelib/kernel/qmetatype.cpp:1868:15: note: ‘info.QMetaType::m_destructor’ was declared here QMetaType info(type); ^~~~ qtbase/src/corelib/kernel/qmetatype.cpp:2600:26: error: ‘info.QMetaType::m_typedDestructor’ may be used uninitialized in this function [-Werror=maybe-uninitialized] m_typedDestructor(m_typeId, data); ~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~ qtbase/src/corelib/kernel/qmetatype.cpp:1868:15: note: ‘info.QMetaType::m_typedDestructor’ was declared here QMetaType info(type); ^~~~ The extended (not inlined) function may be called on a half initialized invalid instance. Change-Id: I26d677a8ad2bd0c5846233f06393e774d377936d Reviewed-by: Liang Qi Reviewed-by: Thiago Macieira --- src/corelib/kernel/qmetatype.cpp | 6 ++++++ tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp | 11 +++++++++++ 2 files changed, 17 insertions(+) diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp index eb67544f21..632b86959d 100644 --- a/src/corelib/kernel/qmetatype.cpp +++ b/src/corelib/kernel/qmetatype.cpp @@ -2566,6 +2566,8 @@ void *QMetaType::createExtended(const void *copy) const */ void QMetaType::destroyExtended(void *data) const { + if (m_typeId == QMetaType::UnknownType) + return; if (Q_UNLIKELY(m_typedDestructor && !m_destructor)) m_typedDestructor(m_typeId, data); else @@ -2582,6 +2584,8 @@ void QMetaType::destroyExtended(void *data) const */ void *QMetaType::constructExtended(void *where, const void *copy) const { + if (m_typeId == QMetaType::UnknownType) + return nullptr; if (m_typedConstructor && !m_constructor) return m_typedConstructor(m_typeId, where, copy); return nullptr; @@ -2596,6 +2600,8 @@ void *QMetaType::constructExtended(void *where, const void *copy) const */ void QMetaType::destructExtended(void *data) const { + if (m_typeId == QMetaType::UnknownType) + return; if (m_typedDestructor && !m_destructor) m_typedDestructor(m_typeId, data); } diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp index 5d9b5ca95c..e6fac74ccc 100644 --- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp +++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp @@ -123,6 +123,7 @@ private slots: void compareCustomType(); void compareCustomEqualOnlyType(); void customDebugStream(); + void unknownType(); }; struct BaseGenericType @@ -2529,6 +2530,16 @@ void tst_QMetaType::customDebugStream() qDebug() << v1; } +void tst_QMetaType::unknownType() +{ + QMetaType invalid(QMetaType::UnknownType); + QVERIFY(!invalid.create()); + QVERIFY(!invalid.sizeOf()); + QVERIFY(!invalid.metaObject()); + int buffer = 0xBAD; + invalid.construct(&buffer); + QCOMPARE(buffer, 0xBAD); +} // Compile-time test, it should be possible to register function pointer types class Undefined; -- cgit v1.2.3