aboutsummaryrefslogtreecommitdiffstats
path: root/src/app/shared
diff options
context:
space:
mode:
authorChristian Kandeler <christian.kandeler@nokia.com>2012-02-23 15:21:00 +0100
committerChristian Kandeler <christian.kandeler@nokia.com>2012-02-24 16:40:08 +0100
commitb96466f4801cc36a9ae630e6d34300a9f0c9f35f (patch)
tree711c5e3f2054581440dc44de9108359ebeb65cc6 /src/app/shared
parent669fc55e22ad81b6606914293f7a696d6b870f5c (diff)
Add support for the magical MT platform.
Change-Id: Iee3228a256980fe2aea0265f0eecca63f37824fb Reviewed-by: Joerg Bornemann <joerg.bornemann@nokia.com>
Diffstat (limited to 'src/app/shared')
-rw-r--r--src/app/shared/specialplatformssetup.cpp228
-rw-r--r--src/app/shared/specialplatformssetup.h99
2 files changed, 327 insertions, 0 deletions
diff --git a/src/app/shared/specialplatformssetup.cpp b/src/app/shared/specialplatformssetup.cpp
new file mode 100644
index 000000000..da5231f3a
--- /dev/null
+++ b/src/app/shared/specialplatformssetup.cpp
@@ -0,0 +1,228 @@
+/**************************************************************************
+**
+** This file is part of the Qt Build Suite
+**
+** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+**
+** GNU Lesser General Public License Usage
+**
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this file.
+** Please review the following information to ensure the GNU Lesser General
+** Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file.
+** Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**************************************************************************/
+#include "specialplatformssetup.h"
+
+#include <QBuffer>
+#include <QCoreApplication>
+#include <QDir>
+#include <QFile>
+#include <QFileInfo>
+#include <QProcess>
+#include <QProcessEnvironment>
+#include <QSettings>
+
+#include <cstdio>
+
+namespace qbs {
+
+SpecialPlatformsSetup::SpecialPlatformsSetup() : m_stdout(stdout), m_helpRequested(false) {}
+SpecialPlatformsSetup::~SpecialPlatformsSetup() {}
+
+void SpecialPlatformsSetup::setup()
+{
+ parseCommandLine();
+ if (helpRequested())
+ return;
+ setupBaseDir();
+
+ const QString qbsPath = QCoreApplication::applicationDirPath() + QLatin1String("/qbs");
+ const QString commandLine = qbsPath + QLatin1String(" platforms print-config-base-dir");
+ const QString configBaseDir = QString::fromLocal8Bit(runProcess(commandLine,
+ QProcessEnvironment::systemEnvironment())).trimmed();
+
+ foreach (const PlatformInfo &pi, gatherPlatformInfo())
+ writeConfigFile(pi, configBaseDir);
+}
+
+QString SpecialPlatformsSetup::helpString() const
+{
+ return tr("This tool sets up qbs platform definitions for all installed "
+ "targets in a given %1 installation.\n").arg(platformTypeName()) + usageString();
+}
+
+QString SpecialPlatformsSetup::usageString() const
+{
+ QString s = tr("Usage: ") + QCoreApplication::applicationFilePath() + ' '
+ + tr("[-h|<base directory>]");
+ const QString &defaultDir = defaultBaseDirectory();
+ if (!defaultDir.isEmpty() == 1)
+ s += QLatin1Char('\n') + tr("The default base directory is '%1'.").arg(defaultDir);
+ return s;
+}
+
+QString SpecialPlatformsSetup::tr(const char *str)
+{
+ return QCoreApplication::translate("SpecialPlatformSetup", str);
+}
+
+void SpecialPlatformsSetup::parseCommandLine()
+{
+ QStringList args = qApp->arguments();
+ args.removeFirst();
+ while (!args.isEmpty()) {
+ const QString arg = args.takeFirst();
+ if (arg == QLatin1String("-h") || arg == QLatin1String("-help")
+ || arg == QLatin1String("--help")) {
+ m_helpRequested = true;
+ return;
+ }
+ if (arg.startsWith(QLatin1Char('-')))
+ throw Exception(tr("Unknown option '%1'\n%2.").arg(arg).arg(usageString()));
+ m_baseDir = arg;
+ }
+}
+
+void SpecialPlatformsSetup::setupBaseDir()
+{
+ if (m_baseDir.isEmpty()) {
+ const QString &defaultDir = defaultBaseDirectory();
+ if (!defaultDir.isEmpty() && QFileInfo(defaultDir).exists())
+ m_baseDir = defaultDir;
+ }
+ if (m_baseDir.isEmpty())
+ throw Exception(tr("No base directory given and none auto-detected."));
+}
+
+QByteArray SpecialPlatformsSetup::runProcess(const QString &commandLine,
+ const QProcessEnvironment &env)
+{
+ QProcess proc;
+ proc.setProcessChannelMode(QProcess::MergedChannels);
+ proc.setProcessEnvironment(env);
+ proc.start(commandLine);
+ if (!proc.waitForStarted())
+ handleProcessError(commandLine, proc.errorString(), QByteArray());
+ if (proc.state() == QProcess::Running && !proc.waitForFinished(5000)) {
+ if (proc.error() == QProcess::UnknownError)
+ handleProcessError(commandLine, tr("Process hangs"), QByteArray());
+ handleProcessError(commandLine, proc.errorString(), QByteArray());
+ }
+ const QByteArray output = proc.readAll();
+ if (proc.exitStatus() == QProcess::CrashExit)
+ handleProcessError(commandLine, proc.errorString(), output);
+ if (proc.exitCode() != 0) {
+ handleProcessError(commandLine, tr("Unexpected exit code %1").arg(proc.exitCode()),
+ output);
+ }
+ return output;
+}
+
+QChar SpecialPlatformsSetup::envVarSeparator() const
+{
+ // TODO: This should not be necessary; qbs should handle it.
+ QChar sep;
+#ifdef Q_OS_UNIX
+ sep = QLatin1Char(':');
+#elif defined(Q_OS_WIN)
+ sep = QLatin1Char(';');
+#else
+#error "Weird platform this is. Not support it we do."
+#endif
+ return sep;
+}
+
+void SpecialPlatformsSetup::handleProcessError(const QString &commandLine, const QString &message,
+ const QByteArray &output)
+{
+ QString completeMsg = tr("Command '%1' failed: %2.")
+ .arg(QDir::toNativeSeparators(commandLine), message);
+ if (!output.isEmpty())
+ completeMsg += QLatin1Char('\n') + tr("Output was: %1").arg(QString::fromLocal8Bit(output));
+ throw Exception(completeMsg);
+}
+
+void SpecialPlatformsSetup::writeConfigFile(const PlatformInfo &platformInfo,
+ const QString &configBaseDir)
+{
+ m_stdout << tr("Setting up platform '%1'...").arg(platformInfo.name) << endl;
+
+ const QString configDir = configBaseDir + QLatin1Char('/') + platformInfo.name;
+
+ /*
+ * A more correct solution would be to recursively remove and then recreate the directory.
+ * However, since it only contains one file, that currently seems like overkill.
+ */
+ if (!QDir::root().mkpath(configDir)) {
+ throw Exception(tr("Directory '%1' could not be created.")
+ .arg(QDir::toNativeSeparators(configDir)));
+ }
+ const QString configFilePath = configDir + QLatin1String("/setup.ini");
+ if (QFileInfo(configFilePath).exists()) {
+ QFile configFile(configFilePath);
+ if (!configFile.remove()) {
+ throw Exception(tr("Failed to remove old config file '%1': %2.")
+ .arg(QDir::toNativeSeparators(configFilePath), configFile.errorString()));
+ }
+ }
+
+ QSettings settings(configFilePath, QSettings::IniFormat);
+
+ settings.setValue(QLatin1String("toolchain"), QLatin1String("gcc"));
+ settings.setValue(QLatin1String("endianness"), QLatin1String("little-endian"));
+ settings.setValue(QLatin1String("targetOS"), QLatin1String("linux"));
+
+ settings.beginGroup(QLatin1String("cpp"));
+ settings.setValue(QLatin1String("toolchainInstallPath"), platformInfo.toolchainDir);
+ settings.setValue(QLatin1String("compilerName"), platformInfo.compilerName);
+ settings.setValue(QLatin1String("sysroot"), platformInfo.sysrootDir);
+ settings.endGroup();
+
+ settings.beginGroup(QLatin1String("qt/core"));
+ settings.setValue(QLatin1String("binPath"), platformInfo.qtBinDir);
+ settings.setValue(QLatin1String("libPath"),
+ platformInfo.sysrootDir + QLatin1String("/usr/lib"));
+ settings.setValue(QLatin1String("incPath"), platformInfo.qtIncDir);
+ settings.setValue(QLatin1String("mkspecsPath"), platformInfo.qtMkspecsDir);
+ settings.setValue(QLatin1String("qtNamespace"), QString());
+ settings.setValue(QLatin1String("qtLibInfix"), QString());
+ settings.endGroup();
+
+ settings.beginGroup(QLatin1String("environment"));
+ for (QHash<QString, QString>::ConstIterator it = platformInfo.environment.constBegin();
+ it != platformInfo.environment.constEnd(); ++it) {
+ settings.setValue(it.key(), it.value());
+ }
+ settings.endGroup();
+
+ settings.sync();
+ if (settings.status() != QSettings::NoError) {
+ throw Exception(tr("Failed to write platform config file '%1'.")
+ .arg(QDir::toNativeSeparators(configFilePath)));
+ }
+}
+
+} // namespace qbs
diff --git a/src/app/shared/specialplatformssetup.h b/src/app/shared/specialplatformssetup.h
new file mode 100644
index 000000000..31886c5d5
--- /dev/null
+++ b/src/app/shared/specialplatformssetup.h
@@ -0,0 +1,99 @@
+/**************************************************************************
+**
+** This file is part of the Qt Build Suite
+**
+** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+**
+** GNU Lesser General Public License Usage
+**
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this file.
+** Please review the following information to ensure the GNU Lesser General
+** Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file.
+** Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**************************************************************************/
+#include <QHash>
+#include <QList>
+#include <QString>
+#include <QStringList>
+#include <QTextStream>
+
+QT_FORWARD_DECLARE_CLASS(QProcessEnvironment)
+
+namespace qbs {
+
+class SpecialPlatformsSetup
+{
+public:
+ struct Exception
+ {
+ Exception(const QString &msg) : errorMessage(msg) {}
+
+ const QString errorMessage;
+ };
+
+ struct PlatformInfo
+ {
+ QString name;
+ QString toolchainDir;
+ QString compilerName;
+ QString sysrootDir;
+ QString qtBinDir;
+ QString qtIncDir;
+ QString qtMkspecsDir;
+ QHash<QString, QString> environment;
+ };
+
+ SpecialPlatformsSetup();
+ virtual ~SpecialPlatformsSetup();
+ void setup();
+
+ bool helpRequested() const { return m_helpRequested; }
+ QString helpString() const;
+ static QString tr(const char *str);
+
+protected:
+ QString baseDirectory() const { return m_baseDir; }
+ QByteArray runProcess(const QString &commandLine, const QProcessEnvironment &env);
+ QChar envVarSeparator() const;
+
+private:
+ virtual QString defaultBaseDirectory() const = 0;
+ virtual QString platformTypeName() const = 0;
+ virtual QList<PlatformInfo> gatherPlatformInfo() = 0;
+
+ QString usageString() const;
+ void parseCommandLine();
+ void setupBaseDir();
+ void handleProcessError(const QString &commandLine, const QString &message,
+ const QByteArray &output);
+ void writeConfigFile(const PlatformInfo &platformInfo, const QString &configBaseDir);
+
+ QString m_baseDir;
+ QTextStream m_stdout;
+ bool m_helpRequested;
+};
+
+} // namespace qbs