Commit 7c9c99dc authored by Friedemann Kleint's avatar Friedemann Kleint
Browse files

Symbian/Linux: Enable building with makefile-based system.

- Autodetect SDK by environment variable EPOCROOT and qt directory
below.
- Environment::appendOrSet/prependOrSet: Avoid duplicate entries
- Rename toolchain enumeration value
- Adapt S60ToolChainMixin to new GnuPoc setup, provide routines for
  all required variables.
- RVCTToolChain: Make RVCT detection smarter (Check for RVCT<v1><v2>BIN
  variable). Set all required variables in case of RVCTToolChain/GnuPoc
- QtVersionManager: Detect toolchain and Qt version properly, make S60
  device run config accept toolchain.
- Modify S60DeviceRunControl to execute 'make sis'
- Modify S60Devices::detectQt...() to check for Qt installed into SDK
  first and symlink as fallback.
parent e5eff803
......@@ -123,14 +123,15 @@ void Environment::appendOrSet(const QString &key, const QString &value, const QS
#else
const QString &_key = key;
#endif
QMap<QString, QString>::const_iterator it = m_values.constFind(key);
if (it == m_values.constEnd()) {
QMap<QString, QString>::iterator it = m_values.find(key);
if (it == m_values.end()) {
m_values.insert(_key, value);
} else {
QString tmp = *it + sep + value;
m_values.insert(_key, tmp);
// Append unless it is already there
const QString toAppend = sep + value;
if (!it.value().endsWith(toAppend))
it.value().append(toAppend);
}
}
void Environment::prependOrSet(const QString&key, const QString &value, const QString &sep)
......@@ -140,12 +141,14 @@ void Environment::prependOrSet(const QString&key, const QString &value, const QS
#else
const QString &_key = key;
#endif
QMap<QString, QString>::const_iterator it = m_values.constFind(key);
if (it == m_values.constEnd()) {
QMap<QString, QString>::iterator it = m_values.find(key);
if (it == m_values.end()) {
m_values.insert(_key, value);
} else {
QString tmp = value + sep + *it;
m_values.insert(_key, tmp);
// Prepend unless it is already there
const QString toPrepend = value + sep;
if (!it.value().startsWith(toPrepend))
it.value().prepend(toPrepend);
}
}
......
......@@ -126,7 +126,7 @@ QString ToolChain::toolChainName(ToolChainType tc)
return QCoreApplication::translate("ToolChain", "GCCE");
case GCCE_GNUPOC:
return QCoreApplication::translate("ToolChain", "GCCE/GnuPoc");
case RVCT_ARMV6_GNUPOC:
case RVCT_ARMV5_GNUPOC:
return QCoreApplication::translate("ToolChain", "RVCT (ARMV6)/GnuPoc");
case RVCT_ARMV5:
return QCoreApplication::translate("ToolChain", "RVCT (ARMV5)");
......
......@@ -86,7 +86,7 @@ public:
RVCT_ARMV6 = 8,
GCC_MAEMO = 9,
GCCE_GNUPOC = 10,
RVCT_ARMV6_GNUPOC = 11,
RVCT_ARMV5_GNUPOC = 11,
LAST_VALID = 11,
OTHER = 200,
UNKNOWN = 201,
......
......@@ -30,11 +30,19 @@
#include "rvcttoolchain.h"
#include "rvctparser.h"
#include <utils/qtcassert.h>
#include <QtCore/QProcess>
#include <QtCore/QProcessEnvironment>
#include <QtCore/QDebug>
#include <QtCore/QFileInfo>
#include <QtCore/QDir>
using namespace ProjectExplorer;
using namespace Qt4ProjectManager::Internal;
static const char rvctBinaryC[] = "armcc";
RVCTToolChain::RVCTToolChain(const S60Devices::Device &device, ToolChain::ToolChainType type) :
m_mixin(device),
m_type(type),
......@@ -45,6 +53,54 @@ RVCTToolChain::RVCTToolChain(const S60Devices::Device &device, ToolChain::ToolCh
{
}
// Return the environment variable indicating the RVCT version
// 'RVCT<major><minor>BIN'
QByteArray RVCTToolChain::rvctBinEnvironmentVariable()
{
static QByteArray binVar;
// Grep the environment list
if (binVar.isEmpty()) {
const QRegExp regex(QLatin1String("^(RVCT\\d\\dBIN)=.*$"));
QTC_ASSERT(regex.isValid(), return QByteArray());
foreach(const QString &v, QProcessEnvironment::systemEnvironment().toStringList()) {
if (regex.exactMatch(v)) {
binVar = regex.cap(1).toLocal8Bit();
break;
}
}
}
return binVar;
}
// Return binary path as pointed to by RVCT<X><X>BIN
QString RVCTToolChain::rvctBinPath()
{
static QString binPath;
if (binPath.isEmpty()) {
const QByteArray binVar = rvctBinEnvironmentVariable();
if (!binVar.isEmpty()) {
const QByteArray binPathB = qgetenv(binVar);
if (!binPathB.isEmpty()) {
const QFileInfo fi(QString::fromLocal8Bit(binPathB));
if (fi.isDir())
binPath = fi.absoluteFilePath();
}
}
}
return binPath;
}
// Return binary expanded by path or resort to PATH
QString RVCTToolChain::rvctBinary()
{
QString executable = QLatin1String(rvctBinaryC);
#ifdef Q_OS_WIN
executable += QLatin1String(".exe");
#endif
const QString binPath = rvctBinPath();
return binPath.isEmpty() ? executable : (binPath + QLatin1Char('/') + executable);
}
ToolChain::ToolChainType RVCTToolChain::type() const
{
return m_type;
......@@ -54,6 +110,7 @@ void RVCTToolChain::updateVersion()
{
if (m_versionUpToDate)
return;
m_versionUpToDate = true;
m_major = 0;
m_minor = 0;
......@@ -62,13 +119,19 @@ void RVCTToolChain::updateVersion()
ProjectExplorer::Environment env = ProjectExplorer::Environment::systemEnvironment();
addToEnvironment(env);
armcc.setEnvironment(env.toStringList());
armcc.start("armcc", QStringList());
const QString binary = rvctBinary();
armcc.start(rvctBinary(), QStringList());
if (!armcc.waitForStarted()) {
qWarning("Unable to run rvct binary '%s' when trying to determine version.", qPrintable(binary));
return;
}
armcc.closeWriteChannel();
armcc.waitForFinished();
QString versionLine = armcc.readAllStandardOutput();
versionLine += armcc.readAllStandardError();
QRegExp versionRegExp("RVCT(\\d*)\\.(\\d*).*\\[Build.(\\d*)\\]",
Qt::CaseInsensitive);
QString versionLine = QString::fromLocal8Bit(armcc.readAllStandardOutput());
versionLine += QString::fromLocal8Bit(armcc.readAllStandardError());
const QRegExp versionRegExp(QLatin1String("RVCT(\\d*)\\.(\\d*).*\\[Build.(\\d*)\\]"),
Qt::CaseInsensitive);
QTC_ASSERT(versionRegExp.isValid(), return);
if (versionRegExp.indexIn(versionLine) != -1) {
m_major = versionRegExp.cap(1).toInt();
m_minor = versionRegExp.cap(2).toInt();
......@@ -113,8 +176,8 @@ QList<HeaderPath> RVCTToolChain::systemHeaderPaths()
if (!rvctInclude.isEmpty())
m_systemHeaderPaths.append(HeaderPath(rvctInclude, HeaderPath::GlobalHeaderPath));
switch (m_type) {
case ProjectExplorer::ToolChain::RVCT_ARMV6_GNUPOC:
m_systemHeaderPaths += m_mixin.gnuPocHeaderPaths();
case ProjectExplorer::ToolChain::RVCT_ARMV5_GNUPOC:
m_systemHeaderPaths += m_mixin.gnuPocRvctHeaderPaths(m_major, m_minor);
break;
default:
m_systemHeaderPaths += m_mixin.epocHeaderPaths();
......@@ -124,11 +187,66 @@ QList<HeaderPath> RVCTToolChain::systemHeaderPaths()
return m_systemHeaderPaths;
}
static inline QStringList headerPathToStringList(const QList<ProjectExplorer::HeaderPath> &hl)
{
QStringList rc;
foreach(const ProjectExplorer::HeaderPath &hp, hl)
rc.push_back(hp.path());
return rc;
}
// Expand an RVCT variable, such as RVCT22BIN, by some new values
void RVCTToolChain::addToRVCTPathVariable(const QString &postfix, const QStringList &values,
ProjectExplorer::Environment &env) const
{
// get old values
const QChar separator = QLatin1Char(',');
const QString variable = QString::fromLatin1("RVCT%1%2%3").arg(m_major).arg(m_minor).arg(postfix);
const QString oldValueS = env.value(variable);
const QStringList oldValue = oldValueS.isEmpty() ? QStringList() : oldValueS.split(separator);
// merge new values
QStringList newValue = oldValue;
foreach(const QString &v, values) {
const QString normalized = QDir::toNativeSeparators(v);
if (!newValue.contains(normalized))
newValue.push_back(normalized);
}
if (newValue != oldValue)
env.set(variable, newValue.join(QString(separator)));
}
// Figure out lib path via
QStringList RVCTToolChain::libPaths()
{
const QByteArray binLocation = qgetenv(rvctBinEnvironmentVariable());
if (binLocation.isEmpty())
return QStringList();
const QString pathRoot = QFileInfo(QString::fromLocal8Bit(binLocation)).path();
QStringList rc;
rc.push_back(pathRoot + QLatin1String("/lib"));
rc.push_back(pathRoot + QLatin1String("/lib/armlib"));
return rc;
}
void RVCTToolChain::addToEnvironment(ProjectExplorer::Environment &env)
{
updateVersion();
switch (m_type) {
case ProjectExplorer::ToolChain::RVCT_ARMV6_GNUPOC:
case ProjectExplorer::ToolChain::RVCT_ARMV5_GNUPOC: {
m_mixin.addGnuPocToEnvironment(&env);
// setup RVCT22INC, LIB
addToRVCTPathVariable(QLatin1String("INC"),
headerPathToStringList(m_mixin.gnuPocRvctHeaderPaths(m_major, m_minor)),
env);
addToRVCTPathVariable(QLatin1String("LIB"),
libPaths() + m_mixin.gnuPocRvctLibPaths(5, true),
env);
// Add rvct to path and set locale to 'C'
const QString binPath = rvctBinPath();
if (!binPath.isEmpty())
env.prependOrSetPath(binPath);
env.set(QLatin1String("LANG"), QString(QLatin1Char('C')));
}
break;
default:
m_mixin.addEpocToEnvironment(&env);
......
......@@ -49,10 +49,19 @@ public:
QString makeCommand() const;
ProjectExplorer::IOutputParser *outputParser() const;
// Return the environment variable indicating the RVCT version
// 'RVCT<major><minor>BIN' and its setting
static QByteArray rvctBinEnvironmentVariable();
static QString rvctBinPath();
static QString rvctBinary();
protected:
bool equals(ToolChain *other) const;
private:
void addToRVCTPathVariable(const QString &postfix, const QStringList &values,
ProjectExplorer::Environment &env) const;
static QStringList libPaths();
void updateVersion();
const S60ToolChainMixin m_mixin;
......
......@@ -179,9 +179,18 @@ ProjectExplorer::ToolChain::ToolChainType S60DeviceRunConfiguration::toolChainTy
bool S60DeviceRunConfiguration::isEnabled(ProjectExplorer::BuildConfiguration *configuration) const
{
Qt4BuildConfiguration *qt4bc = static_cast<Qt4BuildConfiguration *>(configuration);
const ToolChain::ToolChainType type = qt4bc->toolChainType();
return type == ToolChain::GCCE || type == ToolChain::RVCT_ARMV5 || type == ToolChain::RVCT_ARMV6;
const Qt4BuildConfiguration *qt4bc = static_cast<const Qt4BuildConfiguration *>(configuration);
switch (qt4bc->toolChainType()) {
case ToolChain::GCCE:
case ToolChain::RVCT_ARMV5:
case ToolChain::RVCT_ARMV6:
case ToolChain::GCCE_GNUPOC:
case ToolChain::RVCT_ARMV5_GNUPOC:
return true;
default:
break;
}
return false;
}
QWidget *S60DeviceRunConfiguration::configurationWidget()
......@@ -468,8 +477,8 @@ RunConfiguration *S60DeviceRunConfigurationFactory::clone(Target *parent, RunCon
S60DeviceRunControlBase::S60DeviceRunControlBase(RunConfiguration *runConfiguration) :
RunControl(runConfiguration),
m_toolChain(ProjectExplorer::ToolChain::INVALID),
m_makesis(new QProcess(this)),
m_signsis(0),
m_makesisProcess(new QProcess(this)),
m_signsisProcess(0),
m_releaseDeviceAfterLauncherFinish(false),
m_handleDeviceRemoval(true),
m_launcher(0)
......@@ -477,13 +486,13 @@ S60DeviceRunControlBase::S60DeviceRunControlBase(RunConfiguration *runConfigurat
// connect for automatically reporting the "finished deploy" state to the progress manager
connect(this, SIGNAL(finished()), this, SLOT(reportDeployFinished()));
connect(m_makesis, SIGNAL(readyReadStandardError()),
connect(m_makesisProcess, SIGNAL(readyReadStandardError()),
this, SLOT(readStandardError()));
connect(m_makesis, SIGNAL(readyReadStandardOutput()),
connect(m_makesisProcess, SIGNAL(readyReadStandardOutput()),
this, SLOT(readStandardOutput()));
connect(m_makesis, SIGNAL(error(QProcess::ProcessError)),
connect(m_makesisProcess, SIGNAL(error(QProcess::ProcessError)),
this, SLOT(makesisProcessFailed()));
connect(m_makesis, SIGNAL(finished(int,QProcess::ExitStatus)),
connect(m_makesisProcess, SIGNAL(finished(int,QProcess::ExitStatus)),
this, SLOT(makesisProcessFinished()));
S60DeviceRunConfiguration *s60runConfig = qobject_cast<S60DeviceRunConfiguration *>(runConfiguration);
......@@ -509,28 +518,30 @@ S60DeviceRunControlBase::S60DeviceRunControlBase(RunConfiguration *runConfigurat
const S60Devices::Device device = S60Manager::instance()->deviceForQtVersion(activeBuildConf->qtVersion());
switch (m_toolChain) {
case ProjectExplorer::ToolChain::GCCE_GNUPOC:
case ProjectExplorer::ToolChain::RVCT_ARMV6_GNUPOC: {
case ProjectExplorer::ToolChain::RVCT_ARMV5_GNUPOC: {
// 'sis' is a make target here. Set up with correct environment
ProjectExplorer::ToolChain *toolchain = activeBuildConf->toolChain();
m_makesisTool = toolchain->makeCommand();
m_toolsDirectory = device.epocRoot + QLatin1String("/epoc32/tools");
ProjectExplorer::Environment env = ProjectExplorer::Environment::systemEnvironment();
env.set(QLatin1String("QT_SIS_CERTIFICATE"), signSisCertificate());
env.set(QLatin1String("QT_SIS_KEY"), signSisKey());
toolchain->addToEnvironment(env);
m_makesis->setEnvironment(env.toStringList());
m_makesisProcess->setEnvironment(env.toStringList());
}
break;
default:
m_toolsDirectory = device.toolsRoot + QLatin1String("/epoc32/tools");
m_makesisTool = m_toolsDirectory + "/makesis.exe";
// Set up signing packages
m_signsis = new QProcess(this);
connect(m_signsis, SIGNAL(readyReadStandardError()),
m_signsisProcess = new QProcess(this);
connect(m_signsisProcess, SIGNAL(readyReadStandardError()),
this, SLOT(readStandardError()));
connect(m_signsis, SIGNAL(readyReadStandardOutput()),
connect(m_signsisProcess, SIGNAL(readyReadStandardOutput()),
this, SLOT(readStandardOutput()));
connect(m_signsis, SIGNAL(error(QProcess::ProcessError)),
connect(m_signsisProcess, SIGNAL(error(QProcess::ProcessError)),
this, SLOT(signsisProcessFailed()));
connect(m_signsis, SIGNAL(finished(int,QProcess::ExitStatus)),
connect(m_signsisProcess, SIGNAL(finished(int,QProcess::ExitStatus)),
this, SLOT(signsisProcessFinished()));
break;
}
......@@ -589,7 +600,7 @@ void S60DeviceRunControlBase::start()
QStringList makeSisArgs;
switch (m_toolChain) {
case ProjectExplorer::ToolChain::GCCE_GNUPOC:
case ProjectExplorer::ToolChain::RVCT_ARMV6_GNUPOC:
case ProjectExplorer::ToolChain::RVCT_ARMV5_GNUPOC:
makeSisArgs.push_back(QLatin1String("sis"));
break;
default:
......@@ -602,11 +613,11 @@ void S60DeviceRunControlBase::start()
break;
}
m_makesis->setWorkingDirectory(m_workingDirectory);
m_makesisProcess->setWorkingDirectory(m_workingDirectory);
emit addToOutputWindow(this, tr("%1 %2").arg(QDir::toNativeSeparators(m_makesisTool), m_packageFile));
if (debug)
qDebug() << m_makesisTool << makeSisArgs << m_workingDirectory;
m_makesis->start(m_makesisTool, makeSisArgs, QIODevice::ReadOnly);
m_makesisProcess->start(m_makesisTool, makeSisArgs, QIODevice::ReadOnly);
}
static inline void stopProcess(QProcess *p)
......@@ -622,17 +633,17 @@ static inline void stopProcess(QProcess *p)
void S60DeviceRunControlBase::stop()
{
if (m_makesis)
stopProcess(m_makesis);
if (m_signsis)
stopProcess(m_signsis);
if (m_makesisProcess)
stopProcess(m_makesisProcess);
if (m_signsisProcess)
stopProcess(m_signsisProcess);
if (m_launcher)
m_launcher->terminate();
}
bool S60DeviceRunControlBase::isRunning() const
{
return m_makesis->state() != QProcess::NotRunning;
return m_makesisProcess->state() != QProcess::NotRunning;
}
void S60DeviceRunControlBase::readStandardError()
......@@ -672,12 +683,12 @@ bool S60DeviceRunControlBase::createPackageFileFromTemplate(QString *errorMessag
void S60DeviceRunControlBase::makesisProcessFailed()
{
processFailed(m_makesisTool, m_makesis->error());
processFailed(m_makesisTool, m_makesisProcess->error());
}
void S60DeviceRunControlBase::makesisProcessFinished()
{
if (m_makesis->exitCode() != 0) {
if (m_makesisProcess->exitCode() != 0) {
error(this, tr("An error occurred while creating the package."));
stop();
emit finished();
......@@ -686,7 +697,7 @@ void S60DeviceRunControlBase::makesisProcessFinished()
m_deployProgress->setProgressValue(PROGRESS_PACKAGECREATED);
switch (m_toolChain) {
case ProjectExplorer::ToolChain::GCCE_GNUPOC:
case ProjectExplorer::ToolChain::RVCT_ARMV6_GNUPOC:
case ProjectExplorer::ToolChain::RVCT_ARMV5_GNUPOC:
startDeployment();
break;
default:
......@@ -695,32 +706,45 @@ void S60DeviceRunControlBase::makesisProcessFinished()
}
}
QString S60DeviceRunControlBase::signSisKey() const
{
const QString key = m_useCustomSignature ? m_customKeyPath:
m_qtDir + QLatin1String("/src/s60installs/selfsigned.key");
return QDir::toNativeSeparators(key);
}
QString S60DeviceRunControlBase::signSisCertificate() const
{
const QString cert = m_useCustomSignature ? m_customSignaturePath :
m_qtDir + QLatin1String("/src/s60installs/selfsigned.cer");
return QDir::toNativeSeparators(cert);
}
void S60DeviceRunControlBase::startSigning()
{
QString signsisTool = m_toolsDirectory + QLatin1String("/signsis.exe");
QString sisFile = QFileInfo(m_baseFileName + QLatin1String(".sis")).fileName();
QString sisxFile = QFileInfo(m_baseFileName + QLatin1String(".sisx")).fileName();
QString signature = (m_useCustomSignature ? m_customSignaturePath
: m_qtDir + QLatin1String("/src/s60installs/selfsigned.cer"));
QString key = (m_useCustomSignature ? m_customKeyPath
: m_qtDir + QLatin1String("/src/s60installs/selfsigned.key"));
// Signis creates a signed package ('.sisx') from a '.sis'
// using certificate and key.
QString signsisTool = m_toolsDirectory + QLatin1String("/signsis");
#ifdef Q_OS_WIN
signsisTool += QLatin1String(".exe");
#endif
const QString sisFile = QFileInfo(m_baseFileName + QLatin1String(".sis")).fileName();
const QString sisxFile = sisFile + QLatin1Char('x');
QStringList arguments;
arguments << sisFile
<< sisxFile << QDir::toNativeSeparators(signature)
<< QDir::toNativeSeparators(key);
m_signsis->setWorkingDirectory(m_workingDirectory);
arguments << sisFile << sisxFile << signSisCertificate() << signSisKey();
m_signsisProcess->setWorkingDirectory(m_workingDirectory);
emit addToOutputWindow(this, tr("%1 %2").arg(QDir::toNativeSeparators(signsisTool), arguments.join(QString(QLatin1Char(' ')))));
m_signsis->start(signsisTool, arguments, QIODevice::ReadOnly);
m_signsisProcess->start(signsisTool, arguments, QIODevice::ReadOnly);
}
void S60DeviceRunControlBase::signsisProcessFailed()
{
processFailed("signsis.exe", m_signsis->error());
processFailed("signsis.exe", m_signsisProcess->error());
}
void S60DeviceRunControlBase::signsisProcessFinished()
{
if (m_signsis->exitCode() != 0) {
if (m_signsisProcess->exitCode() != 0) {
error(this, tr("An error occurred while creating the package."));
stop();
emit finished();
......
......@@ -156,7 +156,7 @@ public:
/* S60DeviceRunControlBase: Builds the package and starts launcher
* to deploy. Subclasses can configure the launcher to run or start a debugger.
* Building the package comprises for:
* GnuPoc: run 'make sis'
* GnuPoc: run 'make sis' with environment variables for signing set
* Other: run the makesis.exe tool, run signsis */
class S60DeviceRunControlBase : public ProjectExplorer::RunControl
......@@ -211,6 +211,8 @@ private:
bool createPackageFileFromTemplate(QString *errorMessage);
void startSigning();
void startDeployment();
QString signSisKey() const;
QString signSisCertificate() const;
ProjectExplorer::ToolChain::ToolChainType m_toolChain;
QString m_serialPortName;
......@@ -229,8 +231,8 @@ private:
bool m_useCustomSignature;
QString m_customSignaturePath;
QString m_customKeyPath;
QProcess *m_makesis;
QProcess *m_signsis;
QProcess *m_makesisProcess;
QProcess *m_signsisProcess;
QString m_makesisTool;
QString m_packageFile;
bool m_releaseDeviceAfterLauncherFinish;
......
......@@ -85,7 +85,7 @@ S60Devices::S60Devices(QObject *parent)
}
// GNU-Poc stuff
static const char *gnuPocRootC = "GNUPOC_ROOT";
static const char *epocRootC = "EPOCROOT";
static inline QString msgEnvVarNotSet(const char *var)
{
......@@ -100,28 +100,22 @@ static inline QString msgEnvVarDirNotExist(const QString &dir, const char *var)
bool S60Devices::readLinux()
{
// Detect GNUPOC_ROOT/EPOC ROOT
const QByteArray gnuPocRootA = qgetenv(gnuPocRootC);
if (gnuPocRootA.isEmpty()) {
m_errorString = msgEnvVarNotSet(gnuPocRootC);
const QByteArray epocRootA = qgetenv(epocRootC);
if (epocRootA.isEmpty()) {
m_errorString = msgEnvVarNotSet(epocRootC);
return false;
}
const QDir gnuPocRootDir(QString::fromLocal8Bit(gnuPocRootA));
if (!gnuPocRootDir.exists()) {
m_errorString = msgEnvVarDirNotExist(gnuPocRootDir.absolutePath(), gnuPocRootC);
const QDir epocRootDir(QString::fromLocal8Bit(epocRootA));
if (!epocRootDir.exists()) {
m_errorString = msgEnvVarDirNotExist(epocRootDir.absolutePath(), epocRootC);
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.toolsRoot = device.epocRoot = epocRootDir.absolutePath();
device.isDefault = true;
m_devices.push_back(device);
return true;
......@@ -233,40 +227,73 @@ bool S60Devices::readWin()
return true;
}
bool S60Devices::detectQtForDevices()
// Detect a Qt version that is installed into a Symbian SDK
static QString detect_SDK_installedQt(const QString &epocRoot)
{
const QString coreLibDllFileName = epocRoot + QLatin1String("/epoc32/release/winscw/udeb/QtCore.dll");
QFile coreLibDllFile(coreLibDllFileName);
if (!coreLibDllFile.exists() || !coreLibDllFile.open(QIODevice::ReadOnly))
return false;
// Do not normalize these backslashes since they are in ARM binaries:
const QByteArray indicator("\\src\\corelib\\kernel\\qobject.h");
const int indicatorlength = indicator.size();
for (int i = 0; i < m_devices.size(); ++i) {
if (!m_devices.at(i).qt.isEmpty())
continue;
QFile qtDll(QString("%1/epoc32/release/winscw/udeb/QtCore.dll").arg(m_devices.at(i).epocRoot));
if (!qtDll.exists() || !qtDll.open(QIODevice::ReadOnly)) {
m_devices[i].qt.clear();