S60: Work towards new toolchains

Factor out the initialization setting up the environment and headers in
the RVCT/GCCE toolchains.
Modify the RunControl to be able to support different package
building/signing processes.
This commit is contained in:
Friedemann Kleint
2009-11-13 15:47:35 +01:00
parent 7e655aab11
commit e35a754dc9
14 changed files with 381 additions and 127 deletions

View File

@@ -123,6 +123,10 @@ QString ToolChain::toolChainName(ToolChainType tc)
return QCoreApplication::translate("ToolChain", "WINSCW"); return QCoreApplication::translate("ToolChain", "WINSCW");
case GCCE: case GCCE:
return QCoreApplication::translate("ToolChain", "GCCE"); return QCoreApplication::translate("ToolChain", "GCCE");
case GCCE_GNUPOC:
return QCoreApplication::translate("ToolChain", "GCCE/GnuPoc");
case RVCT_ARMV6_GNUPOC:
return QCoreApplication::translate("ToolChain", "RVCT (ARMV6)/GnuPoc");
case RVCT_ARMV5: case RVCT_ARMV5:
return QCoreApplication::translate("ToolChain", "RVCT (ARMV5)"); return QCoreApplication::translate("ToolChain", "RVCT (ARMV5)");
case RVCT_ARMV6: case RVCT_ARMV6:

View File

@@ -84,7 +84,9 @@ public:
RVCT_ARMV5 = 7, RVCT_ARMV5 = 7,
RVCT_ARMV6 = 8, RVCT_ARMV6 = 8,
GCC_MAEMO = 9, GCC_MAEMO = 9,
LAST_VALID = 10, GCCE_GNUPOC = 10,
RVCT_ARMV6_GNUPOC = 11,
LAST_VALID = 11,
OTHER = 200, OTHER = 200,
UNKNOWN = 201, UNKNOWN = 201,
INVALID = 202 INVALID = 202

View File

@@ -30,25 +30,32 @@
#include "gccetoolchain.h" #include "gccetoolchain.h"
#include "qt4project.h" #include "qt4project.h"
#include <utils/qtcassert.h>
#include <QtCore/QDir> #include <QtCore/QDir>
#include <QtDebug> #include <QtCore/QtDebug>
enum { debug = 0 };
using namespace ProjectExplorer; using namespace ProjectExplorer;
using namespace Qt4ProjectManager::Internal; using namespace Qt4ProjectManager::Internal;
GCCEToolChain::GCCEToolChain(S60Devices::Device device, const QString &gcceCommand) GCCEToolChain::GCCEToolChain(const S60Devices::Device &device,
: GccToolChain(gcceCommand), const QString &gcceCommand,
m_deviceId(device.id), ProjectExplorer::ToolChain::ToolChainType type) :
m_deviceName(device.name), GccToolChain(gcceCommand),
m_deviceRoot(device.epocRoot), m_mixin(device),
m_type(type),
m_gcceCommand(gcceCommand) m_gcceCommand(gcceCommand)
{ {
QTC_ASSERT(m_type == ProjectExplorer::ToolChain::GCCE || m_type == ProjectExplorer::ToolChain::GCCE_GNUPOC, return)
if (debug)
qDebug() << "GCCEToolChain on" << m_type << m_mixin.device();
} }
ToolChain::ToolChainType GCCEToolChain::type() const ToolChain::ToolChainType GCCEToolChain::type() const
{ {
return ToolChain::GCCE; return m_type;
} }
QByteArray GCCEToolChain::predefinedMacros() QByteArray GCCEToolChain::predefinedMacros()
@@ -66,34 +73,44 @@ QList<HeaderPath> GCCEToolChain::systemHeaderPaths()
{ {
if (m_systemHeaderPaths.isEmpty()) { if (m_systemHeaderPaths.isEmpty()) {
GccToolChain::systemHeaderPaths(); GccToolChain::systemHeaderPaths();
m_systemHeaderPaths.append(HeaderPath(QString("%1\\epoc32\\include").arg(m_deviceRoot), HeaderPath::GlobalHeaderPath)); switch (m_type) {
m_systemHeaderPaths.append(HeaderPath(QString("%1\\epoc32\\include\\stdapis").arg(m_deviceRoot), HeaderPath::GlobalHeaderPath)); case ProjectExplorer::ToolChain::GCCE:
m_systemHeaderPaths.append(HeaderPath(QString("%1\\epoc32\\include\\stdapis\\sys").arg(m_deviceRoot), HeaderPath::GlobalHeaderPath)); m_systemHeaderPaths += m_mixin.epocHeaderPaths();
m_systemHeaderPaths.append(HeaderPath(QString("%1\\epoc32\\include\\variant").arg(m_deviceRoot), HeaderPath::GlobalHeaderPath)); break;
case ProjectExplorer::ToolChain::GCCE_GNUPOC:
m_systemHeaderPaths += m_mixin.gnuPocHeaderPaths();
break;
default:
break;
}
} }
return m_systemHeaderPaths; return m_systemHeaderPaths;
} }
void GCCEToolChain::addToEnvironment(ProjectExplorer::Environment &env) void GCCEToolChain::addToEnvironment(ProjectExplorer::Environment &env)
{ {
env.prependOrSetPath(QString("%1\\epoc32\\tools").arg(m_deviceRoot)); // e.g. make.exe switch (m_type) {
env.prependOrSetPath(QString("%1\\epoc32\\gcc\\bin").arg(m_deviceRoot)); // e.g. gcc.exe case ProjectExplorer::ToolChain::GCCE:
m_mixin.addEpocToEnvironment(&env);
env.prependOrSetPath(QFileInfo(m_gcceCommand).absolutePath()); env.prependOrSetPath(QFileInfo(m_gcceCommand).absolutePath());
env.set("EPOCDEVICE", QString("%1:%2").arg(m_deviceId, m_deviceName)); case ProjectExplorer::ToolChain::GCCE_GNUPOC:
env.set("EPOCROOT", S60Devices::cleanedRootPath(m_deviceRoot)); break;
default:
m_mixin.addGnuPocToEnvironment(&env);
break;
}
} }
QString GCCEToolChain::makeCommand() const QString GCCEToolChain::makeCommand() const
{ {
return "make"; return QLatin1String("make");
} }
bool GCCEToolChain::equals(ToolChain *other) const bool GCCEToolChain::equals(ToolChain *otherIn) const
{ {
GCCEToolChain *otherGCCE = static_cast<GCCEToolChain *>(other); if (otherIn->type() != type())
return (other->type() == type() return false;
&& m_deviceId == otherGCCE->m_deviceId const GCCEToolChain *other = static_cast<const GCCEToolChain *>(otherIn);
&& m_deviceName == otherGCCE->m_deviceName return m_mixin == other->m_mixin
&& m_deviceRoot == otherGCCE->m_deviceRoot && m_gcceCommand == other->m_gcceCommand;
&& m_gcceCommand == otherGCCE->m_gcceCommand);
} }

