OSDN Git Service

QtVersion: Set qmakeIsExecutable to false if qmake crashes.
authorFriedemann Kleint <Friedemann.Kleint@nokia.com>
Thu, 14 Jul 2011 11:35:40 +0000 (13:35 +0200)
committerFriedemann Kleint <Friedemann.Kleint@nokia.com>
Fri, 29 Jul 2011 13:22:09 +0000 (15:22 +0200)
This prevents literally dozens of crash dialog boxes on Windows.
Check for a crash in the helper library and in updateVersionInfo
consistently whatever is called first.
Initialize qmakeIsExecutable in 2nd constructor as well.

Change-Id: Ifafb7b3edfae8826ac062d634a39a2a804446942
Reviewed-on: http://codereview.qt.nokia.com/1661
Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: Daniel Teske <daniel.teske@nokia.com>
src/libs/utils/buildablehelperlibrary.cpp
src/libs/utils/buildablehelperlibrary.h
src/plugins/qtsupport/baseqtversion.cpp
src/plugins/qtsupport/baseqtversion.h

index 3e2f146..bf2e79c 100644 (file)
@@ -78,12 +78,20 @@ QString BuildableHelperLibrary::qtInstallDataDir(const QString &qmakePath)
 
 QString BuildableHelperLibrary::qtVersionForQMake(const QString &qmakePath)
 {
-    if (qmakePath.isEmpty())
+    bool qmakeIsExecutable;
+    return BuildableHelperLibrary::qtVersionForQMake(qmakePath, &qmakeIsExecutable);
+}
+
+QString BuildableHelperLibrary::qtVersionForQMake(const QString &qmakePath, bool *qmakeIsExecutable)
+{
+    *qmakeIsExecutable = !qmakePath.isEmpty();
+    if (!*qmakeIsExecutable)
         return QString();
 
     QProcess qmake;
     qmake.start(qmakePath, QStringList(QLatin1String("--version")));
     if (!qmake.waitForStarted()) {
+        *qmakeIsExecutable = false;
         qWarning("Cannot start '%s': %s", qPrintable(qmakePath), qPrintable(qmake.errorString()));
         return QString();
     }
@@ -93,9 +101,11 @@ QString BuildableHelperLibrary::qtVersionForQMake(const QString &qmakePath)
         return QString();
     }
     if (qmake.exitStatus() != QProcess::NormalExit) {
+        *qmakeIsExecutable = false;
         qWarning("'%s' crashed.", qPrintable(qmakePath));
         return QString();
     }
+
     const QString output = QString::fromLocal8Bit(qmake.readAllStandardOutput());
     static QRegExp regexp(QLatin1String("(QMake version|QMake version:)[\\s]*([\\d.]*)"),
                           Qt::CaseInsensitive);
index 5a69b4f..9246cee 100644 (file)
@@ -52,7 +52,7 @@ public:
     static QString findSystemQt(const Utils::Environment &env);
     // return true if the qmake at qmakePath is qt4 (used by QtVersion)
     static QString qtVersionForQMake(const QString &qmakePath);
-    static bool checkMinimumQtVersion(const QString &qtversionString, int majorVersion, int minorVersion, int patchVersion);
+    static QString qtVersionForQMake(const QString &qmakePath, bool *qmakeIsExecutable);
     // returns something like qmake4, qmake, qmake-qt4 or whatever distributions have chosen (used by QtVersion)
     static QStringList possibleQMakeCommands();
 
index 1e4d181..03eb345 100644 (file)
@@ -177,7 +177,7 @@ BaseQtVersion::BaseQtVersion(const QString &qmakeCommand, bool isAutodetected, c
       m_hasExamples(false),
       m_hasDemos(false),
       m_hasDocumentation(false),
-      m_qmakeIsExecutable(false)
+      m_qmakeIsExecutable(true)
 {
     ctor(qmakeCommand);
     setDisplayName(defaultDisplayName(qtVersionString(), qmakeCommand, false));
@@ -197,7 +197,8 @@ BaseQtVersion::BaseQtVersion()
     m_notInstalled(false),
     m_hasExamples(false),
     m_hasDemos(false),
-    m_hasDocumentation(false)
+    m_hasDocumentation(false),
+    m_qmakeIsExecutable(true)
 {
     ctor(QString());
 }
@@ -661,12 +662,15 @@ BaseQtVersion::QmakeBuildConfigs BaseQtVersion::defaultBuildConfig() const
 
 QString BaseQtVersion::qtVersionString() const
 {
-    if (m_qtVersionString.isNull()) {
-        QFileInfo qmake(m_qmakeCommand);
-        if (qmake.exists() && qmake.isExecutable())
-            m_qtVersionString = ProjectExplorer::DebuggingHelperLibrary::qtVersionForQMake(qmake.absoluteFilePath());
-        else
-            m_qtVersionString = QLatin1String("");
+    if (!m_qtVersionString.isNull())
+        return m_qtVersionString;
+    m_qtVersionString.clear();
+    if (m_qmakeIsExecutable) {
+        const QString qmake = QFileInfo(qmakeCommand()).absoluteFilePath();
+        m_qtVersionString =
+            ProjectExplorer::DebuggingHelperLibrary::qtVersionForQMake(qmake, &m_qmakeIsExecutable);
+    } else {
+        qWarning("Cannot determine the Qt version: %s cannot be run.", qPrintable(qmakeCommand()));
     }
     return m_qtVersionString;
 }
@@ -680,6 +684,11 @@ void BaseQtVersion::updateVersionInfo() const
 {
     if (m_versionInfoUpToDate)
         return;
+    if (!m_qmakeIsExecutable) {
+        qWarning("Cannot update Qt version information: %s cannot be run.",
+                 qPrintable(qmakeCommand()));
+        return;
+    }
 
     // extract data from qmake executable
     m_versionInfo.clear();
@@ -691,15 +700,7 @@ void BaseQtVersion::updateVersionInfo() const
     m_hasQmlDebuggingLibrary = false;
     m_hasQmlObserver = false;
 
-    m_qmakeIsExecutable = true;
-
-    QFileInfo fi(qmakeCommand());
-    if (!fi.exists() || !fi.isExecutable() || fi.isDir()) {
-        m_qmakeIsExecutable = false;
-        return;
-    }
-
-    if (!queryQMakeVariables(qmakeCommand(), &m_versionInfo))
+    if (!queryQMakeVariables(qmakeCommand(), &m_versionInfo, &m_qmakeIsExecutable))
         return;
 
     if (m_versionInfo.contains("QT_INSTALL_DATA")) {
@@ -983,9 +984,17 @@ QtConfigWidget *BaseQtVersion::createConfigurationWidget() const
 
 bool BaseQtVersion::queryQMakeVariables(const QString &binary, QHash<QString, QString> *versionInfo)
 {
+    bool qmakeIsExecutable;
+    return BaseQtVersion::queryQMakeVariables(binary, versionInfo, &qmakeIsExecutable);
+}
+
+bool BaseQtVersion::queryQMakeVariables(const QString &binary, QHash<QString, QString> *versionInfo,
+                                        bool *qmakeIsExecutable)
+{
     const int timeOutMS = 30000; // Might be slow on some machines.
-    QFileInfo qmake(binary);
-    if (!qmake.exists() || !qmake.isExecutable() || qmake.isDir())
+    const QFileInfo qmake(binary);
+    *qmakeIsExecutable = qmake.exists() && qmake.isExecutable() && !qmake.isDir();
+    if (!*qmakeIsExecutable)
         return false;
     static const char * const variables[] = {
              "QT_VERSION",
@@ -1003,12 +1012,14 @@ bool BaseQtVersion::queryQMakeVariables(const QString &binary, QHash<QString, QS
              "QT_INSTALL_IMPORTS",
              "QMAKEFEATURES"
         };
+    const QString queryArg = QLatin1String("-query");
     QStringList args;
     for (uint i = 0; i < sizeof variables / sizeof variables[0]; ++i)
-        args << "-query" << variables[i];
+        args << queryArg << variables[i];
     QProcess process;
     process.start(qmake.absoluteFilePath(), args, QIODevice::ReadOnly);
     if (!process.waitForStarted()) {
+        *qmakeIsExecutable = false;
         qWarning("Cannot start '%s': %s", qPrintable(binary), qPrintable(process.errorString()));
         return false;
     }
@@ -1018,6 +1029,7 @@ bool BaseQtVersion::queryQMakeVariables(const QString &binary, QHash<QString, QS
         return false;
     }
     if (process.exitStatus() != QProcess::NormalExit) {
+        *qmakeIsExecutable = false;
         qWarning("'%s' crashed.", qPrintable(binary));
         return false;
     }
index 147b100..65ea697 100644 (file)
@@ -179,6 +179,7 @@ public:
     virtual ProjectExplorer::IOutputParser *createOutputParser() const;
 
     static bool queryQMakeVariables(const QString &binary, QHash<QString, QString> *versionInfo);
+    static bool queryQMakeVariables(const QString &binary, QHash<QString, QString> *versionInfo, bool *qmakeIsExecutable);
     static QString mkspecFromVersionInfo(const QHash<QString, QString> &versionInfo);