summaryrefslogtreecommitdiff
path: root/src/plugins/qtsupport/baseqtversion.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/qtsupport/baseqtversion.cpp')
-rw-r--r--src/plugins/qtsupport/baseqtversion.cpp217
1 files changed, 108 insertions, 109 deletions
diff --git a/src/plugins/qtsupport/baseqtversion.cpp b/src/plugins/qtsupport/baseqtversion.cpp
index e9feec7f2a..85d71a9e0e 100644
--- a/src/plugins/qtsupport/baseqtversion.cpp
+++ b/src/plugins/qtsupport/baseqtversion.cpp
@@ -53,9 +53,9 @@
#include <utils/hostosinfo.h>
#include <utils/macroexpander.h>
#include <utils/qtcassert.h>
+#include <utils/qtcprocess.h>
#include <utils/runextensions.h>
#include <utils/stringutils.h>
-#include <utils/synchronousprocess.h>
#include <utils/winutils.h>
#include <resourceeditor/resourcenode.h>
@@ -196,8 +196,10 @@ public:
static QString qmakeProperty(const QHash<ProKey, ProString> &versionInfo,
const QByteArray &name,
PropertyVariant variant = PropertyVariantGet);
- static FilePath mkspecDirectoryFromVersionInfo(const QHash<ProKey,ProString> &versionInfo);
- static FilePath mkspecFromVersionInfo(const QHash<ProKey,ProString> &versionInfo);
+ static FilePath mkspecDirectoryFromVersionInfo(const QHash<ProKey, ProString> &versionInfo,
+ const FilePath &qmakeCommand);
+ static FilePath mkspecFromVersionInfo(const QHash<ProKey,ProString> &versionInfo,
+ const FilePath &qmakeCommand);
static FilePath sourcePath(const QHash<ProKey,ProString> &versionInfo);
void setId(int id); // used by the qtversionmanager for legacy restore
// and by the qtoptionspage to replace Qt versions
@@ -495,6 +497,10 @@ QSet<Id> BaseQtVersion::availableFeatures() const
if (qtVersion().matches(5, 15))
return features;
+ // Qt 6 uses versionless imports
+ features.unite(versionedIds(Constants::FEATURE_QT_QUICK_PREFIX, 6, -1));
+ features.unite(versionedIds(Constants::FEATURE_QT_QUICK_CONTROLS_2_PREFIX, 6, -1));
+
return features;
}
@@ -718,11 +724,24 @@ void BaseQtVersion::fromMap(const QVariantMap &map)
d->m_isAutodetected = map.value(QTVERSIONAUTODETECTED).toBool();
d->m_autodetectionSource = map.value(QTVERSIONAUTODETECTIONSOURCE).toString();
d->m_overrideFeatures = Utils::Id::fromStringList(map.value(QTVERSION_OVERRIDE_FEATURES).toStringList());
- QString string = map.value(QTVERSIONQMAKEPATH).toString();
+ d->m_qmakeCommand = FilePath::fromVariant(map.value(QTVERSIONQMAKEPATH));
+
+ QString string = d->m_qmakeCommand.toString();
if (string.startsWith('~'))
string.remove(0, 1).prepend(QDir::homePath());
+ if (!d->m_qmakeCommand.needsDevice()) {
+ // FIXME: generalize for all devices.
+ QFileInfo fi(string);
+ if (BuildableHelperLibrary::isQtChooser(fi)) {
+ // we don't want to treat qtchooser as a normal qmake
+ // see e.g. QTCREATORBUG-9841, also this lead to users changing what
+ // qtchooser forwards too behind our backs, which will inadvertly lead to bugs
+ string = BuildableHelperLibrary::qtChooserToQmakePath(fi.symLinkTarget());
+ d->m_qmakeCommand = FilePath::fromString(string);
+ }
+ }
- d->m_data.qtSources = FilePath::fromUserInput(map.value(QTVERSIONSOURCEPATH).toString());
+ d->m_data.qtSources = FilePath::fromVariant(map.value(QTVERSIONSOURCEPATH));
// Handle ABIs provided by the SDKTool:
// Note: Creator does not write these settings itself, so it has to come from the SDKTool!
@@ -731,15 +750,6 @@ void BaseQtVersion::fromMap(const QVariantMap &map)
d->m_data.qtAbis = Utils::filtered(d->m_data.qtAbis, &Abi::isValid);
d->m_data.hasQtAbis = !d->m_data.qtAbis.isEmpty();
- QFileInfo fi(string);
- if (BuildableHelperLibrary::isQtChooser(fi)) {
- // we don't want to treat qtchooser as a normal qmake
- // see e.g. QTCREATORBUG-9841, also this lead to users changing what
- // qtchooser forwards too behind our backs, which will inadvertly lead to bugs
- string = BuildableHelperLibrary::qtChooserToQmakePath(fi.symLinkTarget());
- }
-
- d->m_qmakeCommand = FilePath::fromString(string);
updateDefaultDisplayName();
// Clear the cached qmlscene command, it might not match the restored path anymore.
@@ -751,12 +761,13 @@ QVariantMap BaseQtVersion::toMap() const
QVariantMap result;
result.insert(Constants::QTVERSIONID, uniqueId());
d->m_data.unexpandedDisplayName.toMap(result, Constants::QTVERSIONNAME);
+
result.insert(QTVERSIONAUTODETECTED, isAutodetected());
result.insert(QTVERSIONAUTODETECTIONSOURCE, autodetectionSource());
if (!d->m_overrideFeatures.isEmpty())
result.insert(QTVERSION_OVERRIDE_FEATURES, Utils::Id::toStringList(d->m_overrideFeatures));
- result.insert(QTVERSIONQMAKEPATH, qmakeCommand().toString());
+ result.insert(QTVERSIONQMAKEPATH, qmakeCommand().toVariant());
return result;
}
@@ -1138,13 +1149,13 @@ void BaseQtVersionPrivate::updateMkspec()
return;
m_mkspecUpToDate = true;
- m_mkspecFullPath = mkspecFromVersionInfo(versionInfo());
+ m_mkspecFullPath = mkspecFromVersionInfo(versionInfo(), m_qmakeCommand);
m_mkspec = m_mkspecFullPath;
if (m_mkspecFullPath.isEmpty())
return;
- FilePath baseMkspecDir = mkspecDirectoryFromVersionInfo(versionInfo());
+ FilePath baseMkspecDir = mkspecDirectoryFromVersionInfo(versionInfo(), m_qmakeCommand);
if (m_mkspec.isChildOf(baseMkspecDir)) {
m_mkspec = m_mkspec.relativeChildPath(baseMkspecDir);
@@ -1171,7 +1182,9 @@ void BaseQtVersion::ensureMkSpecParsed() const
QMakeVfs vfs;
QMakeGlobals option;
applyProperties(&option);
- option.environment = qmakeRunEnvironment().toProcessEnvironment();
+ Environment env = Environment::systemEnvironment(); // FIXME: Use build device
+ setupQmakeRunEnvironment(env);
+ option.environment = env.toProcessEnvironment();
ProMessageHandler msgHandler(true);
ProFileCacheManager::instance()->incRefCount();
QMakeParser parser(ProFileCacheManager::instance()->cache(), &vfs, &msgHandler);
@@ -1299,60 +1312,49 @@ void BaseQtVersionPrivate::updateVersionInfo()
}
m_qmakeIsExecutable = true;
- m_data.prefix = FilePath::fromUserInput(qmakeProperty("QT_INSTALL_PREFIX"));
-
- m_data.binPath = FilePath::fromUserInput(qmakeProperty("QT_INSTALL_BINS"));
- m_data.libExecPath = FilePath::fromUserInput(qmakeProperty("QT_INSTALL_LIBEXECS"));
- m_data.configurationPath = FilePath::fromUserInput(qmakeProperty("QT_INSTALL_CONFIGURATION"));
- m_data.dataPath = FilePath::fromUserInput(qmakeProperty("QT_INSTALL_DATA"));
- m_data.demosPath = FilePath::fromString(
- QFileInfo(qmakeProperty("QT_INSTALL_DEMOS")).canonicalFilePath());
- m_data.docsPath = FilePath::fromUserInput(qmakeProperty("QT_INSTALL_DOCS"));
- m_data.examplesPath = FilePath::fromString(
- QFileInfo(qmakeProperty("QT_INSTALL_EXAMPLES")).canonicalFilePath());
- m_data.headerPath = FilePath::fromUserInput(qmakeProperty("QT_INSTALL_HEADERS"));
- m_data.importsPath = FilePath::fromUserInput(qmakeProperty("QT_INSTALL_IMPORTS"));
- m_data.libraryPath = FilePath::fromUserInput(qmakeProperty("QT_INSTALL_LIBS"));
- m_data.pluginPath = FilePath::fromUserInput(qmakeProperty("QT_INSTALL_PLUGINS"));
- m_data.qmlPath = FilePath::fromUserInput(qmakeProperty("QT_INSTALL_QML"));
- m_data.translationsPath = FilePath::fromUserInput(qmakeProperty("QT_INSTALL_TRANSLATIONS"));
-
- m_data.hostBinPath = FilePath::fromUserInput(qmakeProperty("QT_HOST_BINS"));
- m_data.hostLibexecPath = FilePath::fromUserInput(qmakeProperty("QT_HOST_LIBEXECS"));
- m_data.hostDataPath = FilePath::fromUserInput(qmakeProperty("QT_HOST_DATA"));
- m_data.hostPrefixPath = FilePath::fromUserInput(qmakeProperty("QT_HOST_PREFIX"));
-
- const QString qtHeaderData = q->headerPath().toString();
+ auto fileProperty = [this](const QByteArray &name) {
+ return FilePath::fromUserInput(qmakeProperty(name)).onDevice(m_qmakeCommand);
+ };
+
+ m_data.prefix = fileProperty("QT_INSTALL_PREFIX");
+ m_data.binPath = fileProperty("QT_INSTALL_BINS");
+ m_data.libExecPath = fileProperty("QT_INSTALL_LIBEXECS");
+ m_data.configurationPath = fileProperty("QT_INSTALL_CONFIGURATION");
+ m_data.dataPath = fileProperty("QT_INSTALL_DATA");
+ m_data.demosPath = fileProperty("QT_INSTALL_DEMOS");
+ m_data.docsPath = fileProperty("QT_INSTALL_DOCS");
+ m_data.examplesPath = fileProperty("QT_INSTALL_EXAMPLES");
+ m_data.headerPath = fileProperty("QT_INSTALL_HEADERS");
+ m_data.importsPath = fileProperty("QT_INSTALL_IMPORTS");
+ m_data.libraryPath = fileProperty("QT_INSTALL_LIBS");
+ m_data.pluginPath = fileProperty("QT_INSTALL_PLUGINS");
+ m_data.qmlPath = fileProperty("QT_INSTALL_QML");
+ m_data.translationsPath = fileProperty("QT_INSTALL_TRANSLATIONS");
+ m_data.hostBinPath = fileProperty("QT_HOST_BINS");
+ m_data.hostLibexecPath = fileProperty("QT_HOST_LIBEXECS");
+ m_data.hostDataPath = fileProperty("QT_HOST_DATA");
+ m_data.hostPrefixPath = fileProperty("QT_HOST_PREFIX");
// Now check for a qt that is configured with a prefix but not installed
- QString installDir = q->hostBinPath().toString();
- if (!installDir.isNull()) {
- if (!QFileInfo::exists(installDir))
- m_data.installed = false;
- }
+ if (!m_data.hostBinPath.isReadableDir())
+ m_data.installed = false;
+
// Framework builds for Qt 4.8 don't use QT_INSTALL_HEADERS
// so we don't check on mac
if (!HostOsInfo::isMacHost()) {
- if (!qtHeaderData.isNull()) {
- if (!QFileInfo::exists(qtHeaderData))
- m_data.installed = false;
- }
- }
- const QString qtInstallDocs = q->docsPath().toString();
- if (!qtInstallDocs.isEmpty()) {
- if (QFileInfo::exists(qtInstallDocs))
- m_data.hasDocumentation = true;
- }
- const QString qtInstallExamples = q->examplesPath().toString();
- if (!qtInstallExamples.isEmpty()) {
- if (QFileInfo::exists(qtInstallExamples))
- m_data.hasExamples = true;
- }
- const QString qtInstallDemos = q->demosPath().toString();
- if (!qtInstallDemos.isEmpty()) {
- if (QFileInfo::exists(qtInstallDemos))
- m_data.hasDemos = true;
+ if (!m_data.headerPath.isReadableDir())
+ m_data.installed = false;
}
+
+ if (m_data.docsPath.isReadableDir())
+ m_data.hasDocumentation = true;
+
+ if (m_data.examplesPath.isReadableDir())
+ m_data.hasExamples = true;
+
+ if (m_data.demosPath.isReadableDir())
+ m_data.hasDemos = true;
+
m_data.qtVersionString = qmakeProperty("QT_VERSION");
m_isUpdating = false;
@@ -1706,9 +1708,17 @@ void BaseQtVersion::addToEnvironment(const Kit *k, Environment &env) const
// One such example is Blackberry which for some reason decided to always use the same
// qmake and use environment variables embedded in their mkspecs to make that point to
// the different Qt installations.
+
Environment BaseQtVersion::qmakeRunEnvironment() const
{
- return Environment::systemEnvironment();
+ Environment env = Environment::systemEnvironment(); // FIXME: Use build environment
+ setupQmakeRunEnvironment(env);
+ return env;
+}
+
+void BaseQtVersion::setupQmakeRunEnvironment(Environment &env) const
+{
+ Q_UNUSED(env);
}
bool BaseQtVersion::hasQmlDumpWithRelocatableFlag() const
@@ -1729,12 +1739,11 @@ Tasks BaseQtVersion::reportIssuesImpl(const QString &proFile, const QString &bui
results.append(BuildSystemTask(Task::Error, msg));
}
- QFileInfo qmakeInfo = qmakeCommand().toFileInfo();
- if (!qmakeInfo.exists() ||
- !qmakeInfo.isExecutable()) {
+ FilePath qmake = qmakeCommand();
+ if (!qmake.isExecutableFile()) {
//: %1: Path to qmake executable
const QString msg = QCoreApplication::translate("QmakeProjectManager::QtVersion",
- "The qmake command \"%1\" was not found or is not executable.").arg(qmakeCommand().toUserOutput());
+ "The qmake command \"%1\" was not found or is not executable.").arg(qmake.toUserOutput());
results.append(BuildSystemTask(Task::Error, msg));
}
@@ -1758,8 +1767,7 @@ QtConfigWidget *BaseQtVersion::createConfigurationWidget() const
return nullptr;
}
-static QByteArray runQmakeQuery(const FilePath &binary, const Environment &env,
- QString *error)
+static QByteArray runQmakeQuery(const FilePath &binary, const Environment &env, QString *error)
{
QTC_ASSERT(error, return QByteArray());
@@ -1768,16 +1776,18 @@ static QByteArray runQmakeQuery(const FilePath &binary, const Environment &env,
// Prevent e.g. qmake 4.x on MinGW to show annoying errors about missing dll's.
WindowsCrashDialogBlocker crashDialogBlocker;
- QProcess process;
- process.setEnvironment(env.toStringList());
- process.start(binary.toString(), QStringList("-query"), QIODevice::ReadOnly);
+ QtcProcess process;
+ process.setEnvironment(env);
+ process.setOpenMode(QIODevice::ReadOnly);
+ process.setCommand({binary, {"-query"}});
+ process.start();
if (!process.waitForStarted()) {
*error = QCoreApplication::translate("QtVersion", "Cannot start \"%1\": %2").arg(binary.toUserOutput()).arg(process.errorString());
return QByteArray();
}
if (!process.waitForFinished(timeOutMS)) {
- SynchronousProcess::stopProcess(process);
+ process.stopProcess();
*error = QCoreApplication::translate("QtVersion", "Timeout running \"%1\" (%2 ms).").arg(binary.toUserOutput()).arg(timeOutMS);
return QByteArray();
}
@@ -1797,8 +1807,7 @@ bool BaseQtVersionPrivate::queryQMakeVariables(const FilePath &binary, const Env
if (!error)
error = &tmp;
- const QFileInfo qmake = binary.toFileInfo();
- if (!qmake.exists() || !qmake.isExecutable() || qmake.isDir()) {
+ if (!binary.isExecutableFile()) {
*error = QCoreApplication::translate("QtVersion", "qmake \"%1\" is not an executable.").arg(binary.toUserOutput());
return false;
}
@@ -1839,17 +1848,19 @@ QString BaseQtVersionPrivate::qmakeProperty(const QByteArray &name,
return qmakeProperty(m_versionInfo, name, variant);
}
-FilePath BaseQtVersionPrivate::mkspecDirectoryFromVersionInfo(const QHash<ProKey, ProString> &versionInfo)
+FilePath BaseQtVersionPrivate::mkspecDirectoryFromVersionInfo(const QHash<ProKey, ProString> &versionInfo,
+ const FilePath &qmakeCommand)
{
QString dataDir = qmakeProperty(versionInfo, "QT_HOST_DATA", PropertyVariantSrc);
if (dataDir.isEmpty())
return FilePath();
- return FilePath::fromUserInput(dataDir + "/mkspecs");
+ return FilePath::fromUserInput(dataDir + "/mkspecs").onDevice(qmakeCommand);
}
-FilePath BaseQtVersionPrivate::mkspecFromVersionInfo(const QHash<ProKey, ProString> &versionInfo)
+FilePath BaseQtVersionPrivate::mkspecFromVersionInfo(const QHash<ProKey, ProString> &versionInfo,
+ const FilePath &qmakeCommand)
{
- FilePath baseMkspecDir = mkspecDirectoryFromVersionInfo(versionInfo);
+ FilePath baseMkspecDir = mkspecDirectoryFromVersionInfo(versionInfo, qmakeCommand);
if (baseMkspecDir.isEmpty())
return FilePath();
@@ -2056,35 +2067,24 @@ FilePaths BaseQtVersionPrivate::qtCorePaths()
updateVersionInfo();
const QString versionString = m_data.qtVersionString;
- const QString installLibsDir = q->libraryPath().toString();
- const QString installBinDir = q->binPath().toString();
-
const QDir::Filters filters = QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot;
- const QFileInfoList entryInfoList = [&]() {
- QFileInfoList result;
- if (!installLibsDir.isEmpty())
- result += QDir(installLibsDir).entryInfoList(filters);
- if (!installBinDir.isEmpty())
- result += QDir(installBinDir).entryInfoList(filters);
- return result;
- }();
+ const FilePaths entries = m_data.libraryPath.dirEntries(filters)
+ + m_data.binPath.dirEntries(filters);
+
FilePaths staticLibs;
FilePaths dynamicLibs;
- for (const QFileInfo &info : entryInfoList) {
- const QString file = info.fileName();
- if (info.isDir()
- && file.startsWith("QtCore")
- && file.endsWith(".framework")) {
+ for (const FilePath &entry : entries) {
+ const QString file = entry.fileName();
+ if (file.startsWith("QtCore") && file.endsWith(".framework") && entry.isReadableDir()) {
// handle Framework
- const FilePath lib = FilePath::fromFileInfo(info);
- dynamicLibs.append(lib.pathAppended(file.left(file.lastIndexOf('.'))));
- } else if (info.isReadable()) {
- if (file.startsWith("libQtCore") || file.startsWith("QtCore")
+ dynamicLibs.append(entry.pathAppended(file.left(file.lastIndexOf('.'))));
+ } else if (file.startsWith("libQtCore") || file.startsWith("QtCore")
|| file.startsWith("libQt5Core") || file.startsWith("Qt5Core")
|| file.startsWith("libQt6Core") || file.startsWith("Qt6Core")) {
+ if (entry.isReadableFile()) {
if (file.endsWith(".a") || file.endsWith(".lib"))
- staticLibs.append(FilePath::fromFileInfo(info));
+ staticLibs.append(entry);
else if (file.endsWith(".dll")
|| file.endsWith(QString::fromLatin1(".so.") + versionString)
|| file.endsWith(".so")
@@ -2092,7 +2092,7 @@ FilePaths BaseQtVersionPrivate::qtCorePaths()
|| file.contains(QRegularExpression("\\.so\\.[0-9]+\\.[0-9]+$")) // QTCREATORBUG-23818
#endif
|| file.endsWith(QLatin1Char('.') + versionString + ".dylib"))
- dynamicLibs.append(FilePath::fromFileInfo(info));
+ dynamicLibs.append(entry);
}
}
}
@@ -2298,7 +2298,7 @@ BaseQtVersion *QtVersionFactory::createQtVersionFromQMakePath
QHash<ProKey, ProString> versionInfo;
if (!BaseQtVersionPrivate::queryQMakeVariables(qmakePath, Environment::systemEnvironment(), &versionInfo, error))
return nullptr;
- FilePath mkspec = BaseQtVersionPrivate::mkspecFromVersionInfo(versionInfo);
+ FilePath mkspec = BaseQtVersionPrivate::mkspecFromVersionInfo(versionInfo, qmakePath);
QMakeVfs vfs;
QMakeGlobals globals;
@@ -2307,15 +2307,14 @@ BaseQtVersion *QtVersionFactory::createQtVersionFromQMakePath
ProFileCacheManager::instance()->incRefCount();
QMakeParser parser(ProFileCacheManager::instance()->cache(), &vfs, &msgHandler);
ProFileEvaluator evaluator(&globals, &parser, &vfs, &msgHandler);
- evaluator.loadNamedSpec(mkspec.toString(), false);
+ evaluator.loadNamedSpec(mkspec.path(), false);
QList<QtVersionFactory *> factories = g_qtVersionFactories;
Utils::sort(factories, [](const QtVersionFactory *l, const QtVersionFactory *r) {
return l->m_priority > r->m_priority;
});
- QFileInfo fi = qmakePath.toFileInfo();
- if (!fi.exists() || !fi.isExecutable() || !fi.isFile())
+ if (!qmakePath.isExecutableFile())
return nullptr;
QtVersionFactory::SetupData setup;