View File

@@ -40,20 +40,23 @@ namespace Internal {
class GCCEToolChain : public ProjectExplorer::GccToolChain class GCCEToolChain : public ProjectExplorer::GccToolChain
{ {
public: public:
GCCEToolChain(S60Devices::Device device, const QString &gcceCommand); explicit GCCEToolChain(const S60Devices::Device &device,
const QString &gcceCommand,
ProjectExplorer::ToolChain::ToolChainType type);
QByteArray predefinedMacros(); QByteArray predefinedMacros();
QList<ProjectExplorer::HeaderPath> systemHeaderPaths(); virtual QList<ProjectExplorer::HeaderPath> systemHeaderPaths();
void addToEnvironment(ProjectExplorer::Environment &env); virtual void addToEnvironment(ProjectExplorer::Environment &env);
ProjectExplorer::ToolChain::ToolChainType type() const; virtual ProjectExplorer::ToolChain::ToolChainType type() const;
QString makeCommand() const; virtual QString makeCommand() const;
protected: protected:
bool equals(ToolChain *other) const; virtual bool equals(ToolChain *other) const;
private: private:
QString m_deviceId; const S60ToolChainMixin m_mixin;
QString m_deviceName; const ProjectExplorer::ToolChain::ToolChainType m_type;
QString m_deviceRoot; const QString m_gcceCommand;
QString m_gcceCommand;
}; };
} // namespace Internal } // namespace Internal

View File

@@ -33,12 +33,13 @@
using namespace ProjectExplorer; using namespace ProjectExplorer;
using namespace Qt4ProjectManager::Internal; using namespace Qt4ProjectManager::Internal;
RVCTToolChain::RVCTToolChain(S60Devices::Device device, ToolChain::ToolChainType type) RVCTToolChain::RVCTToolChain(const S60Devices::Device &device, ToolChain::ToolChainType type) :
: m_versionUpToDate(false), m_mixin(device),
m_deviceId(device.id), m_type(type),
m_deviceName(device.name), m_versionUpToDate(false),
m_deviceRoot(device.epocRoot), m_major(0),
m_type(type) m_minor(0),
m_build(0)
{ {
} }
@@ -109,31 +110,40 @@ QList<HeaderPath> RVCTToolChain::systemHeaderPaths()
QString rvctInclude = env.value(QString::fromLatin1("RVCT%1%2INC").arg(m_major).arg(m_minor)); QString rvctInclude = env.value(QString::fromLatin1("RVCT%1%2INC").arg(m_major).arg(m_minor));
if (!rvctInclude.isEmpty()) if (!rvctInclude.isEmpty())
m_systemHeaderPaths.append(HeaderPath(rvctInclude, HeaderPath::GlobalHeaderPath)); m_systemHeaderPaths.append(HeaderPath(rvctInclude, HeaderPath::GlobalHeaderPath));
m_systemHeaderPaths.append(HeaderPath(QString("%1\\epoc32\\include").arg(m_deviceRoot), HeaderPath::GlobalHeaderPath)); switch (m_type) {
m_systemHeaderPaths.append(HeaderPath(QString("%1\\epoc32\\include\\stdapis").arg(m_deviceRoot), HeaderPath::GlobalHeaderPath)); case ProjectExplorer::ToolChain::RVCT_ARMV6_GNUPOC:
m_systemHeaderPaths.append(HeaderPath(QString("%1\\epoc32\\include\\stdapis\\sys").arg(m_deviceRoot), HeaderPath::GlobalHeaderPath)); m_systemHeaderPaths += m_mixin.gnuPocHeaderPaths();
m_systemHeaderPaths.append(HeaderPath(QString("%1\\epoc32\\include\\variant").arg(m_deviceRoot), HeaderPath::GlobalHeaderPath)); break;
default:
m_systemHeaderPaths += m_mixin.epocHeaderPaths();
break;
}
} }
return m_systemHeaderPaths; return m_systemHeaderPaths;
} }
void RVCTToolChain::addToEnvironment(ProjectExplorer::Environment &env) void RVCTToolChain::addToEnvironment(ProjectExplorer::Environment &env)
{ {
env.prependOrSetPath(QString("%1\\epoc32\\tools").arg(m_deviceRoot)); // e.g. make.exe switch (m_type) {
env.prependOrSetPath(QString("%1\\epoc32\\gcc\\bin").arg(m_deviceRoot)); // e.g. gcc.exe case ProjectExplorer::ToolChain::RVCT_ARMV6_GNUPOC:
env.set("EPOCDEVICE", QString("%1:%2").arg(m_deviceId, m_deviceName)); m_mixin.addGnuPocToEnvironment(&env);
env.set("EPOCROOT", S60Devices::cleanedRootPath(m_deviceRoot)); break;
default:
m_mixin.addEpocToEnvironment(&env);
break;
}
} }
QString RVCTToolChain::makeCommand() const QString RVCTToolChain::makeCommand() const
{ {
return "make"; return QLatin1String("make");
} }
bool RVCTToolChain::equals(ToolChain *other) const bool RVCTToolChain::equals(ToolChain *otherIn) const
{ {
return (other->type() == type() if (otherIn->type() != type())
&& m_deviceId == static_cast<RVCTToolChain *>(other)->m_deviceId return false;
&& m_deviceName == static_cast<RVCTToolChain *>(other)->m_deviceName); const RVCTToolChain *other = static_cast<const RVCTToolChain *>(otherIn);
return other->m_mixin == m_mixin;
} }

