diff options
author | Christian Kandeler <christian.kandeler@qt.io> | 2018-10-12 13:17:46 +0200 |
---|---|---|
committer | Christian Kandeler <christian.kandeler@qt.io> | 2018-10-12 13:17:46 +0200 |
commit | 6f3e1896fa567bca8a9f3d35ea26cae518a9313e (patch) | |
tree | 7475ec4153bece275efc1a97d5fa7420aa07a880 | |
parent | ec709675476e507ea094348091b0475084de976e (diff) | |
parent | fa5e42f915211637da0d6461c9764962ee47f923 (diff) |
Merge 1.12 into master
Change-Id: I96c735aeda89e02f1fa9107ecfc10ebf4b554dbc
36 files changed, 374 insertions, 110 deletions
diff --git a/changelogs/changes-1.12.2.md b/changelogs/changes-1.12.2.md new file mode 100644 index 000000000..f578c8357 --- /dev/null +++ b/changelogs/changes-1.12.2.md @@ -0,0 +1,2 @@ +# Important bugfixes +* The Visual Studio 2017 Build Tools are properly supported now. diff --git a/doc/appendix/qbs-porting.qdoc b/doc/appendix/qbs-porting.qdoc index ffe935ad9..e17d7b0ac 100644 --- a/doc/appendix/qbs-porting.qdoc +++ b/doc/appendix/qbs-porting.qdoc @@ -144,15 +144,16 @@ } \endcode - \section2 HEADERS, SOURCES, FORMS, RESOURCES + \section2 HEADERS, SOURCES, FORMS, RESOURCES, OTHER_FILES - Include header, source, form, and resource files as values of - \l{Product::files}{Product.files} property: + Include header, source, form, and resource files as well as any + other files as values of a \l{Product::files}{Product.files} + or \l{Group::files}{Group.files} property: \code QtApplication { name: "myapp" - files: ["myapp.h", "myapp.cpp", "myapp.ui", "myapp.qrc"] + files: ["myapp.h", "myapp.cpp", "myapp.ui", "myapp.qrc", "readme.txt"] } \endcode diff --git a/doc/reference/modules/android-ndk-module.qdoc b/doc/reference/modules/android-ndk-module.qdoc index 08f54a9c9..8113a7c68 100644 --- a/doc/reference/modules/android-ndk-module.qdoc +++ b/doc/reference/modules/android-ndk-module.qdoc @@ -86,12 +86,12 @@ \list \li \c "c++_shared" \li \c "c++_static" - \li \c "gabi++_shared" - \li \c "gabi++_static" - \li \c "gnustl_shared" - \li \c "gnustl_static" - \li \c "stlport_shared" - \li \c "stlport_static" + \li \c "gabi++_shared" (until r17) + \li \c "gabi++_static" (until r17) + \li \c "gnustl_shared" (until r17) + \li \c "gnustl_static" (until r17) + \li \c "stlport_shared" (until r17) + \li \c "stlport_static" (until r17) \li \c "system" \endlist diff --git a/share/qbs/imports/qbs/Probes/MsvcProbe.qbs b/share/qbs/imports/qbs/Probes/MsvcProbe.qbs index d7e26b8e1..2d5faecdd 100644 --- a/share/qbs/imports/qbs/Probes/MsvcProbe.qbs +++ b/share/qbs/imports/qbs/Probes/MsvcProbe.qbs @@ -81,6 +81,8 @@ PathProbe { var inclPath = FileInfo.joinPaths(clParentDir, "INCLUDE"); if (!File.exists(inclPath)) inclPath = FileInfo.joinPaths(clParentDir, "..", "INCLUDE"); + if (!File.exists(inclPath)) + inclPath = FileInfo.joinPaths(clParentDir, "..", "..", "INCLUDE"); if (File.exists(inclPath)) includePaths = [inclPath]; diff --git a/share/qbs/modules/Android/ndk/utils.js b/share/qbs/modules/Android/ndk/utils.js index 4940f3ea1..7d1f7d6d0 100644 --- a/share/qbs/modules/Android/ndk/utils.js +++ b/share/qbs/modules/Android/ndk/utils.js @@ -61,7 +61,7 @@ function androidAbi(arch) { } } -function commonCompilerFlags(buildVariant, abi, armMode) { +function commonCompilerFlags(toolchain, buildVariant, abi, armMode) { var flags = ["-ffunction-sections", "-funwind-tables", "-Wa,--noexecstack", "-Werror=format-security"]; @@ -71,13 +71,17 @@ function commonCompilerFlags(buildVariant, abi, armMode) { flags.push("-fomit-frame-pointer"); if (abi === "arm64-v8a") { - flags.push("-fpic", "-fstack-protector", "-funswitch-loops", "-finline-limit=300"); + flags.push("-fpic", "-fstack-protector") + if (!toolchain.contains("clang")) + flags.push("-finline-limit=300", "-funswitch-loops"); if (buildVariant === "release") flags.push("-fstrict-aliasing"); } if (abi === "armeabi" || abi === "armeabi-v7a") { - flags.push("-fpic", "-fstack-protector", "-finline-limit=64"); + flags.push("-fpic", "-fstack-protector"); + if (!toolchain.contains("clang")) + flags.push("-finline-limit=64"); if (abi === "armeabi") flags.push("-mtune=xscale", "-msoft-float"); @@ -95,12 +99,17 @@ function commonCompilerFlags(buildVariant, abi, armMode) { flags.push("-fpic", "-finline-functions", "-fmessage-length=0", "-fno-inline-functions-called-once", "-fgcse-after-reload", "-frerun-cse-after-loop", "-frename-registers"); - if (buildVariant === "release") - flags.push("-funswitch-loops", "-finline-limit=300", "-fno-strict-aliasing"); + if (buildVariant === "release") { + flags.push("-fno-strict-aliasing"); + if (!toolchain.contains("clang")) + flags.push("-funswitch-loops", "-finline-limit=300"); + } } if (abi === "x86" || abi === "x86_64") { - flags.push("-fstack-protector", "-funswitch-loops", "-finline-limit=300"); + flags.push("-fstack-protector"); + if (!toolchain.contains("clang")) + flags.push("-funswitch-loops", "-finline-limit=300"); if (buildVariant === "release") flags.push("-fstrict-aliasing"); } @@ -114,3 +123,9 @@ function commonCompilerFlags(buildVariant, abi, armMode) { function commonLinkerFlags(abi) { return ["-z", "noexecstack", "-z", "relro", "-z", "now"]; } + +function getBinutilsPath(ndk, toolchainPrefix) { + if (["x86", "x86_64"].contains(ndk.abi)) + return ndk.abi + "-" + ndk.toolchainVersionNumber; + return toolchainPrefix + ndk.toolchainVersionNumber; +} diff --git a/share/qbs/modules/Android/sdk/sdk.qbs b/share/qbs/modules/Android/sdk/sdk.qbs index e2eb97929..8f4ec14d4 100644 --- a/share/qbs/modules/Android/sdk/sdk.qbs +++ b/share/qbs/modules/Android/sdk/sdk.qbs @@ -149,10 +149,13 @@ Module { buildToolsVersion, "24.0.3") >= 0 property stringList aidlSearchPaths - Depends { name: "java" } - java.languageVersion: platformJavaVersion - java.runtimeVersion: platformJavaVersion - java.bootClassPaths: androidJarFilePath + Depends { name: "java"; condition: _enableRules } + Properties { + condition: _enableRules + java.languageVersion: platformJavaVersion + java.runtimeVersion: platformJavaVersion + java.bootClassPaths: androidJarFilePath + } validate: { if (!sdkDir) { diff --git a/share/qbs/modules/Exporter/qbs/qbsexporter.js b/share/qbs/modules/Exporter/qbs/qbsexporter.js index 45324bb4e..16408174b 100644 --- a/share/qbs/modules/Exporter/qbs/qbsexporter.js +++ b/share/qbs/modules/Exporter/qbs/qbsexporter.js @@ -154,7 +154,7 @@ function stringifyValue(project, product, moduleInstallDir, prop, value) var deployedModuleInstallDir = moduleInstallDir.slice(fullInstallPrefix.length); return "FileInfo.cleanPath(FileInfo.joinPaths(path, FileInfo.relativePath(" + JSON.stringify(deployedModuleInstallDir) + ", " - + JSON.stringify(value.slice(valuePrefixToStrip.length)) + ")))"; + + JSON.stringify(value.slice(valuePrefixToStrip.length) || "/") + ")))"; } return JSON.stringify(value); diff --git a/share/qbs/modules/cpp/android-gcc.qbs b/share/qbs/modules/cpp/android-gcc.qbs index 18ca1c25d..e20f1e198 100644 --- a/share/qbs/modules/cpp/android-gcc.qbs +++ b/share/qbs/modules/cpp/android-gcc.qbs @@ -32,7 +32,9 @@ import qbs.File import qbs.FileInfo import qbs.ModUtils import qbs.TextFile +import qbs.Utilities import "../../modules/Android/ndk/utils.js" as NdkUtils +import 'gcc.js' as Gcc LinuxGCC { Depends { name: "Android.ndk" } @@ -43,11 +45,11 @@ LinuxGCC { rpaths: [rpathOrigin] property string toolchainDir: { - if (qbs.toolchain && qbs.toolchain.contains("clang")) - return "llvm-" + Android.ndk.toolchainVersionNumber; - if (["x86", "x86_64"].contains(Android.ndk.abi)) - return Android.ndk.abi + "-" + Android.ndk.toolchainVersionNumber; - return toolchainPrefix + Android.ndk.toolchainVersionNumber; + if (qbs.toolchain && qbs.toolchain.contains("clang")) { + return Utilities.versionCompare(Android.ndk.version, "10") <= 0 + ? "llvm-" + Android.ndk.toolchainVersionNumber : "llvm"; + } + return NdkUtils.getBinutilsPath(Android.ndk, toolchainTriple + "-") } property string cxxStlBaseDir: FileInfo.joinPaths(Android.ndk.ndkDir, "sources", "cxx-stl") @@ -126,8 +128,8 @@ LinuxGCC { enableExceptions: Android.ndk.appStl !== "system" enableRtti: Android.ndk.appStl !== "system" - commonCompilerFlags: NdkUtils.commonCompilerFlags(qbs.buildVariant, Android.ndk.abi, - Android.ndk.armMode) + commonCompilerFlags: NdkUtils.commonCompilerFlags(qbs.toolchain, qbs.buildVariant, + Android.ndk.abi, Android.ndk.armMode) linkerFlags: NdkUtils.commonLinkerFlags(Android.ndk.abi) @@ -171,7 +173,10 @@ LinuxGCC { includes.push(FileInfo.joinPaths(gnuStlBaseDir, "libs", Android.ndk.abi, "include")); includes.push(FileInfo.joinPaths(gnuStlBaseDir, "include", "backward")); } else if (Android.ndk.appStl.startsWith("c++_")) { - includes.push(FileInfo.joinPaths(llvmStlBaseDir, "libcxx", "include")); + if (Utilities.versionCompare(Android.ndk.version, "13") >= 0) + includes.push(FileInfo.joinPaths(llvmStlBaseDir, "include")); + else + includes.push(FileInfo.joinPaths(llvmStlBaseDir, "libcxx", "include")); includes.push(FileInfo.joinPaths(llvmStlBaseDir + "abi", "libcxxabi", "include")); } return includes; @@ -184,6 +189,12 @@ LinuxGCC { } return list; } + binutilsPath: FileInfo.joinPaths(Android.ndk.ndkDir, "toolchains", + NdkUtils.getBinutilsPath(Android.ndk, toolchainTriple + "-"), + "prebuilt", Android.ndk.hostArch, "bin"); + binutilsPathPrefix: Gcc.pathPrefix(binutilsPath, toolchainTriple + "-") + driverFlags: qbs.toolchain.contains("clang") + ? ["-gcc-toolchain", FileInfo.path(binutilsPath)].concat(base || []) : base syslibroot: FileInfo.joinPaths(Android.ndk.ndkDir, "platforms", Android.ndk.platform, "arch-" + NdkUtils.abiNameToDirName(Android.ndk.abi)) diff --git a/src/app/qbs-setup-android/android-setup.cpp b/src/app/qbs-setup-android/android-setup.cpp index eb5ba92dd..d32cdbc05 100644 --- a/src/app/qbs-setup-android/android-setup.cpp +++ b/src/app/qbs-setup-android/android-setup.cpp @@ -46,6 +46,7 @@ #include <tools/settings.h> #include <tools/version.h> +#include <QtCore/qbytearraylist.h> #include <QtCore/qcoreapplication.h> #include <QtCore/qdir.h> #include <QtCore/qdiriterator.h> @@ -65,10 +66,7 @@ static QStringList expectedArchs() { return QStringList() << QStringLiteral("arm64") - << QStringLiteral("armv5te") << QStringLiteral("armv7a") - << QStringLiteral("mips") - << QStringLiteral("mips64") << QStringLiteral("x86") << QStringLiteral("x86_64"); } @@ -181,6 +179,29 @@ static QString maximumPlatform(const QString &platform1, const QString &platform return prefix + QString::number(std::max(value1, value2)); } +static QString getToolchainType(const QString &ndkDirPath) +{ + QFile sourceProperties(ndkDirPath + qls("/source.properties")); + if (!sourceProperties.open(QIODevice::ReadOnly)) + return QLatin1String("gcc"); // <= r10 + while (!sourceProperties.atEnd()) { + const QByteArray curLine = sourceProperties.readLine().simplified(); + static const QByteArray prefix = "Pkg.Revision = "; + if (!curLine.startsWith(prefix)) + continue; + qbs::Version ndkVersion = qbs::Version::fromString( + QString::fromLatin1(curLine.mid(prefix.size()))); + if (!ndkVersion.isValid()) { + qWarning("Unexpected format of NDK revision string in '%s'", + qPrintable(sourceProperties.fileName())); + return QLatin1String("clang"); + } + return qls(ndkVersion.majorVersion() >= 18 ? "clang" : "gcc"); + } + qWarning("No revision entry found in '%s'", qPrintable(sourceProperties.fileName())); + return QLatin1String("clang"); +} + static void setupNdk(qbs::Settings *settings, const QString &profileName, const QString &ndkDirPath, const QString &qtSdkDirPath) { @@ -194,7 +215,7 @@ static void setupNdk(qbs::Settings *settings, const QString &profileName, const mainProfile.setValue(qls("Android.ndk.ndkDir"), QDir::cleanPath(ndkDirPath)); mainProfile.setValue(qls("Android.sdk.ndkDir"), QDir::cleanPath(ndkDirPath)); } - mainProfile.setValue(qls("qbs.toolchain"), QStringList() << qls("gcc")); + mainProfile.setValue(qls("qbs.toolchainType"), getToolchainType(ndkDirPath)); const QStringList archs = expectedArchs(); const QtInfoPerArch infoPerArch = getQtAndroidInfo(qtSdkDirPath); const QStringList archsForProfile = infoPerArch.empty() diff --git a/src/app/qbs-setup-toolchains/msvcprobe.cpp b/src/app/qbs-setup-toolchains/msvcprobe.cpp index 919f88d12..967d443a2 100644 --- a/src/app/qbs-setup-toolchains/msvcprobe.cpp +++ b/src/app/qbs-setup-toolchains/msvcprobe.cpp @@ -55,9 +55,14 @@ #include <QtCore/qdir.h> #include <QtCore/qfileinfo.h> +#include <QtCore/qjsonarray.h> +#include <QtCore/qjsondocument.h> +#include <QtCore/qjsonobject.h> +#include <QtCore/qprocess.h> #include <QtCore/qsettings.h> #include <QtCore/qstringlist.h> +#include <algorithm> #include <vector> using namespace qbs; @@ -155,15 +160,92 @@ static QString wow6432Key() #endif } -struct MSVCRegistryEntry +struct MSVCInstallInfo { QString version; QString installDir; }; -static std::vector<MSVCRegistryEntry> installedMSVCsFromRegistry() +static QString vswhereFilePath() { - std::vector<MSVCRegistryEntry> result; + static const std::vector<const char *> envVarCandidates{"ProgramFiles", "ProgramFiles(x86)"}; + for (const char * const envVar : envVarCandidates) { + const QString value = QDir::fromNativeSeparators(QString::fromLocal8Bit(qgetenv(envVar))); + const QString cmd = value + + QStringLiteral("/Microsoft Visual Studio/Installer/vswhere.exe"); + if (QFileInfo(cmd).exists()) + return cmd; + } + return QString(); +} + +enum class ProductType { VisualStudio, BuildTools }; +static std::vector<MSVCInstallInfo> retrieveInstancesFromVSWhere(ProductType productType) +{ + std::vector<MSVCInstallInfo> result; + const QString cmd = vswhereFilePath(); + if (cmd.isEmpty()) + return result; + QProcess vsWhere; + QStringList args = productType == ProductType::VisualStudio + ? QStringList({QStringLiteral("-all"), QStringLiteral("-legacy"), + QStringLiteral("-prerelease")}) + : QStringList({QStringLiteral("-products"), + QStringLiteral("Microsoft.VisualStudio.Product.BuildTools")}); + args << QStringLiteral("-format") << QStringLiteral("json") << QStringLiteral("-utf8"); + vsWhere.start(cmd, args); + if (!vsWhere.waitForStarted(-1)) + return result; + if (!vsWhere.waitForFinished(-1)) { + qbsWarning() << Tr::tr("The vswhere tool failed to run: %1").arg(vsWhere.errorString()); + return result; + } + if (vsWhere.exitCode() != 0) { + qbsWarning() << Tr::tr("The vswhere tool failed to run: %1") + .arg(QString::fromLocal8Bit(vsWhere.readAllStandardError())); + return result; + } + QJsonParseError parseError; + QJsonDocument jsonOutput = QJsonDocument::fromJson(vsWhere.readAllStandardOutput(), + &parseError); + if (parseError.error != QJsonParseError::NoError) { + qbsWarning() << Tr::tr("The vswhere tool produced invalid JSON output: %1") + .arg(parseError.errorString()); + return result; + } + for (const QJsonValue &v : jsonOutput.array()) { + const QJsonObject o = v.toObject(); + MSVCInstallInfo info; + info.version = o.value(QStringLiteral("installationVersion")).toString(); + if (productType == ProductType::BuildTools) { + // For build tools, the version is e.g. "15.8.28010.2036", rather than "15.0". + const int dotIndex = info.version.indexOf(QLatin1Char('.')); + if (dotIndex != -1) + info.version = info.version.left(dotIndex); + } + info.installDir = o.value(QStringLiteral("installationPath")).toString(); + if (!info.version.isEmpty() && !info.installDir.isEmpty()) + result.push_back(info); + } + return result; +} + +static std::vector<MSVCInstallInfo> installedMSVCsFromVsWhere() +{ + const std::vector<MSVCInstallInfo> vsInstallations + = retrieveInstancesFromVSWhere(ProductType::VisualStudio); + const std::vector<MSVCInstallInfo> buildToolInstallations + = retrieveInstancesFromVSWhere(ProductType::BuildTools); + std::vector<MSVCInstallInfo> all; + std::copy(vsInstallations.begin(), vsInstallations.end(), std::back_inserter(all)); + std::copy(buildToolInstallations.begin(), buildToolInstallations.end(), + std::back_inserter(all)); + return all; +} + +static std::vector<MSVCInstallInfo> installedMSVCsFromRegistry() +{ + std::vector<MSVCInstallInfo> result; // Detect Visual Studio const QSettings vsRegistry( @@ -172,7 +254,7 @@ static std::vector<MSVCRegistryEntry> installedMSVCsFromRegistry() QSettings::NativeFormat); const auto vsNames = vsRegistry.childKeys(); for (const QString &vsName : vsNames) { - MSVCRegistryEntry entry; + MSVCInstallInfo entry; entry.version = vsName; entry.installDir = vsRegistry.value(vsName).toString(); result.push_back(entry); @@ -189,7 +271,7 @@ static std::vector<MSVCRegistryEntry> installedMSVCsFromRegistry() bool ok; int installed = vcbtRegistry.value(QStringLiteral("Installed")).toInt(&ok); if (ok && installed) { - MSVCRegistryEntry entry; + MSVCInstallInfo entry; entry.version = childGroup; const QSettings vsRegistry( QStringLiteral("HKEY_LOCAL_MACHINE\\SOFTWARE") + wow6432Key() @@ -208,14 +290,16 @@ static std::vector<MSVCRegistryEntry> installedMSVCsFromRegistry() static std::vector<MSVC> installedMSVCs() { std::vector<MSVC> msvcs; - const std::vector<MSVCRegistryEntry> ®istryEntries = installedMSVCsFromRegistry(); - for (const MSVCRegistryEntry ®istryEntry : registryEntries) { + std::vector<MSVCInstallInfo> installInfos = installedMSVCsFromVsWhere(); + if (installInfos.empty()) + installInfos = installedMSVCsFromRegistry(); + for (const MSVCInstallInfo &installInfo : installInfos) { MSVC msvc; - msvc.internalVsVersion = Version::fromString(registryEntry.version); + msvc.internalVsVersion = Version::fromString(installInfo.version); if (!msvc.internalVsVersion.isValid()) continue; - QDir vsInstallDir(registryEntry.installDir); + QDir vsInstallDir(installInfo.installDir); msvc.vsInstallPath = vsInstallDir.absolutePath(); if (vsInstallDir.dirName() != QStringLiteral("VC") && !vsInstallDir.cd(QStringLiteral("VC"))) { @@ -223,9 +307,9 @@ static std::vector<MSVC> installedMSVCs() } msvc.version = QString::number(Internal::VisualStudioVersionInfo( - Version::fromString(registryEntry.version)).marketingVersion()); + Version::fromString(installInfo.version)).marketingVersion()); if (msvc.version.isEmpty()) { - qbsWarning() << Tr::tr("Unknown MSVC version %1 found.").arg(registryEntry.version); + qbsWarning() << Tr::tr("Unknown MSVC version %1 found.").arg(installInfo.version); continue; } diff --git a/src/lib/corelib/language/astpropertiesitemhandler.cpp b/src/lib/corelib/language/astpropertiesitemhandler.cpp index 1b53f2f0b..1ea78bf79 100644 --- a/src/lib/corelib/language/astpropertiesitemhandler.cpp +++ b/src/lib/corelib/language/astpropertiesitemhandler.cpp @@ -135,7 +135,6 @@ private: void doApply(const QString &propertyName, Item *item, JSSourceValuePtr value, const JSSourceValuePtr &conditionalValue) { - QBS_ASSERT(!value || value->file() == conditionalValue->file(), return); if (!value) { value = JSSourceValue::create(true); value->setFile(conditionalValue->file()); diff --git a/src/lib/corelib/tools/persistence.h b/src/lib/corelib/tools/persistence.h index bd18bdf9d..e8d938ad3 100644 --- a/src/lib/corelib/tools/persistence.h +++ b/src/lib/corelib/tools/persistence.h @@ -52,7 +52,6 @@ #include <QtCore/qstring.h> #include <QtCore/qvariant.h> -#include <ctime> #include <memory> #include <type_traits> #include <unordered_map> @@ -371,19 +370,6 @@ template<> struct PPHelper<long> } }; -template<typename T> -struct PPHelper<T, std::enable_if_t<std::is_same<T, std::time_t>::value - && !std::is_same<T, long>::value>> -{ - static void store(std::time_t value, PersistentPool *pool) { pool->m_stream << qint64(value); } - static void load(std::time_t &value, PersistentPool *pool) - { - qint64 v; - pool->m_stream >> v; - value = static_cast<std::time_t>(v); - } -}; - template<typename T> struct PPHelper<T, std::enable_if_t<std::is_enum<T>::value>> { using U = std::underlying_type_t<T>; diff --git a/src/lib/corelib/tools/vsenvironmentdetector.cpp b/src/lib/corelib/tools/vsenvironmentdetector.cpp index 32e6d3497..21ce3406f 100644 --- a/src/lib/corelib/tools/vsenvironmentdetector.cpp +++ b/src/lib/corelib/tools/vsenvironmentdetector.cpp @@ -218,7 +218,7 @@ void VsEnvironmentDetector::writeBatchFile(QIODevice *device, const QString &vcv { const QStringList varnames = QStringList() << StringConstants::pathEnvVar() << QLatin1String("INCLUDE") << QLatin1String("LIB") << QLatin1String("WindowsSdkDir") - << QLatin1String("WindowsSDKVersion"); + << QLatin1String("WindowsSDKVersion") << QLatin1String("VSINSTALLDIR"); QTextStream s(device); s << "@echo off" << endl; for (const MSVC *msvc : msvcs) { diff --git a/src/lib/qtprofilesetup/qtmoduleinfo.cpp b/src/lib/qtprofilesetup/qtmoduleinfo.cpp index 95799632c..56827a458 100644 --- a/src/lib/qtprofilesetup/qtmoduleinfo.cpp +++ b/src/lib/qtprofilesetup/qtmoduleinfo.cpp @@ -280,6 +280,25 @@ static QStringList makeList(const QByteArray &s) return QString::fromLatin1(s).split(QLatin1Char(' '), QString::SkipEmptyParts); } +static QString guessLibraryFilePath(const QString &prlFilePath, const QString &libDir, + const QtEnvironment &qtEnv) +{ + const QString baseName = QFileInfo(prlFilePath).baseName(); + const QStringList prefixCandidates{QString(), QLatin1String("lib")}; + const QStringList suffixCandidates{QLatin1String("so.") + qtEnv.qtVersion, + QLatin1String("so"), QLatin1String("a"), QLatin1String("lib"), + QLatin1String("dll.a")}; + for (const QString &prefix : prefixCandidates) { + for (const QString &suffix : suffixCandidates) { + const QString candidate = libDir + QLatin1Char('/') + prefix + baseName + + QLatin1Char('.') + suffix; + if (QFile::exists(candidate)) + return candidate; + } + } + return QString(); +} + void QtModuleInfo::setupLibraries(const QtEnvironment &qtEnv, bool debugBuild, Internal::Set<QString> *nonExistingPrlFiles) { @@ -337,19 +356,17 @@ void QtModuleInfo::setupLibraries(const QtEnvironment &qtEnv, bool debugBuild, if (isNonStaticQt4OnWindows) prlFilePath.chop(1); // The prl file base name does *not* contain the version number... prlFilePath.append(QLatin1String(".prl")); - if (nonExistingPrlFiles->contains(prlFilePath)) - return; QFile prlFile(prlFilePath); if (!prlFile.open(QIODevice::ReadOnly)) { - // We can't error out here, as some modules in a self-built Qt don't have the expected - // file names. Real-life example: "libQt0Feedback.prl". This is just too stupid - // to work around, so let's ignore it. - if (mustExist) { - qDebug("Skipping prl file '%s', because it cannot be opened (%s).", - qPrintable(prlFilePath), - qPrintable(prlFile.errorString())); + libFilePath = guessLibraryFilePath(prlFilePath, libDir, qtEnv); + if (nonExistingPrlFiles->insert(prlFilePath).second) { + if (mustExist && libFilePath.isEmpty()) { + qDebug("Could not open prl file '%s' for module '%s' (%s), and failed to deduce " + "the library file path. This module will likely not be usable by qbs.", + qPrintable(prlFilePath), qPrintable(name), + qPrintable(prlFile.errorString())); + } } - nonExistingPrlFiles->insert(prlFilePath); return; } const QList<QByteArray> prlLines = prlFile.readAll().split('\n'); @@ -643,6 +660,34 @@ static QList<QByteArray> getPriFileContentsRecursively(const Profile &profile, return lines; } +static QStringList extractPaths(const QByteArray &rhs, const QString &filePath) +{ + QStringList paths; + int startIndex = 0; + for (;;) { + while (startIndex < rhs.size() && rhs.at(startIndex) == ' ') + ++startIndex; + if (startIndex >= rhs.size()) + break; + int endIndex; + if (rhs.at(startIndex) == '"') { + ++startIndex; + endIndex = rhs.indexOf('"', startIndex); + if (endIndex == -1) { + qDebug("Unmatched quote in file '%s'", qPrintable(filePath)); + break; + } + } else { + endIndex = rhs.indexOf(' ', startIndex + 1); + if (endIndex == -1) + endIndex = rhs.size(); + } + paths << QString::fromLocal8Bit(rhs.mid(startIndex, endIndex - startIndex)); + startIndex = endIndex + 1; + } + return paths; +} + QList<QtModuleInfo> allQt5Modules(const Profile &profile, const QtEnvironment &qtEnvironment) { Internal::Set<QString> nonExistingPrlFiles; @@ -705,7 +750,7 @@ QList<QtModuleInfo> allQt5Modules(const Profile &profile, const QtEnvironment &q hasV2 = true; } } else if (key.endsWith(".includes")) { - moduleInfo.includePaths = QString::fromLocal8Bit(value).split(QLatin1Char(' ')); + moduleInfo.includePaths = extractPaths(value, dit.filePath()); for (auto &includePath : moduleInfo.includePaths) { includePath .replace(QLatin1String("$$QT_MODULE_INCLUDE_BASE"), diff --git a/src/lib/qtprofilesetup/templates/core.qbs b/src/lib/qtprofilesetup/templates/core.qbs index fe961f219..7f7329501 100644 --- a/src/lib/qtprofilesetup/templates/core.qbs +++ b/src/lib/qtprofilesetup/templates/core.qbs @@ -115,6 +115,20 @@ Module { } return defines; } + cpp.driverFlags: { + var flags = []; + if (qbs.toolchain.contains("gcc")) { + if (config.contains("sanitize_address")) + flags.push("-fsanitize=address"); + if (config.contains("sanitize_undefined")) + flags.push("-fsanitize=undefined"); + if (config.contains("sanitize_thread")) + flags.push("-fsanitize=thread"); + if (config.contains("sanitize_memory")) + flags.push("-fsanitize=memory"); + } + return flags; + } cpp.includePaths: { var paths = @includes@; paths.push(mkspecPath, generatedHeadersDir); diff --git a/tests/auto/blackbox/testdata-android/multiple-apks-per-project/product1/product1.qbs b/tests/auto/blackbox/testdata-android/multiple-apks-per-project/product1/product1.qbs index 5d2978f7e..c4a78a30b 100644 --- a/tests/auto/blackbox/testdata-android/multiple-apks-per-project/product1/product1.qbs +++ b/tests/auto/blackbox/testdata-android/multiple-apks-per-project/product1/product1.qbs @@ -5,8 +5,9 @@ Project { name: "p1lib1" files: ["src/main/jni/lib1.cpp"] qbs.targetPlatform: "android" + Properties { condition: qbs.toolchain.contains("clang"); Android.ndk.appStl: "c++_shared" } Android.ndk.appStl: "stlport_shared" - qbs.architectures: !qbs.architecture ? ["mips", "x86"] : undefined + qbs.architectures: !qbs.architecture ? ["armv7a", "x86"] : undefined cpp.useRPaths: false } @@ -16,6 +17,7 @@ Project { name: "p1lib2" files: ["src/main/jni/lib2.cpp"] qbs.targetPlatform: "android" + Properties { condition: qbs.toolchain.contains("clang"); Android.ndk.appStl: "c++_shared" } Android.ndk.appStl: "stlport_shared" cpp.useRPaths: false } diff --git a/tests/auto/blackbox/testdata-android/multiple-apks-per-project/product2/product2.qbs b/tests/auto/blackbox/testdata-android/multiple-apks-per-project/product2/product2.qbs index 63065883b..9be70dcda 100644 --- a/tests/auto/blackbox/testdata-android/multiple-apks-per-project/product2/product2.qbs +++ b/tests/auto/blackbox/testdata-android/multiple-apks-per-project/product2/product2.qbs @@ -13,6 +13,7 @@ Project { name: "p2lib2" files: ["src/main/jni/lib2.cpp"] qbs.targetPlatform: "android" + Properties { condition: qbs.toolchain.contains("clang"); Android.ndk.appStl: "c++_shared" } Android.ndk.appStl: "stlport_shared" } diff --git a/tests/auto/blackbox/testdata-android/multiple-libs-per-apk/multiple-libs-per-apk.qbs b/tests/auto/blackbox/testdata-android/multiple-libs-per-apk/multiple-libs-per-apk.qbs index 2aafd5861..8b9ded211 100644 --- a/tests/auto/blackbox/testdata-android/multiple-libs-per-apk/multiple-libs-per-apk.qbs +++ b/tests/auto/blackbox/testdata-android/multiple-libs-per-apk/multiple-libs-per-apk.qbs @@ -5,6 +5,7 @@ Project { name: "lib1" files: ["src/main/jni/lib1.cpp"] qbs.targetPlatform: "android" + Properties { condition: qbs.toolchain.contains("clang"); Android.ndk.appStl: "c++_shared" } Android.ndk.appStl: "stlport_shared" cpp.useRPaths: false } @@ -15,6 +16,7 @@ Project { name: "lib2" files: ["src/main/jni/lib2.cpp"] qbs.targetPlatform: "android" + Properties { condition: qbs.toolchain.contains("clang"); Android.ndk.appStl: "c++_shared" } Android.ndk.appStl: "stlport_shared" cpp.useRPaths: false } diff --git a/tests/auto/blackbox/testdata-android/teapot/teapot.qbs b/tests/auto/blackbox/testdata-android/teapot/teapot.qbs index 69e06a032..2b5cb8aba 100644 --- a/tests/auto/blackbox/testdata-android/teapot/teapot.qbs +++ b/tests/auto/blackbox/testdata-android/teapot/teapot.qbs @@ -5,6 +5,7 @@ Project { StaticLibrary { name: "native-glue" qbs.targetPlatform: "android" + cpp.warningLevel: "none" Depends { name: "cpp" } Group { id: glue_sources @@ -22,6 +23,7 @@ Project { StaticLibrary { name: "ndk-helper" qbs.targetPlatform: "android" + cpp.warningLevel: "none" Depends { name: "Android.ndk" } Depends { name: "cpp" } Depends { name: "native-glue" } @@ -49,6 +51,7 @@ Project { files: ["*.cpp", "*.h"].concat( !File.exists(ndkHelperProbe.dir + "/gl3stub.cpp") ? ["gl3stub.c"] : []) } + Properties { condition: qbs.toolchain.contains("clang"); Android.ndk.appStl: "c++_shared" } Android.ndk.appStl: "gnustl_shared" cpp.cxxLanguageVersion: "c++11" @@ -133,6 +136,7 @@ Project { Android.sdk.apkBaseName: name Android.sdk.packageName: "com.sample.teapot" Android.sdk.sourceSetDir: teapotProbe.dir + Properties { condition: qbs.toolchain.contains("clang"); Android.ndk.appStl: "c++_shared" } Android.ndk.appStl: "gnustl_shared" cpp.cxxLanguageVersion: "c++11" cpp.dynamicLibraries: ["log", "android", "EGL", "GLESv2"] diff --git a/tests/auto/blackbox/testdata-apple/apple-multiconfig/apple-multiconfig.qbs b/tests/auto/blackbox/testdata-apple/apple-multiconfig/apple-multiconfig.qbs index 289678dfc..6dca8ffd3 100644 --- a/tests/auto/blackbox/testdata-apple/apple-multiconfig/apple-multiconfig.qbs +++ b/tests/auto/blackbox/testdata-apple/apple-multiconfig/apple-multiconfig.qbs @@ -2,6 +2,7 @@ import qbs.Utilities Project { minimumQbsVersion: "1.8" + property bool enableX86 CppApplication { Depends { name: "singlelib" } @@ -10,7 +11,7 @@ Project { targetName: "singleapp" files: ["app.c"] cpp.rpaths: [cpp.rpathOrigin + "/../../../"] - cpp.minimumMacosVersion: "10.5" + cpp.minimumMacosVersion: "10.6" // Turn off multiplexing aggregate: false @@ -27,7 +28,7 @@ Project { targetName: "singleapp_agg" files: ["app.c"] cpp.rpaths: [cpp.rpathOrigin + "/../../../"] - cpp.minimumMacosVersion: "10.5" + cpp.minimumMacosVersion: "10.6" // Force aggregation when not needed aggregate: true @@ -62,7 +63,7 @@ Project { targetName: "multiapp" files: ["app.c"] cpp.rpaths: [cpp.rpathOrigin + "/../../../"] - cpp.minimumMacosVersion: "10.5" + cpp.minimumMacosVersion: "10.6" install: true installDir: "" @@ -75,8 +76,11 @@ Project { targetName: "fatmultiapp" files: ["app.c"] cpp.rpaths: [cpp.rpathOrigin + "/../../../"] - cpp.minimumMacosVersion: "10.5" - qbs.architectures: ["x86", "x86_64"] + cpp.minimumMacosVersion: "10.6" + qbs.architectures: project.enableX86 ? ["x86", "x86_64"] : ["x86_64"] + qbs.architecture: "x86_64" + multiplexByQbsProperties: project.enableX86 ? ["architectures", "buildVariants"] + : ["buildVariants"] install: true installDir: "" @@ -89,8 +93,8 @@ Project { targetName: "fatmultiappmultivariant" files: ["app.c"] cpp.rpaths: [cpp.rpathOrigin + "/../../../"] - cpp.minimumMacosVersion: "10.5" - qbs.architectures: ["x86", "x86_64"] + cpp.minimumMacosVersion: "10.6" + qbs.architectures: project.enableX86 ? ["x86", "x86_64"] : ["x86_64"] qbs.buildVariants: ["debug", "profile"] install: true @@ -105,7 +109,7 @@ Project { files: ["lib.c"] cpp.sonamePrefix: qbs.targetOS.contains("darwin") ? "@rpath" : undefined cpp.defines: ["VARIANT=" + Utilities.cStringQuote(qbs.buildVariant)] - qbs.architectures: ["x86", "x86_64"] + qbs.architectures: project.enableX86 ? ["x86", "x86_64"] : ["x86_64"] qbs.buildVariants: ["release", "debug", "profile"] install: true @@ -120,7 +124,7 @@ Project { files: ["lib.c"] cpp.sonamePrefix: qbs.targetOS.contains("darwin") ? "@rpath" : undefined cpp.defines: ["VARIANT=" + Utilities.cStringQuote(qbs.buildVariant)] - qbs.architectures: ["x86", "x86_64"] + qbs.architectures: project.enableX86 ? ["x86", "x86_64"] : ["x86_64"] qbs.buildVariants: ["debug", "profile"] install: true @@ -135,7 +139,7 @@ Project { files: ["lib.c"] cpp.sonamePrefix: "@rpath" cpp.defines: ["VARIANT=" + Utilities.cStringQuote(qbs.buildVariant)] - qbs.architectures: ["x86", "x86_64"] + qbs.architectures: project.enableX86 ? ["x86", "x86_64"] : ["x86_64"] qbs.buildVariants: ["debug", "profile"] install: true installDir: "" @@ -147,7 +151,7 @@ Project { files: ["lib.c"] cpp.sonamePrefix: "@rpath" cpp.defines: ["VARIANT=" + Utilities.cStringQuote(qbs.buildVariant)] - qbs.architectures: ["x86", "x86_64"] + qbs.architectures: project.enableX86 ? ["x86", "x86_64"] : ["x86_64"] qbs.buildVariants: ["debug", "profile"] install: true installDir: "" diff --git a/tests/auto/blackbox/testdata-apple/deploymentTarget/deployment.qbs b/tests/auto/blackbox/testdata-apple/deploymentTarget/deployment.qbs index 9f1a466df..9eff57b60 100644 --- a/tests/auto/blackbox/testdata-apple/deploymentTarget/deployment.qbs +++ b/tests/auto/blackbox/testdata-apple/deploymentTarget/deployment.qbs @@ -4,7 +4,7 @@ CppApplication { // Minimum deployment targets that: // - will actually link (as of Xcode 8.1) // - exist for the given architecture(s) - cpp.minimumMacosVersion: qbs.architecture === "x86_64h" ? "10.12" : "10.4" + cpp.minimumMacosVersion: qbs.architecture === "x86_64h" ? "10.12" : "10.6" cpp.minimumIosVersion: ["armv7s", "arm64", "x86_64"].contains(qbs.architecture) ? "7.0" : "6.0" cpp.minimumTvosVersion: "9.0" cpp.minimumWatchosVersion: "2.0" diff --git a/tests/auto/blackbox/testdata-apple/embedInfoPlist/embedInfoPlist.qbs b/tests/auto/blackbox/testdata-apple/embedInfoPlist/embedInfoPlist.qbs index ba36d134c..ba23dc32c 100644 --- a/tests/auto/blackbox/testdata-apple/embedInfoPlist/embedInfoPlist.qbs +++ b/tests/auto/blackbox/testdata-apple/embedInfoPlist/embedInfoPlist.qbs @@ -7,7 +7,7 @@ Project { files: ["main.m"] cpp.frameworks: ["Foundation"] cpp.rpaths: [cpp.rpathOrigin] - cpp.minimumMacosVersion: "10.5" + cpp.minimumMacosVersion: "10.6" bundle.infoPlist: ({ "QBS": "org.qt-project.qbs.testdata.embedInfoPlist" }) diff --git a/tests/auto/blackbox/testdata/dynamic-library-in-module/Dll.qbs b/tests/auto/blackbox/testdata/dynamic-library-in-module/Dll.qbs index b3d901389..1acf606dc 100644 --- a/tests/auto/blackbox/testdata/dynamic-library-in-module/Dll.qbs +++ b/tests/auto/blackbox/testdata/dynamic-library-in-module/Dll.qbs @@ -4,7 +4,7 @@ DynamicLibrary { Properties { condition: qbs.targetOS.contains("darwin") bundle.isBundle: false - cpp.minimumMacosVersion: "10.5" // For -rpath + cpp.minimumMacosVersion: "10.7" // For -rpath } install: true diff --git a/tests/auto/blackbox/testdata/dynamic-library-in-module/theapp.qbs b/tests/auto/blackbox/testdata/dynamic-library-in-module/theapp.qbs index 0be9a2fd4..b9149d091 100644 --- a/tests/auto/blackbox/testdata/dynamic-library-in-module/theapp.qbs +++ b/tests/auto/blackbox/testdata/dynamic-library-in-module/theapp.qbs @@ -1,7 +1,7 @@ Project { CppApplication { name: "theapp" - cpp.minimumMacosVersion: "10.5" // For -rpath + cpp.minimumMacosVersion: "10.7" // For -rpath Depends { name: "theotherlib" } Depends { name: "thethirdlib" } Depends { name: "thefourthlib" } diff --git a/tests/auto/blackbox/testdata/minimumSystemVersion/macappstore.qbs b/tests/auto/blackbox/testdata/minimumSystemVersion/macappstore.qbs index 400bc9397..8440da779 100644 --- a/tests/auto/blackbox/testdata/minimumSystemVersion/macappstore.qbs +++ b/tests/auto/blackbox/testdata/minimumSystemVersion/macappstore.qbs @@ -6,5 +6,5 @@ CppApplication { files: ["main.mm"] consoleApplication: true cpp.frameworks: "Foundation" - cpp.minimumMacosVersion: "10.6.8" + cpp.minimumMacosVersion: "10.7.1" } diff --git a/tests/auto/blackbox/testdata/minimumSystemVersion/specific.qbs b/tests/auto/blackbox/testdata/minimumSystemVersion/specific.qbs index b0b7a7a9b..f6ecab418 100644 --- a/tests/auto/blackbox/testdata/minimumSystemVersion/specific.qbs +++ b/tests/auto/blackbox/testdata/minimumSystemVersion/specific.qbs @@ -20,6 +20,6 @@ CppApplication { Properties { condition: qbs.targetOS.contains("macos") cpp.frameworks: "Foundation" - cpp.minimumMacosVersion: "10.6" + cpp.minimumMacosVersion: "10.7" } } diff --git a/tests/auto/blackbox/testdata/symbolLinkMode/symbolLinkMode.qbs b/tests/auto/blackbox/testdata/symbolLinkMode/symbolLinkMode.qbs index b2df70033..2d3d64b00 100644 --- a/tests/auto/blackbox/testdata/symbolLinkMode/symbolLinkMode.qbs +++ b/tests/auto/blackbox/testdata/symbolLinkMode/symbolLinkMode.qbs @@ -27,7 +27,7 @@ Project { return ["WEAK_IMPORT=", installLib]; } cpp.cxxLanguageVersion: "c++11" - cpp.minimumMacosVersion: "10.5" + cpp.minimumMacosVersion: "10.7" cpp.rpaths: [cpp.rpathOrigin + "/../lib"] Group { @@ -48,7 +48,7 @@ Project { name: "functions" files: ["lib.cpp"] cpp.cxxLanguageVersion: "c++11" - cpp.minimumMacosVersion: "10.5" + cpp.minimumMacosVersion: "10.7" cpp.rpaths: [cpp.rpathOrigin] Properties { @@ -90,7 +90,7 @@ Project { name: "indirect" files: ["indirect.cpp"] cpp.cxxLanguageVersion: "c++11" - cpp.minimumMacosVersion: "10.5" + cpp.minimumMacosVersion: "10.7" Properties { condition: qbs.targetOS.contains("darwin") diff --git a/tests/auto/blackbox/tst_blackbox.cpp b/tests/auto/blackbox/tst_blackbox.cpp index ea8b9bd52..5dc858585 100644 --- a/tests/auto/blackbox/tst_blackbox.cpp +++ b/tests/auto/blackbox/tst_blackbox.cpp @@ -1671,7 +1671,7 @@ void TestBlackbox::cxxLanguageVersion() QString mapKey; if (version == "c++17" && m_qbsStdout.contains("is even newer MSVC: true")) mapKey = "msvc-brandnew"; - if (m_qbsStdout.contains("is newer MSVC: true")) + else if (m_qbsStdout.contains("is newer MSVC: true")) mapKey = "msvc-new"; else if (m_qbsStdout.contains("is older MSVC: true")) mapKey = "msvc_old"; @@ -6212,7 +6212,7 @@ void TestBlackbox::minimumSystemVersion_data() const QString specific = []() -> QString { if (HostOsInfo::isMacosHost()) - return "__MAC_OS_X_VERSION_MIN_REQUIRED=1060\nversion 10.6\n"; + return "__MAC_OS_X_VERSION_MIN_REQUIRED=1070\nversion 10.7\n"; if (HostOsInfo::isWindowsHost()) return "WINVER=1536\n6.00 operating system version\n6.00 subsystem version\n"; @@ -6228,8 +6228,8 @@ void TestBlackbox::minimumSystemVersion_data() QTest::newRow("fakewindows") << "fakewindows" << "WINVER=1283\n5.03 operating system " "version\n5.03 subsystem version\n"; if (HostOsInfo::isMacosHost()) - QTest::newRow("macappstore") << "macappstore" << "__MAC_OS_X_VERSION_MIN_REQUIRED=1068\n" - "version 10.6"; + QTest::newRow("macappstore") << "macappstore" << "__MAC_OS_X_VERSION_MIN_REQUIRED=1071\n" + "version 10.7"; } void TestBlackbox::missingBuildGraph() diff --git a/tests/auto/blackbox/tst_blackboxandroid.cpp b/tests/auto/blackbox/tst_blackboxandroid.cpp index d0cf37741..2b8f2bd76 100644 --- a/tests/auto/blackbox/tst_blackboxandroid.cpp +++ b/tests/auto/blackbox/tst_blackboxandroid.cpp @@ -180,6 +180,10 @@ void TestBlackboxAndroid::android_data() .replace("armv5te", "armeabi") .replace("arm64", "arm64-v8a"); }); + const bool usesClang = p.value(QLatin1String("qbs.toolchainType")).toString() == "clang"; + const auto cxxLibPath = [usesClang](const QByteArray &oldcxxLib) { + return QByteArray("lib/${ARCH}/") + (usesClang ? "libc++_shared.so" : oldcxxLib); + }; auto expandArchs = [] (const QByteArrayList &archs, const QByteArrayList &lst) { const QByteArray &archPlaceHolder = "${ARCH}"; @@ -210,7 +214,7 @@ void TestBlackboxAndroid::android_data() "assets/Shaders/ShaderPlain.fsh", "assets/Shaders/VS_ShaderPlain.vsh", "lib/${ARCH}/libgdbserver.so", - "lib/${ARCH}/libgnustl_shared.so", + cxxLibPath("libgnustl_shared.so"), "lib/${ARCH}/libTeapotNativeActivity.so", "res/layout/widgets.xml"})); QTest::newRow("no native") @@ -244,23 +248,23 @@ void TestBlackboxAndroid::android_data() "lib/${ARCH}/libgdbserver.so", "lib/${ARCH}/liblib1.so", "lib/${ARCH}/liblib2.so", - "lib/${ARCH}/libstlport_shared.so"})); + cxxLibPath("libstlport_shared.so")})); QByteArrayList expectedFiles1 = (commonFiles - + expandArchs(QByteArrayList{"mips", "x86"}, { + + expandArchs(QByteArrayList{"armeabi-v7a", "x86"}, { "resources.arsc", "lib/${ARCH}/libgdbserver.so", "lib/${ARCH}/libp1lib1.so", - "lib/${ARCH}/libstlport_shared.so"}) + cxxLibPath("libstlport_shared.so")}) + expandArchs(QByteArrayList{archs}, { "resources.arsc", "lib/${ARCH}/libgdbserver.so", "lib/${ARCH}/libp1lib2.so", - "lib/${ARCH}/libstlport_shared.so"})).toSet().toList(); + cxxLibPath("libstlport_shared.so")})).toSet().toList(); QByteArrayList expectedFiles2 = commonFiles + expandArchs(archs, { "lib/${ARCH}/libgdbserver.so", "lib/${ARCH}/libp2lib1.so", "lib/${ARCH}/libp2lib2.so", - "lib/${ARCH}/libstlport_shared.so"}); + cxxLibPath("libstlport_shared.so")}); QTest::newRow("multiple apks") << "multiple-apks-per-project" << (QStringList() << "twolibs1" << "twolibs2") diff --git a/tests/auto/blackbox/tst_blackboxapple.cpp b/tests/auto/blackbox/tst_blackboxapple.cpp index 76234e6c8..0cb4d5abb 100644 --- a/tests/auto/blackbox/tst_blackboxapple.cpp +++ b/tests/auto/blackbox/tst_blackboxapple.cpp @@ -76,8 +76,13 @@ void TestBlackboxApple::initTestCase() void TestBlackboxApple::appleMultiConfig() { + const auto xcodeVersion = findXcodeVersion(); + const bool supportsX86 = xcodeVersion < qbs::Version(10); + QDir::setCurrent(testDataDir + "/apple-multiconfig"); - QCOMPARE(runQbs(QbsRunParameters(QStringList{"qbs.installPrefix:''"})), 0); + QCOMPARE(runQbs(QbsRunParameters(QStringList{ + "qbs.installPrefix:''", + QString("project.enableX86:") + (supportsX86 ? "true" : "false")})), 0); QVERIFY(QFileInfo2(defaultInstallRoot + "/singleapp.app/Contents/MacOS/singleapp").isExecutable()); QVERIFY(QFileInfo2(defaultInstallRoot + "/singleapp.app/Contents/Info.plist").isRegularFile()); @@ -164,7 +169,6 @@ void TestBlackboxApple::assetCatalog() QFETCH(bool, flatten); const auto xcodeVersion = findXcodeVersion(); - QDir::setCurrent(testDataDir + QLatin1String("/ib/assetcatalog")); rmDirR(relativeBuildDir()); @@ -578,14 +582,16 @@ void TestBlackboxApple::deploymentTarget_data() QTest::addColumn<QString>("cflags"); QTest::addColumn<QString>("lflags"); - QTest::newRow("macos x86") << "macosx" << macos << "x86" - << "-triple i386-apple-macosx10.4" - << "-macosx_version_min 10.4"; + const auto xcodeVersion = findXcodeVersion(); + if (xcodeVersion < qbs::Version(10)) { + QTest::newRow("macos x86") << "macosx" << macos << "x86" + << "-triple i386-apple-macosx10.6" + << "-macosx_version_min 10.6"; + } QTest::newRow("macos x86_64") << "macosx" << macos << "x86_64" - << "-triple x86_64-apple-macosx10.4" - << "-macosx_version_min 10.4"; + << "-triple x86_64-apple-macosx10.6" + << "-macosx_version_min 10.6"; - const auto xcodeVersion = findXcodeVersion(); if (xcodeVersion >= qbs::Version(6)) QTest::newRow("macos x86_64h") << "macosx" << macos << "x86_64h" << "-triple x86_64h-apple-macosx10.12" diff --git a/tests/auto/language/testdata/inherited-properties-items/imports/DebugName.qbs b/tests/auto/language/testdata/inherited-properties-items/imports/DebugName.qbs new file mode 100644 index 000000000..5ac15658c --- /dev/null +++ b/tests/auto/language/testdata/inherited-properties-items/imports/DebugName.qbs @@ -0,0 +1,6 @@ +import qbs + +Properties { + condition: qbs.buildVariant === "debug" + name: "product_debug" +} diff --git a/tests/auto/language/testdata/inherited-properties-items/imports/ReleaseName.qbs b/tests/auto/language/testdata/inherited-properties-items/imports/ReleaseName.qbs new file mode 100644 index 000000000..e33c5652b --- /dev/null +++ b/tests/auto/language/testdata/inherited-properties-items/imports/ReleaseName.qbs @@ -0,0 +1,6 @@ +import qbs + +Properties { + condition: qbs.buildVariant === "release" + name: "product_release" +} diff --git a/tests/auto/language/testdata/inherited-properties-items/inherited-properties-items-product.qbs b/tests/auto/language/testdata/inherited-properties-items/inherited-properties-items-product.qbs new file mode 100644 index 000000000..c20f045c8 --- /dev/null +++ b/tests/auto/language/testdata/inherited-properties-items/inherited-properties-items-product.qbs @@ -0,0 +1,7 @@ +import qbs + +Product { + name: "product_default" + DebugName {} + ReleaseName {} +} diff --git a/tests/auto/language/testdata/inherited-properties-items/inherited-properties-items.qbs b/tests/auto/language/testdata/inherited-properties-items/inherited-properties-items.qbs new file mode 100644 index 000000000..40d41c2fb --- /dev/null +++ b/tests/auto/language/testdata/inherited-properties-items/inherited-properties-items.qbs @@ -0,0 +1,6 @@ +import qbs + +Project { + qbsSearchPaths: sourceDirectory + references: "inherited-properties-items-product.qbs" +} diff --git a/tests/auto/language/tst_language.cpp b/tests/auto/language/tst_language.cpp index fce799a0f..da8f1d7a8 100644 --- a/tests/auto/language/tst_language.cpp +++ b/tests/auto/language/tst_language.cpp @@ -1360,6 +1360,37 @@ void TestLanguage::importCollection() QVERIFY(!exceptionCaught); } +void TestLanguage::inheritedPropertiesItems_data() +{ + QTest::addColumn<QString>("buildVariant"); + QTest::addColumn<QString>("productName"); + QTest::newRow("debug build") << "debug" << "product_debug"; + QTest::newRow("release build") << "release" << "product_release"; +} + +void TestLanguage::inheritedPropertiesItems() +{ + bool exceptionCaught = false; + try { + SetupProjectParameters params = defaultParameters; + QFETCH(QString, buildVariant); + QFETCH(QString, productName); + params.setProjectFilePath + (testProject("inherited-properties-items/inherited-properties-items.qbs")); + params.setOverriddenValues(QVariantMap{std::make_pair("qbs.buildVariant", buildVariant)}); + TopLevelProjectPtr project = loader->loadProject(params); + QVERIFY(!!project); + QHash<QString, ResolvedProductPtr> products = productsFromProject(project); + QCOMPARE(products.size(), 1); + QVERIFY(!!products.value(productName)); + } + catch (const ErrorInfo &e) { + exceptionCaught = true; + qDebug() << e.toString(); + } + QVERIFY(!exceptionCaught); +} + void TestLanguage::invalidBindingInDisabledItem() { bool exceptionCaught = false; diff --git a/tests/auto/language/tst_language.h b/tests/auto/language/tst_language.h index 18027ab45..d724e5fc6 100644 --- a/tests/auto/language/tst_language.h +++ b/tests/auto/language/tst_language.h @@ -113,6 +113,8 @@ private slots: void idUsage(); void idUniqueness(); void importCollection(); + void inheritedPropertiesItems_data(); + void inheritedPropertiesItems(); void invalidBindingInDisabledItem(); void invalidOverrides(); void invalidOverrides_data(); |