summaryrefslogtreecommitdiff
path: root/src/plugins/qt4projectmanager/qmakeprojectimporter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/qt4projectmanager/qmakeprojectimporter.cpp')
-rw-r--r--src/plugins/qt4projectmanager/qmakeprojectimporter.cpp254
1 files changed, 254 insertions, 0 deletions
diff --git a/src/plugins/qt4projectmanager/qmakeprojectimporter.cpp b/src/plugins/qt4projectmanager/qmakeprojectimporter.cpp
new file mode 100644
index 0000000000..953e2daed0
--- /dev/null
+++ b/src/plugins/qt4projectmanager/qmakeprojectimporter.cpp
@@ -0,0 +1,254 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "qmakeprojectimporter.h"
+
+#include "qmakebuildinfo.h"
+#include "qmakekitinformation.h"
+#include "qt4buildconfiguration.h"
+#include "qt4project.h"
+
+#include <coreplugin/icore.h>
+#include <coreplugin/idocument.h>
+#include <projectexplorer/kitmanager.h>
+#include <projectexplorer/target.h>
+#include <qtsupport/qtkitinformation.h>
+#include <qtsupport/qtsupportconstants.h>
+#include <qtsupport/qtversionfactory.h>
+#include <qtsupport/qtversionmanager.h>
+#include <utils/qtcprocess.h>
+
+#include <QDir>
+#include <QFileInfo>
+#include <QStringList>
+
+#include <QMessageBox>
+
+static const Core::Id QT_IS_TEMPORARY("Qmake.TempQt");
+
+namespace Qt4ProjectManager {
+namespace Internal {
+
+QmakeProjectImporter::QmakeProjectImporter(const QString &path) :
+ ProjectExplorer::ProjectImporter(path)
+{ }
+
+QList<ProjectExplorer::BuildInfo *> QmakeProjectImporter::import(const Utils::FileName &importPath,
+ bool silent)
+{
+ QList<ProjectExplorer::BuildInfo *> result;
+ QFileInfo fi = importPath.toFileInfo();
+ if (!fi.exists() && !fi.isDir())
+ return result;
+
+ QStringList makefiles = QDir(importPath.toString()).entryList(QStringList(QLatin1String("Makefile*")));
+
+ QtSupport::BaseQtVersion *version = 0;
+ bool temporaryVersion = false;
+
+ foreach (const QString &file, makefiles) {
+ // find interesting makefiles
+ QString makefile = importPath.toString() + QLatin1Char('/') + file;
+ Utils::FileName qmakeBinary = QtSupport::QtVersionManager::findQMakeBinaryFromMakefile(makefile);
+ QFileInfo qmakeFi = qmakeBinary.toFileInfo();
+ Utils::FileName canonicalQmakeBinary = Utils::FileName::fromString(qmakeFi.canonicalFilePath());
+ if (canonicalQmakeBinary.isEmpty())
+ continue;
+ if (QtSupport::QtVersionManager::makefileIsFor(makefile, projectFilePath()) != QtSupport::QtVersionManager::SameProject)
+ continue;
+
+ // Find version:
+ foreach (QtSupport::BaseQtVersion *v, QtSupport::QtVersionManager::versions()) {
+ QFileInfo vfi = v->qmakeCommand().toFileInfo();
+ Utils::FileName current = Utils::FileName::fromString(vfi.canonicalFilePath());
+ if (current == canonicalQmakeBinary) {
+ version = v;
+ break;
+ }
+ }
+
+ // Create a new version if not found:
+ if (!version) {
+ // Do not use the canonical path here...
+ version = QtSupport::QtVersionFactory::createQtVersionFromQMakePath(qmakeBinary);
+ if (!version)
+ continue;
+
+ setIsUpdating(true);
+ QtSupport::QtVersionManager::addVersion(version);
+ setIsUpdating(false);
+ temporaryVersion = true;
+ }
+
+ // find qmake arguments and mkspec
+ QPair<QtSupport::BaseQtVersion::QmakeBuildConfigs, QString> makefileBuildConfig =
+ QtSupport::QtVersionManager::scanMakeFile(makefile, version->defaultBuildConfig());
+
+ QString additionalArguments = makefileBuildConfig.second;
+ Utils::FileName parsedSpec =
+ Qt4BuildConfiguration::extractSpecFromArguments(&additionalArguments, importPath.toString(), version);
+ Utils::FileName versionSpec = version->mkspec();
+ if (parsedSpec.isEmpty() || parsedSpec == Utils::FileName::fromString(QLatin1String("default")))
+ parsedSpec = versionSpec;
+
+ QString specArgument;
+ // Compare mkspecs and add to additional arguments
+ if (parsedSpec != versionSpec)
+ specArgument = QLatin1String("-spec ") + Utils::QtcProcess::quoteArg(parsedSpec.toUserOutput());
+ Utils::QtcProcess::addArgs(&specArgument, additionalArguments);
+
+ // Find kits (can be more than one, e.g. (Linux-)Desktop and embedded linux):
+ QList<ProjectExplorer::Kit *> kitList;
+ foreach (ProjectExplorer::Kit *k, ProjectExplorer::KitManager::kits()) {
+ QtSupport::BaseQtVersion *kitVersion = QtSupport::QtKitInformation::qtVersion(k);
+ Utils::FileName kitSpec = QmakeKitInformation::mkspec(k);
+ ProjectExplorer::ToolChain *tc = ProjectExplorer::ToolChainKitInformation::toolChain(k);
+ if (kitSpec.isEmpty() && kitVersion)
+ kitSpec = kitVersion->mkspecFor(tc);
+
+ if (kitVersion == version
+ && kitSpec == parsedSpec)
+ kitList.append(k);
+ }
+ if (kitList.isEmpty())
+ kitList.append(createTemporaryKit(version, temporaryVersion, parsedSpec));
+
+ foreach (ProjectExplorer::Kit *k, kitList) {
+ addProject(k);
+
+ Qt4BuildConfigurationFactory *factory
+ = qobject_cast<Qt4BuildConfigurationFactory *>(
+ ProjectExplorer::IBuildConfigurationFactory::find(k, projectFilePath()));
+
+ if (!factory)
+ continue;
+
+ // create info:
+ QmakeBuildInfo *info = new QmakeBuildInfo(factory);
+ if (makefileBuildConfig.first | QtSupport::BaseQtVersion::DebugBuild) {
+ info->type = ProjectExplorer::BuildConfiguration::Debug;
+ info->displayName = QCoreApplication::translate("Qt4ProjectManager::Internal::QmakeProjectImporter", "Debug");
+ } else {
+ info->type = ProjectExplorer::BuildConfiguration::Release;
+ info->displayName = QCoreApplication::translate("Qt4ProjectManager::Internal::QmakeProjectImporter", "Release");
+ }
+ info->kitId = k->id();
+ info->buildDirectory = Utils::FileName::fromString(fi.absoluteFilePath());
+ info->additionalArguments = additionalArguments;
+ info->makefile = makefile;
+
+ result << info;
+ }
+ }
+
+ if (result.isEmpty() && !silent)
+ QMessageBox::critical(Core::ICore::mainWindow(),
+ QCoreApplication::translate("Qt4ProjectManager::Internal::QmakeProjectImporter", "No Build Found"),
+ QCoreApplication::translate("Qt4ProjectManager::Internal::QmakeProjectImporter", "No build found in %1 matching project %2.")
+ .arg(importPath.toUserOutput()).arg(projectFilePath()));
+
+ return result;
+}
+
+QStringList QmakeProjectImporter::importCandidates(const Utils::FileName &projectPath)
+{
+ QStringList candidates;
+
+ QFileInfo pfi = projectPath.toFileInfo();
+ const QString prefix = pfi.baseName();
+ candidates << pfi.absolutePath();
+
+ QList<ProjectExplorer::Kit *> kitList = ProjectExplorer::KitManager::kits();
+ foreach (ProjectExplorer::Kit *k, kitList) {
+ QFileInfo fi(Qt4Project::shadowBuildDirectory(projectPath.toString(), k, QString()));
+ const QString baseDir = fi.absolutePath();
+
+ foreach (const QString &dir, QDir(baseDir).entryList()) {
+ const QString path = baseDir + QLatin1Char('/') + dir;
+ if (dir.startsWith(prefix) && !candidates.contains(path))
+ candidates << path;
+ }
+ }
+ return candidates;
+}
+
+ProjectExplorer::Target *QmakeProjectImporter::preferredTarget(const QList<ProjectExplorer::Target *> &possibleTargets)
+{
+ // Select active target
+ // a) The default target
+ // b) Simulator target
+ // c) Desktop target
+ // d) the first target
+ ProjectExplorer::Target *activeTarget = possibleTargets.isEmpty() ? 0 : possibleTargets.at(0);
+ int activeTargetPriority = 0;
+ foreach (ProjectExplorer::Target *t, possibleTargets) {
+ QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(t->kit());
+ if (t->kit() == ProjectExplorer::KitManager::defaultKit()) {
+ activeTarget = t;
+ activeTargetPriority = 3;
+ } else if (activeTargetPriority < 2 && version && version->type() == QLatin1String(QtSupport::Constants::SIMULATORQT)) {
+ activeTarget = t;
+ activeTargetPriority = 2;
+ } else if (activeTargetPriority < 1 && version && version->type() == QLatin1String(QtSupport::Constants::DESKTOPQT)) {
+ activeTarget = t;
+ activeTargetPriority = 1;
+ }
+ }
+ return activeTarget;
+}
+
+void QmakeProjectImporter::cleanupKit(ProjectExplorer::Kit *k)
+{
+ QtSupport::BaseQtVersion *version = QtSupport::QtVersionManager::version(k->value(QT_IS_TEMPORARY, -1).toInt());
+ if (version)
+ QtSupport::QtVersionManager::removeVersion(version);
+}
+
+ProjectExplorer::Kit *QmakeProjectImporter::createTemporaryKit(QtSupport::BaseQtVersion *version,
+ bool temporaryVersion,
+ const Utils::FileName &parsedSpec)
+{
+ ProjectExplorer::Kit *k = new ProjectExplorer::Kit;
+ QtSupport::QtKitInformation::setQtVersion(k, version);
+ ProjectExplorer::ToolChainKitInformation::setToolChain(k, version->preferredToolChain(parsedSpec));
+ QmakeKitInformation::setMkspec(k, parsedSpec);
+
+ markTemporary(k);
+ if (temporaryVersion)
+ k->setValue(QT_IS_TEMPORARY, version->uniqueId());
+
+ k->setDisplayName(version->displayName());
+ setIsUpdating(true);
+ ProjectExplorer::KitManager::registerKit(k);
+ setIsUpdating(false);
+ return k;
+}
+
+} // namespace Internal
+} // namespace Qt4ProjectManager