/*************************************************************************** ** ** This file is part of Qt Creator ** ** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). ** ** Contact: Qt Software Information (qt-info@nokia.com) ** ** ** Non-Open Source Usage ** ** Licensees may use this file in accordance with the Qt Beta Version ** License Agreement, Agreement version 2.2 provided with the Software or, ** alternatively, in accordance with the terms contained in a written ** agreement between you and Nokia. ** ** GNU General Public License Usage ** ** Alternatively, this file may be used under the terms of the GNU General ** Public License versions 2.0 or 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 GNU ** General Public Licensing requirements will be met: ** ** http://www.fsf.org/licensing/licenses/info/GPLv2.html and ** http://www.gnu.org/copyleft/gpl.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt GPL Exception ** version 1.2, included in the file GPL_EXCEPTION.txt in this package. ** ***************************************************************************/ ***************************************************************************/ #include "qtversionmanager.h" #include "qt4projectmanagerconstants.h" #include "msvcenvironment.h" #include "cesdkhandler.h" #include #include #include #include #include #include #include #include #include #include using namespace Qt4ProjectManager::Internal; using ProjectExplorer::Environment; static const char *QtVersionsSectionName = "QtVersions"; static const char *defaultQtVersionKey = "DefaultQtVersion"; static const char *newQtVersionsKey = "NewQtVersions"; QtVersionManager::QtVersionManager() : m_emptyVersion(new QtVersion) { m_core = ExtensionSystem::PluginManager::instance()->getObject(); QSettings *s = m_core->settings(); m_defaultVersion = s->value(defaultQtVersionKey, 0).toInt(); 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(); else if (id > m_idcount) m_idcount = id; QtVersion *version = new QtVersion(s->value("Name").toString(), s->value("Path").toString(), id, s->value("IsSystemVersion", false).toBool()); version->setMingwDirectory(s->value("MingwDirectory").toString()); version->setPrependPath(s->value("PrependPath").toString()); version->setMsvcVersion(s->value("msvcVersion").toString()); m_versions.append(version); } s->endArray(); updateUniqueIdToIndexMap(); ++m_idcount; addNewVersionsFromInstaller(); updateSystemVersion(); writeVersionsIntoSettings(); updateDocumentation(); } QtVersionManager::~QtVersionManager() { qDeleteAll(m_versions); m_versions.clear(); delete m_emptyVersion; m_emptyVersion = 0; } void QtVersionManager::addVersion(QtVersion *version) { m_versions.append(version); emit qtVersionsChanged(); } void QtVersionManager::updateDocumentation() { Help::HelpManager *helpManager = m_core->pluginManager()->getObject(); Q_ASSERT(helpManager); if (!helpManager) return; QStringList fileEndings = QStringList() << "/qch/qt.qch" << "/qch/qmake.qch" << "/qch/designer.qch"; QStringList files; foreach (QtVersion *version, m_versions) { QString docPath = version->versionInfo().value("QT_INSTALL_DOCS"); foreach (const QString &fileEnding, fileEndings) files << docPath+fileEnding; } helpManager->registerDocumentation(files); } int QtVersionManager::getUniqueId() { return m_idcount++; } QString QtVersionManager::name() const { return tr(Constants::QTVERSION_PAGE); } QString QtVersionManager::category() const { return Constants::QT_CATEGORY; } QString QtVersionManager::trCategory() const { return tr(Constants::QT_CATEGORY); } QWidget *QtVersionManager::createPage(QWidget *parent) { if (m_widget) delete m_widget; m_widget = new QtDirWidget(parent, m_versions, m_defaultVersion); return m_widget; } void QtVersionManager::updateUniqueIdToIndexMap() { m_uniqueIdToIndex.clear(); for(int i=0; iuniqueId(), i); } void QtVersionManager::finished(bool accepted) { if (!accepted) return; m_widget->finish(); QList newVersions = m_widget->versions(); bool versionPathsChanged = m_versions.size() != newVersions.size(); if (!versionPathsChanged) { for (int i = 0; i < m_versions.size(); ++i) { if (m_versions.at(i)->path() != newVersions.at(i)->path()) { versionPathsChanged = true; break; } } } m_versions = m_widget->versions(); if (versionPathsChanged) updateDocumentation(); updateUniqueIdToIndexMap(); bool emitDefaultChanged = false; if (m_defaultVersion != m_widget->defaultVersion()) { m_defaultVersion = m_widget->defaultVersion(); emitDefaultChanged = true; } emit qtVersionsChanged(); if (emitDefaultChanged) emit defaultQtVersionChanged(); writeVersionsIntoSettings(); } void QtVersionManager::writeVersionsIntoSettings() { QSettings *s = m_core->settings(); s->setValue(defaultQtVersionKey, m_defaultVersion); s->beginWriteArray("QtVersions"); for (int i = 0; i < m_versions.size(); ++i) { s->setArrayIndex(i); s->setValue("Name", m_versions.at(i)->name()); s->setValue("Path", m_versions.at(i)->path()); s->setValue("Id", m_versions.at(i)->uniqueId()); s->setValue("MingwDirectory", m_versions.at(i)->mingwDirectory()); s->setValue("PrependPath", m_versions.at(i)->prependPath()); s->setValue("msvcVersion", m_versions.at(i)->msvcVersion()); s->setValue("IsSystemVersion", m_versions.at(i)->isSystemVersion()); } s->endArray(); } QList QtVersionManager::versions() const { return m_versions; } QtVersion *QtVersionManager::version(int id) const { int pos = m_uniqueIdToIndex.value(id, -1); if (pos != -1) return m_versions.at(pos); if(m_defaultVersion < m_versions.count()) return m_versions.at(m_defaultVersion); else return m_emptyVersion; } 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;qt embedded=c:\\qtembedded;" // or NewQtVersions="qt 4.3.2=c:\\qt\\qt432=c:\\qtcreator\\mingw\\=prependToPath; // Duplicate entries are not added, the first new version is set as default. QSettings *settings = m_core->settings(); if (!settings->contains(newQtVersionsKey)) return; // qDebug()<<"QtVersionManager::addNewVersionsFromInstaller()"; QString newVersionsValue = settings->value(newQtVersionsKey).toString(); QStringList newVersionsList = newVersionsValue.split(';', QString::SkipEmptyParts); bool defaultVersionWasReset = false; foreach (QString newVersion, newVersionsList) { QStringList newVersionData = newVersion.split('='); if(newVersionData.count()>=2) { if (QDir(newVersionData[1]).exists()) { QtVersion *version = new QtVersion(newVersionData[0], newVersionData[1], m_idcount++ ); if(newVersionData.count() >= 3) version->setMingwDirectory(newVersionData[2]); if(newVersionData.count() >= 4) version->setPrependPath(newVersionData[3]); bool versionWasAlreadyInList = false; foreach(const QtVersion * const it, m_versions) { if(QDir(version->path()).canonicalPath() == QDir(it->path()).canonicalPath()) { versionWasAlreadyInList = true; break; } } if (!versionWasAlreadyInList) { m_versions.append(version); } else { // clean up delete version; } if (!defaultVersionWasReset) { m_defaultVersion = versionWasAlreadyInList? m_defaultVersion : m_versions.count() - 1; defaultVersionWasReset = true; } } } } settings->remove(newQtVersionsKey); updateUniqueIdToIndexMap(); } void QtVersionManager::updateSystemVersion() { bool haveSystemVersion = false; foreach (QtVersion *version, m_versions) { if (version->isSystemVersion()) { version->setPath(findSystemQt()); haveSystemVersion = true; } } if (haveSystemVersion) return; QtVersion *version = new QtVersion(tr("System Qt"), findSystemQt(), getUniqueId(), true); m_versions.prepend(version); updateUniqueIdToIndexMap(); if (m_versions.size() > 1) // we had other versions before adding system version ++m_defaultVersion; } QStringList QtVersionManager::possibleQMakeCommands() { // On windows noone has renamed qmake, right? #ifdef Q_OS_WIN return QStringList() << "qmake.exe"; #endif // On unix some distributions renamed qmake to avoid clashes QStringList result; result << "qmake-qt4" << "qmake4" << "qmake"; return result; } bool QtVersionManager::checkQMakeVersion(const QString &qmakePath) { QProcess qmake; qmake.start(qmakePath, QStringList()<<"--version"); if (!qmake.waitForFinished()) return false; QString output = qmake.readAllStandardOutput(); QRegExp regexp("(QMake version|Qmake version:)[\\s]*([\\d.]*)"); regexp.indexIn(output); if (regexp.cap(2).startsWith("2.")) return true; return false; } QString QtVersionManager::findSystemQt() const { Environment env = Environment::systemEnvironment(); QStringList paths = env.path(); foreach (const QString &path, paths) { foreach (const QString &possibleCommand, possibleQMakeCommands()) { QFileInfo qmake(path + "/" + possibleCommand); if (qmake.exists()) { if (checkQMakeVersion(qmake.absoluteFilePath())) { QDir dir(qmake.absoluteDir()); dir.cdUp(); return dir.absolutePath(); } } } } return tr(""); } QtVersion *QtVersionManager::currentQtVersion() const { if(m_defaultVersion < m_versions.count()) return m_versions.at(m_defaultVersion); else return m_emptyVersion; } //----------------------------------------------------- QtDirWidget::QtDirWidget(QWidget *parent, QList versions, int defaultVersion) : QWidget(parent) , m_versions(versions) , m_defaultVersion(defaultVersion) , m_specifyNameString(tr("")) , m_specifyPathString(tr("")) { m_ui.setupUi(this); m_ui.addButton->setIcon(QIcon(Core::Constants::ICON_PLUS)); m_ui.delButton->setIcon(QIcon(Core::Constants::ICON_MINUS)); for (int i = 0; i < m_versions.count(); ++i) { const QtVersion * const version = m_versions.at(i); QTreeWidgetItem *item = new QTreeWidgetItem(m_ui.qtdirList); item->setText(0, version->name()); item->setText(1, version->path()); item->setData(0, Qt::UserRole, version->uniqueId()); m_ui.defaultCombo->addItem(version->name()); if (i == m_defaultVersion) m_ui.defaultCombo->setCurrentIndex(i); } connect(m_ui.nameEdit, SIGNAL(textEdited(const QString &)), this, SLOT(updateCurrentQtName())); connect(m_ui.pathEdit, SIGNAL(textEdited(const QString &)), this, SLOT(updateCurrentQtPath())); connect(m_ui.mingwLineEdit, SIGNAL(textEdited(const QString &)), this, SLOT(updateCurrentMingwDirectory())); connect(m_ui.addButton, SIGNAL(clicked()), this, SLOT(addQtDir())); connect(m_ui.delButton, SIGNAL(clicked()), this, SLOT(removeQtDir())); connect(m_ui.browseButton, SIGNAL(clicked()), this, SLOT(browse())); connect(m_ui.mingwBrowseButton, SIGNAL(clicked()), this, SLOT(mingwBrowse())); connect(m_ui.qtdirList, SIGNAL(currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)), this, SLOT(versionChanged(QTreeWidgetItem *, QTreeWidgetItem *))); connect(m_ui.defaultCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(defaultChanged(int))); connect(m_ui.msvcComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(msvcVersionChanged())); showEnvironmentPage(0); updateState(); } void QtDirWidget::addQtDir() { QtVersion *newVersion = new QtVersion(m_specifyNameString, m_specifyPathString); m_versions.append(newVersion); QTreeWidgetItem *item = new QTreeWidgetItem(m_ui.qtdirList); item->setText(0, newVersion->name()); item->setText(1, newVersion->path()); item->setData(0, Qt::UserRole, newVersion->uniqueId()); m_ui.nameEdit->setText(newVersion->name()); m_ui.pathEdit->setText(newVersion->path()); m_ui.defaultCombo->addItem(newVersion->name()); m_ui.qtdirList->setCurrentItem(item); m_ui.nameEdit->setFocus(); m_ui.nameEdit->selectAll(); } void QtDirWidget::removeQtDir() { QTreeWidgetItem *item = m_ui.qtdirList->currentItem(); int index = m_ui.qtdirList->indexOfTopLevelItem(item); if (index < 0) return; for (int i = 0; i < m_ui.defaultCombo->count(); ++i) { if (m_ui.defaultCombo->itemText(i) == item->text(0)) { m_ui.defaultCombo->removeItem(i); break; } } delete item; delete m_versions.takeAt(index); updateState(); } void QtDirWidget::updateState() { bool enabled = (m_ui.qtdirList->currentItem() != 0); bool isSystemVersion = (enabled && m_versions.at(m_ui.qtdirList->indexOfTopLevelItem(m_ui.qtdirList->currentItem()))->isSystemVersion()); m_ui.delButton->setEnabled(enabled && !isSystemVersion); m_ui.nameEdit->setEnabled(enabled && !isSystemVersion); m_ui.pathEdit->setEnabled(enabled && !isSystemVersion); m_ui.browseButton->setEnabled(enabled && !isSystemVersion); m_ui.mingwBrowseButton->setEnabled(enabled); m_ui.mingwLineEdit->setEnabled(enabled); } void QtDirWidget::showEnvironmentPage(QTreeWidgetItem *item) { m_ui.msvcComboBox->setVisible(false); if(item) { int index = m_ui.qtdirList->indexOfTopLevelItem(item); m_ui.errorLabel->setText(""); QtVersion::ToolchainType t = m_versions.at(index)->toolchainType(); if(t == QtVersion::MinGW) { m_ui.msvcComboBox->setVisible(false); m_ui.msvcLabel->setVisible(false); m_ui.mingwLineEdit->setVisible(true); m_ui.mingwLabel->setVisible(true); m_ui.mingwBrowseButton->setVisible(true); m_ui.mingwLineEdit->setText(m_versions.at(index)->mingwDirectory()); } else if(t == QtVersion::MSVC || t == QtVersion::WINCE){ m_ui.msvcComboBox->setVisible(false); m_ui.msvcLabel->setVisible(true); m_ui.mingwLineEdit->setVisible(false); m_ui.mingwLabel->setVisible(false); m_ui.mingwBrowseButton->setVisible(false); QList msvcenvironments = MSVCEnvironment::availableVersions(); if(msvcenvironments.count() == 0) { m_ui.msvcLabel->setText(tr("No Visual Studio Installation found")); } else if(msvcenvironments.count() == 1) { m_ui.msvcLabel->setText( msvcenvironments.at(0).description()); } else { m_ui.msvcComboBox->setVisible(true); m_ui.msvcComboBox->clear(); bool block = m_ui.msvcComboBox->blockSignals(true); foreach(const MSVCEnvironment msvcenv, msvcenvironments) { m_ui.msvcComboBox->addItem(msvcenv.name()); if (msvcenv.name() == m_versions.at(index)->msvcVersion()) { m_ui.msvcComboBox->setCurrentIndex(m_ui.msvcComboBox->count() - 1); m_ui.msvcLabel->setText(msvcenv.description()); } } m_ui.msvcComboBox->blockSignals(block); } } else if(t == QtVersion::INVALID) { m_ui.msvcComboBox->setVisible(false); m_ui.msvcLabel->setVisible(false); m_ui.mingwLineEdit->setVisible(false); m_ui.mingwLabel->setVisible(false); m_ui.mingwBrowseButton->setVisible(false); if (!m_versions.at(index)->isInstalled()) m_ui.errorLabel->setText(tr("The Qt Version is not installed. Run make install") .arg(m_versions.at(index)->path())); else m_ui.errorLabel->setText(tr("%1 is not a valid qt directory").arg(m_versions.at(index)->path())); } else { //QtVersion::Other m_ui.msvcComboBox->setVisible(false); m_ui.msvcLabel->setVisible(false); m_ui.mingwLineEdit->setVisible(false); m_ui.mingwLabel->setVisible(false); m_ui.mingwBrowseButton->setVisible(false); m_ui.errorLabel->setText("Found qt version: " + m_versions.at(index)->mkspec()); } } else { m_ui.msvcComboBox->setVisible(false); m_ui.msvcLabel->setVisible(false); m_ui.mingwLineEdit->setVisible(false); m_ui.mingwLabel->setVisible(false); m_ui.mingwBrowseButton->setVisible(false); } } void QtDirWidget::versionChanged(QTreeWidgetItem *item, QTreeWidgetItem *old) { if(old) { fixQtVersionName(m_ui.qtdirList->indexOfTopLevelItem(old)); } if (item) { m_ui.nameEdit->setText(item->text(0)); m_ui.pathEdit->setText(item->text(1)); } else { m_ui.nameEdit->clear(); m_ui.pathEdit->clear(); } showEnvironmentPage(item); updateState(); } void QtDirWidget::browse() { QString dir = QFileDialog::getExistingDirectory(this, tr("Select QTDIR")); if (dir.isEmpty()) return; dir = QDir::toNativeSeparators(dir); m_ui.pathEdit->setText(dir); updateCurrentQtPath(); if (m_ui.nameEdit->text().isEmpty() || m_ui.nameEdit->text() == m_specifyNameString) { QStringList dirSegments = dir.split(QDir::separator(), QString::SkipEmptyParts); if (!dirSegments.isEmpty()) m_ui.nameEdit->setText(dirSegments.last()); updateCurrentQtName(); } updateState(); } void QtDirWidget::mingwBrowse() { QString dir = QFileDialog::getExistingDirectory(this, tr("Select MinGW Directory")); if (dir.isEmpty()) return; dir = QDir::toNativeSeparators(dir); m_ui.mingwLineEdit->setText(dir); updateCurrentMingwDirectory(); updateState(); } void QtDirWidget::defaultChanged(int) { for (int i=0; icount(); ++i) { if (m_versions.at(i)->name() == m_ui.defaultCombo->currentText()) { m_defaultVersion = i; return; } } m_defaultVersion = 0; } void QtDirWidget::updateCurrentQtName() { QTreeWidgetItem *currentItem = m_ui.qtdirList->currentItem(); Q_ASSERT(currentItem); int currentItemIndex = m_ui.qtdirList->indexOfTopLevelItem(currentItem); m_versions[currentItemIndex]->setName(m_ui.nameEdit->text()); currentItem->setText(0, m_versions[currentItemIndex]->name()); m_ui.defaultCombo->setItemText(currentItemIndex, m_versions[currentItemIndex]->name()); } void QtDirWidget::finish() { if(QTreeWidgetItem *item = m_ui.qtdirList->currentItem()) fixQtVersionName(m_ui.qtdirList->indexOfTopLevelItem(item)); } /* Checks that the qt version name is unique * and otherwise changes the name * */ void QtDirWidget::fixQtVersionName(int index) { int count = m_versions.count(); for(int i=0; iname() == m_versions.at(index)->name()) { // Same name, find new name QString name = m_versions.at(index)->name(); QRegExp regexp("^(.*)\\((\\d)\\)$"); if (regexp.exactMatch(name)) { // Alreay in Name (#) format name = regexp.cap(1) + "(" + QString().setNum(regexp.cap(2).toInt() + 1) + ")"; } else { name = name + " (2)"; } // set new name m_versions[index]->setName(name); m_ui.qtdirList->topLevelItem(index)->setText(0, name); m_ui.defaultCombo->setItemText(index, name); // Now check again... fixQtVersionName(index); } } } } void QtDirWidget::updateCurrentQtPath() { QTreeWidgetItem *currentItem = m_ui.qtdirList->currentItem(); Q_ASSERT(currentItem); int currentItemIndex = m_ui.qtdirList->indexOfTopLevelItem(currentItem); m_versions[currentItemIndex]->setPath(m_ui.pathEdit->text()); currentItem->setText(1, m_versions[currentItemIndex]->path()); showEnvironmentPage(currentItem); } void QtDirWidget::updateCurrentMingwDirectory() { QTreeWidgetItem *currentItem = m_ui.qtdirList->currentItem(); Q_ASSERT(currentItem); int currentItemIndex = m_ui.qtdirList->indexOfTopLevelItem(currentItem); m_versions[currentItemIndex]->setMingwDirectory(m_ui.mingwLineEdit->text()); } void QtDirWidget::msvcVersionChanged() { const QString &msvcVersion = m_ui.msvcComboBox->currentText(); QTreeWidgetItem *currentItem = m_ui.qtdirList->currentItem(); Q_ASSERT(currentItem); int currentItemIndex = m_ui.qtdirList->indexOfTopLevelItem(currentItem); m_versions[currentItemIndex]->setMsvcVersion(msvcVersion); //get descriptionx QList msvcEnvironments = MSVCEnvironment::availableVersions(); foreach(const MSVCEnvironment &msvcEnv, msvcEnvironments) { if(msvcEnv.name() == msvcVersion) { m_ui.msvcLabel->setText(msvcEnv.description()); break; } } } QList QtDirWidget::versions() const { return m_versions; } int QtDirWidget::defaultVersion() const { return m_defaultVersion; } /// /// QtVersion /// QtVersion::QtVersion(const QString &name, const QString &path, int id, bool isSystemVersion) : m_name(name), m_isSystemVersion(isSystemVersion), m_notInstalled(false), m_defaultConfigIsDebug(true), m_defaultConfigIsDebugAndRelease(true) { setPath(path); if(id == -1) m_id = getUniqueId(); else m_id = id; } QtVersion::QtVersion(const QString &name, const QString &path) : m_name(name), m_versionInfoUpToDate(false), m_mkspecUpToDate(false), m_isSystemVersion(false) { setPath(path); m_id = getUniqueId(); } QString QtVersion::name() const { return m_name; } QString QtVersion::path() const { return m_path; } QString QtVersion::sourcePath() const { return m_sourcePath; } QString QtVersion::mkspec() const { updateMkSpec(); return m_mkspec; } QHash QtVersion::versionInfo() const { updateVersionInfo(); return m_versionInfo; } void QtVersion::setName(const QString &name) { m_name = name; } void QtVersion::setPath(const QString &path) { m_path = QDir::cleanPath(path); updateSourcePath(); m_versionInfoUpToDate = false; m_mkspecUpToDate = false; m_qmakeCommand = QString::null; } void QtVersion::updateSourcePath() { m_sourcePath = m_path; QFile qmakeCache(m_path + 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; } } } } // Returns the version that was used to build the project in that directory // That is returns the directory // To find out wheter we already have a qtversion for that directory call // QtVersion *QtVersionManager::qtVersionForDirectory(const QString directory); QString QtVersionManager::findQtVersionFromMakefile(const QString &directory) { QString result = QString::null; bool debugAdding = false; QFile makefile(directory + "/Makefile" ); if (makefile.exists() && makefile.open(QFile::ReadOnly)) { QTextStream ts(&makefile); while (!ts.atEnd()) { QString line = ts.readLine(); QRegExp r1("QMAKE\\s*=(.*)"); if (r1.exactMatch(line)) { if (debugAdding) qDebug()<<"#~~ QMAKE is:"<path() == directory) { return v; break; } } return 0; } QtVersion::QmakeBuildConfig QtVersionManager::scanMakefileForQmakeConfig(const QString &directory, QtVersion::QmakeBuildConfig defaultBuildConfig) { bool debugScan = false; QtVersion::QmakeBuildConfig result = QtVersion::NoBuild; QFile makefile(directory + "/Makefile" ); if (makefile.exists() && makefile.open(QFile::ReadOnly)) { QTextStream ts(&makefile); while (!ts.atEnd()) { QString line = ts.readLine(); if (line.startsWith("# Command:")) { // if nothing is specified result = defaultBuildConfig; // Actually parsing that line is not trivial in the general case // There might things like this // # Command: /home/dteske/git/bqt-45/bin/qmake -unix CONFIG+=debug\ release CONFIG\ +=\ debug_and_release\ debug -o Makefile test.pro // which sets debug_and_release and debug // or something like this: //[...] CONFIG+=debug\ release CONFIG\ +=\ debug_and_release\ debug CONFIG\ -=\ debug_and_release CONFIG\ -=\ debug -o Makefile test.pro // which sets -build_all and release // To parse that, we search for the first CONFIG, then look for " " which is not after a "\" or the end // And then look at each config individually // we then remove all "\ " with just " " // += sets adding flags // -= sets removing flags // and then split the string after the = // and go over each item separetly // debug sets/removes the flag DebugBuild // release removes/sets the flag DebugBuild // debug_and_release sets/removes the flag BuildAll int pos = line.indexOf("CONFIG"); if (pos != -1) { // Chopped of anything that is not interesting line = line.mid(pos); line = line.trimmed(); if (debugScan) qDebug()<<"chopping line :"<= 17 && QStringRef(&part, i, 17) == "debug_and_release") { if (setFlags) result = QtVersion::QmakeBuildConfig(result | QtVersion::BuildAll); else result = QtVersion::QmakeBuildConfig(result & ~QtVersion::BuildAll); if (debugScan) qDebug()<<"found debug_and_release new value"<=7 && QStringRef(&part, i, 7) == "release") { if (setFlags) result = QtVersion::QmakeBuildConfig(result & ~QtVersion::DebugBuild); else result = QtVersion::QmakeBuildConfig(result | QtVersion::DebugBuild); if (debugScan) qDebug()<<"found release new value"<= 5 && QStringRef(&part, i, 5) == "debug") { if (setFlags) result = QtVersion::QmakeBuildConfig(result | QtVersion::DebugBuild); else result = QtVersion::QmakeBuildConfig(result & ~QtVersion::DebugBuild); if (debugScan) qDebug()<<"found debug new value"< &temp = line.split('='); if(temp.size() == 2) { mkspec = temp.at(1).trimmed(); if (mkspec.startsWith("$$QT_BUILD_TREE/mkspecs/")) mkspec = mkspec.mid(QString("$$QT_BUILD_TREE/mkspecs/").length()); else if (mkspec.startsWith("$$QT_BUILD_TREE\\mkspecs\\")) mkspec = mkspec.mid(QString("$$QT_BUILD_TREE\\mkspecs\\").length()); } break; } } f.close(); } else { // no .qmake.cache so look at the default mkspec QString mkspecPath = versionInfo().value("QMAKE_MKSPECS"); if (mkspecPath.isEmpty()) mkspecPath = path() + "/mkspecs/default"; else mkspecPath = mkspecPath + "/default"; // qDebug() << "default mkspec is located at" << mkspecPath; #ifdef Q_OS_WIN QFile f2(mkspecPath + "/qmake.conf"); if (f2.exists() && f2.open(QIODevice::ReadOnly)) { while(!f2.atEnd()) { QByteArray line = f2.readLine(); if(line.startsWith("QMAKESPEC_ORIGINAL")) { const QList &temp = line.split('='); if (temp.size() == 2) { mkspec = temp.at(1); } break; } } f2.close(); } #elif defined(Q_OS_MAC) QFile f2(mkspecPath + "/qmake.conf"); if (f2.exists() && f2.open(QIODevice::ReadOnly)) { while(!f2.atEnd()) { QByteArray line = f2.readLine(); if(line.startsWith("MAKEFILE_GENERATOR")) { const QList &temp = line.split('='); if (temp.size() == 2) { const QByteArray &value = temp.at(1); if (value.contains("XCODE")) { // we don't want to generate xcode projects... // qDebug() << "default mkspec is xcode, falling back to g++"; mkspec = "macx-g++"; } else { //resolve mkspec link QFileInfo f3(mkspecPath); if (f3.isSymLink()) { mkspec = f3.symLinkTarget(); } } } break; } } f2.close(); } #else QFileInfo f2(mkspecPath); if (f2.isSymLink()) { mkspec = f2.symLinkTarget(); } #endif } int index =mkspec.lastIndexOf('/'); if(index == -1) index = mkspec.lastIndexOf('\\'); if (index >= 0 && QDir(mkspec.left(index)).canonicalPath() == QDir(m_path + "/mkspecs/").canonicalPath()) mkspec = mkspec.mid(index+1).trimmed(); m_mkspec = mkspec; m_mkspecUpToDate = true; // qDebug()<<"mkspec for "< list = MSVCEnvironment::availableVersions(); if(list.count() == 1) { e = list.at(0).addToEnvironment(e); } else { foreach(const MSVCEnvironment &m, list) { if(m.name() == m_msvcVersion) { e = m.addToEnvironment(e); break; } } } } else if(t == QtVersion::WINCE) { QString msvcPath; // Find MSVC path QList list = MSVCEnvironment::availableVersions(); if(list.count() == 1) { msvcPath = list.at(0).path(); e = list.at(0).addToEnvironment(e); } else { foreach(const MSVCEnvironment &m, list) { if(m.name() == m_msvcVersion) { e = m.addToEnvironment(e); msvcPath = m.path(); break; } } } msvcPath += "/"; // qDebug()<<"MSVC path"<getObject(); return vm->getUniqueId(); } bool QtVersion::isValid() const { return (!(m_id == -1 || m_path == QString::null || m_name == QString::null || mkspec() == QString::null) && !m_notInstalled); } QtVersion::QmakeBuildConfig QtVersion::defaultBuildConfig() const { updateVersionInfo(); QtVersion::QmakeBuildConfig result = QtVersion::QmakeBuildConfig(0); if (m_defaultConfigIsDebugAndRelease) result = QtVersion::BuildAll; if (m_defaultConfigIsDebug) result = QtVersion::QmakeBuildConfig(result | QtVersion::DebugBuild); return result; }