Fix subdir project deployment for symbian

We create a .sis package per leaf project now, deploy all of them and
start the executable for the runconfiguration that was selected. This
does not cover all use cases, but works for development.
This commit is contained in:
dt
2010-07-23 16:37:10 +02:00
parent 253cbf3c03
commit 05ae17eadd
11 changed files with 430 additions and 109 deletions

View File

@@ -31,13 +31,18 @@
#include "qt4projectmanagerconstants.h" #include "qt4projectmanagerconstants.h"
#include "qt4buildconfiguration.h" #include "qt4buildconfiguration.h"
#include "qt4nodes.h"
#include "qt4project.h"
#include "abldparser.h" #include "abldparser.h"
#include <projectexplorer/buildconfiguration.h> #include <projectexplorer/buildconfiguration.h>
#include <projectexplorer/target.h> #include <projectexplorer/target.h>
#include <projectexplorer/project.h>
#include <projectexplorer/gnumakeparser.h> #include <projectexplorer/gnumakeparser.h>
#include <projectexplorer/task.h>
#include <QtCore/QDir> #include <QtCore/QDir>
#include <QtCore/QTimer>
using namespace Qt4ProjectManager::Internal; using namespace Qt4ProjectManager::Internal;
@@ -49,30 +54,41 @@ namespace {
const char * const SMART_INSTALLER_KEY("Qt4ProjectManager.S60CreatorPackageStep.SmartInstaller"); const char * const SMART_INSTALLER_KEY("Qt4ProjectManager.S60CreatorPackageStep.SmartInstaller");
} }
// #pragma mark -- S60SignBuildStep
S60CreatePackageStep::S60CreatePackageStep(ProjectExplorer::BuildConfiguration *bc) : S60CreatePackageStep::S60CreatePackageStep(ProjectExplorer::BuildConfiguration *bc) :
MakeStep(bc, QLatin1String(SIGN_BS_ID)), BuildStep(bc, QLatin1String(SIGN_BS_ID)),
m_signingMode(SignSelf), m_signingMode(SignSelf),
m_createSmartInstaller(false) m_createSmartInstaller(false),
m_outputParserChain(0),
m_process(0),
m_timer(0),
m_eventLoop(0),
m_futureInterface(0)
{ {
ctor_package(); ctor_package();
} }
S60CreatePackageStep::S60CreatePackageStep(ProjectExplorer::BuildConfiguration *bc, S60CreatePackageStep *bs) : S60CreatePackageStep::S60CreatePackageStep(ProjectExplorer::BuildConfiguration *bc, S60CreatePackageStep *bs) :
MakeStep(bc, bs), BuildStep(bc, bs),
m_signingMode(bs->m_signingMode), m_signingMode(bs->m_signingMode),
m_customSignaturePath(bs->m_customSignaturePath), m_customSignaturePath(bs->m_customSignaturePath),
m_customKeyPath(bs->m_customKeyPath), m_customKeyPath(bs->m_customKeyPath),
m_createSmartInstaller(bs->m_createSmartInstaller) m_createSmartInstaller(bs->m_createSmartInstaller),
m_outputParserChain(0),
m_timer(0),
m_eventLoop(0),
m_futureInterface(0)
{ {
ctor_package(); ctor_package();
} }
S60CreatePackageStep::S60CreatePackageStep(ProjectExplorer::BuildConfiguration *bc, const QString &id) : S60CreatePackageStep::S60CreatePackageStep(ProjectExplorer::BuildConfiguration *bc, const QString &id) :
MakeStep(bc, id), BuildStep(bc, id),
m_signingMode(SignSelf), m_signingMode(SignSelf),
m_createSmartInstaller(false) m_createSmartInstaller(false),
m_outputParserChain(0),
m_timer(0),
m_eventLoop(0),
m_futureInterface(0)
{ {
ctor_package(); ctor_package();
} }
@@ -88,7 +104,7 @@ S60CreatePackageStep::~S60CreatePackageStep()
QVariantMap S60CreatePackageStep::toMap() const QVariantMap S60CreatePackageStep::toMap() const
{ {
QVariantMap map(MakeStep::toMap()); QVariantMap map(BuildStep::toMap());
map.insert(QLatin1String(SIGNMODE_KEY), (int)m_signingMode); map.insert(QLatin1String(SIGNMODE_KEY), (int)m_signingMode);
map.insert(QLatin1String(CERTIFICATE_KEY), m_customSignaturePath); map.insert(QLatin1String(CERTIFICATE_KEY), m_customSignaturePath);
map.insert(QLatin1String(KEYFILE_KEY), m_customKeyPath); map.insert(QLatin1String(KEYFILE_KEY), m_customKeyPath);
@@ -102,34 +118,224 @@ bool S60CreatePackageStep::fromMap(const QVariantMap &map)
m_customSignaturePath = map.value(QLatin1String(CERTIFICATE_KEY)).toString(); m_customSignaturePath = map.value(QLatin1String(CERTIFICATE_KEY)).toString();
m_customKeyPath = map.value(QLatin1String(KEYFILE_KEY)).toString(); m_customKeyPath = map.value(QLatin1String(KEYFILE_KEY)).toString();
m_createSmartInstaller = map.value(QLatin1String(SMART_INSTALLER_KEY), false).toBool(); m_createSmartInstaller = map.value(QLatin1String(SMART_INSTALLER_KEY), false).toBool();
return MakeStep::fromMap(map); return BuildStep::fromMap(map);
}
Qt4BuildConfiguration *S60CreatePackageStep::qt4BuildConfiguration() const
{
return static_cast<Qt4BuildConfiguration *>(buildConfiguration());
} }
bool S60CreatePackageStep::init() bool S60CreatePackageStep::init()
{ {
if (!MakeStep::init()) Qt4Project *pro = qobject_cast<Qt4Project *>(buildConfiguration()->target()->project());
return false;
Qt4BuildConfiguration *bc = qt4BuildConfiguration();
ProjectExplorer::Environment environment = bc->environment();
setEnvironment(environment);
QStringList args;
if (m_createSmartInstaller)
args << QLatin1String("installer_sis");
else
args << QLatin1String("sis");
if (signingMode() == SignCustom) {
args << QLatin1String("QT_SIS_CERTIFICATE=") + QDir::toNativeSeparators(customSignaturePath())
<< QLatin1String("QT_SIS_KEY=") + QDir::toNativeSeparators(customKeyPath());
}
setArguments(args); // overwrite any stuff done in make step
ProjectExplorer::GnuMakeParser *parser = new ProjectExplorer::GnuMakeParser; QList<Qt4ProFileNode *> nodes = pro->leafProFiles();
parser->appendOutputParser(new Qt4ProjectManager::AbldParser);
setOutputParser(parser); m_workingDirectories.clear();
foreach (Qt4ProFileNode *node, nodes)
m_workingDirectories << node->buildDir();
m_makeCmd = qt4BuildConfiguration()->makeCommand();
if (!QFileInfo(m_makeCmd).isAbsolute()) {
// Try to detect command in environment
const QString tmp = buildConfiguration()->environment().searchInPath(m_makeCmd);
if (tmp.isEmpty()) {
emit addOutput(tr("Could not find make command: %1 in the build environment").arg(m_makeCmd), BuildStep::ErrorOutput);
return false;
}
m_makeCmd = tmp;
}
m_environment = qt4BuildConfiguration()->environment();
m_args.clear();
if (m_createSmartInstaller)
m_args << QLatin1String("installer_sis");
else
m_args << QLatin1String("sis");
if (signingMode() == SignCustom) {
m_args << QLatin1String("QT_SIS_CERTIFICATE=") + QDir::toNativeSeparators(customSignaturePath())
<< QLatin1String("QT_SIS_KEY=") + QDir::toNativeSeparators(customKeyPath());
}
delete m_outputParserChain;
m_outputParserChain = new ProjectExplorer::GnuMakeParser;
m_outputParserChain->appendOutputParser(new Qt4ProjectManager::AbldParser);
connect(m_outputParserChain, SIGNAL(addOutput(QString, ProjectExplorer::BuildStep::OutputFormat)),
this, SLOT(outputAdded(QString, ProjectExplorer::BuildStep::OutputFormat)));
connect(m_outputParserChain, SIGNAL(addTask(ProjectExplorer::Task)),
this, SLOT(taskAdded(ProjectExplorer::Task)));
return true; return true;
} }
void S60CreatePackageStep::run(QFutureInterface<bool> &fi)
{
m_futureInterface = &fi;
if (m_workingDirectories.isEmpty()) {
fi.reportResult(true);
return;
}
// Setup everything...
m_process = new QProcess();
m_process->setEnvironment(m_environment.toStringList());
connect(m_process, SIGNAL(readyReadStandardOutput()),
this, SLOT(processReadyReadStdOutput()),
Qt::DirectConnection);
connect(m_process, SIGNAL(readyReadStandardError()),
this, SLOT(processReadyReadStdError()),
Qt::DirectConnection);
connect(m_process, SIGNAL(finished(int, QProcess::ExitStatus)),
this, SLOT(slotProcessFinished(int, QProcess::ExitStatus)),
Qt::DirectConnection);
m_timer = new QTimer();
connect(m_timer, SIGNAL(timeout()), this, SLOT(checkForCancel()), Qt::DirectConnection);
m_timer->start(500);
m_eventLoop = new QEventLoop;
bool returnValue = false;
if (startProcess())
returnValue = m_eventLoop->exec();
// Finished
m_timer->stop();
delete m_timer;
m_timer = 0;
delete m_process;
m_process = 0;
delete m_eventLoop;
m_eventLoop = 0;
fi.reportResult(returnValue);
m_futureInterface = 0;
return;
}
void S60CreatePackageStep::slotProcessFinished(int, QProcess::ExitStatus)
{
QString line = QString::fromLocal8Bit(m_process->readAllStandardError());
if (!line.isEmpty())
stdError(line);
line = QString::fromLocal8Bit(m_process->readAllStandardOutput());
if (!line.isEmpty())
stdOutput(line);
bool returnValue = false;
if (m_process->exitStatus() == QProcess::NormalExit && m_process->exitCode() == 0) {
emit addOutput(tr("The process \"%1\" exited normally.")
.arg(QDir::toNativeSeparators(m_makeCmd)),
BuildStep::MessageOutput);
returnValue = true;
} else if (m_process->exitStatus() == QProcess::NormalExit) {
emit addOutput(tr("The process \"%1\" exited with code %2.")
.arg(QDir::toNativeSeparators(m_makeCmd), QString::number(m_process->exitCode())),
BuildStep::ErrorMessageOutput);
} else {
emit addOutput(tr("The process \"%1\" crashed.").arg(QDir::toNativeSeparators(m_makeCmd)), BuildStep::ErrorMessageOutput);
}
if (m_workingDirectories.isEmpty() || !returnValue) {
m_eventLoop->exit(returnValue);
} else {
// Success, do next
if (!startProcess())
m_eventLoop->exit(returnValue);
}
}
bool S60CreatePackageStep::startProcess()
{
QString workingDirectory = m_workingDirectories.takeFirst();
QDir wd(workingDirectory);
if (!wd.exists())
wd.mkpath(wd.absolutePath());
m_process->setWorkingDirectory(workingDirectory);
// Go for it!
m_process->start(m_makeCmd, m_args);
if (!m_process->waitForStarted()) {
emit addOutput(tr("Could not start process \"%1\" in %2")
.arg(QDir::toNativeSeparators(m_makeCmd),
workingDirectory),
BuildStep::ErrorMessageOutput);
return false;
}
emit addOutput(tr("Starting: \"%1\" %2 in %3\n")
.arg(QDir::toNativeSeparators(m_makeCmd),
m_args.join(" "),
workingDirectory),
BuildStep::MessageOutput);
return true;
}
void S60CreatePackageStep::processReadyReadStdOutput()
{
m_process->setReadChannel(QProcess::StandardOutput);
while (m_process->canReadLine()) {
QString line = QString::fromLocal8Bit(m_process->readLine());
stdOutput(line);
}
}
void S60CreatePackageStep::stdOutput(const QString &line)
{
if (m_outputParserChain)
m_outputParserChain->stdOutput(line);
emit addOutput(line, BuildStep::NormalOutput);
}
void S60CreatePackageStep::processReadyReadStdError()
{
m_process->setReadChannel(QProcess::StandardError);
while (m_process->canReadLine()) {
QString line = QString::fromLocal8Bit(m_process->readLine());
stdError(line);
}
}
void S60CreatePackageStep::stdError(const QString &line)
{
if (m_outputParserChain)
m_outputParserChain->stdError(line);
emit addOutput(line, BuildStep::ErrorOutput);
}
void S60CreatePackageStep::checkForCancel()
{
if (m_futureInterface->isCanceled() && m_timer->isActive()) {
m_timer->stop();
m_process->terminate();
m_process->waitForFinished(5000);
m_process->kill();
}
}
void S60CreatePackageStep::taskAdded(const ProjectExplorer::Task &task)
{
ProjectExplorer::Task editable(task);
QString filePath = QDir::cleanPath(task.file.trimmed());
if (!filePath.isEmpty() && !QDir::isAbsolutePath(filePath)) {
// TODO which kind of tasks do we get from package building?
// No absoulte path
}
emit addTask(editable);
}
void S60CreatePackageStep::outputAdded(const QString &string, ProjectExplorer::BuildStep::OutputFormat format)
{
emit addOutput(string, format);
}
bool S60CreatePackageStep::immutable() const bool S60CreatePackageStep::immutable() const
{ {
return false; return false;

View File

@@ -59,7 +59,8 @@ public:
ProjectExplorer::BuildStep *clone(ProjectExplorer::BuildConfiguration *parent, ProjectExplorer::BuildStep::Type type, ProjectExplorer::BuildStep *product); ProjectExplorer::BuildStep *clone(ProjectExplorer::BuildConfiguration *parent, ProjectExplorer::BuildStep::Type type, ProjectExplorer::BuildStep *product);
}; };
class S60CreatePackageStep : public MakeStep { class S60CreatePackageStep : public ProjectExplorer::BuildStep
{
Q_OBJECT Q_OBJECT
friend class S60CreatePackageStepFactory; friend class S60CreatePackageStepFactory;
public: public:
@@ -72,6 +73,7 @@ public:
virtual ~S60CreatePackageStep(); virtual ~S60CreatePackageStep();
virtual bool init(); virtual bool init();
virtual void run(QFutureInterface<bool> &fi);
virtual ProjectExplorer::BuildStepConfigWidget *createConfigWidget(); virtual ProjectExplorer::BuildStepConfigWidget *createConfigWidget();
virtual bool immutable() const; virtual bool immutable() const;
@@ -91,13 +93,38 @@ protected:
S60CreatePackageStep(ProjectExplorer::BuildConfiguration *bc, const QString &id); S60CreatePackageStep(ProjectExplorer::BuildConfiguration *bc, const QString &id);
bool fromMap(const QVariantMap &map); bool fromMap(const QVariantMap &map);
Qt4BuildConfiguration *qt4BuildConfiguration() const;
private slots:
void slotProcessFinished(int, QProcess::ExitStatus);
void processReadyReadStdOutput();
void processReadyReadStdError();
void taskAdded(const ProjectExplorer::Task &task);
void outputAdded(const QString &string, ProjectExplorer::BuildStep::OutputFormat format);
void checkForCancel();
private: private:
void stdOutput(const QString &line);
void stdError(const QString &line);
bool startProcess();
QStringList m_workingDirectories;
QString m_makeCmd;
ProjectExplorer::Environment m_environment;
QStringList m_args;
void ctor_package(); void ctor_package();
SigningMode m_signingMode; SigningMode m_signingMode;
QString m_customSignaturePath; QString m_customSignaturePath;
QString m_customKeyPath; QString m_customKeyPath;
bool m_createSmartInstaller; bool m_createSmartInstaller;
ProjectExplorer::IOutputParser *m_outputParserChain;
QProcess *m_process;
QTimer *m_timer;
QEventLoop *m_eventLoop;
QFutureInterface<bool> *m_futureInterface;
}; };
class S60CreatePackageStepConfigWidget : public ProjectExplorer::BuildStepConfigWidget class S60CreatePackageStepConfigWidget : public ProjectExplorer::BuildStepConfigWidget

View File

@@ -126,8 +126,9 @@ bool S60DeployStep::init()
} }
m_serialPortName = runConfiguration->serialPortName(); m_serialPortName = runConfiguration->serialPortName();
m_serialPortFriendlyName = SymbianUtils::SymbianDeviceManager::instance()->friendlyNameForPort(m_serialPortName); m_serialPortFriendlyName = SymbianUtils::SymbianDeviceManager::instance()->friendlyNameForPort(m_serialPortName);
m_packageFileNameWithTarget = runConfiguration->packageFileNameWithTargetInfo(); m_packageFileNamesWithTarget = runConfiguration->packageFileNamesWithTargetInfo();
m_signedPackage = runConfiguration->signedPackage(); m_signedPackages = runConfiguration->signedPackages();
m_installationDrive = runConfiguration->installationDrive(); m_installationDrive = runConfiguration->installationDrive();
m_silentInstall = runConfiguration->silentInstall(); m_silentInstall = runConfiguration->silentInstall();
@@ -174,31 +175,31 @@ void S60DeployStep::appendMessage(const QString &error, bool isError)
bool S60DeployStep::processPackageName(QString &errorMessage) bool S60DeployStep::processPackageName(QString &errorMessage)
{ {
QFileInfo packageInfo(m_signedPackage); for (int i = 0; i < m_signedPackages.count(); ++i) {
{ QFileInfo packageInfo(m_signedPackages.at(i));
// support for 4.6.1 and pre, where make sis creates 'targetname_armX_udeb.sis' instead of 'targetname.sis' // support for 4.6.1 and pre, where make sis creates 'targetname_armX_udeb.sis' instead of 'targetname.sis'
QFileInfo packageWithTargetInfo(m_packageFileNameWithTarget); QFileInfo packageWithTargetInfo(m_packageFileNamesWithTarget.at(i));
// does the 4.6.1 version exist? // does the 4.6.1 version exist?
if (packageWithTargetInfo.exists() && packageWithTargetInfo.isFile()) { if (packageWithTargetInfo.exists() && packageWithTargetInfo.isFile()) {
// is the 4.6.1 version newer? (to guard against behavior change Qt Creator 1.3 --> 2.0) // is the 4.6.1 version newer? (to guard against behavior change Qt Creator 1.3 --> 2.0)
if (!packageInfo.exists() || packageInfo.lastModified() < packageWithTargetInfo.lastModified()) { //TODO change the QtCore if (!packageInfo.exists() || packageInfo.lastModified() < packageWithTargetInfo.lastModified()) { //TODO change the QtCore
// the 'targetname_armX_udeb.sis' crap exists and is new, rename it // the 'targetname_armX_udeb.sis' crap exists and is new, rename it
appendMessage(tr("Renaming new package '%1' to '%2'") appendMessage(tr("Renaming new package '%1' to '%2'")
.arg(QDir::toNativeSeparators(m_packageFileNameWithTarget), .arg(QDir::toNativeSeparators(m_packageFileNamesWithTarget.at(i)),
QDir::toNativeSeparators(m_signedPackage)), false); QDir::toNativeSeparators(m_signedPackages.at(i))), false);
return renameFile(m_packageFileNameWithTarget, m_signedPackage, &errorMessage); return renameFile(m_packageFileNamesWithTarget.at(i), m_signedPackages.at(i), &errorMessage);
} else { } else {
// the 'targetname_armX_udeb.sis' crap exists but is old, remove it // the 'targetname_armX_udeb.sis' crap exists but is old, remove it
appendMessage(tr("Removing old package '%1'") appendMessage(tr("Removing old package '%1'")
.arg(QDir::toNativeSeparators(m_packageFileNameWithTarget)), .arg(QDir::toNativeSeparators(m_packageFileNamesWithTarget.at(i))),
false); false);
ensureDeleteFile(m_packageFileNameWithTarget, &errorMessage); ensureDeleteFile(m_packageFileNamesWithTarget.at(i), &errorMessage);
} }
} }
} if (!packageInfo.exists() || !packageInfo.isFile()) {
if (!packageInfo.exists() || !packageInfo.isFile()) { errorMessage = tr("'%1': Package file not found").arg(m_signedPackages.at(i));
errorMessage = tr("Package file not found"); return false;
return false; }
} }
return true; return true;
} }
@@ -217,7 +218,7 @@ void S60DeployStep::start()
if (processPackageName(errorMessage)) { if (processPackageName(errorMessage)) {
startDeployment(); startDeployment();
} else { } else {
errorMessage = tr("Failed to find package '%1': %2").arg(m_signedPackage, errorMessage); errorMessage = tr("Failed to find package %1").arg(errorMessage);
appendMessage(errorMessage, true); appendMessage(errorMessage, true);
stop(); stop();
emit finished(); emit finished();
@@ -253,16 +254,19 @@ void S60DeployStep::startDeployment()
setupConnections(); setupConnections();
const QString copyDst = QString::fromLatin1("%1:\\Data\\%2").arg(m_installationDrive).arg(QFileInfo(m_signedPackage).fileName()); QStringList copyDst;
foreach (const QString &signedPackage, m_signedPackages)
copyDst << QString::fromLatin1("%1:\\Data\\%1").arg(m_installationDrive).arg(QFileInfo(signedPackage).fileName());
m_launcher->setCopyFileName(m_signedPackage, copyDst); m_launcher->setCopyFileNames(m_signedPackages, copyDst);
m_launcher->setInstallFileName(copyDst); m_launcher->setInstallFileNames(copyDst);
m_launcher->setInstallationDrive(m_installationDrive); m_launcher->setInstallationDrive(m_installationDrive);
m_launcher->setInstallationMode(m_silentInstall?trk::Launcher::InstallationModeSilentAndUser: m_launcher->setInstallationMode(m_silentInstall?trk::Launcher::InstallationModeSilentAndUser:
trk::Launcher::InstallationModeUser); trk::Launcher::InstallationModeUser);
m_launcher->addStartupActions(trk::Launcher::ActionCopyInstall); m_launcher->addStartupActions(trk::Launcher::ActionCopyInstall);
appendMessage(tr("Package: %1\nDeploying application to '%2'...").arg(m_signedPackage, m_serialPortFriendlyName), false); // TODO readd information about packages? msgListFile(m_signedPackage)
appendMessage(tr("Deploying application to '%2'...").arg(m_serialPortFriendlyName), false);
QString errorMessage; QString errorMessage;
if (!m_launcher->startServer(&errorMessage)) { if (!m_launcher->startServer(&errorMessage)) {

View File

@@ -129,8 +129,8 @@ signals:
private: private:
QString m_serialPortName; QString m_serialPortName;
QString m_serialPortFriendlyName; QString m_serialPortFriendlyName;
QString m_packageFileNameWithTarget; // Support for 4.6.1 QStringList m_packageFileNamesWithTarget; // Support for 4.6.1
QString m_signedPackage; QStringList m_signedPackages;
QTimer *m_timer; QTimer *m_timer;

View File

@@ -286,16 +286,22 @@ static inline QString fixBaseNameTarget(const QString &in)
return in; return in;
} }
QString S60DeviceRunConfiguration::packageFileNameWithTargetInfo() const QStringList S60DeviceRunConfiguration::packageFileNamesWithTargetInfo() const
{ {
TargetInformation ti = qt4Target()->qt4Project()->rootProjectNode()->targetInformation(m_proFilePath); QList<Qt4ProFileNode *> leafs = qt4Target()->qt4Project()->leafProFiles();
if (!ti.valid)
return QString(); QStringList result;
QString baseFileName = ti.buildDir + QLatin1Char('/') + ti.target; foreach (Qt4ProFileNode *qt4ProFileNode, leafs) {
baseFileName += QLatin1Char('_') TargetInformation ti = qt4ProFileNode->targetInformation();
+ (isDebug() ? QLatin1String("debug") : QLatin1String("release")) if (!ti.valid)
+ QLatin1Char('-') + symbianPlatform() + QLatin1String(".sis"); continue;
return baseFileName; QString baseFileName = ti.buildDir + QLatin1Char('/') + ti.target;
baseFileName += QLatin1Char('_')
+ (isDebug() ? QLatin1String("debug") : QLatin1String("release"))
+ QLatin1Char('-') + symbianPlatform() + QLatin1String(".sis");
result << baseFileName;
}
return result;
} }
QString S60DeviceRunConfiguration::symbianPlatform() const QString S60DeviceRunConfiguration::symbianPlatform() const
@@ -323,7 +329,19 @@ QString S60DeviceRunConfiguration::symbianTarget() const
return isDebug() ? QLatin1String("udeb") : QLatin1String("urel"); return isDebug() ? QLatin1String("udeb") : QLatin1String("urel");
} }
QString S60DeviceRunConfiguration::packageTemplateFileName() const QStringList S60DeviceRunConfiguration::packageTemplateFileNames() const
{
QList<Qt4ProFileNode *> list = qt4Target()->qt4Project()->leafProFiles();
QStringList result;
foreach (Qt4ProFileNode *node, list) {
TargetInformation ti = node->targetInformation();
if (ti.valid)
result << ti.buildDir + QLatin1Char('/') + ti.target + QLatin1String("_template.pkg");
}
return result;
}
QString S60DeviceRunConfiguration::appPackageTemplateFileName() const
{ {
TargetInformation ti = qt4Target()->qt4Project()->rootProjectNode()->targetInformation(m_proFilePath); TargetInformation ti = qt4Target()->qt4Project()->rootProjectNode()->targetInformation(m_proFilePath);
if (!ti.valid) if (!ti.valid)
@@ -331,6 +349,7 @@ QString S60DeviceRunConfiguration::packageTemplateFileName() const
return ti.buildDir + QLatin1Char('/') + ti.target + QLatin1String("_template.pkg"); return ti.buildDir + QLatin1Char('/') + ti.target + QLatin1String("_template.pkg");
} }
/* Grep a package file for the '.exe' file. Curently for use on Linux only /* Grep a package file for the '.exe' file. Curently for use on Linux only
* as the '.pkg'-files on Windows do not contain drive letters, which is not * as the '.pkg'-files on Windows do not contain drive letters, which is not
* handled here. \code * handled here. \code
@@ -373,7 +392,7 @@ QString S60DeviceRunConfiguration::localExecutableFileName() const
switch (toolChainType()) { switch (toolChainType()) {
case ToolChain::GCCE_GNUPOC: case ToolChain::GCCE_GNUPOC:
case ToolChain::RVCT_ARMV5_GNUPOC: case ToolChain::RVCT_ARMV5_GNUPOC:
localExecutable = executableFromPackageUnix(packageTemplateFileName()); localExecutable = executableFromPackageUnix(appPackageTemplateFileName());
break; break;
default: { default: {
const QtVersion *qtv = qtVersion(); const QtVersion *qtv = qtVersion();
@@ -403,7 +422,21 @@ bool S60DeviceRunConfiguration::runSmartInstaller() const
return false; return false;
} }
QString S60DeviceRunConfiguration::signedPackage() const QStringList S60DeviceRunConfiguration::signedPackages() const
{
QList<Qt4ProFileNode *> list = qt4Target()->qt4Project()->leafProFiles();
QStringList result;
foreach (Qt4ProFileNode *node, list) {
TargetInformation ti = node->targetInformation();
if (ti.valid)
result << ti.buildDir + QLatin1Char('/') + ti.target
+ (runSmartInstaller() ? QLatin1String("_installer") : QLatin1String(""))
+ QLatin1String(".sis");
}
return result;
}
QString S60DeviceRunConfiguration::appSignedPackage() const
{ {
TargetInformation ti = qt4Target()->qt4Project()->rootProjectNode()->targetInformation(m_proFilePath); TargetInformation ti = qt4Target()->qt4Project()->rootProjectNode()->targetInformation(m_proFilePath);
if (!ti.valid) if (!ti.valid)
@@ -640,7 +673,6 @@ void S60DeviceRunControlBase::startDeployment()
if (!m_commandLineArguments.isEmpty()) if (!m_commandLineArguments.isEmpty())
m_launcher->setCommandLineArgs(m_commandLineArguments); m_launcher->setCommandLineArgs(m_commandLineArguments);
const QString runFileName = QString::fromLatin1("%1:\\sys\\bin\\%2.exe").arg(m_installationDrive).arg(m_targetName); const QString runFileName = QString::fromLatin1("%1:\\sys\\bin\\%2.exe").arg(m_installationDrive).arg(m_targetName);
initLauncher(runFileName, m_launcher); initLauncher(runFileName, m_launcher);
const trk::PromptStartCommunicationResult src = const trk::PromptStartCommunicationResult src =

View File

@@ -82,15 +82,14 @@ public:
char installationDrive() const; char installationDrive() const;
void setInstallationDrive(char drive); void setInstallationDrive(char drive);
QStringList packageFileNamesWithTargetInfo() const;
QStringList packageTemplateFileNames() const;
QString appPackageTemplateFileName() const;
QString targetName() const; QString targetName() const;
QString packageFileNameWithTargetInfo() const;
QString symbianPlatform() const;
QString symbianTarget() const;
bool isDebug() const;
QString packageTemplateFileName() const;
QString localExecutableFileName() const; QString localExecutableFileName() const;
QString signedPackage() const; QStringList signedPackages() const;
QString appSignedPackage() const;
const QtVersion *qtVersion() const; const QtVersion *qtVersion() const;
QStringList commandLineArguments() const; QStringList commandLineArguments() const;
@@ -107,6 +106,7 @@ signals:
void targetInformationChanged(); void targetInformationChanged();
void serialPortNameChanged(); void serialPortNameChanged();
private slots: private slots:
void proFileUpdate(Qt4ProjectManager::Internal::Qt4ProFileNode *pro); void proFileUpdate(Qt4ProjectManager::Internal::Qt4ProFileNode *pro);
void updateActiveBuildConfiguration(ProjectExplorer::BuildConfiguration *buildConfiguration); void updateActiveBuildConfiguration(ProjectExplorer::BuildConfiguration *buildConfiguration);
@@ -116,6 +116,9 @@ protected:
virtual bool fromMap(const QVariantMap &map); virtual bool fromMap(const QVariantMap &map);
private: private:
QString symbianPlatform() const;
QString symbianTarget() const;
bool isDebug() const;
ProjectExplorer::ToolChain::ToolChainType toolChainType(ProjectExplorer::BuildConfiguration *configuration) const; ProjectExplorer::ToolChain::ToolChainType toolChainType(ProjectExplorer::BuildConfiguration *configuration) const;
void ctor(); void ctor();
@@ -197,7 +200,6 @@ private:
QString m_serialPortFriendlyName; QString m_serialPortFriendlyName;
QString m_targetName; QString m_targetName;
QStringList m_commandLineArguments; QStringList m_commandLineArguments;
QString m_workingDirectory;
QString m_executableFileName; QString m_executableFileName;
QString m_qtDir; QString m_qtDir;
QString m_qtBinPath; QString m_qtBinPath;

View File

@@ -247,7 +247,7 @@ void S60DeviceRunConfigurationWidget::argumentsEdited(const QString &text)
void S60DeviceRunConfigurationWidget::updateTargetInformation() void S60DeviceRunConfigurationWidget::updateTargetInformation()
{ {
m_sisFileLabel->setText(QDir::toNativeSeparators(m_runConfiguration->signedPackage())); m_sisFileLabel->setText(QDir::toNativeSeparators(m_runConfiguration->appPackageTemplateFileName()));
} }
void S60DeviceRunConfigurationWidget::setInstallationDrive(int index) void S60DeviceRunConfigurationWidget::setInstallationDrive(int index)

View File

@@ -977,6 +977,19 @@ QList<BuildConfigWidget*> Qt4Project::subConfigWidgets()
return subWidgets; return subWidgets;
} }
void Qt4Project::collectLeafProFiles(QList<Qt4ProFileNode *> &list, Qt4ProFileNode *node)
{
if (node->projectType() != Internal::SubDirsTemplate) {
list.append(node);
}
foreach (ProjectNode *n, node->subProjectNodes()) {
Qt4ProFileNode *qt4ProFileNode = qobject_cast<Qt4ProFileNode *>(n);
if (qt4ProFileNode)
collectLeafProFiles(list, qt4ProFileNode);
}
}
void Qt4Project::collectApplicationProFiles(QList<Qt4ProFileNode *> &list, Qt4ProFileNode *node) void Qt4Project::collectApplicationProFiles(QList<Qt4ProFileNode *> &list, Qt4ProFileNode *node)
{ {
if (node->projectType() == Internal::ApplicationTemplate if (node->projectType() == Internal::ApplicationTemplate
@@ -1035,6 +1048,15 @@ void Qt4Project::createApplicationProjects()
} }
} }
QList<Qt4ProFileNode *> Qt4Project::leafProFiles() const
{
QList<Qt4ProFileNode *> list;
if (!rootProjectNode())
return list;
collectLeafProFiles(list, rootProjectNode());
return list;
}
QList<Qt4ProFileNode *> Qt4Project::applicationProFiles() const QList<Qt4ProFileNode *> Qt4Project::applicationProFiles() const
{ {
QList<Qt4ProFileNode *> list; QList<Qt4ProFileNode *> list;

View File

@@ -136,6 +136,7 @@ public:
ProjectExplorer::BuildConfigWidget *createConfigWidget(); ProjectExplorer::BuildConfigWidget *createConfigWidget();
QList<ProjectExplorer::BuildConfigWidget*> subConfigWidgets(); QList<ProjectExplorer::BuildConfigWidget*> subConfigWidgets();
QList<Internal::Qt4ProFileNode *> leafProFiles() const;
QList<Internal::Qt4ProFileNode *> applicationProFiles() const; QList<Internal::Qt4ProFileNode *> applicationProFiles() const;
bool hasApplicationProFile(const QString &path) const; bool hasApplicationProFile(const QString &path) const;
QStringList applicationProFilePathes(const QString &prepend = QString()) const; QStringList applicationProFilePathes(const QString &prepend = QString()) const;
@@ -191,6 +192,7 @@ private:
void updateCodeModel(); void updateCodeModel();
void updateFileList(); void updateFileList();
static void collectLeafProFiles(QList<Internal::Qt4ProFileNode *> &list, Internal::Qt4ProFileNode *node);
static void collectApplicationProFiles(QList<Internal::Qt4ProFileNode *> &list, Internal::Qt4ProFileNode *node); static void collectApplicationProFiles(QList<Internal::Qt4ProFileNode *> &list, Internal::Qt4ProFileNode *node);
static void findProFile(const QString& fileName, Internal::Qt4ProFileNode *root, QList<Internal::Qt4ProFileNode *> &list); static void findProFile(const QString& fileName, Internal::Qt4ProFileNode *root, QList<Internal::Qt4ProFileNode *> &list);
static bool hasSubNode(Internal::Qt4PriFileNode *root, const QString &path); static bool hasSubNode(Internal::Qt4PriFileNode *root, const QString &path);

View File

@@ -74,15 +74,24 @@ void CrashReportState::clear()
} }
struct LauncherPrivate { struct LauncherPrivate {
struct CopyState { struct TransferState {
QString sourceFileName; int currentFileName;
QString destinationFileName;
uint copyFileHandle; uint copyFileHandle;
QScopedPointer<QByteArray> data; QScopedPointer<QByteArray> data;
qint64 position; qint64 position;
QScopedPointer<QFile> localFile; QScopedPointer<QFile> localFile;
}; };
struct CopyState : public TransferState {
QStringList sourceFileNames;
QStringList destinationFileNames;
};
struct DownloadState : public TransferState {
QString sourceFileName;
QString destinationFileName;
};
explicit LauncherPrivate(const TrkDevicePtr &d); explicit LauncherPrivate(const TrkDevicePtr &d);
TrkDevicePtr m_device; TrkDevicePtr m_device;
@@ -94,10 +103,11 @@ struct LauncherPrivate {
Session m_session; // global-ish data (process id, target information) Session m_session; // global-ish data (process id, target information)
CopyState m_copyState; CopyState m_copyState;
CopyState m_downloadState; DownloadState m_downloadState;
QString m_fileName; QString m_fileName;
QStringList m_commandLineArgs; QStringList m_commandLineArgs;
QString m_installFileName; QStringList m_installFileNames;
int m_currentInstallFileName;
int m_verbose; int m_verbose;
Launcher::Actions m_startupActions; Launcher::Actions m_startupActions;
bool m_closeDevice; bool m_closeDevice;
@@ -188,10 +198,11 @@ void Launcher::setFileName(const QString &name)
d->m_fileName = name; d->m_fileName = name;
} }
void Launcher::setCopyFileName(const QString &srcName, const QString &dstName) void Launcher::setCopyFileNames(const QStringList &srcNames, const QStringList &dstNames)
{ {
d->m_copyState.sourceFileName = srcName; d->m_copyState.sourceFileNames = srcNames;
d->m_copyState.destinationFileName = dstName; d->m_copyState.destinationFileNames = dstNames;
d->m_copyState.currentFileName = 0;
} }
void Launcher::setDownloadFileName(const QString &srcName, const QString &dstName) void Launcher::setDownloadFileName(const QString &srcName, const QString &dstName)
@@ -200,9 +211,10 @@ void Launcher::setDownloadFileName(const QString &srcName, const QString &dstNam
d->m_downloadState.destinationFileName = dstName; d->m_downloadState.destinationFileName = dstName;
} }
void Launcher::setInstallFileName(const QString &name) void Launcher::setInstallFileNames(const QStringList &names)
{ {
d->m_installFileName = name; d->m_installFileNames = names;
d->m_currentInstallFileName = 0;
} }
void Launcher::setCommandLineArgs(const QStringList &args) void Launcher::setCommandLineArgs(const QStringList &args)
@@ -255,28 +267,29 @@ bool Launcher::startServer(QString *errorMessage)
str << " Executable=" << d->m_fileName; str << " Executable=" << d->m_fileName;
if (!d->m_commandLineArgs.isEmpty()) if (!d->m_commandLineArgs.isEmpty())
str << " Arguments= " << d->m_commandLineArgs.join(QString(QLatin1Char(' '))); str << " Arguments= " << d->m_commandLineArgs.join(QString(QLatin1Char(' ')));
if (!d->m_copyState.sourceFileName.isEmpty()) for (int i = 0; i < d->m_copyState.sourceFileNames.size(); ++i) {
str << " Package/Source=" << d->m_copyState.sourceFileName; str << " Package/Source=" << d->m_copyState.sourceFileNames.at(i);
if (!d->m_copyState.destinationFileName.isEmpty()) str << " Remote Package/Destination=" << d->m_copyState.destinationFileNames.at(i);
str << " Remote Package/Destination=" << d->m_copyState.destinationFileName; }
if (!d->m_downloadState.sourceFileName.isEmpty()) if (!d->m_downloadState.sourceFileName.isEmpty())
str << " Source=" << d->m_downloadState.sourceFileName; str << " Source=" << d->m_downloadState.sourceFileName;
if (!d->m_downloadState.destinationFileName.isEmpty()) if (!d->m_downloadState.destinationFileName.isEmpty())
str << " Destination=" << d->m_downloadState.destinationFileName; str << " Destination=" << d->m_downloadState.destinationFileName;
if (!d->m_installFileName.isEmpty()) if (!d->m_installFileNames.isEmpty())
str << " Install file=" << d->m_installFileName; foreach (const QString &installFileName, d->m_installFileNames)
str << " Install file=" << installFileName;
logMessage(msg); logMessage(msg);
} }
if (d->m_startupActions & ActionCopy) { if (d->m_startupActions & ActionCopy) {
if (d->m_copyState.sourceFileName.isEmpty()) { if (d->m_copyState.sourceFileNames.isEmpty()) {
qWarning("No local filename given for copying package."); qWarning("No local filename given for copying package.");
return false; return false;
} else if (d->m_copyState.destinationFileName.isEmpty()) { } else if (d->m_copyState.destinationFileNames.isEmpty()) {
qWarning("No remote filename given for copying package."); qWarning("No remote filename given for copying package.");
return false; return false;
} }
} }
if (d->m_startupActions & ActionInstall && d->m_installFileName.isEmpty()) { if (d->m_startupActions & ActionInstall && d->m_installFileNames.isEmpty()) {
qWarning("No package name given for installing."); qWarning("No package name given for installing.");
return false; return false;
} }
@@ -573,15 +586,15 @@ static inline QString msgCannotOpenLocalFile(const QString &fileName, const QStr
void Launcher::handleFileCreation(const TrkResult &result) void Launcher::handleFileCreation(const TrkResult &result)
{ {
if (result.errorCode() || result.data.size() < 6) { if (result.errorCode() || result.data.size() < 6) {
const QString msg = msgCannotOpenRemoteFile(d->m_copyState.destinationFileName, result.errorString()); const QString msg = msgCannotOpenRemoteFile(d->m_copyState.destinationFileNames.at(d->m_copyState.currentFileName), result.errorString());
logMessage(msg); logMessage(msg);
emit canNotCreateFile(d->m_copyState.destinationFileName, msg); emit canNotCreateFile(d->m_copyState.destinationFileNames.at(d->m_copyState.currentFileName), msg);
disconnectTrk(); disconnectTrk();
return; return;
} }
const char *data = result.data.data(); const char *data = result.data.data();
d->m_copyState.copyFileHandle = extractInt(data + 2); d->m_copyState.copyFileHandle = extractInt(data + 2);
const QString localFileName = d->m_copyState.sourceFileName; const QString localFileName = d->m_copyState.sourceFileNames.at(d->m_copyState.currentFileName);
QFile file(localFileName); QFile file(localFileName);
d->m_copyState.position = 0; d->m_copyState.position = 0;
if (!file.open(QIODevice::ReadOnly)) { if (!file.open(QIODevice::ReadOnly)) {
@@ -657,7 +670,7 @@ void Launcher::handleCopy(const TrkResult &result)
{ {
if (result.errorCode() || result.data.size() < 4) { if (result.errorCode() || result.data.size() < 4) {
closeRemoteFile(true); closeRemoteFile(true);
emit canNotWriteFile(d->m_copyState.destinationFileName, result.errorString()); emit canNotWriteFile(d->m_copyState.destinationFileNames.at(d->m_copyState.currentFileName), result.errorString());
disconnectTrk(); disconnectTrk();
} else { } else {
continueCopying(extractShort(result.data.data() + 2)); continueCopying(extractShort(result.data.data() + 2));
@@ -693,7 +706,7 @@ void Launcher::closeRemoteFile(bool failed)
d->m_device->sendTrkMessage(TrkCloseFile, d->m_device->sendTrkMessage(TrkCloseFile,
failed ? TrkCallback() : TrkCallback(this, &Launcher::handleFileCopied), failed ? TrkCallback() : TrkCallback(this, &Launcher::handleFileCopied),
ba); ba);
d->m_copyState.data.reset(); d->m_copyState.data.reset(0);
d->m_copyState.copyFileHandle = 0; d->m_copyState.copyFileHandle = 0;
d->m_copyState.position = 0; d->m_copyState.position = 0;
} }
@@ -701,15 +714,21 @@ void Launcher::closeRemoteFile(bool failed)
void Launcher::handleFileCopied(const TrkResult &result) void Launcher::handleFileCopied(const TrkResult &result)
{ {
if (result.errorCode()) if (result.errorCode())
emit canNotCloseFile(d->m_copyState.destinationFileName, result.errorString()); emit canNotCloseFile(d->m_copyState.destinationFileNames.at(d->m_copyState.currentFileName), result.errorString());
if (d->m_startupActions & ActionInstall)
++d->m_copyState.currentFileName;
if (d->m_startupActions & ActionInstall && d->m_copyState.currentFileName < d->m_copyState.sourceFileNames.size()) {
copyFileToRemote();
} else if (d->m_startupActions & ActionInstall) {
installRemotePackage(); installRemotePackage();
else if (d->m_startupActions & ActionRun) } else if (d->m_startupActions & ActionRun) {
startInferiorIfNeeded(); startInferiorIfNeeded();
else if (d->m_startupActions & ActionDownload) } else if (d->m_startupActions & ActionDownload) {
copyFileFromRemote(); copyFileFromRemote();
else } else {
disconnectTrk(); disconnectTrk();
}
} }
void Launcher::handleCpuType(const TrkResult &result) void Launcher::handleCpuType(const TrkResult &result)
@@ -856,7 +875,7 @@ void Launcher::copyFileToRemote()
emit copyingStarted(); emit copyingStarted();
QByteArray ba; QByteArray ba;
ba.append(char(10)); //kDSFileOpenWrite | kDSFileOpenBinary ba.append(char(10)); //kDSFileOpenWrite | kDSFileOpenBinary
appendString(&ba, d->m_copyState.destinationFileName.toLocal8Bit(), TargetByteOrder, false); appendString(&ba, d->m_copyState.destinationFileNames.at(d->m_copyState.currentFileName).toLocal8Bit(), TargetByteOrder, false);
d->m_device->sendTrkMessage(TrkOpenFile, TrkCallback(this, &Launcher::handleFileCreation), ba); d->m_device->sendTrkMessage(TrkOpenFile, TrkCallback(this, &Launcher::handleFileCreation), ba);
} }
@@ -875,7 +894,7 @@ void Launcher::installRemotePackageSilently()
d->m_currentInstallationStep = InstallationModeSilent; d->m_currentInstallationStep = InstallationModeSilent;
QByteArray ba; QByteArray ba;
ba.append((char)QChar::toUpper((ushort)d->m_installationDrive)); ba.append((char)QChar::toUpper((ushort)d->m_installationDrive));
appendString(&ba, d->m_installFileName.toLocal8Bit(), TargetByteOrder, false); appendString(&ba, d->m_installFileNames.at(d->m_currentInstallFileName).toLocal8Bit(), TargetByteOrder, false);
d->m_device->sendTrkMessage(TrkInstallFile, TrkCallback(this, &Launcher::handleInstallPackageFinished), ba); d->m_device->sendTrkMessage(TrkInstallFile, TrkCallback(this, &Launcher::handleInstallPackageFinished), ba);
} }
@@ -884,7 +903,7 @@ void Launcher::installRemotePackageByUser()
emit installingStarted(); emit installingStarted();
d->m_currentInstallationStep = InstallationModeUser; d->m_currentInstallationStep = InstallationModeUser;
QByteArray ba; QByteArray ba;
appendString(&ba, d->m_installFileName.toLocal8Bit(), TargetByteOrder, false); appendString(&ba, d->m_installFileNames.at(d->m_currentInstallFileName).toLocal8Bit(), TargetByteOrder, false);
d->m_device->sendTrkMessage(TrkInstallFile2, TrkCallback(this, &Launcher::handleInstallPackageFinished), ba); d->m_device->sendTrkMessage(TrkInstallFile2, TrkCallback(this, &Launcher::handleInstallPackageFinished), ba);
} }
@@ -911,13 +930,19 @@ void Launcher::handleInstallPackageFinished(const TrkResult &result)
installRemotePackageByUser(); installRemotePackageByUser();
return; return;
} }
emit canNotInstall(d->m_installFileName, result.errorString()); emit canNotInstall(d->m_installFileNames.at(d->m_currentInstallFileName), result.errorString());
disconnectTrk(); disconnectTrk();
return; return;
} else {
emit installingFinished();
} }
if (d->m_startupActions & ActionRun) {
++d->m_currentInstallFileName;
if (d->m_currentInstallFileName == d->m_installFileNames.size())
emit installingFinished();
if (d->m_startupActions & ActionInstall && d->m_currentInstallFileName < d->m_installFileNames.size()) {
installRemotePackage();
} else if (d->m_startupActions & ActionRun) {
startInferiorIfNeeded(); startInferiorIfNeeded();
} else if (d->m_startupActions & ActionDownload) { } else if (d->m_startupActions & ActionDownload) {
copyFileFromRemote(); copyFileFromRemote();
@@ -973,6 +998,7 @@ void Launcher::startInferiorIfNeeded()
logMessage("Process already 'started'"); logMessage("Process already 'started'");
return; return;
} }
d->m_device->sendTrkMessage(TrkCreateItem, TrkCallback(this, &Launcher::handleCreateProcess), d->m_device->sendTrkMessage(TrkCreateItem, TrkCallback(this, &Launcher::handleCreateProcess),
startProcessMessage(d->m_fileName, d->m_commandLineArgs)); // Create Item startProcessMessage(d->m_fileName, d->m_commandLineArgs)); // Create Item
} }

View File

@@ -89,9 +89,9 @@ public:
void setTrkServerName(const QString &name); void setTrkServerName(const QString &name);
QString trkServerName() const; QString trkServerName() const;
void setFileName(const QString &name); void setFileName(const QString &name);
void setCopyFileName(const QString &srcName, const QString &dstName); void setCopyFileNames(const QStringList &srcName, const QStringList &dstName);
void setDownloadFileName(const QString &srcName, const QString &dstName); void setDownloadFileName(const QString &srcName, const QString &dstName);
void setInstallFileName(const QString &name); void setInstallFileNames(const QStringList &names);
void setCommandLineArgs(const QStringList &args); void setCommandLineArgs(const QStringList &args);
bool startServer(QString *errorMessage); bool startServer(QString *errorMessage);
void setInstallationMode(InstallationMode installation); void setInstallationMode(InstallationMode installation);