diff --git a/src/plugins/qtsupport/baseqtversion.cpp b/src/plugins/qtsupport/baseqtversion.cpp index 2869a769c8891d4a50c2a0e467ae5dd2d7e27813..ec781d717ad495a0b6df7bf210bdb0e61037f159 100644 --- a/src/plugins/qtsupport/baseqtversion.cpp +++ b/src/plugins/qtsupport/baseqtversion.cpp @@ -1185,49 +1185,69 @@ bool BaseQtVersion::queryQMakeVariables(const Utils::FileName &binary, QHash<QSt return BaseQtVersion::queryQMakeVariables(binary, versionInfo, &qmakeIsExecutable); } -bool BaseQtVersion::queryQMakeVariables(const Utils::FileName &binary, QHash<QString, QString> *versionInfo, - bool *qmakeIsExecutable) +static QByteArray runQmakeQuery(const Utils::FileName &binary, const Utils::Environment &env, + bool *isExecutable) { const int timeOutMS = 30000; // Might be slow on some machines. - const QFileInfo qmake = binary.toFileInfo(); - *qmakeIsExecutable = qmake.exists() && qmake.isExecutable() && !qmake.isDir(); - if (!*qmakeIsExecutable) - return false; QProcess process; - Utils::Environment env = Utils::Environment::systemEnvironment(); - -#ifdef Q_OS_WIN - // Add tool chain environment. This is necessary for non-static qmakes e.g. using mingw on windows - // We can not just add all the environments of all tool chains since that will make PATH too long - // which in turn will trigger a crash when parsing the results of vcvars.bat of MSVC. - QList<ProjectExplorer::Abi> abiList = ProjectExplorer::Abi::abisOfBinary(binary); - QList<ProjectExplorer::ToolChain *> tcList = ProjectExplorer::ToolChainManager::instance()->toolChains(); - foreach (ProjectExplorer::ToolChain *tc, tcList) { - if (abiList.contains(tc->targetAbi())) - tc->addToEnvironment(env); - } -#endif - process.setEnvironment(env.toStringList()); - process.start(qmake.absoluteFilePath(), QStringList(QLatin1String("-query")), QIODevice::ReadOnly); + process.start(binary.toString(), QStringList(QLatin1String("-query")), QIODevice::ReadOnly); if (!process.waitForStarted()) { - *qmakeIsExecutable = false; qWarning("Cannot start '%s': %s", qPrintable(binary.toUserOutput()), qPrintable(process.errorString())); - return false; + *isExecutable = false; + return QByteArray(); } if (!process.waitForFinished(timeOutMS)) { Utils::SynchronousProcess::stopProcess(process); + *isExecutable = true; qWarning("Timeout running '%s' (%dms).", qPrintable(binary.toUserOutput()), timeOutMS); - return false; + return QByteArray(); } if (process.exitStatus() != QProcess::NormalExit) { - *qmakeIsExecutable = false; qWarning("'%s' crashed.", qPrintable(binary.toUserOutput())); + *isExecutable = false; + return QByteArray(); + } + + *isExecutable = true; + return process.readAllStandardOutput(); +} + +bool BaseQtVersion::queryQMakeVariables(const Utils::FileName &binary, QHash<QString, QString> *versionInfo, + bool *qmakeIsExecutable) +{ + const QFileInfo qmake = binary.toFileInfo(); + *qmakeIsExecutable = qmake.exists() && qmake.isExecutable() && !qmake.isDir(); + if (!*qmakeIsExecutable) return false; + + QByteArray output; + output = runQmakeQuery(binary, Utils::Environment::systemEnvironment(), qmakeIsExecutable); + + if (output.isNull() && !qmakeIsExecutable) { + // Note: Don't rerun if we were able to execute the binary before. + + // Try running qmake with all kinds of tool chains set up in the environment. + // This is required to make non-static qmakes work on windows where every tool chain + // tries to be incompatible with any other. + QList<ProjectExplorer::Abi> abiList = ProjectExplorer::Abi::abisOfBinary(binary); + QList<ProjectExplorer::ToolChain *> tcList = ProjectExplorer::ToolChainManager::instance()->toolChains(); + foreach (ProjectExplorer::ToolChain *tc, tcList) { + if (!abiList.contains(tc->targetAbi())) + continue; + Utils::Environment env = Utils::Environment::systemEnvironment(); + tc->addToEnvironment(env); + output = runQmakeQuery(binary, env, qmakeIsExecutable); + if (qmakeIsExecutable) + break; + } } - QByteArray output = process.readAllStandardOutput(); + + if (output.isNull()) + return false; + QTextStream stream(&output); while (!stream.atEnd()) { const QString line = stream.readLine();