diff --git a/mkspecs/features/data/cmake/Qt5BasicConfig.cmake.in b/mkspecs/features/data/cmake/Qt5BasicConfig.cmake.in index 2b56e1d369..4c3086a1f6 100644 --- a/mkspecs/features/data/cmake/Qt5BasicConfig.cmake.in +++ b/mkspecs/features/data/cmake/Qt5BasicConfig.cmake.in @@ -111,7 +111,7 @@ function(_qt5_$${CMAKE_MODULE_NAME}_process_prl_file prl_file_location Configura if(current_search_paths) find_library(_Qt5$${CMAKE_MODULE_NAME}_${Configuration}_${_lib}_PATH ${_lib} HINTS ${current_search_paths} NO_DEFAULT_PATH) endif() - find_library(_Qt5$${CMAKE_MODULE_NAME}_${Configuration}_${_lib}_PATH ${_lib}) + find_library(_Qt5$${CMAKE_MODULE_NAME}_${Configuration}_${_lib}_PATH ${_lib} HINTS ${CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES}) mark_as_advanced(_Qt5$${CMAKE_MODULE_NAME}_${Configuration}_${_lib}_PATH) if(_Qt5$${CMAKE_MODULE_NAME}_${Configuration}_${_lib}_PATH) list(APPEND _lib_deps diff --git a/mkspecs/features/qt_android_deps.prf b/mkspecs/features/qt_android_deps.prf index e50c24b966..354e40ed23 100644 --- a/mkspecs/features/qt_android_deps.prf +++ b/mkspecs/features/qt_android_deps.prf @@ -46,8 +46,8 @@ build_pass:!isEmpty(QT_ARCH): { EXTENDS = $$section(LIB_FILE, ":", 1, 1) !isEmpty(EXTENDS): EXTENDS = "extends=\"$$EXTENDS\"" LIB_FILE = $$section(LIB_FILE, ":", 0, 0) - LIB_FILE = $$replace(LIB_FILE,".so", "_$${QT_ARCH}.so") - !isEmpty(EXTENDS): EXTENDS = $$replace(EXTENDS,".so", "_$${QT_ARCH}.so") + LIB_FILE = $$replace(LIB_FILE,"\.so", "_$${QT_ARCH}.so") + !isEmpty(EXTENDS): EXTENDS = $$replace(EXTENDS,"\.so", "_$${QT_ARCH}.so") FILE_CONTENT += "" } } @@ -56,14 +56,14 @@ build_pass:!isEmpty(QT_ARCH): { for(REPLACEMENT, ANDROID_LIB_DEPENDENCY_REPLACEMENTS) { REPLACEMENT_FILE = $$section(REPLACEMENT, ":", 0, 0) LIB_FILE = $$section(REPLACEMENT, ":", 1, 1) - REPLACEMENT_FILE = $$replace(REPLACEMENT_FILE,".so", "_$${QT_ARCH}.so") + REPLACEMENT_FILE = $$replace(REPLACEMENT_FILE,"\.so", "_$${QT_ARCH}.so") FILE_CONTENT += "" } } !isEmpty(ANDROID_BUNDLED_FILES) { for (BUNDLED_FILE, ANDROID_BUNDLED_FILES) { - BUNDLED_FILE = $$replace(BUNDLED_FILE,".so", "_$${QT_ARCH}.so") + BUNDLED_FILE = $$replace(BUNDLED_FILE,"\.so", "_$${QT_ARCH}.so") FILE_CONTENT += "" } } diff --git a/mkspecs/features/resources_functions.prf b/mkspecs/features/resources_functions.prf index f0ca2ed793..fe2dc17d4d 100644 --- a/mkspecs/features/resources_functions.prf +++ b/mkspecs/features/resources_functions.prf @@ -34,7 +34,18 @@ defineTest(qtFlattenResources) { next() } - resource_file = $$absolute_path($$RCC_DIR/qmake_$${resource}.qrc, $$OUT_PWD) + RESOURCES -= $$resource + !android|isEmpty(BUILDS)|build_pass { + resource_file = $$absolute_path($$RCC_DIR/qmake_$${resource}.qrc, $$OUT_PWD) + RESOURCES += $$resource_file + } else { + # Android will need a resource file for each architecture make sure it is placed + # correctly for other functions that need the right paths for these files + for (arch, ANDROID_ABIS) { + resource_file = $$absolute_path($$RCC_DIR/qmake_$${resource}.qrc, $$OUT_PWD/$$arch) + RESOURCES += $$resource_file + } + } isEmpty(BUILDS)|build_pass { # Collection of files, generate qrc file @@ -69,9 +80,6 @@ defineTest(qtFlattenResources) { !write_file($$resource_file, resource_file_content): \ error() } - - RESOURCES -= $$resource - RESOURCES += $$resource_file } export(RCC_DIR) export(QMAKE_RESOURCES_IMMEDIATE_NR) diff --git a/qmake/doc/src/qmake-manual.qdoc b/qmake/doc/src/qmake-manual.qdoc index 3a1d79cb79..4c71ceb929 100644 --- a/qmake/doc/src/qmake-manual.qdoc +++ b/qmake/doc/src/qmake-manual.qdoc @@ -917,7 +917,7 @@ Specifies project configuration and compiler options. The values are recognized internally by qmake and have special meaning. - The following \c CONFIG values control compilation flags: + The following \c CONFIG values control compiler and linker flags: \table \header \li Option \li Description @@ -948,6 +948,8 @@ \row \li warn_off \li The compiler should output as few warnings as possible. \row \li exceptions \li Exception support is enabled. Set by default. \row \li exceptions_off \li Exception support is disabled. + \row \li ltcg \li Link time code generation is enabled. + This option is off by default. \row \li rtti \li RTTI support is enabled. By default, the compiler default is used. \row \li rtti_off \li RTTI support is disabled. By default, the compiler diff --git a/src/corelib/io/qstorageinfo_unix.cpp b/src/corelib/io/qstorageinfo_unix.cpp index 37b8a60c37..698c4ddf41 100644 --- a/src/corelib/io/qstorageinfo_unix.cpp +++ b/src/corelib/io/qstorageinfo_unix.cpp @@ -60,6 +60,7 @@ #elif defined(Q_OS_LINUX) || defined(Q_OS_HURD) # include # include +# include #elif defined(Q_OS_SOLARIS) # include # include @@ -152,7 +153,7 @@ private: //(2) parent ID: the ID of the parent mount (or of self for the top of the mount tree). // int parent_id; //(3) major:minor: the value of st_dev for files on this filesystem (see stat(2)). -// dev_t rdev; + dev_t rdev; //(4) root: the pathname of the directory in the filesystem which forms the root of this mount. char *subvolume; //(5) mount point: the pathname of the mount point relative to the process's root directory. @@ -503,8 +504,7 @@ inline bool QStorageIterator::next() int rdevminor = qstrtoll(ptr + 1, const_cast(&ptr), 10, &ok); if (!ptr || !ok) return false; - Q_UNUSED(rdevmajor); - Q_UNUSED(rdevminor); + mnt.rdev = makedev(rdevmajor, rdevminor); if (*ptr != ' ') return false; @@ -566,6 +566,21 @@ inline QByteArray QStorageIterator::fileSystemType() const inline QByteArray QStorageIterator::device() const { + // check that the device exists + if (mnt.mnt_fsname[0] == '/' && access(mnt.mnt_fsname, F_OK) != 0) { + // It doesn't, so let's try to resolve the dev_t from /dev/block. + // Note how strlen("4294967295") == digits10 + 1, so we need to add 1 + // for each number, plus the ':'. + char buf[sizeof("/dev/block/") + 2 * std::numeric_limits::digits10 + 3]; + QByteArray dev(PATH_MAX, Qt::Uninitialized); + char *devdata = dev.data(); + + snprintf(buf, sizeof(buf), "/dev/block/%u:%u", major(mnt.rdev), minor(mnt.rdev)); + if (realpath(buf, devdata)) { + dev.truncate(strlen(devdata)); + return dev; + } + } return QByteArray(mnt.mnt_fsname); } diff --git a/src/plugins/platforms/android/qandroidplatformfiledialoghelper.cpp b/src/plugins/platforms/android/qandroidplatformfiledialoghelper.cpp index 7585b7eb95..fb979ab6cc 100644 --- a/src/plugins/platforms/android/qandroidplatformfiledialoghelper.cpp +++ b/src/plugins/platforms/android/qandroidplatformfiledialoghelper.cpp @@ -100,10 +100,13 @@ bool QAndroidPlatformFileDialogHelper::show(Qt::WindowFlags windowFlags, Qt::Win void QAndroidPlatformFileDialogHelper::exec() { + m_eventLoop.exec(QEventLoop::DialogExec); } void QAndroidPlatformFileDialogHelper::hide() { + if (m_eventLoop.isRunning()) + m_eventLoop.exit(); QtAndroidPrivate::unregisterActivityResultListener(this); } diff --git a/src/plugins/platforms/android/qandroidplatformfiledialoghelper.h b/src/plugins/platforms/android/qandroidplatformfiledialoghelper.h index e445aa2fef..5cd26af7c9 100644 --- a/src/plugins/platforms/android/qandroidplatformfiledialoghelper.h +++ b/src/plugins/platforms/android/qandroidplatformfiledialoghelper.h @@ -41,6 +41,7 @@ #define QANDROIDPLATFORMFILEDIALOGHELPER_H #include +#include #include #include @@ -72,6 +73,7 @@ public: bool handleActivityResult(jint requestCode, jint resultCode, jobject data) override; private: + QEventLoop m_eventLoop; QUrl m_selectedFile; }; diff --git a/src/tools/androiddeployqt/main.cpp b/src/tools/androiddeployqt/main.cpp index 5ac22287e2..3d378024c9 100644 --- a/src/tools/androiddeployqt/main.cpp +++ b/src/tools/androiddeployqt/main.cpp @@ -2287,7 +2287,8 @@ static bool mergeGradleProperties(const QString &path, GradleProperties properti bool buildAndroidProject(const Options &options) { GradleProperties localProperties; - localProperties["sdk.dir"] = options.sdkPath.toLocal8Bit(); + localProperties["sdk.dir"] = options.sdkPath.toUtf8(); + localProperties["ndk.dir"] = options.ndkPath.toUtf8(); if (!mergeGradleProperties(options.outputDirectory + QLatin1String("local.properties"), localProperties)) return false; diff --git a/tests/auto/corelib/text/qstringapisymmetry/tst_qstringapisymmetry.cpp b/tests/auto/corelib/text/qstringapisymmetry/tst_qstringapisymmetry.cpp index 24382a2b61..bcf4e73108 100644 --- a/tests/auto/corelib/text/qstringapisymmetry/tst_qstringapisymmetry.cpp +++ b/tests/auto/corelib/text/qstringapisymmetry/tst_qstringapisymmetry.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2015 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Marc Mutz +** Copyright (C) 2019 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Marc Mutz ** Copyright (C) 2019 Mail.ru Group. ** Contact: https://www.qt.io/licensing/ ** @@ -80,6 +80,13 @@ MAKE_ALL(const char*, QChar) #undef MAKE_RELOP // END FIXME +static Q_DECL_CONSTEXPR int sign(int i) noexcept +{ + return i < 0 ? -1 : + i > 0 ? +1 : + /*else*/ 0 ; +} + // Return a plain ASCII row name consisting of maximum 16 chars and the // size for data static QByteArray rowName(const QByteArray &data) @@ -162,6 +169,12 @@ private Q_SLOTS: void compare_QStringView_QStringView() { compare_impl(); } void compare_QStringView_QLatin1String_data() { compare_data(); } void compare_QStringView_QLatin1String() { compare_impl(); } +#ifdef NOT_YET_IMPLMENTED + void compare_QStringView_QByteArray_data() { compare_data(); } + void compare_QStringView_QByteArray() { compare_impl(); } + void compare_QStringView_const_char_star_data() { compare_data(); } + void compare_QStringView_const_char_star() { compare_impl(); } +#endif void compare_QLatin1String_QChar_data() { compare_data(false); } void compare_QLatin1String_QChar() { compare_impl(); } @@ -204,6 +217,111 @@ private Q_SLOTS: //void compare_const_char_star_const_char_star_data() { compare_data(); } //void compare_const_char_star_const_char_star() { compare_impl(); } +private: + void member_compare_data(bool hasConceptOfNullAndEmpty=true) { compare_data(hasConceptOfNullAndEmpty); } + template + void member_compare_impl() const; + +private Q_SLOTS: + // test all combinations of {QChar, QStringRef, QString, QStringView, QLatin1String, QByteArray, const char*} +#ifdef NOT_YET_IMPLEMENTED // probably never will be - what's the point of QChar::compare(QStringView)? + void member_compare_QChar_QChar_data() { member_compare_data(false); } + void member_compare_QChar_QChar() { member_compare_impl(); } + void member_compare_QChar_QStringRef_data() { member_compare_data(false); } + void member_compare_QChar_QStringRef() { member_compare_impl(); } + void member_compare_QChar_QString_data() { member_compare_data(false); } + void member_compare_QChar_QString() { member_compare_impl(); } + void member_compare_QChar_QStringView_data() { member_compare_data(false); } + void member_compare_QChar_QStringView() { member_compare_impl(); } + void member_compare_QChar_QLatin1String_data() { member_compare_data(false); } + void member_compare_QChar_QLatin1String() { member_compare_impl(); } + void member_compare_QChar_QByteArray_data() { member_compare_data(false); } + void member_compare_QChar_QByteArray() { member_compare_impl(); } + void member_compare_QChar_const_char_star_data() { member_compare_data(false); } + void member_compare_QChar_const_char_star() { member_compare_impl(); } +#endif + + void member_compare_QStringRef_QChar_data() { member_compare_data(false); } + void member_compare_QStringRef_QChar() { member_compare_impl(); } + void member_compare_QStringRef_QStringRef_data() { member_compare_data(); } + void member_compare_QStringRef_QStringRef() { member_compare_impl(); } + void member_compare_QStringRef_QString_data() { member_compare_data(); } + void member_compare_QStringRef_QString() { member_compare_impl(); } +#ifdef NOT_YET_IMPLEMENTED + void member_compare_QStringRef_QStringView_data() { member_compare_data(); } + void member_compare_QStringRef_QStringView() { member_compare_impl(); } +#endif + void member_compare_QStringRef_QLatin1String_data() { member_compare_data(); } + void member_compare_QStringRef_QLatin1String() { member_compare_impl(); } + void member_compare_QStringRef_QByteArray_data() { member_compare_data(); } + void member_compare_QStringRef_QByteArray() { member_compare_impl(); } +#ifdef NOT_YET_IMPLEMENTED + void member_compare_QStringRef_const_char_star_data() { member_compare_data(); } + void member_compare_QStringRef_const_char_star() { member_compare_impl(); } +#endif + + void member_compare_QString_QChar_data() { member_compare_data(false); } + void member_compare_QString_QChar() { member_compare_impl(); } + void member_compare_QString_QStringRef_data() { member_compare_data(); } + void member_compare_QString_QStringRef() { member_compare_impl(); } + void member_compare_QString_QString_data() { member_compare_data(); } + void member_compare_QString_QString() { member_compare_impl(); } + void member_compare_QString_QStringView_data() { member_compare_data(); } + void member_compare_QString_QStringView() { member_compare_impl(); } + void member_compare_QString_QLatin1String_data() { member_compare_data(); } + void member_compare_QString_QLatin1String() { member_compare_impl(); } + void member_compare_QString_QByteArray_data() { member_compare_data(); } + void member_compare_QString_QByteArray() { member_compare_impl(); } + void member_compare_QString_const_char_star_data() { member_compare_data(); } + void member_compare_QString_const_char_star() { member_compare_impl(); } + +#ifdef NOT_YET_IMPLEMENTED // QChar doesn't implicitly convert to QStringView + void member_compare_QStringView_QChar_data() { member_compare_data(false); } + void member_compare_QStringView_QChar() { member_compare_impl(); } +#endif + void member_compare_QStringView_QStringRef_data() { member_compare_data(); } + void member_compare_QStringView_QStringRef() { member_compare_impl(); } + void member_compare_QStringView_QString_data() { member_compare_data(); } + void member_compare_QStringView_QString() { member_compare_impl(); } + void member_compare_QStringView_QStringView_data() { member_compare_data(); } + void member_compare_QStringView_QStringView() { member_compare_impl(); } +#ifdef NOT_YET_IMPLEMENTED + void member_compare_QStringView_QLatin1String_data() { member_compare_data(); } + void member_compare_QStringView_QLatin1String() { member_compare_impl(); } + void member_compare_QStringView_QByteArray_data() { member_compare_data(); } + void member_compare_QStringView_QByteArray() { member_compare_impl(); } + void member_compare_QStringView_const_char_star_data() { member_compare_data(); } + void member_compare_QStringView_const_char_star() { member_compare_impl(); } + + void member_compare_QLatin1String_QChar_data() { member_compare_data(false); } + void member_compare_QLatin1String_QChar() { member_compare_impl(); } + void member_compare_QLatin1String_QStringRef_data() { member_compare_data(); } + void member_compare_QLatin1String_QStringRef() { member_compare_impl(); } + void member_compare_QLatin1String_QString_data() { member_compare_data(); } + void member_compare_QLatin1String_QString() { member_compare_impl(); } + void member_compare_QLatin1String_QStringView_data() { member_compare_data(); } + void member_compare_QLatin1String_QStringView() { member_compare_impl(); } + void member_compare_QLatin1String_QLatin1String_data() { member_compare_data(); } + void member_compare_QLatin1String_QLatin1String() { member_compare_impl(); } + void member_compare_QLatin1String_QByteArray_data() { member_compare_data(); } + void member_compare_QLatin1String_QByteArray() { member_compare_impl(); } + void member_compare_QLatin1String_const_char_star_data() { member_compare_data(); } + void member_compare_QLatin1String_const_char_star() { member_compare_impl(); } + + void member_compare_QByteArray_QChar_data() { member_compare_data(false); } + void member_compare_QByteArray_QChar() { member_compare_impl(); } + void member_compare_QByteArray_QStringRef_data() { member_compare_data(); } + void member_compare_QByteArray_QStringRef() { member_compare_impl(); } + void member_compare_QByteArray_QString_data() { member_compare_data(); } + void member_compare_QByteArray_QString() { member_compare_impl(); } + void member_compare_QByteArray_QLatin1String_data() { member_compare_data(); } + void member_compare_QByteArray_QLatin1String() { member_compare_impl(); } +#endif + void member_compare_QByteArray_QByteArray_data() { member_compare_data(); } + void member_compare_QByteArray_QByteArray() { member_compare_impl(); } + void member_compare_QByteArray_const_char_star_data() { member_compare_data(); } + void member_compare_QByteArray_const_char_star() { member_compare_impl(); } + private: void startsWith_data(bool rhsIsQChar = false); template void startsWith_impl() const; @@ -601,7 +719,7 @@ void tst_QStringApiSymmetry::compare_data(bool hasConceptOfNullAndEmpty) QTest::newRow(qUtf8Printable(QLatin1String("'" lhs "' <> '" rhs "': "))) \ << QStringRef(&pinned[0]) << QLatin1String(lhs) \ << QStringRef(&pinned[1]) << QLatin1String(rhs) \ - << qstrcmp(lhs, rhs) << qstricmp(lhs, rhs); \ + << sign(qstrcmp(lhs, rhs)) << sign(qstricmp(lhs, rhs)); \ } while (false) ROW("", "0"); ROW("0", ""); @@ -691,6 +809,44 @@ void tst_QStringApiSymmetry::compare_impl() const #undef CHECK } +template +void tst_QStringApiSymmetry::member_compare_impl() const +{ + QFETCH(QStringRef, lhsUnicode); + QFETCH(QLatin1String, lhsLatin1); + QFETCH(QStringRef, rhsUnicode); + QFETCH(QLatin1String, rhsLatin1); + QFETCH(const int, caseSensitiveCompareResult); + QFETCH(const int, caseInsensitiveCompareResult); + + const auto lhsU8 = lhsUnicode.toUtf8(); + const auto rhsU8 = rhsUnicode.toUtf8(); + + const auto lhs = make(lhsUnicode, lhsLatin1, lhsU8); + const auto rhs = make(rhsUnicode, rhsLatin1, rhsU8); + +#define QVERIFY_NOEXCEPT(expr) do { \ + if (has_nothrow_compare::value) {} else \ + QEXPECT_FAIL("", "Qt is missing a nothrow utf8-utf16 comparator", Continue); \ + QVERIFY(noexcept(expr)); } while (0) + + if (std::is_same::value || // needs to simply be marked as noexcept + ((std::is_same::value || std::is_same::value) + && std::is_same::value)) // implict QChar -> QString conversion kills noexcept + QEXPECT_FAIL("", "known issues, will be fixed before 5.14 release", Continue); + QVERIFY_NOEXCEPT(lhs.compare(rhs, Qt::CaseSensitive)); + + QCOMPARE(sign(lhs.compare(rhs)), caseSensitiveCompareResult); + QCOMPARE(sign(lhs.compare(rhs, Qt::CaseSensitive)), caseSensitiveCompareResult); + if (is_utf8_encoded::value && is_utf8_encoded::value && + caseSensitiveCompareResult != caseInsensitiveCompareResult && + (!QtPrivate::isAscii(lhsUnicode) || !QtPrivate::isAscii(rhsUnicode))) + { + QEXPECT_FAIL("", "Qt is missing a case-insensitive UTF-8/UTF-8 comparator", Continue); + } + QCOMPARE(sign(lhs.compare(rhs, Qt::CaseInsensitive)), caseInsensitiveCompareResult); +} + static QString empty = QLatin1String(""); static QString null; // the tests below rely on the fact that these objects' names match their contents: