From 3572170da9b8254f3f350cb1685eb7f10e5e5d53 Mon Sep 17 00:00:00 2001
From: Friedemann Kleint <Friedemann.Kleint@nokia.com>
Date: Fri, 18 Nov 2011 11:08:43 +0100
Subject: [PATCH] Cache the environment to be set for the qmake executable.

As of 4.8, qmake/MinGW requires the toolchain path for MinGW
to be set as it can no longer be linked statically
due to gcc 4.6 / 64bit (TDM) not supporting the option.
---
 src/plugins/projectexplorer/toolchainmanager.cpp |   12 +++++++
 src/plugins/projectexplorer/toolchainmanager.h   |    6 ++++
 src/plugins/qtsupport/baseqtversion.cpp          |   35 +++++++++++++++++----
 3 files changed, 46 insertions(+), 7 deletions(-)

diff --git a/src/plugins/projectexplorer/toolchainmanager.cpp b/src/plugins/projectexplorer/toolchainmanager.cpp
index 9f616ea..908b0cf 100644
--- a/src/plugins/projectexplorer/toolchainmanager.cpp
+++ b/src/plugins/projectexplorer/toolchainmanager.cpp
@@ -274,4 +274,16 @@ void ToolChainManager::deregisterToolChain(ToolChain *tc)
     delete tc;
 }
 
+bool ToolChainManager::addToolChainEnvironment(const Abi &abi, Utils::Environment &environment)
+{
+    if (abi.isValid()) {
+        const QList<ToolChain *> allToolchains = ToolChainManager::instance()->findToolChains(abi);        
+        if (!allToolchains.isEmpty()) {
+            allToolchains.first()->addToEnvironment(environment);
+            return true;
+        }
+    }
+    return false;
+}
+
 } // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/toolchainmanager.h b/src/plugins/projectexplorer/toolchainmanager.h
index 0c9e0c0..8ed38f0 100644
--- a/src/plugins/projectexplorer/toolchainmanager.h
+++ b/src/plugins/projectexplorer/toolchainmanager.h
@@ -39,6 +39,10 @@
 #include <QtCore/QObject>
 #include <QtCore/QString>
 
+namespace Utils {
+class Environment;
+} // namespace
+
 namespace ProjectExplorer {
 class ProjectExplorerPlugin;
 class ToolChain;
@@ -67,6 +71,8 @@ public:
 
     QString defaultDebugger(const Abi &abi) const;
 
+    static bool addToolChainEnvironment(const Abi &abi, Utils::Environment &environment);
+
 public slots:
     bool registerToolChain(ProjectExplorer::ToolChain *tc);
     void deregisterToolChain(ProjectExplorer::ToolChain *tc);
diff --git a/src/plugins/qtsupport/baseqtversion.cpp b/src/plugins/qtsupport/baseqtversion.cpp
index c56a92a..a176a44 100644
--- a/src/plugins/qtsupport/baseqtversion.cpp
+++ b/src/plugins/qtsupport/baseqtversion.cpp
@@ -909,12 +909,9 @@ Utils::Environment BaseQtVersion::qmlToolsEnvironment() const
     addToEnvironment(environment);
 
     // add preferred tool chain, as that is how the tools are built, compare QtVersion::buildDebuggingHelperLibrary
-    if (!qtAbis().isEmpty()) {
-        QList<ProjectExplorer::ToolChain *> alltc =
-                ProjectExplorer::ToolChainManager::instance()->findToolChains(qtAbis().at(0));
-        if (!alltc.isEmpty())
-            alltc.first()->addToEnvironment(environment);
-    }
+    const QList<ProjectExplorer::Abi> abis = qtAbis();
+    if (!abis.isEmpty())
+        ProjectExplorer::ToolChainManager::addToolChainEnvironment(abis.first(), environment);
 
     return environment;
 }
@@ -1039,6 +1036,17 @@ QtConfigWidget *BaseQtVersion::createConfigurationWidget() const
     return 0;
 }
 
+/* Cache the environment to be set for qmake to run by executable.
+ * Some toolchains require the environment to be set, for example
+ * MinGW. qmake is not built fully statically there
+ * since TDM gcc 4.6/64bit does not support -static-libstdc++ . */
+
+typedef QHash<QString, QStringList> QMakeBinaryEnvironmentHash;
+typedef QMakeBinaryEnvironmentHash::iterator QMakeBinaryEnvironmentIterator;
+
+Q_GLOBAL_STATIC(QMakeBinaryEnvironmentHash, qMakeBinaryEnvironmentHash)
+
+
 bool BaseQtVersion::queryQMakeVariables(const QString &binary, QHash<QString, QString> *versionInfo)
 {
     bool qmakeIsExecutable;
@@ -1074,7 +1082,20 @@ bool BaseQtVersion::queryQMakeVariables(const QString &binary, QHash<QString, QS
     for (uint i = 0; i < sizeof variables / sizeof variables[0]; ++i)
         args << queryArg << variables[i];
     QProcess process;
-    process.start(qmake.absoluteFilePath(), args, QIODevice::ReadOnly);
+    const QString absoluteQMakePath = qmake.absoluteFilePath();
+    QMakeBinaryEnvironmentIterator envIt = qMakeBinaryEnvironmentHash()->find(absoluteQMakePath);
+    if (envIt == qMakeBinaryEnvironmentHash()->end()) {
+        Utils::Environment environment = Utils::Environment::systemEnvironment();
+        const QList<ProjectExplorer::Abi> abis = ProjectExplorer::Abi::abisOfBinary(absoluteQMakePath);
+        const bool ok = !abis.isEmpty() && ProjectExplorer::ToolChainManager::addToolChainEnvironment(abis.first(), environment);
+        if (!ok)
+            qWarning("Unable to set toolchain environment for qmake executable '%s'.",
+                     qPrintable(absoluteQMakePath));
+        envIt = qMakeBinaryEnvironmentHash()->insert(absoluteQMakePath, environment.toStringList());
+    }
+    process.setEnvironment(envIt.value());
+    process.start(absoluteQMakePath, args, QIODevice::ReadOnly);
+
     if (!process.waitForStarted()) {
         *qmakeIsExecutable = false;
         qWarning("Cannot start '%s': %s", qPrintable(binary), qPrintable(process.errorString()));
-- 
1.7.6.msysgit.0

