summaryrefslogtreecommitdiff
path: root/src/plugins/qnx/qnxutils.cpp
diff options
context:
space:
mode:
authorDavid Kaspar <dkaspar@blackberry.com>2013-11-05 10:05:03 +0100
committerDavid Kaspar <dkaspar@blackberry.com>2013-11-05 10:18:15 +0100
commit851b2bd1ef5c0918485c72c54796764a9f9cfec6 (patch)
tree11d208d7bd7a0d02f6b35cfc61c756040f8e9db4 /src/plugins/qnx/qnxutils.cpp
parentcd37acf69e57ce295d90fc30e1f96e23fc47debd (diff)
downloadqt-creator-851b2bd1ef5c0918485c72c54796764a9f9cfec6.tar.gz
Qnx: executing instead of parsing bbndk-env script file
QnxUtils::qnxEnvironmentFromNdkFile() function was parsing the content of the bbndk-env.sh/bat script file to resolve environment for BB10 tools. The content of the script file is not documented and is a subject of heavy and frequent changes. Now QnxUtils::qnxEnvironmentFromNdkFile() function executes the script file and dumps the important env. variables that are parsed standard way. Change-Id: Ie7636054d62ec62b32cd3ab3d93a59b7d6c0882a Reviewed-by: Tobias Nätterlund <tobias.naetterlund@kdab.com> Reviewed-by: Nicolas Arnaud-Cormos <nicolas@kdab.com>
Diffstat (limited to 'src/plugins/qnx/qnxutils.cpp')
-rw-r--r--src/plugins/qnx/qnxutils.cpp170
1 files changed, 61 insertions, 109 deletions
diff --git a/src/plugins/qnx/qnxutils.cpp b/src/plugins/qnx/qnxutils.cpp
index f799fb524f..befc66c2c4 100644
--- a/src/plugins/qnx/qnxutils.cpp
+++ b/src/plugins/qnx/qnxutils.cpp
@@ -33,14 +33,25 @@
#include "qnxabstractqtversion.h"
#include <utils/hostosinfo.h>
+#include <utils/synchronousprocess.h>
#include <QDir>
#include <QDesktopServices>
#include <QDomDocument>
+#include <QProcess>
+#include <QTemporaryFile>
+#include <QApplication>
using namespace Qnx;
using namespace Qnx::Internal;
+namespace {
+const char *EVAL_ENV_VARS[] = {
+ "QNX_TARGET", "QNX_HOST", "QNX_CONFIGURATION", "MAKEFLAGS", "LD_LIBRARY_PATH",
+ "PATH", "QDE", "CPUVARDIR", "PYTHONPATH"
+};
+}
+
QString QnxUtils::addQuotes(const QString &string)
{
return QLatin1Char('"') + string + QLatin1Char('"');
@@ -81,122 +92,63 @@ QList<Utils::EnvironmentItem> QnxUtils::qnxEnvironmentFromNdkFile(const QString
{
QList <Utils::EnvironmentItem> items;
- QFile file(fileName);
- if (!file.open(QIODevice::ReadOnly))
+ if (!QFileInfo(fileName).exists())
return items;
- QTextStream str(&file);
- QMap<QString, QString> fileContent;
- while (!str.atEnd()) {
- QString line = str.readLine();
- if (!line.contains(QLatin1Char('=')))
- continue;
-
- int equalIndex = line.indexOf(QLatin1Char('='));
- QString var = line.left(equalIndex);
- //Remove set in front
- if (var.startsWith(QLatin1String("set ")))
- var = var.right(var.size() - 4);
-
- QString value = line.mid(equalIndex + 1);
-
- // BASE_DIR (and BASE_DIR_REPLACED in some recent internal versions) variable is
- // evaluated when souring the bbnk-env script
- // BASE_DIR="$( cd "$(dirname "${BASH_SOURCE[0]}" )" && pwd )"
- // We already know the NDK path so we can set the variable value
- // TODO: Do not parse bbnk-env!
- if (var == QLatin1String("BASE_DIR") || var == QLatin1String("BASE_DIR_REPLACED"))
- value = QFileInfo(fileName).dir().absolutePath();
-
- // LATEST_LINUX_JRE is evaluated when sourcing the file script
- // TODO: run the script and get environment instead of parsing it(?)
- if (var == QLatin1String("LATEST_LINUX_JRE"))
- continue;
-
- if (Utils::HostOsInfo::isWindowsHost()) {
- QRegExp systemVarRegExp(QLatin1String("IF NOT DEFINED ([\\w\\d]+)\\s+set ([\\w\\d]+)=([\\w\\d]+)"));
- if (line.contains(systemVarRegExp)) {
- var = systemVarRegExp.cap(2);
- Utils::Environment sysEnv = Utils::Environment::systemEnvironment();
- QString sysVar = systemVarRegExp.cap(1);
- if (sysEnv.hasKey(sysVar))
- value = sysEnv.value(sysVar);
- else
- value = systemVarRegExp.cap(3);
- }
- } else if (Utils::HostOsInfo::isAnyUnixHost()) {
- QRegExp systemVarRegExp(QLatin1String("\\$\\{([\\w\\d]+):=([\\w\\d]+)\\}")); // to match e.g. "${QNX_HOST_VERSION:=10_0_9_52}"
- if (value.contains(systemVarRegExp)) {
- Utils::Environment sysEnv = Utils::Environment::systemEnvironment();
- QString sysVar = systemVarRegExp.cap(1);
- if (sysEnv.hasKey(sysVar))
- value = sysEnv.value(sysVar);
- else
- value = systemVarRegExp.cap(2);
- }
- }
+ const bool isWindows = Utils::HostOsInfo::isWindowsHost();
- if (value.startsWith(QLatin1Char('"')))
- value = value.mid(1);
- if (value.endsWith(QLatin1Char('"')))
- value = value.left(value.size() - 1);
+ // locking creating bbndk-env file wrapper script
+ QTemporaryFile tmpFile(
+ QDir::tempPath() + QDir::separator()
+ + QLatin1String("bbndk-env-eval-XXXXXX") + QLatin1String(isWindows ? ".bat" : ".sh"));
+ if (!tmpFile.open())
+ return items;
+ tmpFile.setTextModeEnabled(true);
- fileContent[var] = value;
+ // writing content to wrapper script
+ QTextStream fileContent(&tmpFile);
+ if (isWindows)
+ fileContent << QLatin1String("@echo off\n")
+ << QLatin1String("call ") << fileName << QLatin1Char('\n');
+ else
+ fileContent << QLatin1String("#!/bin/bash\n")
+ << QLatin1String(". ") << fileName << QLatin1Char('\n');
+ QString linePattern = QString::fromLatin1(isWindows ? "echo %1=%%1%" : "echo %1=$%1");
+ for (int i = 0, len = sizeof(EVAL_ENV_VARS) / sizeof(const char *); i < len; ++i)
+ fileContent << linePattern.arg(QLatin1String(EVAL_ENV_VARS[i])) << QLatin1Char('\n');
+ tmpFile.close();
+
+ // running wrapper script
+ QProcess process;
+ if (isWindows)
+ process.start(QLatin1String("cmd.exe"),
+ QStringList() << QLatin1String("/C") << tmpFile.fileName());
+ else
+ process.start(QLatin1String("/bin/bash"),
+ QStringList() << tmpFile.fileName());
+
+ // waiting for finish
+ QApplication::setOverrideCursor(Qt::BusyCursor);
+ bool waitResult = process.waitForFinished(10000);
+ QApplication::restoreOverrideCursor();
+ if (!waitResult) {
+ Utils::SynchronousProcess::stopProcess(process);
+ return items;
}
- file.close();
- QMapIterator<QString, QString> it(fileContent);
- while (it.hasNext()) {
- it.next();
- QStringList values;
- if (Utils::HostOsInfo::isWindowsHost())
- values = it.value().split(QLatin1Char(';'));
- else if (Utils::HostOsInfo::isAnyUnixHost())
- values = it.value().split(QLatin1Char(':'));
-
- QString key = it.key();
- QStringList modifiedValues;
- foreach (const QString &value, values) {
- const QString ownKeyAsWindowsVar = QLatin1Char('%') + key + QLatin1Char('%');
- const QString ownKeyAsUnixVar = QLatin1Char('$') + key;
- if (value == ownKeyAsUnixVar) { // e.g. $PATH ==> ${PATH}
- QString val = key;
- val.prepend(QLatin1String("${"));
- val.append(QLatin1Char('}'));
- modifiedValues.append(val);
- } else if (value == ownKeyAsWindowsVar) {
- modifiedValues.append(value);
- } else {
- if (value.contains(QLatin1String("LATEST_LINUX_JRE"))) // Skip evaluated LATEST_LINUX_JRE variable
- continue;
-
- QString val = value;
- if (val.contains(QLatin1Char('%')) || val.contains(QLatin1Char('$'))) {
- QMapIterator<QString, QString> replaceIt(fileContent);
- while (replaceIt.hasNext()) {
- replaceIt.next();
- const QString replaceKey = replaceIt.key();
- if (replaceKey == key)
- continue;
-
- const QString keyAsWindowsVar = QLatin1Char('%') + replaceKey + QLatin1Char('%');
- const QString keyAsUnixVar = QLatin1Char('$') + replaceKey;
- if (val.contains(keyAsWindowsVar))
- val.replace(keyAsWindowsVar, replaceIt.value());
- if (val.contains(keyAsUnixVar))
- val.replace(keyAsUnixVar, replaceIt.value());
- }
- }
-
- // This variable will be properly set based on the qt version architecture
- if (key == QLatin1String("CPUVARDIR"))
- continue;
-
- modifiedValues.append(val);
- }
- }
+ if (process.exitStatus() != QProcess::NormalExit || process.exitCode() != 0)
+ return items;
- items.append(Utils::EnvironmentItem(key, modifiedValues.join(QString(Utils::HostOsInfo::pathListSeparator()))));
+ // parsing process output
+ QTextStream str(&process);
+ while (!str.atEnd()) {
+ QString line = str.readLine();
+ int equalIndex = line.indexOf(QLatin1Char('='));
+ if (equalIndex < 0)
+ continue;
+ QString var = line.left(equalIndex);
+ QString value = line.mid(equalIndex + 1);
+ items.append(Utils::EnvironmentItem(var, value));
}
return items;