View File

@@ -40,7 +40,8 @@ namespace Internal {
class RVCTToolChain : public ProjectExplorer::ToolChain class RVCTToolChain : public ProjectExplorer::ToolChain
{ {
public: public:
RVCTToolChain(S60Devices::Device device, ProjectExplorer::ToolChain::ToolChainType type); explicit RVCTToolChain(const S60Devices::Device &device,
ProjectExplorer::ToolChain::ToolChainType type);
virtual QByteArray predefinedMacros(); virtual QByteArray predefinedMacros();
QList<ProjectExplorer::HeaderPath> systemHeaderPaths(); QList<ProjectExplorer::HeaderPath> systemHeaderPaths();
void addToEnvironment(ProjectExplorer::Environment &env); void addToEnvironment(ProjectExplorer::Environment &env);
@@ -52,14 +53,13 @@ protected:
private: private:
void updateVersion(); void updateVersion();
const S60ToolChainMixin m_mixin;
const ProjectExplorer::ToolChain::ToolChainType m_type;
bool m_versionUpToDate; bool m_versionUpToDate;
int m_major; int m_major;
int m_minor; int m_minor;
int m_build; int m_build;
QString m_deviceId;
QString m_deviceName;
QString m_deviceRoot;
ProjectExplorer::ToolChain::ToolChainType m_type;
QByteArray m_predefinedMacros; QByteArray m_predefinedMacros;
QList<ProjectExplorer::HeaderPath> m_systemHeaderPaths; QList<ProjectExplorer::HeaderPath> m_systemHeaderPaths;
}; };

View File

@@ -56,6 +56,8 @@
using namespace ProjectExplorer; using namespace ProjectExplorer;
using namespace Qt4ProjectManager::Internal; using namespace Qt4ProjectManager::Internal;
enum { debug = 0 };
// Format information about a file // Format information about a file
static QString lsFile(const QString &f) static QString lsFile(const QString &f)
{ {
@@ -317,13 +319,18 @@ void S60DeviceRunConfiguration::updateTarget()
m_packageTemplateFileName = QDir::cleanPath( m_packageTemplateFileName = QDir::cleanPath(
m_workingDir + QLatin1Char('/') + m_targetName + QLatin1String("_template.pkg")); m_workingDir + QLatin1Char('/') + m_targetName + QLatin1String("_template.pkg"));
ToolChain::ToolChainType toolchain = pro->toolChainType(pro->activeBuildConfiguration()); switch (pro->toolChainType(pro->activeBuildConfiguration())) {
if (toolchain == ToolChain::GCCE) case ToolChain::GCCE:
case ToolChain::GCCE_GNUPOC:
m_platform = QLatin1String("gcce"); m_platform = QLatin1String("gcce");
else if (toolchain == ToolChain::RVCT_ARMV5) break;
case ToolChain::RVCT_ARMV5:
m_platform = QLatin1String("armv5"); m_platform = QLatin1String("armv5");
else break;
default: // including ToolChain::RVCT_ARMV6_GNUPOC:
m_platform = QLatin1String("armv6"); m_platform = QLatin1String("armv6");
break;
}
if (projectBuildConfiguration & QtVersion::DebugBuild) if (projectBuildConfiguration & QtVersion::DebugBuild)
m_target = QLatin1String("udeb"); m_target = QLatin1String("udeb");
else else
@@ -396,8 +403,9 @@ QSharedPointer<RunConfiguration> S60DeviceRunConfigurationFactory::create(Projec
S60DeviceRunControlBase::S60DeviceRunControlBase(const QSharedPointer<RunConfiguration> &runConfiguration) : S60DeviceRunControlBase::S60DeviceRunControlBase(const QSharedPointer<RunConfiguration> &runConfiguration) :
RunControl(runConfiguration), RunControl(runConfiguration),
m_toolChain(ProjectExplorer::ToolChain::INVALID),
m_makesis(new QProcess(this)), m_makesis(new QProcess(this)),
m_signsis(new QProcess(this)), m_signsis(0),
m_launcher(0) m_launcher(0)
{ {
connect(m_makesis, SIGNAL(readyReadStandardError()), connect(m_makesis, SIGNAL(readyReadStandardError()),
@@ -409,21 +417,12 @@ S60DeviceRunControlBase::S60DeviceRunControlBase(const QSharedPointer<RunConfigu
connect(m_makesis, SIGNAL(finished(int,QProcess::ExitStatus)), connect(m_makesis, SIGNAL(finished(int,QProcess::ExitStatus)),
this, SLOT(makesisProcessFinished())); this, SLOT(makesisProcessFinished()));
connect(m_signsis, SIGNAL(readyReadStandardError()),
this, SLOT(readStandardError()));
connect(m_signsis, SIGNAL(readyReadStandardOutput()),
this, SLOT(readStandardOutput()));
connect(m_signsis, SIGNAL(error(QProcess::ProcessError)),
this, SLOT(signsisProcessFailed()));
connect(m_signsis, SIGNAL(finished(int,QProcess::ExitStatus)),
this, SLOT(signsisProcessFinished()));
Qt4Project *project = qobject_cast<Qt4Project *>(runConfiguration->project()); Qt4Project *project = qobject_cast<Qt4Project *>(runConfiguration->project());
QTC_ASSERT(project, return); QTC_ASSERT(project, return);
QSharedPointer<S60DeviceRunConfiguration> s60runConfig = runConfiguration.objectCast<S60DeviceRunConfiguration>(); QSharedPointer<S60DeviceRunConfiguration> s60runConfig = runConfiguration.objectCast<S60DeviceRunConfiguration>();
QTC_ASSERT(s60runConfig, return); QTC_ASSERT(s60runConfig, return);
m_toolChain = s60runConfig->toolChainType();
m_serialPortName = s60runConfig->serialPortName(); m_serialPortName = s60runConfig->serialPortName();
m_serialPortFriendlyName = S60Manager::instance()->serialDeviceLister()->friendlyNameForPort(m_serialPortName); m_serialPortFriendlyName = S60Manager::instance()->serialDeviceLister()->friendlyNameForPort(m_serialPortName);
m_communicationType = s60runConfig->communicationType(); m_communicationType = s60runConfig->communicationType();
@@ -437,13 +436,42 @@ S60DeviceRunControlBase::S60DeviceRunControlBase(const QSharedPointer<RunConfigu
m_useCustomSignature = (s60runConfig->signingMode() == S60DeviceRunConfiguration::SignCustom); m_useCustomSignature = (s60runConfig->signingMode() == S60DeviceRunConfiguration::SignCustom);
m_customSignaturePath = s60runConfig->customSignaturePath(); m_customSignaturePath = s60runConfig->customSignaturePath();
m_customKeyPath = s60runConfig->customKeyPath(); m_customKeyPath = s60runConfig->customKeyPath();
m_toolsDirectory = S60Manager::instance()->deviceForQtVersion(
project->qtVersion(project->activeBuildConfiguration())).toolsRoot ProjectExplorer::BuildConfiguration *const activeBuildConf = project->activeBuildConfiguration();
+ "/epoc32/tools"; const S60Devices::Device device = S60Manager::instance()->deviceForQtVersion(project->qtVersion(activeBuildConf));
m_executableFileName = lsFile(s60runConfig->localExecutableFileName()); switch (m_toolChain) {
case ProjectExplorer::ToolChain::GCCE_GNUPOC:
case ProjectExplorer::ToolChain::RVCT_ARMV6_GNUPOC: {
// 'sis' is a make target here. Set up with correct environment
ProjectExplorer::ToolChain *toolchain = project->toolChain(activeBuildConf);
m_makesisTool = toolchain->makeCommand();
m_toolsDirectory = device.epocRoot + QLatin1String("/epoc32/tools");
ProjectExplorer::Environment env = ProjectExplorer::Environment::systemEnvironment();
toolchain->addToEnvironment(env);
m_makesis->setEnvironment(env.toStringList());
}
break;
default:
m_toolsDirectory = device.toolsRoot + QLatin1String("/epoc32/tools");
m_makesisTool = m_toolsDirectory + "/makesis.exe"; m_makesisTool = m_toolsDirectory + "/makesis.exe";
// Set up signing packages
m_signsis = new QProcess(this);
connect(m_signsis, SIGNAL(readyReadStandardError()),
this, SLOT(readStandardError()));
connect(m_signsis, SIGNAL(readyReadStandardOutput()),
this, SLOT(readStandardOutput()));
connect(m_signsis, SIGNAL(error(QProcess::ProcessError)),
this, SLOT(signsisProcessFailed()));
connect(m_signsis, SIGNAL(finished(int,QProcess::ExitStatus)),
this, SLOT(signsisProcessFinished()));
break;
}
m_executableFileName = s60runConfig->localExecutableFileName();
m_packageFilePath = s60runConfig->packageFileName(); m_packageFilePath = s60runConfig->packageFileName();
m_packageFile = QFileInfo(m_packageFilePath).fileName(); m_packageFile = QFileInfo(m_packageFilePath).fileName();
if (debug)
qDebug() << "S60DeviceRunControlBase" << m_targetName << ProjectExplorer::ToolChain::toolChainName(m_toolChain)
<< m_serialPortName << m_communicationType << m_workingDirectory;
} }
S60DeviceRunControlBase::~S60DeviceRunControlBase() S60DeviceRunControlBase::~S60DeviceRunControlBase()
@@ -464,7 +492,7 @@ void S60DeviceRunControlBase::start()
} }
emit addToOutputWindow(this, tr("Creating %1.sisx ...").arg(QDir::toNativeSeparators(m_baseFileName))); emit addToOutputWindow(this, tr("Creating %1.sisx ...").arg(QDir::toNativeSeparators(m_baseFileName)));
emit addToOutputWindow(this, tr("Executable file: %1").arg(m_executableFileName)); emit addToOutputWindow(this, tr("Executable file: %1").arg(lsFile(m_executableFileName)));
QString errorMessage; QString errorMessage;
QString settingsCategory; QString settingsCategory;
@@ -478,14 +506,27 @@ void S60DeviceRunControlBase::start()
return; return;
} }
QStringList makeSisArgs;
switch (m_toolChain) {
case ProjectExplorer::ToolChain::GCCE_GNUPOC:
case ProjectExplorer::ToolChain::RVCT_ARMV6_GNUPOC:
makeSisArgs.push_back(QLatin1String("sis"));
break;
default:
makeSisArgs.push_back(m_packageFile);
if (!createPackageFileFromTemplate(&errorMessage)) { if (!createPackageFileFromTemplate(&errorMessage)) {
error(this, errorMessage); error(this, errorMessage);
emit finished(); emit finished();
return; return;
} }
break;
}
m_makesis->setWorkingDirectory(m_workingDirectory); m_makesis->setWorkingDirectory(m_workingDirectory);
emit addToOutputWindow(this, tr("%1 %2").arg(QDir::toNativeSeparators(m_makesisTool), m_packageFile)); emit addToOutputWindow(this, tr("%1 %2").arg(QDir::toNativeSeparators(m_makesisTool), m_packageFile));
m_makesis->start(m_makesisTool, QStringList(m_packageFile), QIODevice::ReadOnly); if (debug)
qDebug() << m_makesisTool << makeSisArgs << m_workingDirectory;
m_makesis->start(m_makesisTool, makeSisArgs, QIODevice::ReadOnly);
} }
static inline void stopProcess(QProcess *p) static inline void stopProcess(QProcess *p)
@@ -551,7 +592,7 @@ bool S60DeviceRunControlBase::createPackageFileFromTemplate(QString *errorMessag
void S60DeviceRunControlBase::makesisProcessFailed() void S60DeviceRunControlBase::makesisProcessFailed()
{ {
processFailed("makesis.exe", m_makesis->error()); processFailed(m_makesisTool, m_makesis->error());
} }
void S60DeviceRunControlBase::makesisProcessFinished() void S60DeviceRunControlBase::makesisProcessFinished()
@@ -562,6 +603,19 @@ void S60DeviceRunControlBase::makesisProcessFinished()
emit finished(); emit finished();
return; return;
} }
switch (m_toolChain) {
case ProjectExplorer::ToolChain::GCCE_GNUPOC:
case ProjectExplorer::ToolChain::RVCT_ARMV6_GNUPOC:
startDeployment();
break;
default:
startSigning();
break;
}
}
void S60DeviceRunControlBase::startSigning()
{
QString signsisTool = m_toolsDirectory + QLatin1String("/signsis.exe"); QString signsisTool = m_toolsDirectory + QLatin1String("/signsis.exe");
QString sisFile = QFileInfo(m_baseFileName + QLatin1String(".sis")).fileName(); QString sisFile = QFileInfo(m_baseFileName + QLatin1String(".sis")).fileName();
QString sisxFile = QFileInfo(m_baseFileName + QLatin1String(".sisx")).fileName(); QString sisxFile = QFileInfo(m_baseFileName + QLatin1String(".sisx")).fileName();
@@ -589,8 +643,13 @@ void S60DeviceRunControlBase::signsisProcessFinished()
error(this, tr("An error occurred while creating the package.")); error(this, tr("An error occurred while creating the package."));
stop(); stop();
emit finished(); emit finished();
return; } else {
startDeployment();
} }
}
void S60DeviceRunControlBase::startDeployment()
{
m_launcher = new trk::Launcher(); m_launcher = new trk::Launcher();
connect(m_launcher, SIGNAL(finished()), this, SLOT(launcherFinished())); connect(m_launcher, SIGNAL(finished()), this, SLOT(launcherFinished()));
connect(m_launcher, SIGNAL(canNotConnect(QString)), this, SLOT(printConnectFailed(QString))); connect(m_launcher, SIGNAL(canNotConnect(QString)), this, SLOT(printConnectFailed(QString)));

View File

@@ -127,8 +127,11 @@ public:
QSharedPointer<ProjectExplorer::RunConfiguration> create(ProjectExplorer::Project *project, const QString &type); QSharedPointer<ProjectExplorer::RunConfiguration> create(ProjectExplorer::Project *project, const QString &type);
}; };
/* S60DeviceRunControlBase: Builds and signs package and starts launcher /* S60DeviceRunControlBase: Builds the package and starts launcher
* to deploy. Subclasses can configure the launcher to run or start a debugger. */ * to deploy. Subclasses can configure the launcher to run or start a debugger.
* Building the package comprises for:
* GnuPoc: run 'make sis'
* Other: run the makesis.exe tool, run signsis */
class S60DeviceRunControlBase : public ProjectExplorer::RunControl class S60DeviceRunControlBase : public ProjectExplorer::RunControl
{ {
@@ -175,7 +178,10 @@ private slots:
private: private:
bool createPackageFileFromTemplate(QString *errorMessage); bool createPackageFileFromTemplate(QString *errorMessage);
void startSigning();
void startDeployment();
ProjectExplorer::ToolChain::ToolChainType m_toolChain;
QString m_serialPortName; QString m_serialPortName;
QString m_serialPortFriendlyName; QString m_serialPortFriendlyName;
int m_communicationType; int m_communicationType;

View File

@@ -28,6 +28,9 @@
**************************************************************************/ **************************************************************************/
#include "s60devices.h" #include "s60devices.h"
#include "gccetoolchain.h"
#include <projectexplorer/environment.h>
#include <QtCore/QSettings> #include <QtCore/QSettings>
#include <QtCore/QXmlStreamReader> #include <QtCore/QXmlStreamReader>
@@ -81,10 +84,47 @@ S60Devices::S60Devices(QObject *parent)
{ {
} }
// GNU-Poc stuff
static const char *gnuPocRootC = "GNUPOC_ROOT";
static inline QString msgEnvVarNotSet(const char *var)
{
return QString::fromLatin1("The environment variable %1 is not set.").arg(QLatin1String(var));
}
static inline QString msgEnvVarDirNotExist(const QString &dir, const char *var)
{
return QString::fromLatin1("The directory %1 pointed to by the environment variable %2 is not set.").arg(dir, QLatin1String(var));
}
bool S60Devices::readLinux() bool S60Devices::readLinux()
{ {
m_errorString = QLatin1String("not implemented."); // Detect GNUPOC_ROOT/EPOC ROOT
const QByteArray gnuPocRootA = qgetenv(gnuPocRootC);
if (gnuPocRootA.isEmpty()) {
m_errorString = msgEnvVarNotSet(gnuPocRootC);
return false; return false;
}
const QDir gnuPocRootDir(QString::fromLocal8Bit(gnuPocRootA));
if (!gnuPocRootDir.exists()) {
m_errorString = msgEnvVarDirNotExist(gnuPocRootDir.absolutePath(), gnuPocRootC);
return false;
}
const QDir epocDir(gnuPocRootDir.absolutePath() + QLatin1String("/symbian-sdks/5.0"));
if (!epocDir.exists()) {
m_errorString = QString::fromLatin1("EPOC could not be found at %1.").arg(epocDir.absolutePath());
return false;
}
// Check Qt
Device device;
device.id = device.name = QLatin1String("GnuPoc");
device.epocRoot = epocDir.absolutePath();
device.toolsRoot = gnuPocRootDir.absolutePath();
device.isDefault = true;
m_devices.push_back(device);
return true;
} }
bool S60Devices::read() bool S60Devices::read()
@@ -162,6 +202,8 @@ bool S60Devices::readWin()
bool S60Devices::detectQtForDevices() bool S60Devices::detectQtForDevices()
{ {
for (int i = 0; i < m_devices.size(); ++i) { for (int i = 0; i < m_devices.size(); ++i) {
if (!m_devices[i].qt.isEmpty())
continue;
QFile qtDll(QString("%1/epoc32/release/winscw/udeb/QtCore.dll").arg(m_devices[i].epocRoot)); QFile qtDll(QString("%1/epoc32/release/winscw/udeb/QtCore.dll").arg(m_devices[i].epocRoot));
if (!qtDll.exists() || !qtDll.open(QIODevice::ReadOnly)) { if (!qtDll.exists() || !qtDll.open(QIODevice::ReadOnly)) {
m_devices[i].qt = QString(); m_devices[i].qt = QString();
@@ -237,6 +279,57 @@ QString S60Devices::cleanedRootPath(const QString &deviceRoot)
return path; return path;
} }
// S60ToolChainMixin
S60ToolChainMixin::S60ToolChainMixin(const S60Devices::Device &d) :
m_device(d)
{
}
const S60Devices::Device & S60ToolChainMixin::device() const
{
return m_device;
}
bool S60ToolChainMixin::equals(const S60ToolChainMixin &rhs) const
{
return m_device.id == rhs.m_device.id
&& m_device.name == rhs.m_device.name;
}
QList<ProjectExplorer::HeaderPath> S60ToolChainMixin::epocHeaderPaths() const
{
QList<ProjectExplorer::HeaderPath> rc;
rc << ProjectExplorer::HeaderPath(m_device.epocRoot + QLatin1String("\\epoc32\\include"),
ProjectExplorer::HeaderPath::GlobalHeaderPath)
<< ProjectExplorer::HeaderPath(m_device.epocRoot + QLatin1String("\\epoc32\\include\\stdapis"),
ProjectExplorer::HeaderPath::GlobalHeaderPath)
<< ProjectExplorer::HeaderPath(m_device.epocRoot + QLatin1String("\\epoc32\\include\\stdapis\\sys"),
ProjectExplorer::HeaderPath::GlobalHeaderPath)
<< ProjectExplorer::HeaderPath(m_device.epocRoot + QLatin1String("\\epoc32\\include\\variant"),
ProjectExplorer::HeaderPath::GlobalHeaderPath);
return rc;
}
void S60ToolChainMixin::addEpocToEnvironment(ProjectExplorer::Environment *env) const
{
env->prependOrSetPath(m_device.epocRoot + QLatin1String("\\epoc32\\tools")); // e.g. make.exe
env->prependOrSetPath(m_device.epocRoot + QLatin1String("\\epoc32\\gcc\\bin")); // e.g. gcc.exe
env->set(QLatin1String("EPOCDEVICE"), m_device.id + QLatin1Char(':') + m_device.name);
env->set(QLatin1String("EPOCROOT"), S60Devices::cleanedRootPath(m_device.epocRoot));
}
QList<ProjectExplorer::HeaderPath> S60ToolChainMixin::gnuPocHeaderPaths() const
{
return QList<ProjectExplorer::HeaderPath>(); // TODO:
}
void S60ToolChainMixin::addGnuPocToEnvironment(ProjectExplorer::Environment *env) const
{
env->prependOrSetPath(m_device.toolsRoot + QLatin1String("/bin"));
// # trailing "/" is required!
env->set(QLatin1String("EPOCROOT"), m_device.epocRoot + QLatin1Char('/'));
}
QDebug operator<<(QDebug db, const S60Devices::Device &d) QDebug operator<<(QDebug db, const S60Devices::Device &d)
{ {
QDebug nospace = db.nospace(); QDebug nospace = db.nospace();

View File

@@ -30,6 +30,8 @@
#ifndef S60DEVICES_H #ifndef S60DEVICES_H
#define S60DEVICES_H #define S60DEVICES_H
#include <projectexplorer/toolchain.h>
#include <QtCore/QObject> #include <QtCore/QObject>
#include <QtCore/QString> #include <QtCore/QString>
#include <QtCore/QList> #include <QtCore/QList>
@@ -76,6 +78,35 @@ private:
QList<Device> m_devices; QList<Device> m_devices;
}; };
/* Mixin for the toolchains with convenience functions for EPOC
* (Windows) and GnuPoc (Linux). */
class S60ToolChainMixin {
Q_DISABLE_COPY(S60ToolChainMixin)
public:
explicit S60ToolChainMixin(const S60Devices::Device &device);
const S60Devices::Device &device() const;
// Epoc
QList<ProjectExplorer::HeaderPath> epocHeaderPaths() const;
void addEpocToEnvironment(ProjectExplorer::Environment *env) const;
// GnuPoc
QList<ProjectExplorer::HeaderPath> gnuPocHeaderPaths() const;
void addGnuPocToEnvironment(ProjectExplorer::Environment *env) const;
bool equals(const S60ToolChainMixin &rhs) const;
private:
const S60Devices::Device m_device;
};
inline bool operator==(const S60ToolChainMixin &s1, const S60ToolChainMixin &s2)
{ return s1.equals(s2); }
inline bool operator!=(const S60ToolChainMixin &s1, const S60ToolChainMixin &s2)
{ return !s1.equals(s2); }
QDebug operator<<(QDebug dbg, const S60Devices::Device &d); QDebug operator<<(QDebug dbg, const S60Devices::Device &d);
QDebug operator<<(QDebug dbg, const S60Devices &d); QDebug operator<<(QDebug dbg, const S60Devices &d);

View File

@@ -155,6 +155,15 @@ QString S60Manager::deviceIdFromDetectionSource(const QString &autoDetectionSour
return QString(); return QString();
} }
static inline QString qmakeFromQtDir(const QString &qtDir)
{
QString qmake = qtDir + QLatin1String("/bin/qmake");
#ifdef Q_OS_WIN
qmake += QLatin1String(".exe");
#endif
return qmake;
}
void S60Manager::updateQtVersions() void S60Manager::updateQtVersions()
{ {
// This assumes that the QtVersionManager has already read // This assumes that the QtVersionManager has already read
@@ -176,11 +185,11 @@ void S60Manager::updateQtVersions()
} }
} }
if (deviceVersion) { if (deviceVersion) {
deviceVersion->setQMakeCommand(device.qt+"/bin/qmake.exe"); deviceVersion->setQMakeCommand(qmakeFromQtDir(device.qt));
deviceVersion->setName(QString("%1 (Qt %2)").arg(device.id, deviceVersion->qtVersionString())); deviceVersion->setName(QString("%1 (Qt %2)").arg(device.id, deviceVersion->qtVersionString()));
handledVersions.append(deviceVersion); handledVersions.append(deviceVersion);
} else { } else {
deviceVersion = new QtVersion(QString("%1 (Qt %2)").arg(device.id), device.qt+"/bin/qmake.exe", deviceVersion = new QtVersion(QString("%1 (Qt %2)").arg(device.id), qmakeFromQtDir(device.qt),
true, QString("%1.%2").arg(S60_AUTODETECTION_SOURCE, device.id)); true, QString("%1.%2").arg(S60_AUTODETECTION_SOURCE, device.id));
deviceVersion->setName(deviceVersion->name().arg(deviceVersion->qtVersionString())); deviceVersion->setName(deviceVersion->name().arg(deviceVersion->qtVersionString()));
versionsToAdd.append(deviceVersion); versionsToAdd.append(deviceVersion);
@@ -211,7 +220,12 @@ ProjectExplorer::ToolChain *S60Manager::createGCCEToolChain(const Qt4ProjectMana
ProjectExplorer::Environment env = ProjectExplorer::Environment::systemEnvironment(); ProjectExplorer::Environment env = ProjectExplorer::Environment::systemEnvironment();
env.prependOrSetPath(version->gcceDirectory()+"/bin"); env.prependOrSetPath(version->gcceDirectory()+"/bin");
QString gcceCommandPath= env.searchInPath(GCCE_COMMAND); QString gcceCommandPath= env.searchInPath(GCCE_COMMAND);
return new GCCEToolChain(deviceForQtVersion(version), gcceCommandPath); return new GCCEToolChain(deviceForQtVersion(version), gcceCommandPath, ProjectExplorer::ToolChain::GCCE);
}
ProjectExplorer::ToolChain *S60Manager::createGCCE_GnuPocToolChain(const Qt4ProjectManager::QtVersion *version) const
{
return new GCCEToolChain(deviceForQtVersion(version), QLatin1String("arm-none-symbianelf-g++"), ProjectExplorer::ToolChain::GCCE_GNUPOC);
} }
ProjectExplorer::ToolChain *S60Manager::createRVCTToolChain( ProjectExplorer::ToolChain *S60Manager::createRVCTToolChain(

View File

@@ -54,6 +54,7 @@ public:
ProjectExplorer::ToolChain *createWINSCWToolChain(const Qt4ProjectManager::QtVersion *version) const; ProjectExplorer::ToolChain *createWINSCWToolChain(const Qt4ProjectManager::QtVersion *version) const;
ProjectExplorer::ToolChain *createGCCEToolChain(const Qt4ProjectManager::QtVersion *version) const; ProjectExplorer::ToolChain *createGCCEToolChain(const Qt4ProjectManager::QtVersion *version) const;
ProjectExplorer::ToolChain *createGCCE_GnuPocToolChain(const Qt4ProjectManager::QtVersion *version) const;
ProjectExplorer::ToolChain *createRVCTToolChain(const Qt4ProjectManager::QtVersion *version, ProjectExplorer::ToolChain *createRVCTToolChain(const Qt4ProjectManager::QtVersion *version,
ProjectExplorer::ToolChain::ToolChainType type) const; ProjectExplorer::ToolChain::ToolChainType type) const;

View File

@@ -505,24 +505,37 @@ QString Qt4Project::makeCommand(BuildConfiguration *configuration) const
return tc ? tc->makeCommand() : "make"; return tc ? tc->makeCommand() : "make";
} }
#ifdef QTCREATOR_WITH_S60
static inline QString symbianMakeTarget(QtVersion::QmakeBuildConfig buildConfig,
const QString &type)
{
QString rc = (buildConfig & QtVersion::DebugBuild) ?
QLatin1String("debug-") : QLatin1String("release-");
rc += type;
return rc;
}
#endif
QString Qt4Project::defaultMakeTarget(BuildConfiguration *configuration) const QString Qt4Project::defaultMakeTarget(BuildConfiguration *configuration) const
{ {
#ifdef QTCREATOR_WITH_S60 #ifdef QTCREATOR_WITH_S60
ToolChain *tc = toolChain(configuration); ToolChain *tc = toolChain(configuration);
if (!tc) if (!tc)
return QString::null; return QString::null;
QtVersion::QmakeBuildConfig buildConfig const QtVersion::QmakeBuildConfig buildConfig
= QtVersion::QmakeBuildConfig(activeBuildConfiguration()->value("buildConfiguration").toInt()); = QtVersion::QmakeBuildConfig(activeBuildConfiguration()->value("buildConfiguration").toInt());
if (tc->type() == ToolChain::GCCE) { switch (tc->type()) {
if (!(buildConfig & QtVersion::DebugBuild)) { case ToolChain::GCCE:
return "release-gcce"; case ToolChain::GCCE_GNUPOC:
} return symbianMakeTarget(buildConfig, QLatin1String("gcce"));
return "debug-gcce"; case ToolChain::RVCT_ARMV5:
} else if (tc->type() == ToolChain::RVCT_ARMV5) { return symbianMakeTarget(buildConfig, QLatin1String("armv5"));
return (buildConfig & QtVersion::DebugBuild ? "debug-" : "release-") + QLatin1String("armv5"); case ToolChain::RVCT_ARMV6:
} else if (tc->type() == ToolChain::RVCT_ARMV6) { case ToolChain::RVCT_ARMV6_GNUPOC:
return (buildConfig & QtVersion::DebugBuild ? "debug-" : "release-") + QLatin1String("armv6"); return symbianMakeTarget(buildConfig, QLatin1String("armv6"));
default:
break;
} }
#else #else
Q_UNUSED(configuration); Q_UNUSED(configuration);

View File

@@ -1049,6 +1049,7 @@ ProjectExplorer::ToolChain::ToolChainType QtVersion::defaultToolchainType() cons
// if none, then it's INVALID everywhere this function is called // if none, then it's INVALID everywhere this function is called
void QtVersion::updateToolChainAndMkspec() const void QtVersion::updateToolChainAndMkspec() const
{ {
typedef QSharedPointer<ProjectExplorer::ToolChain> ToolChainPtr;
if (m_toolChainUpToDate) if (m_toolChainUpToDate)
return; return;
@@ -1156,35 +1157,36 @@ void QtVersion::updateToolChainAndMkspec() const
QString ce_arch = reader->value("CE_ARCH"); QString ce_arch = reader->value("CE_ARCH");
QString qt_arch = reader->value("QT_ARCH"); QString qt_arch = reader->value("QT_ARCH");
if (!ce_sdk.isEmpty() && !ce_arch.isEmpty()) { if (!ce_sdk.isEmpty() && !ce_arch.isEmpty()) {
QString wincePlatformName = ce_sdk + " (" + ce_arch + ")"; QString wincePlatformName = ce_sdk + " (" + ce_arch + QLatin1Char(')');
m_toolChains << QSharedPointer<ProjectExplorer::ToolChain>( m_toolChains << ToolChainPtr(ProjectExplorer::ToolChain::createWinCEToolChain(msvcVersion(), wincePlatformName));
ProjectExplorer::ToolChain::createWinCEToolChain(msvcVersion(), wincePlatformName));
} else if (makefileGenerator == "SYMBIAN_ABLD") { } else if (makefileGenerator == "SYMBIAN_ABLD") {
#ifdef QTCREATOR_WITH_S60 #ifdef QTCREATOR_WITH_S60
m_toolChains << QSharedPointer<ProjectExplorer::ToolChain>( if (S60Manager *s60mgr = S60Manager::instance()) {
S60Manager::instance()->createGCCEToolChain(this)); # ifdef Q_OS_WIN
m_toolChains << QSharedPointer<ProjectExplorer::ToolChain>( m_toolChains << ToolChainPtr(s60mgr->createGCCEToolChain(this))
S60Manager::instance()->createRVCTToolChain(this, ProjectExplorer::ToolChain::RVCT_ARMV5)); << ToolChainPtr(s60mgr->createRVCTToolChain(this, ProjectExplorer::ToolChain::RVCT_ARMV5))
m_toolChains << QSharedPointer<ProjectExplorer::ToolChain>( << ToolChainPtr(s60mgr->createRVCTToolChain(this, ProjectExplorer::ToolChain::RVCT_ARMV6))
S60Manager::instance()->createRVCTToolChain(this, ProjectExplorer::ToolChain::RVCT_ARMV6)); << ToolChainPtr(s60mgr->createWINSCWToolChain(this));
m_toolChains << QSharedPointer<ProjectExplorer::ToolChain>( # else
S60Manager::instance()->createWINSCWToolChain(this)); m_toolChains << ToolChainPtr(s60mgr->createGCCE_GnuPocToolChain(this))
<< ToolChainPtr(s60mgr->createRVCTToolChain(this, ProjectExplorer::ToolChain::RVCT_ARMV6_GNUPOC));
# endif
}
#endif #endif
} else if (qt_arch == "arm") { } else if (qt_arch == "arm") {
#ifdef QTCREATOR_WITH_MAEMO #ifdef QTCREATOR_WITH_MAEMO
m_toolChains << QSharedPointer<ProjectExplorer::ToolChain>( m_toolChains << ToolChainPtr(MaemoManager::instance()->maemoToolChain(this));
MaemoManager::instance()->maemoToolChain(this));
#endif #endif
} else if (qmakeCXX == "cl" || qmakeCXX == "icl") { } else if (qmakeCXX == "cl" || qmakeCXX == "icl") {
// TODO proper support for intel cl // TODO proper support for intel cl
m_toolChains << QSharedPointer<ProjectExplorer::ToolChain>( m_toolChains << ToolChainPtr(
ProjectExplorer::ToolChain::createMSVCToolChain(msvcVersion(), isQt64Bit())); ProjectExplorer::ToolChain::createMSVCToolChain(msvcVersion(), isQt64Bit()));
} else if (qmakeCXX == "g++" && makefileGenerator == "MINGW") { } else if (qmakeCXX == "g++" && makefileGenerator == "MINGW") {
ProjectExplorer::Environment env = ProjectExplorer::Environment::systemEnvironment(); ProjectExplorer::Environment env = ProjectExplorer::Environment::systemEnvironment();
//addToEnvironment(env); //addToEnvironment(env);
env.prependOrSetPath(mingwDirectory() + "/bin"); env.prependOrSetPath(mingwDirectory() + "/bin");
qmakeCXX = env.searchInPath(qmakeCXX); qmakeCXX = env.searchInPath(qmakeCXX);
m_toolChains << QSharedPointer<ProjectExplorer::ToolChain>( m_toolChains << ToolChainPtr(
ProjectExplorer::ToolChain::createMinGWToolChain(qmakeCXX, mingwDirectory())); ProjectExplorer::ToolChain::createMinGWToolChain(qmakeCXX, mingwDirectory()));
} else if (qmakeCXX == "g++" || qmakeCXX == "icc") { } else if (qmakeCXX == "g++" || qmakeCXX == "icc") {
ProjectExplorer::Environment env = ProjectExplorer::Environment::systemEnvironment(); ProjectExplorer::Environment env = ProjectExplorer::Environment::systemEnvironment();
@@ -1195,8 +1197,7 @@ void QtVersion::updateToolChainAndMkspec() const
// Unfortunately, we need a valid QMAKE_CXX to configure the parser. // Unfortunately, we need a valid QMAKE_CXX to configure the parser.
qmakeCXX = QLatin1String("cc"); qmakeCXX = QLatin1String("cc");
} }
m_toolChains << QSharedPointer<ProjectExplorer::ToolChain>( m_toolChains << ToolChainPtr(ProjectExplorer::ToolChain::createGccToolChain(qmakeCXX));
ProjectExplorer::ToolChain::createGccToolChain(qmakeCXX));
} }
if (m_toolChains.isEmpty()) { if (m_toolChains.isEmpty()) {