diff options
author | David Kaspar <dkaspar@blackberry.com> | 2013-11-05 10:05:03 +0100 |
---|---|---|
committer | David Kaspar <dkaspar@blackberry.com> | 2013-11-05 10:18:15 +0100 |
commit | 851b2bd1ef5c0918485c72c54796764a9f9cfec6 (patch) | |
tree | 11d208d7bd7a0d02f6b35cfc61c756040f8e9db4 /src/plugins | |
parent | cd37acf69e57ce295d90fc30e1f96e23fc47debd (diff) | |
download | qt-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')
-rw-r--r-- | src/plugins/qnx/qnxutils.cpp | 170 |
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; |