Newer
Older
/**************************************************************************
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Nokia Corporation (qt-info@nokia.com)
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
** GNU Lesser General Public License Usage
** Alternatively, 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.
** If you are unsure which license is appropriate for your use, please
**************************************************************************/
#include "qt4projectmanagerconstants.h"
#include "profilereader.h"
#include "qt-s60/s60projectchecker.h"
#include "qmlobservertool.h"
#include <projectexplorer/debugginghelper.h>
#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/cesdkhandler.h>
#include <utils/synchronousprocess.h>
#include <coreplugin/coreconstants.h>
#include <coreplugin/icore.h>
#include <extensionsystem/pluginmanager.h>
#ifdef Q_OS_WIN
# include <utils/winutils.h>
#endif
#include <QtCore/QTextStream>
#include <QtGui/QApplication>
#include <QtGui/QDesktopServices>
using namespace Qt4ProjectManager;
using namespace Qt4ProjectManager::Internal;
using ProjectExplorer::DebuggingHelperLibrary;
static const char *QtVersionsSectionName = "QtVersions";
static const char *newQtVersionsKey = "NewQtVersions";
static const char *PATH_AUTODETECTION_SOURCE = "PATH";
enum { debug = 0 };
QtVersionManager *QtVersionManager::m_self = 0;
QtVersionManager::QtVersionManager()
: m_emptyVersion(new QtVersion)
{
QSettings *s = Core::ICore::instance()->settings();
m_idcount = 1;
int size = s->beginReadArray(QtVersionsSectionName);
for (int i = 0; i < size; ++i) {
s->setArrayIndex(i);
// Find the right id
// Either something saved or something generated
// Note: This code assumes that either all ids are read from the settings
// or generated on the fly.
int id = s->value("Id", -1).toInt();
if (id == -1)
id = getUniqueId();
QString autodetectionSource;
if (s->contains("isAutodetected")) {
isAutodetected = s->value("isAutodetected", false).toBool();
autodetectionSource = s->value("autodetectionSource", QString()).toString();
} else {// compatibility
isAutodetected = s->value("IsSystemVersion", false).toBool();
if (isAutodetected)
autodetectionSource = QLatin1String(PATH_AUTODETECTION_SOURCE);
}
QString qmakePath = s->value("QMakePath").toString();
if (qmakePath.isEmpty()) {
QString path = s->value("Path").toString();
if (!path.isEmpty()) {
foreach(const QString& command, ProjectExplorer::DebuggingHelperLibrary::possibleQMakeCommands())
{
QFileInfo fi(path + "/bin/" + command);
if (fi.exists())
{
qmakePath = fi.filePath();
break;
}
}
}
}
qmakePath,
isAutodetected,
autodetectionSource);
version->setMingwDirectory(s->value("MingwDirectory").toString());
version->setMsvcVersion(s->value("msvcVersion").toString());
version->setMwcDirectory(s->value("MwcDirectory").toString());
version->setS60SDKDirectory(s->value("S60SDKDirectory").toString());
version->setGcceDirectory(s->value("GcceDirectory").toString());
version->setSbsV2Directory(s->value(QLatin1String("SBSv2Directory")).toString());
m_versions.append(version);
}
s->endArray();
updateUniqueIdToIndexMap();
++m_idcount;
addNewVersionsFromInstaller();
updateSystemVersion();
writeVersionsIntoSettings();
// cannot call from ctor, needs to get connected extenernally first
QTimer::singleShot(0, this, SLOT(updateExamples()));
}
QtVersionManager::~QtVersionManager()
{
qDeleteAll(m_versions);
m_versions.clear();
delete m_emptyVersion;
m_emptyVersion = 0;
}
QtVersionManager *QtVersionManager::instance()
if (m_versions.contains(version))
return;
int uniqueId = version->uniqueId();
m_uniqueIdToIndex.insert(uniqueId, m_versions.count() - 1);
emit qtVersionsChanged(QList<int>() << uniqueId);
writeVersionsIntoSettings();
void QtVersionManager::removeVersion(QtVersion *version)
{
int uniqueId = version->uniqueId();
m_uniqueIdToIndex.remove(uniqueId);
emit qtVersionsChanged(QList<int>() << uniqueId);
writeVersionsIntoSettings();
delete version;
}
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
bool QtVersionManager::supportsTargetId(const QString &id) const
{
foreach (QtVersion *version, m_versions) {
if (version->supportsTargetId(id))
return true;
}
return false;
}
QList<QtVersion *> QtVersionManager::versionsForTargetId(const QString &id) const
{
QList<QtVersion *> targetVersions;
foreach (QtVersion *version, m_versions) {
if (version->supportsTargetId(id))
targetVersions.append(version);
}
return targetVersions;
}
QSet<QString> QtVersionManager::supportedTargetIds() const
{
QSet<QString> results;
foreach (QtVersion *version, m_versions)
results.unite(version->supportedTargetIds());
return results;
}
Core::HelpManager *helpManager = Core::HelpManager::instance();
const QString docPath = version->documentationPath() + QLatin1String("/qch/");
const QDir versionHelpDir(docPath);
foreach (const QString &helpFile,
versionHelpDir.entryList(QStringList() << QLatin1String("*.qch"), QDir::Files))
files << docPath + helpFile;
void QtVersionManager::updateExamples()
{
QtVersion *version = 0;
QList<QtVersion*> candidates;
// try to find a version which has both, demos and examples
foreach (version, m_versions) {
if (version->hasExamples() && version->hasDemos())
candidates.append(version);
}
// in SDKs, we want to prefer the Qt version shipping with the SDK
QSettings *settings = Core::ICore::instance()->settings();
QString preferred = settings->value(QLatin1String("PreferredQMakePath")).toString();
preferred = QDir::fromNativeSeparators(preferred);
#ifdef Q_OS_WIN
preferred = preferred.toLower();
if (!preferred.endsWith(QLatin1String(".exe")))
preferred.append(QLatin1String(".exe"));
#endif
foreach (version, candidates) {
if (version->qmakeCommand() == preferred) {
emit updateExamples(version->examplesPath(), version->demosPath(), version->sourcePath());
return;
}
}
}
// prefer versions with declarative examples
foreach (version, candidates) {
if (QDir(version->examplesPath()+"/declarative").exists()) {
emit updateExamples(version->examplesPath(), version->demosPath(), version->sourcePath());
if (!candidates.isEmpty()) {
version = candidates.first();
emit updateExamples(version->examplesPath(), version->demosPath(), version->sourcePath());
return;
}
return;
int QtVersionManager::getUniqueId()
{
return m_idcount++;
}
void QtVersionManager::updateUniqueIdToIndexMap()
{
m_uniqueIdToIndex.clear();
m_uniqueIdToIndex.insert(m_versions.at(i)->uniqueId(), i);
}
void QtVersionManager::writeVersionsIntoSettings()
{
QSettings *s = Core::ICore::instance()->settings();
s->beginWriteArray(QtVersionsSectionName);
const QtVersion *version = m_versions.at(i);
s->setValue("Name", version->displayName());
// for downwards compat
s->setValue("Path", version->versionInfo().value("QT_INSTALL_DATA"));
s->setValue("QMakePath", version->qmakeCommand());
s->setValue("Id", version->uniqueId());
s->setValue("MingwDirectory", version->mingwDirectory());
s->setValue("msvcVersion", version->msvcVersion());
s->setValue("isAutodetected", version->isAutodetected());
if (version->isAutodetected())
s->setValue("autodetectionSource", version->autodetectionSource());
s->setValue("MwcDirectory", version->mwcDirectory());
s->setValue("S60SDKDirectory", version->s60SDKDirectory());
s->setValue("GcceDirectory", version->gcceDirectory());
s->setValue(QLatin1String("SBSv2Directory"), version->sbsV2Directory());
QList<QtVersion *> QtVersionManager::versions() const
QList<QtVersion *> QtVersionManager::validVersions() const
{
QList<QtVersion *> results;
foreach(QtVersion *v, m_versions) {
if (v->isValid())
results.append(v);
}
return results;
}
bool QtVersionManager::isValidId(int id) const
{
int pos = m_uniqueIdToIndex.value(id, -1);
return (pos != -1);
}
QtVersion *QtVersionManager::version(int id) const
{
int pos = m_uniqueIdToIndex.value(id, -1);
if (pos != -1)
return m_versions.at(pos);
}
void QtVersionManager::addNewVersionsFromInstaller()
{
// Add new versions which may have been installed by the WB installer in the form:
// NewQtVersions="qt 4.3.2=c:\\qt\\qt432\bin\qmake.exe;qt embedded=c:\\qtembedded;"
// or NewQtVersions="qt 4.3.2=c:\\qt\\qt432bin\qmake.exe=c:\\qtcreator\\mingw\\=MSVCName;
// i.e.
// NewQtVersions="versionname=pathtoversion=mingw=s60sdk=gcce=carbide;"
// Duplicate entries are not added, the first new version is set as default.
QSettings *settings = Core::ICore::instance()->settings();
QSettings *globalSettings = Core::ICore::instance()->settings(QSettings::SystemScope);

Daniel Molkentin
committed
QDateTime lastUpdateFromGlobalSettings = globalSettings->value(
QLatin1String("General/LastQtVersionUpdate")).toDateTime();
const QFileInfo gsFi(globalSettings->fileName());
if ( !lastUpdateFromGlobalSettings.isNull() &&
(!gsFi.exists() || (gsFi.lastModified() > lastUpdateFromGlobalSettings)) )
if (!globalSettings->contains(newQtVersionsKey) &&
!globalSettings->contains(QLatin1String("Installer/")+newQtVersionsKey))
{
return;
}
QString newVersionsValue = settings->value(newQtVersionsKey).toString();

Daniel Molkentin
committed
if (newVersionsValue.isEmpty())
newVersionsValue = settings->value(QLatin1String("Installer/")+newQtVersionsKey).toString();
QStringList newVersionsList = newVersionsValue.split(';', QString::SkipEmptyParts);
foreach (const QString &newVersion, newVersionsList) {
if (newVersionData.count() >= 2) {
if (QFile::exists(newVersionData[1])) {
QtVersion *version = new QtVersion(newVersionData[0], newVersionData[1], m_idcount++ );
if (newVersionData.count() >= 4)
version->setS60SDKDirectory(QDir::fromNativeSeparators(newVersionData[3]));
if (newVersionData.count() >= 5)
version->setGcceDirectory(QDir::fromNativeSeparators(newVersionData[4]));
if (newVersionData.count() >= 6)
version->setMwcDirectory(QDir::fromNativeSeparators(newVersionData[5]));
if (newVersionData.count() >= 7)
version->setMsvcVersion(newVersionData[6]);
if (newVersionData.count() >= 8)
version->setSbsV2Directory(QDir::fromNativeSeparators(newVersionData[7]));
bool versionWasAlreadyInList = false;
foreach(const QtVersion * const it, m_versions) {
if (QDir(version->qmakeCommand()).canonicalPath() == QDir(it->qmakeCommand()).canonicalPath()) {
versionWasAlreadyInList = true;
break;
}
}
if (!versionWasAlreadyInList) {
m_versions.append(version);
} else {
// clean up
delete version;
}
}
}
}
updateUniqueIdToIndexMap();
settings->setValue(QLatin1String("General/LastQtVersionUpdate"), QDateTime::currentDateTime());
}
void QtVersionManager::updateSystemVersion()
{
bool haveSystemVersion = false;
QString systemQMakePath = DebuggingHelperLibrary::findSystemQt(Utils::Environment::systemEnvironment());
if (systemQMakePath.isNull())
systemQMakePath = tr("<not found>");
if (version->isAutodetected()
&& version->autodetectionSource() == PATH_AUTODETECTION_SOURCE) {
version->setQMakeCommand(systemQMakePath);
version->setDisplayName(tr("Qt in PATH"));
haveSystemVersion = true;
}
}
if (haveSystemVersion)
return;
QtVersion *version = new QtVersion(tr("Qt in PATH"),
systemQMakePath,
true,
PATH_AUTODETECTION_SOURCE);
m_versions.prepend(version);
updateUniqueIdToIndexMap();
}
QtVersion *QtVersionManager::emptyVersion() const
class SortByUniqueId
{
public:
bool operator()(QtVersion *a, QtVersion *b)
{
return a->uniqueId() < b->uniqueId();
}
};
bool QtVersionManager::equals(QtVersion *a, QtVersion *b)
{
if (a->m_qmakeCommand != b->m_qmakeCommand)
return false;
if (a->m_id != b->m_id)
return false;
if (a->m_mingwDirectory != b->m_mingwDirectory
|| a->m_msvcVersion != b->m_msvcVersion
|| a->m_mwcDirectory != b->m_mwcDirectory)
return false;
if (a->m_displayName != b->displayName())
return false;
void QtVersionManager::setNewQtVersions(QList<QtVersion *> newVersions)
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
// We want to preserve the same order as in the settings dialog
// so we sort a copy
QList<QtVersion *> sortedNewVersions = newVersions;
SortByUniqueId sortByUniqueId;
qSort(sortedNewVersions.begin(), sortedNewVersions.end(), sortByUniqueId);
qSort(m_versions.begin(), m_versions.end(), sortByUniqueId);
QList<int> changedVersions;
// So we trying to find the minimal set of changed versions,
// iterate over both sorted list
// newVersions and oldVersions iterator
QList<QtVersion *>::const_iterator nit, nend, oit, oend;
nit = sortedNewVersions.constBegin();
nend = sortedNewVersions.constEnd();
oit = m_versions.constBegin();
oend = m_versions.constEnd();
while (nit != nend && oit != oend) {
int nid = (*nit)->uniqueId();
int oid = (*oit)->uniqueId();
if (nid < oid) {
changedVersions.push_back(nid);
++nit;
} else if (oid < nid) {
changedVersions.push_back(oid);
++oit;
} else {
if (!equals(*oit, *nit))
changedVersions.push_back(oid);
++oit;
++nit;
while (nit != nend) {
changedVersions.push_back((*nit)->uniqueId());
}
while (oit != oend) {
changedVersions.push_back((*oit)->uniqueId());
qDeleteAll(m_versions);
m_versions.clear();
if (!changedVersions.isEmpty())
updateDocumentation();
updateUniqueIdToIndexMap();
updateExamples();
writeVersionsIntoSettings();
if (!changedVersions.isEmpty())
emit qtVersionsChanged(changedVersions);
QtVersion::QtVersion(const QString &name, const QString &qmakeCommand, int id,
bool isAutodetected, const QString &autodetectionSource)
m_isAutodetected(isAutodetected),
m_autodetectionSource(autodetectionSource),
m_hasDebuggingHelper(false),
m_hasQmlDump(false),
m_hasQmlObserver(false),
m_toolChainUpToDate(false),
m_versionInfoUpToDate(false),
m_notInstalled(false),
m_defaultConfigIsDebug(true),
m_defaultConfigIsDebugAndRelease(true),
m_hasExamples(false),
m_hasDemos(false),
setQMakeCommand(qmakeCommand);
QtVersion::QtVersion(const QString &name, const QString &qmakeCommand,
bool isAutodetected, const QString &autodetectionSource)
m_isAutodetected(isAutodetected),
m_autodetectionSource(autodetectionSource),
m_hasDebuggingHelper(false),
m_hasQmlDump(false),
m_hasQmlObserver(false),
m_toolChainUpToDate(false),
m_versionInfoUpToDate(false),
m_notInstalled(false),
m_defaultConfigIsDebug(true),
m_defaultConfigIsDebugAndRelease(true),
m_hasExamples(false),
m_hasDemos(false),
m_hasDocumentation(false)
{
m_id = getUniqueId();
setQMakeCommand(qmakeCommand);
}
QtVersion::QtVersion(const QString &qmakeCommand, bool isAutodetected, const QString &autodetectionSource)
: m_isAutodetected(isAutodetected),
m_autodetectionSource(autodetectionSource),
m_hasDebuggingHelper(false),
m_hasQmlDump(false),
m_hasQmlObserver(false),
m_toolChainUpToDate(false),
m_versionInfoUpToDate(false),
m_notInstalled(false),
m_defaultConfigIsDebug(true),
m_defaultConfigIsDebugAndRelease(true),
m_hasExamples(false),
m_hasDemos(false),
m_hasDocumentation(false)
setQMakeCommand(qmakeCommand);
m_isAutodetected(false),
m_hasDebuggingHelper(false),
m_hasQmlDump(false),
m_hasQmlObserver(false),
m_toolChainUpToDate(false),
m_versionInfoUpToDate(false),
m_notInstalled(false),
m_defaultConfigIsDebug(true),
m_defaultConfigIsDebugAndRelease(true),
m_hasExamples(false),
m_hasDemos(false),
m_hasDocumentation(false)
{
QtVersion::~QtVersion()
{
}
QString QtVersion::toHtml() const
{
QString rc;
QTextStream str(&rc);
str << "<tr><td><b>" << QtVersionManager::tr("Name:")
<< "</b></td><td>" << displayName() << "</td></tr>";
str << "<tr><td><b>" << QtVersionManager::tr("Source:")
<< "</b></td><td>" << sourcePath() << "</td></tr>";
str << "<tr><td><b>" << QtVersionManager::tr("mkspec:")
<< "</b></td><td>" << mkspec() << "</td></tr>";
str << "<tr><td><b>" << QtVersionManager::tr("qmake:")
<< "</b></td><td>" << m_qmakeCommand << "</td></tr>";
if (m_defaultConfigIsDebug || m_defaultConfigIsDebugAndRelease) {
str << "<tr><td><b>" << QtVersionManager::tr("Default:") << "</b></td><td>"
<< (m_defaultConfigIsDebug ? "debug" : "release");
if (m_defaultConfigIsDebugAndRelease)
str << " debug_and_release";
str << "</td></tr>";
} // default config.
str << "<tr><td><b>" << QtVersionManager::tr("Version:")
<< "</b></td><td>" << qtVersionString() << "</td></tr>";
if (hasDebuggingHelper())
str << "<tr><td><b>" << QtVersionManager::tr("Debugging helper:")
<< "</b></td><td>" << debuggingHelperLibrary() << "</td></tr>";
const QHash<QString,QString> vInfo = versionInfo();
if (!vInfo.isEmpty()) {
const QHash<QString,QString>::const_iterator vcend = vInfo.constEnd();
for (QHash<QString,QString>::const_iterator it = vInfo.constBegin(); it != vcend; ++it)
str << "<tr><td><pre>" << it.key() << "</pre></td><td>" << it.value() << "</td></tr>";
}
return rc;
}
bool QtVersion::supportsShadowBuilds() const
{
QSet<QString> targets = supportedTargetIds();
// Symbian does not support shadow building
if (targets.contains(Constants::S60_DEVICE_TARGET_ID) ||
targets.contains(Constants::S60_EMULATOR_TARGET_ID)) {
// We can not support shadow building with the ABLD system
return false;
}
return true;
}
QList<ProjectExplorer::Task>
QtVersion::reportIssues(const QString &proFile, const QString &buildDir)
{
QList<ProjectExplorer::Task> results;
QString tmpBuildDir = buildDir;
if (!buildDir.endsWith(QChar('/')))
tmpBuildDir.append(QChar('/'));
if (!isValid()) {
//: %1: Reason for being invalid
const QString msg = QCoreApplication::translate("Qt4ProjectManager::QtVersion", "The Qt version is invalid: %1").arg(invalidReason());
results.append(ProjectExplorer::Task(ProjectExplorer::Task::Error, msg, QString(), -1,
QLatin1String(ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM)));
QFileInfo qmakeInfo(qmakeCommand());
if (!qmakeInfo.exists() ||
!qmakeInfo.isExecutable()) {
//: %1: Path to qmake executable
const QString msg = QCoreApplication::translate("Qt4ProjectManager::QtVersion",
"The qmake command \"%1\" was not found or is not executable.").arg(qmakeCommand());
results.append(ProjectExplorer::Task(ProjectExplorer::Task::Error, msg, QString(), -1,
QLatin1String(ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM)));
QString sourcePath = QFileInfo(proFile).absolutePath();
if (!sourcePath.endsWith(QChar('/')))
sourcePath.append(QChar('/'));
if ((tmpBuildDir.startsWith(sourcePath)) && (tmpBuildDir != sourcePath)) {
const QString msg = QCoreApplication::translate("Qt4ProjectManager::QtVersion",
"Qmake does not support build directories below the source directory.");
results.append(ProjectExplorer::Task(ProjectExplorer::Task::Warning, msg, QString(), -1,
QLatin1String(ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM)));
} else if (tmpBuildDir.count(QChar('/')) != sourcePath.count(QChar('/'))) {
const QString msg = QCoreApplication::translate("Qt4ProjectManager::QtVersion",
"The build directory needs to be at the same level as the source directory.");
results.append(ProjectExplorer::Task(ProjectExplorer::Task::Warning, msg, QString(), -1,
QLatin1String(ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM)));
}
QSet<QString> targets = supportedTargetIds();
if (targets.contains(Constants::S60_DEVICE_TARGET_ID) ||
targets.contains(Constants::S60_EMULATOR_TARGET_ID))
results.append(S60ProjectChecker::reportIssues(proFile, this));
return results;
}
QString QtVersion::displayName() const
QString QtVersion::qmakeCommand() const
return m_qmakeCommand;
}
QString QtVersion::sourcePath() const
{
return m_sourcePath;
}
QString QtVersion::mkspec() const
{
bool QtVersion::isBuildWithSymbianSbsV2() const
{
updateToolChainAndMkspec();
return m_isBuildUsingSbsV2;
}
QString QtVersion::qtVersionString() const
{
if (m_qtVersionString.isNull()) {
QFileInfo qmake(m_qmakeCommand);
if (qmake.exists() && qmake.isExecutable()) {
m_qtVersionString = DebuggingHelperLibrary::qtVersionForQMake(qmake.absoluteFilePath());
} else {
m_qtVersionString = QLatin1String("");
}
}
return m_qtVersionString;
}
QHash<QString,QString> QtVersion::versionInfo() const
{
updateVersionInfo();
return m_versionInfo;
}
void QtVersion::setDisplayName(const QString &name)
void QtVersion::setQMakeCommand(const QString& qmakeCommand)
m_qmakeCommand = QDir::fromNativeSeparators(qmakeCommand);
m_qmakeCommand = m_qmakeCommand.toLower();
m_designerCommand.clear();
m_linguistCommand.clear();

Kai Koehne
committed
m_qmlviewerCommand.clear();
m_toolChainUpToDate = false;
// TODO do i need to optimize this?
m_versionInfoUpToDate = false;
updateSourcePath();
updateVersionInfo();
const QString installData = m_versionInfo["QT_INSTALL_DATA"];
m_sourcePath = installData;
QFile qmakeCache(installData + QLatin1String("/.qmake.cache"));
if (qmakeCache.exists()) {
qmakeCache.open(QIODevice::ReadOnly | QIODevice::Text);
QTextStream stream(&qmakeCache);
while (!stream.atEnd()) {
QString line = stream.readLine().trimmed();
if (line.startsWith(QLatin1String("QT_SOURCE_TREE"))) {
m_sourcePath = line.split(QLatin1Char('=')).at(1).trimmed();
if (m_sourcePath.startsWith(QLatin1String("$$quote("))) {
m_sourcePath.remove(0, 8);
m_sourcePath.chop(1);
}
break;
}
}
}
m_sourcePath = QDir::cleanPath(m_sourcePath);
#ifdef Q_OS_WIN
m_sourcePath = m_sourcePath.toLower();
#endif
}
// Returns the version that was used to build the project in that directory
// That is returns the directory
// To find out whether we already have a qtversion for that directory call
// QtVersion *QtVersionManager::qtVersionForDirectory(const QString directory);
QString QtVersionManager::findQMakeBinaryFromMakefile(const QString &makefile)
QFile fi(makefile);
if (fi.exists() && fi.open(QFile::ReadOnly)) {
QTextStream ts(&fi);
while (!ts.atEnd()) {
QString line = ts.readLine();
if (r1.exactMatch(line)) {
if (debugAdding)
qDebug()<<"#~~ QMAKE is:"<<r1.cap(1).trimmed();
QFileInfo qmake(r1.cap(1).trimmed());
QString qmakePath = qmake.filePath();
if (!qmakePath.endsWith(QLatin1String(".exe")))
qmakePath.append(QLatin1String(".exe"));
// Is qmake still installed?
QFileInfo fi(qmakePath);
if (fi.exists()) {
qmakePath = fi.absoluteFilePath();
#ifdef Q_OS_WIN
qmakePath = qmakePath.toLower();
#endif
return qmakePath;
QtVersion *QtVersionManager::qtVersionForQMakeBinary(const QString &qmakePath)
if (v->qmakeCommand() == qmakePath) {
return v;
break;
}
}
void dumpQMakeAssignments(const QList<QMakeAssignment> &list)
foreach(const QMakeAssignment &qa, list) {
qDebug()<<qa.variable<<qa.op<<qa.value;
}
}
bool QtVersionManager::makefileIsFor(const QString &makefile, const QString &proFile)
{
if (proFile.isEmpty())
return true;
QString line = findQMakeLine(makefile, QLatin1String("# Project:")).trimmed();
if (line.isEmpty())
return false;
line = line.mid(line.indexOf(QChar(':')) + 1);
line = line.trimmed();
QFileInfo srcFileInfo(QFileInfo(makefile).absoluteDir(), line);
QFileInfo proFileInfo(proFile);
return srcFileInfo == proFileInfo;
}
QPair<QtVersion::QmakeBuildConfigs, QString> QtVersionManager::scanMakeFile(const QString &makefile, QtVersion::QmakeBuildConfigs defaultBuildConfig)
if (debug)
qDebug()<<"ScanMakeFile, the gory details:";
QtVersion::QmakeBuildConfigs result = defaultBuildConfig;
QString line = findQMakeLine(makefile, QLatin1String("# Command:"));
if (debug)
qDebug()<<"Found line"<<line;
line = trimLine(line);
QList<QMakeAssignment> assignments;
QList<QMakeAssignment> afterAssignments;
parseArgs(line, &assignments, &afterAssignments, &result2);
if (debug) {
dumpQMakeAssignments(assignments);
if (!afterAssignments.isEmpty())
qDebug()<<"-after";
dumpQMakeAssignments(afterAssignments);
}
// Search in assignments for CONFIG(+=,-=,=)(debug,release,debug_and_release)
// Also remove them from the list
result = qmakeBuildConfigFromCmdArgs(&assignments, defaultBuildConfig);
foreach(const QMakeAssignment &qa, assignments)
Utils::QtcProcess::addArg(&result2, qa.variable + qa.op + qa.value);
if (!afterAssignments.isEmpty()) {
Utils::QtcProcess::addArg(&result2, QLatin1String("-after"));
foreach(const QMakeAssignment &qa, afterAssignments)
Utils::QtcProcess::addArg(&result2, qa.variable + qa.op + qa.value);
}
}
// Dump the gathered information:
if (debug) {
qDebug()<<"\n\nDumping information from scanMakeFile";
qDebug()<<"QMake CONFIG variable parsing";
qDebug()<<" "<< (result & QtVersion::NoBuild ? "No Build" : QString::number(int(result)));
qDebug()<<" "<< (result & QtVersion::DebugBuild ? "debug" : "release");
qDebug()<<" "<< (result & QtVersion::BuildAll ? "debug_and_release" : "no debug_and_release");
qDebug()<<"\nAddtional Arguments";
qDebug()<<result2;
qDebug()<<"\n\n";
}
return qMakePair(result, result2);
}
QString QtVersionManager::findQMakeLine(const QString &makefile, const QString &key)
QFile fi(makefile);
if (fi.exists() && fi.open(QFile::ReadOnly)) {
QTextStream ts(&fi);
if (line.startsWith(key))
return line;
}
}
return QString();
}
/// This function trims the "#Command /path/to/qmake" from the the line
QString QtVersionManager::trimLine(const QString line)
{
// Actually the first space after #Command: /path/to/qmake
const int firstSpace = line.indexOf(QLatin1Char(' '), 11);
return line.mid(firstSpace).trimmed();
}
void QtVersionManager::parseArgs(const QString &args, QList<QMakeAssignment> *assignments, QList<QMakeAssignment> *afterAssignments, QString *additionalArguments)
{
QRegExp regExp("([^\\s\\+-]*)\\s*(\\+=|=|-=|~=)(.*)");
bool after = false;
bool ignoreNext = false;
*additionalArguments = args;
Utils::QtcProcess::ArgIterator ait(additionalArguments);
while (ait.next()) {
if (ignoreNext) {
// Ignoring
ignoreNext = false;
ait.deleteArg();
} else if (ait.value() == QLatin1String("-after")) {
ait.deleteArg();
} else if (ait.value().contains(QLatin1Char('='))) {
if (regExp.exactMatch(ait.value())) {
QMakeAssignment qa;
qa.variable = regExp.cap(1);
qa.op = regExp.cap(2);
qa.value = regExp.cap(3).trimmed();
if (after)
afterAssignments->append(qa);
else
assignments->append(qa);
} else {
qDebug()<<"regexp did not match";
}
ait.deleteArg();
} else if (ait.value() == QLatin1String("-o")) {