Commit 6cc7d1ff authored by Christian Kandeler's avatar Christian Kandeler
Browse files

Provide build system independent deployment data.



Attach an object containing deployment information
to the target. The respective build system plugins are
responsible for setting up this information. The
Qt4ProjectManager already does that; others should
follow (which is expected to result in gradual
refinements of the design).
The immediate motivation here is to free the
RemoteLinux plugin from the requirement that
qmake must be used for building the projects,
which makes it much less generic than it could
and should be.

Change-Id: I9943787f4e352d014e721082016542b10c8cce90
Reviewed-by: default avatarDaniel Teske <daniel.teske@nokia.com>
parent c3fad8ab
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: http://www.qt-project.org/
**
**
** 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.
**
** 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.
**
**
**************************************************************************/
#ifndef BUILDTARGETINFO_H
#define BUILDTARGETINFO_H
#include "projectexplorer_export.h"
#include <utils/fileutils.h>
#include <QList>
namespace ProjectExplorer {
class PROJECTEXPLORER_EXPORT BuildTargetInfo
{
public:
BuildTargetInfo() {}
BuildTargetInfo(const Utils::FileName &targetFilePath, const Utils::FileName &projectFilePath)
: targetFilePath(targetFilePath), projectFilePath(projectFilePath)
{
}
BuildTargetInfo(const QString &targetFilePath, const QString &projectFilePath)
: targetFilePath(Utils::FileName::fromUserInput(targetFilePath)),
projectFilePath(Utils::FileName::fromUserInput(projectFilePath))
{
}
Utils::FileName targetFilePath;
Utils::FileName projectFilePath;
bool isValid() const { return !targetFilePath.isEmpty(); }
};
class PROJECTEXPLORER_EXPORT BuildTargetInfoList
{
public:
Utils::FileName targetForProject(const QString &projectFilePath) const
{
return targetForProject(Utils::FileName::fromString(projectFilePath));
}
Utils::FileName targetForProject(const Utils::FileName &projectFilePath) const
{
foreach (const BuildTargetInfo &ti, list) {
if (ti.projectFilePath == projectFilePath)
return ti.targetFilePath;
}
return Utils::FileName();
}
QList<BuildTargetInfo> list;
};
} // namespace ProjectExplorer
#endif // BUILDTARGETINFO_H
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: http://www.qt-project.org/
**
**
** 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.
**
** 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 "deployablefile.h"
#include <QFileInfo>
#include <QHash>
#include <QPair>
using namespace Utils;
namespace ProjectExplorer {
DeployableFile::DeployableFile()
{
}
DeployableFile::DeployableFile(const QString &localFilePath, const QString &remoteDir)
: m_localFilePath(FileName::fromUserInput(localFilePath)), m_remoteDir(remoteDir)
{
}
DeployableFile::DeployableFile(const FileName &localFilePath, const QString &remoteDir)
: m_localFilePath(localFilePath), m_remoteDir(remoteDir)
{
}
QString DeployableFile::remoteFilePath() const
{
return m_remoteDir.isEmpty()
? QString() : m_remoteDir + QLatin1Char('/') + m_localFilePath.toFileInfo().fileName();
}
bool DeployableFile::isValid() const
{
return !m_localFilePath.toString().isEmpty() && !m_remoteDir.isEmpty();
}
uint qHash(const DeployableFile &d)
{
return qHash(qMakePair(d.localFilePath().toString(), d.remoteDirectory()));
}
} // namespace ProjectExplorer
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: http://www.qt-project.org/
**
**
** 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.
**
** 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.
**
**
**************************************************************************/
#ifndef DEPLOYABLEFILE_H
#define DEPLOYABLEFILE_H
#include "projectexplorer_export.h"
#include <utils/fileutils.h>
#include <QString>
namespace ProjectExplorer {
class PROJECTEXPLORER_EXPORT DeployableFile
{
public:
DeployableFile();
DeployableFile(const QString &m_localFilePath, const QString &m_remoteDir);
DeployableFile(const Utils::FileName &localFilePath, const QString &remoteDir);
Utils::FileName localFilePath() const { return m_localFilePath; }
QString remoteDirectory() const { return m_remoteDir; }
QString remoteFilePath() const;
bool isValid() const;
private:
Utils::FileName m_localFilePath;
QString m_remoteDir;
};
inline bool operator==(const DeployableFile &d1, const DeployableFile &d2)
{
return d1.localFilePath() == d2.localFilePath() && d1.remoteDirectory() == d2.remoteDirectory();
}
inline bool operator!=(const DeployableFile &d1, const DeployableFile &d2)
{
return !(d1 == d2);
}
PROJECTEXPLORER_EXPORT uint qHash(const DeployableFile &d);
} // namespace ProjectExplorer
#endif // DEPLOYABLEFILE_H
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: http://www.qt-project.org/
**
**
** 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.
**
** 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.
**
**
**************************************************************************/
#ifndef PROJECTEXPLORER_DEPLOYMENTINFO_H
#define PROJECTEXPLORER_DEPLOYMENTINFO_H
#include "deployablefile.h"
#include "projectexplorer_export.h"
#include <QList>
#include <QSet>
namespace ProjectExplorer {
class PROJECTEXPLORER_EXPORT DeploymentData
{
public:
void setFileList(const QList<DeployableFile> &files) { m_files = files; }
void addFile(const DeployableFile &file)
{
if (!m_files.contains(file))
m_files << file;
}
void addFile(const QString &localFilePath, const QString &remoteDirectory)
{
addFile(DeployableFile(localFilePath, remoteDirectory));
}
int fileCount() const { return m_files.count(); }
DeployableFile fileAt(int index) const { return m_files.at(index); }
QList<DeployableFile> allFiles() const { return m_files; }
DeployableFile deployableForLocalFile(const QString &localFilePath) const
{
foreach (const DeployableFile &d, m_files) {
if (d.localFilePath().toString() == localFilePath)
return d;
}
return DeployableFile();
}
bool operator==(const DeploymentData &other) const
{
return m_files.toSet() == other.m_files.toSet();
}
private:
QList<DeployableFile> m_files;
};
inline bool operator!=(const DeploymentData &d1, const DeploymentData &d2)
{
return !(d1 == d2);
}
} // namespace ProjectExplorer
#endif // PROJECTEXPLORER_DEPLOYMENTINFO_H
......@@ -31,6 +31,7 @@
#include "projectexplorer.h"
#include "buildsteplist.h"
#include "deployablefile.h"
#include "deployconfiguration.h"
#include "gcctoolchainfactories.h"
#include "project.h"
......@@ -316,6 +317,7 @@ bool ProjectExplorerPlugin::parseArguments(const QStringList &arguments, QString
bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *error)
{
qRegisterMetaType<ProjectExplorer::RunControl *>();
qRegisterMetaType<ProjectExplorer::DeployableFile>("ProjectExplorer::DeployableFile");
if (!parseArguments(arguments, error))
return false;
......
......@@ -113,6 +113,7 @@ HEADERS += projectexplorer.h \
codestylesettingspropertiespage.h \
settingsaccessor.h \
environmentitemswidget.h \
deployablefile.h \
devicesupport/idevice.h \
devicesupport/desktopdevice.h \
devicesupport/desktopdevicefactory.h \
......@@ -128,7 +129,9 @@ HEADERS += projectexplorer.h \
devicesupport/deviceusedportsgatherer.h \
devicesupport/deviceapplicationrunner.h \
devicesupport/localprocesslist.h \
devicesupport/sshdeviceprocesslist.h
devicesupport/sshdeviceprocesslist.h \
deploymentdata.h \
buildtargetinfo.h
SOURCES += projectexplorer.cpp \
abi.cpp \
......@@ -233,7 +236,8 @@ SOURCES += projectexplorer.cpp \
devicesupport/deviceusedportsgatherer.cpp \
devicesupport/deviceapplicationrunner.cpp \
devicesupport/localprocesslist.cpp \
devicesupport/sshdeviceprocesslist.cpp
devicesupport/sshdeviceprocesslist.cpp \
deployablefile.cpp
FORMS += processstep.ui \
editorsettingspropertiespage.ui \
......
......@@ -231,6 +231,10 @@ QtcPlugin {
"customwizard/customwizardscriptgenerator.h",
"customwizard/customwizard.cpp",
"customwizard/customwizardparameters.cpp",
"deployablefile.h",
"deployablefile.cpp",
"deploymentdata.h",
"buildtargetinfo.h",
"images/BuildSettings.png",
"images/CodeStyleSettings.png",
"images/DeviceConnected.png",
......
......@@ -30,6 +30,8 @@
#include "target.h"
#include "buildtargetinfo.h"
#include "deploymentdata.h"
#include "profile.h"
#include "profileinformation.h"
#include "profilemanager.h"
......@@ -90,6 +92,8 @@ public:
DeployConfiguration *m_activeDeployConfiguration;
QList<RunConfiguration *> m_runConfigurations;
RunConfiguration* m_activeRunConfiguration;
DeploymentData m_deploymentData;
BuildTargetInfoList m_appTargets;
QPixmap m_connectedPixmap;
QPixmap m_readyToUsePixmap;
......@@ -368,6 +372,26 @@ void Target::setActiveDeployConfiguration(DeployConfiguration *dc)
updateDeviceState();
}
void Target::setDeploymentData(const DeploymentData &deploymentData)
{
d->m_deploymentData = deploymentData;
}
DeploymentData Target::deploymentData() const
{
return d->m_deploymentData;
}
void Target::setApplicationTargets(const BuildTargetInfoList &appTargets)
{
d->m_appTargets = appTargets;
}
BuildTargetInfoList Target::applicationTargets() const
{
return d->m_appTargets;
}
QList<RunConfiguration *> Target::runConfigurations() const
{
return d->m_runConfigurations;
......
......@@ -40,6 +40,8 @@ QT_FORWARD_DECLARE_CLASS(QIcon)
namespace Utils { class Environment; }
namespace ProjectExplorer {
class BuildTargetInfoList;
class DeploymentData;
class RunConfiguration;
class BuildConfiguration;
class DeployConfiguration;
......@@ -81,6 +83,12 @@ public:
DeployConfiguration *activeDeployConfiguration() const;
void setActiveDeployConfiguration(DeployConfiguration *configuration);
void setDeploymentData(const DeploymentData &deploymentData);
DeploymentData deploymentData() const;
void setApplicationTargets(const BuildTargetInfoList &appTargets);
BuildTargetInfoList applicationTargets() const;
// Running
QList<RunConfiguration *> runConfigurations() const;
void addRunConfiguration(RunConfiguration *runConfiguration);
......
......@@ -1587,6 +1587,12 @@ QStringList Qt4ProFileNode::variableValue(const Qt4Variable var) const
return m_varValues.value(var);
}
QString Qt4ProFileNode::singleVariableValue(const Qt4Variable var) const
{
const QStringList &values = variableValue(var);
return values.isEmpty() ? QString() : values.first();
}
void Qt4ProFileNode::emitProFileUpdatedRecursive()
{
foreach (ProjectExplorer::NodesWatcher *watcher, watchers())
......@@ -2008,6 +2014,11 @@ void Qt4ProFileNode::applyEvaluate(EvalResult evalResult, bool async)
newVarValues[QtVar] = m_readerExact->values(QLatin1String("QT"));
newVarValues[ObjectExt] = m_readerExact->values(QLatin1String("QMAKE_EXT_OBJ"));
newVarValues[ObjectsDir] = m_readerExact->values(QLatin1String("OBJECTS_DIR"));
newVarValues[VersionVar] = m_readerExact->values(QLatin1String("VERSION"));
newVarValues[TargetVersionExtVar]
= m_readerExact->values(QLatin1String("TARGET_VERSION_EXT"));
newVarValues[StaticLibExtensionVar] = m_readerExact->values("QMAKE_EXTENSION_STATICLIB");
newVarValues[ShLibExtensionVar] = m_readerExact->values("QMAKE_EXTENSION_SHLIB");
m_isDeployable = false;
if (m_projectType == ApplicationTemplate) {
......
......@@ -95,7 +95,11 @@ enum Qt4Variable {
Makefile,
SymbianCapabilities,
ObjectExt,
ObjectsDir
ObjectsDir,
VersionVar,
TargetVersionExtVar,
StaticLibExtensionVar,
ShLibExtensionVar
};
// Import base classes into namespace
......@@ -358,6 +362,7 @@ public:
Qt4ProjectType projectType() const;
QStringList variableValue(const Qt4Variable var) const;
QString singleVariableValue(const Qt4Variable var) const;
bool isSubProjectDeployable(const QString &filePath) const {
return !m_subProjectsNotToDeploy.contains(filePath);
......
......@@ -50,6 +50,8 @@
#include <extensionsystem/pluginmanager.h>
#include <cpptools/ModelManagerInterface.h>
#include <qmljs/qmljsmodelmanagerinterface.h>
#include <projectexplorer/buildtargetinfo.h>
#include <projectexplorer/deploymentdata.h>
#include <projectexplorer/toolchain.h>
#include <projectexplorer/headerpath.h>
#include <projectexplorer/target.h>
......@@ -637,6 +639,7 @@ void Qt4Project::update()
qDebug()<<"State is now Base";
m_asyncUpdateState = Base;
enableActiveQt4BuildConfiguration(activeTarget(), true);
updateBuildSystemData();
buildSystemEvaluationFinished(true);
}
......@@ -787,6 +790,7 @@ void Qt4Project::decrementPendingEvaluateFutures()
enableActiveQt4BuildConfiguration(activeTarget(), true);
updateFileList();
updateCodeModels();
updateBuildSystemData();
buildSystemEvaluationFinished(true);
if (debug)
qDebug()<<" Setting state to Base";
......@@ -1404,6 +1408,141 @@ Target *Qt4Project::createTarget(Profile *p, const QList<BuildConfigurationInfo>
return t;
}
void Qt4Project::updateBuildSystemData()
{
Target * const target = activeTarget();
if (!target)
return;
const Qt4ProFileNode * const rootNode = rootQt4ProjectNode();
if (!rootNode || rootNode->parseInProgress())
return;
DeploymentData deploymentData;
collectData(rootNode, deploymentData);
target->setDeploymentData(deploymentData);
BuildTargetInfoList appTargetList;
foreach (const Qt4ProFileNode * const node, applicationProFiles())
appTargetList.list << BuildTargetInfo(node->targetInformation().executable, node->path());
target->setApplicationTargets(appTargetList);
}
void Qt4Project::collectData(const Qt4ProFileNode *node, DeploymentData &deploymentData)
{
if (!node->isSubProjectDeployable(node->path()))
return;
const InstallsList &installsList = node->installsList();
foreach (const InstallsItem &item, installsList.items) {
foreach (const QString &localFile, item.files)
deploymentData.addFile(localFile, item.path);
}
switch (node->projectType()) {
case ApplicationTemplate:
if (!installsList.targetPath.isEmpty())
deploymentData.addFile(node->targetInformation().executable, installsList.targetPath);
break;
case LibraryTemplate:
collectLibraryData(node, deploymentData);
break;
case SubDirsTemplate:
foreach (const ProjectNode * const subProject, node->subProjectNodesExact()) {
const Qt4ProFileNode * const qt4SubProject
= qobject_cast<const Qt4ProFileNode *>(subProject);
if (!qt4SubProject)
continue;
collectData(qt4SubProject, deploymentData);
}
break;
default:
break;
}
}
void Qt4Project::collectLibraryData(const Qt4ProFileNode *node, DeploymentData &deploymentData)
{
const QString targetPath = node->installsList().targetPath;
if (targetPath.isEmpty())
return;
const ProjectExplorer::Profile * const profile = activeTarget()->profile();
const ProjectExplorer::ToolChain * const toolchain
= ProjectExplorer::ToolChainProfileInformation::toolChain(profile);
if (!toolchain)
return;
TargetInformation ti = node->targetInformation();
QString targetFileName = ti.target;
const QStringList config = node->variableValue(ConfigVar);
const bool isStatic = config.contains(QLatin1String("static"));
const bool isPlugin = config.contains(QLatin1String("plugin"));
switch (toolchain->targetAbi().os()) {
case ProjectExplorer::Abi::WindowsOS: {
QString targetVersionExt = node->singleVariableValue(TargetVersionExtVar);
if (targetVersionExt.isEmpty()) {
const QString version = node->singleVariableValue(VersionVar);
if (!version.isEmpty()) {
targetVersionExt = version.left(version.indexOf(QLatin1Char('.')));
if (targetVersionExt == QLatin1String("0"))
targetVersionExt.clear();
}
}
targetFileName += targetVersionExt + QLatin1Char('.');
targetFileName += QLatin1String(isStatic ? "lib" : "dll");
deploymentData.addFile(ti.workingDir + QLatin1Char('/') + targetFileName, targetPath);
break;
}
case ProjectExplorer::Abi::MacOS:
if (config.contains("lib_bundle")) {
ti.workingDir.append(QLatin1Char('/')).append(ti.target)
.append(QLatin1String(".framework"));