summaryrefslogtreecommitdiffstats
path: root/qmake/generators/symbian/symmake_sbsv2.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'qmake/generators/symbian/symmake_sbsv2.cpp')
-rw-r--r--qmake/generators/symbian/symmake_sbsv2.cpp351
1 files changed, 231 insertions, 120 deletions
diff --git a/qmake/generators/symbian/symmake_sbsv2.cpp b/qmake/generators/symbian/symmake_sbsv2.cpp
index c66c1b8..32c31ee 100644
--- a/qmake/generators/symbian/symmake_sbsv2.cpp
+++ b/qmake/generators/symbian/symmake_sbsv2.cpp
@@ -56,12 +56,21 @@ SymbianSbsv2MakefileGenerator::~SymbianSbsv2MakefileGenerator() { }
#define FLM_DEST_DIR "epoc32/tools/makefile_templates/qt"
#define FLM_SOURCE_DIR "/mkspecs/symbian-sbsv2/flm/qt"
-#define UNDETECTED_GCCE_VERSION "0"
#define PLATFORM_GCCE "gcce"
#define PLATFORM_WINSCW "winscw"
-#define PLATFORM_ARMV5 "armv5"
+#define PLATFORM_ARM_PREFIX "arm"
#define BUILD_DEBUG "udeb"
#define BUILD_RELEASE "urel"
+#define SBS_RVCT_PREFIX "rvct"
+
+static QString winscwPlatform;
+static QString armPlatformPrefix;
+static QString gccePlatform;
+static QString sbsRvctPrefix;
+
+#if defined(Q_OS_UNIX)
+ extern char **environ;
+#endif
// Copies Qt FLMs to correct location under epocroot.
// This is not done by configure as it is possible to change epocroot after configure.
@@ -96,64 +105,95 @@ void SymbianSbsv2MakefileGenerator::exportFlm()
}
}
-QString SymbianSbsv2MakefileGenerator::gcceVersion()
+void SymbianSbsv2MakefileGenerator::findInstalledCompilerVersions(const QString &matchExpression,
+ const QString &versionPrefix,
+ QStringList *versionList)
{
- static QString gcceVersionStr;
-
- if (gcceVersionStr.isEmpty()) {
- // First check if QT_GCCE_VERSION has been set, and use that if it is
- QByteArray qtGcceVersion = qgetenv("QT_GCCE_VERSION");
- if (!qtGcceVersion.isEmpty()) {
- // Check that QT_GCCE_VERSION is in proper format
- QString check(qtGcceVersion);
- check.replace(QRegExp("^\\d+\\.\\d+\\.\\d+$"),QString());
- if (check.isEmpty()) {
- gcceVersionStr = PLATFORM_GCCE + QString(qtGcceVersion).replace(".","_");
- return gcceVersionStr;
- } else {
- fprintf(stderr, "Warning: Environment variable QT_GCCE_VERSION ('%s') is in incorrect "
- "format, expected format is: '1.2.3'. Attempting to autodetect GCCE version.",
- qtGcceVersion.constData());
+ // No need to be able to find env variables on other operating systems,
+ // as only linux and windows have support for symbian-sbsv2 toolchain
+#if defined(Q_OS_UNIX) || defined(Q_OS_WIN)
+ char *entry = 0;
+ int count = 0;
+ QRegExp matcher(matchExpression);
+ while ((entry = environ[count++])) {
+ if (matcher.exactMatch(QString::fromLocal8Bit(entry))
+ && fileInfo(matcher.cap(matcher.captureCount())).exists()) {
+ // First capture (index 0) is the whole match, which is skipped.
+ // Next n captures are version numbers, which are interesting.
+ // Final capture is the env var value, which we alrady used, so that is skipped, too.
+ int capture = 1;
+ int finalCapture = matcher.captureCount() - 1;
+ QString version = versionPrefix;
+ while (capture <= finalCapture) {
+ version.append(matcher.cap(capture));
+ if (capture != finalCapture)
+ version.append(QLatin1Char('.'));
+ capture++;
}
+ *versionList << version;
}
- // Sbsv2 has separate env variable defined for each gcce version, so try to determine
- // which user is likely to want to use by checking version 4.0.0 to 9.9.9 and taking
- // the highest found version that actually points to a valid path.
- // This is kind of a kludge, but since qmake doesn't bootstrap QProcess, there
- // is no Qt API available to get all environment variables.
- for (int i = 9; i >= 4; i--) {
- for (int j = 9; j >= 0; j--) {
- for (int k = 9; k >= 0; k--) {
- QByteArray gcceVar = qgetenv(qPrintable(QString("SBS_GCCE%1%2%3BIN").arg(i).arg(j).arg(k)));
- if (!gcceVar.isEmpty() && fileInfo(QString::fromLocal8Bit(gcceVar.constData())).exists()) {
- gcceVersionStr = QString(PLATFORM_GCCE "%1_%2_%3").arg(i).arg(j).arg(k);
- return gcceVersionStr;
- }
- }
- }
+ }
+#endif
+}
+
+void SymbianSbsv2MakefileGenerator::findGcceVersions(QStringList *gcceVersionList,
+ QString *defaultVersion)
+{
+ QString matchStr = QLatin1String("SBS_GCCE(\\d)(\\d)(\\d)BIN=(.*)");
+ findInstalledCompilerVersions(matchStr, gccePlatform, gcceVersionList);
+
+ QString qtGcceVersion = QString::fromLocal8Bit(qgetenv("QT_GCCE_VERSION"));
+
+ if (!qtGcceVersion.isEmpty()) {
+ if (QRegExp("\\d+\\.\\d+\\.\\d+").exactMatch(qtGcceVersion)) {
+ *defaultVersion = gccePlatform + qtGcceVersion;
+ } else {
+ fprintf(stderr, "Warning: Variable QT_GCCE_VERSION ('%s') is in incorrect "
+ "format, expected format is: 'x.y.z'. Attempting to autodetect GCCE version.\n",
+ qPrintable(qtGcceVersion));
}
}
- // Indicate undetected version to avoid rechecking multiple times
- if (gcceVersionStr.isEmpty())
- gcceVersionStr = UNDETECTED_GCCE_VERSION;
+ if (defaultVersion->isEmpty() && gcceVersionList->size()) {
+ gcceVersionList->sort();
+ *defaultVersion = gcceVersionList->last();
+ }
+}
+
+void SymbianSbsv2MakefileGenerator::findRvctVersions(QStringList *rvctVersionList,
+ QString *defaultVersion)
+{
+ QString matchStr = QLatin1String("RVCT(\\d)(\\d)BIN=(.*)");
+ findInstalledCompilerVersions(matchStr, sbsRvctPrefix, rvctVersionList);
+
+ QString qtRvctVersion = QString::fromLocal8Bit(qgetenv("QT_RVCT_VERSION"));
- return gcceVersionStr;
+ if (!qtRvctVersion.isEmpty()) {
+ if (QRegExp("\\d+\\.\\d+").exactMatch(qtRvctVersion)) {
+ *defaultVersion = sbsRvctPrefix + qtRvctVersion;
+ } else {
+ fprintf(stderr, "Warning: Variable QT_RVCT_VERSION ('%s') is in incorrect "
+ "format, expected format is: 'x.y'.\n",
+ qPrintable(qtRvctVersion));
+ }
+ }
}
-QString SymbianSbsv2MakefileGenerator::configClause(QString &platform,
- QString &build,
- QString &winscwClauseTemplate,
- QString &gcceClauseTemplate,
- QString &genericClauseTemplate)
+QString SymbianSbsv2MakefileGenerator::configClause(const QString &platform,
+ const QString &build,
+ const QString &compilerVersion,
+ const QString &clauseTemplate)
{
QString retval;
- if (QString::compare(platform, PLATFORM_WINSCW) == 0)
- retval = winscwClauseTemplate.arg(build);
- else if (QString::compare(platform, PLATFORM_GCCE) == 0)
- retval = gcceClauseTemplate.arg(build);
- else
- retval = genericClauseTemplate.arg(platform).arg(build);
+ if (QString::compare(platform, winscwPlatform) == 0) {
+ retval = clauseTemplate.arg(build);
+ } else if (platform.startsWith(armPlatformPrefix)) {
+ QString fixedCompilerVersion = compilerVersion;
+ fixedCompilerVersion.replace(".","_");
+ retval = clauseTemplate.arg(platform.mid(sizeof(PLATFORM_ARM_PREFIX)-1))
+ .arg(build)
+ .arg(fixedCompilerVersion);
+ } // else - Unsupported platform for makefile target, return empty clause
return retval;
}
@@ -185,52 +225,101 @@ void SymbianSbsv2MakefileGenerator::writeMkFile(const QString& wrapperFileName,
void SymbianSbsv2MakefileGenerator::writeWrapperMakefile(QFile& wrapperFile, bool isPrimaryMakefile)
{
- static QString debugBuild(BUILD_DEBUG);
- static QString releaseBuild(BUILD_RELEASE);
+ static QString debugBuild;
+ static QString releaseBuild;
+ static QString defaultGcceCompilerVersion;
+ static QString defaultRvctCompilerVersion;
+ static QStringList rvctVersions;
+ static QStringList gcceVersions;
+ static QStringList allArmCompilerVersions;
+
+ // Initialize static variables used in makefile creation
+ if (debugBuild.isEmpty()) {
+ debugBuild.append(QLatin1String(BUILD_DEBUG));
+ releaseBuild.append(QLatin1String(BUILD_RELEASE));
+ winscwPlatform.append(QLatin1String(PLATFORM_WINSCW));
+ gccePlatform.append(QLatin1String(PLATFORM_GCCE));
+ armPlatformPrefix.append(QLatin1String(PLATFORM_ARM_PREFIX));
+ sbsRvctPrefix.append(QLatin1String(SBS_RVCT_PREFIX));
+
+ findGcceVersions(&gcceVersions, &defaultGcceCompilerVersion);
+ findRvctVersions(&rvctVersions, &defaultRvctCompilerVersion);
+
+ allArmCompilerVersions << rvctVersions << gcceVersions;
+
+ if (!allArmCompilerVersions.size()) {
+ fprintf(stderr, "Warning: No HW compilers detected. "
+ "Please install either GCCE or RVCT compiler to enable release builds.\n");
+ }
+ }
QStringList allPlatforms;
foreach(QString platform, project->values("SYMBIAN_PLATFORMS")) {
allPlatforms << platform.toLower();
}
+ if (!gcceVersions.size())
+ allPlatforms.removeAll(gccePlatform);
+
QString testClause;
if (project->isActiveConfig(SYMBIAN_TEST_CONFIG))
testClause = QLatin1String(".test");
else
testClause = QLatin1String("");
- QString genericClause = " -c %1_%2" + testClause;
- QString winscwClause = " -c winscw_%1.mwccinc" + testClause;
- QString gcceClause;
- bool stripArmv5 = false;
+ // Note: armClause is used for gcce, too, which has a side effect
+ // of requiring armv* platform(s) in SYMBIAN_PLATFORMS in order
+ // to get any compiler version specific targets.
+ QString armClause = " -c " PLATFORM_ARM_PREFIX ".%1.%2.%3" + testClause;
+ QString genericArmClause;
+ if (defaultRvctCompilerVersion.isEmpty()) {
+ // Note: Argument %3 needs to be empty string in this version of clause
+ genericArmClause = " -c " PLATFORM_ARM_PREFIX "%1_%2%3" + testClause;
+ } else {
+ // If defaultRvctCompilerVersion is defined, use specific sbs clause for "generic" clause
+ genericArmClause = armClause;
+ }
+ QString winscwClause = " -c " PLATFORM_WINSCW "_%1.mwccinc" + testClause;;
- if (allPlatforms.contains(PLATFORM_GCCE)) {
- if (QString::compare(gcceVersion(), UNDETECTED_GCCE_VERSION) == 0) {
- allPlatforms.removeAll(PLATFORM_GCCE);
- } else {
- gcceClause = " -c arm.v5.%1." + gcceVersion() + testClause;
- // Since gcce building is enabled, do not add armv5 for any sbs command
- // that also contains gcce, because those will build same targets.
- stripArmv5 = true;
+ QStringList armPlatforms = allPlatforms.filter(QRegExp("^" PLATFORM_ARM_PREFIX));
+
+ if (!allArmCompilerVersions.size()) {
+ foreach (QString item, armPlatforms) {
+ allPlatforms.removeAll(item);
}
+ armPlatforms.clear();
}
QStringList allClauses;
QStringList debugClauses;
QStringList releaseClauses;
+ // Only winscw and arm platforms are supported
QStringList debugPlatforms = allPlatforms;
QStringList releasePlatforms = allPlatforms;
- releasePlatforms.removeAll(PLATFORM_WINSCW); // No release for emulator
+ releasePlatforms.removeAll(winscwPlatform); // No release for emulator
- foreach(QString item, debugPlatforms) {
- if (item != PLATFORM_ARMV5 || !stripArmv5)
- debugClauses << configClause(item, debugBuild, winscwClause, gcceClause, genericClause);
+ if (!releasePlatforms.size()) {
+ fprintf(stderr, "Warning: No valid release platforms in SYMBIAN_PLATFORMS (%s)\n"
+ "Most likely required compiler(s) are not properly installed.\n",
+ qPrintable(project->values("SYMBIAN_PLATFORMS").join(" ")));
}
- foreach(QString item, releasePlatforms) {
- if (item != PLATFORM_ARMV5 || !stripArmv5)
- releaseClauses << configClause(item, releaseBuild, winscwClause, gcceClause, genericClause);
+
+ if (debugPlatforms.contains(winscwPlatform))
+ debugClauses << configClause(winscwPlatform, debugBuild, QString(), winscwClause);
+
+ foreach(QString item, armPlatforms) {
+ // Only use single clause per arm platform even if multiple compiler versions were found,
+ // otherwise we get makefile target collisions from sbsv2 toolchain.
+ if (rvctVersions.size()) {
+ debugClauses << configClause(item, debugBuild, defaultRvctCompilerVersion, genericArmClause);
+ releaseClauses << configClause(item, releaseBuild, defaultRvctCompilerVersion, genericArmClause);
+ } else {
+ debugClauses << configClause(item, debugBuild, defaultGcceCompilerVersion, armClause);
+ releaseClauses << configClause(item, releaseBuild, defaultGcceCompilerVersion, armClause);
+ }
}
+
allClauses << debugClauses << releaseClauses;
QTextStream t(&wrapperFile);
@@ -270,22 +359,20 @@ void SymbianSbsv2MakefileGenerator::writeWrapperMakefile(QFile& wrapperFile, boo
t << " -I\"" << values.at(i) << "\" ";
}
}
- t << endl;
- t << "first: default" << endl;
- if (debugPlatforms.contains(PLATFORM_WINSCW))
- t << "default: debug-winscw";
- else if (debugPlatforms.contains(PLATFORM_ARMV5))
- t << "default: debug-armv5";
- else if (debugPlatforms.size())
- t << "default: debug-" << debugPlatforms.first();
- else
- t << "default: all";
t << endl;
+ t << "first: default" << endl << endl;
if (!isPrimaryMakefile) {
- t << "all:" << endl;
+ t << "all:" << endl << endl;
+ t << "default: all" << endl << endl;
} else {
- t << "all: debug release" << endl;
+ t << "all: debug release" << endl << endl;
+ if (debugPlatforms.contains(winscwPlatform))
+ t << "default: debug-winscw";
+ else if (debugPlatforms.size())
+ t << "default: debug-" << debugPlatforms.first();
+ else
+ t << "default: all";
t << endl;
QString qmakeCmd = "\t$(QMAKE) \"" + project->projectFile() + "\" " + buildArgs();
@@ -302,30 +389,80 @@ void SymbianSbsv2MakefileGenerator::writeWrapperMakefile(QFile& wrapperFile, boo
t << "debug: " << BLD_INF_FILENAME << endl;
t << "\t$(SBS)";
- foreach(QString item, debugClauses) {
- t << item;
+ foreach(QString clause, debugClauses) {
+ t << clause;
+ }
+ t << endl;
+ t << "clean-debug: " << BLD_INF_FILENAME << endl;
+ t << "\t$(SBS) reallyclean";
+ foreach(QString clause, debugClauses) {
+ t << clause;
}
t << endl;
t << "release: " << BLD_INF_FILENAME << endl;
t << "\t$(SBS)";
- foreach(QString item, releaseClauses) {
- t << item;
+ foreach(QString clause, releaseClauses) {
+ t << clause;
}
t << endl;
+ t << "clean-release: " << BLD_INF_FILENAME << endl;
+ t << "\t$(SBS) reallyclean";
+ foreach(QString clause, releaseClauses) {
+ t << clause;
+ }
+ t << endl << endl;
+
+ QString defaultGcceArmVersion;
+ if (armPlatforms.size()) {
+ defaultGcceArmVersion = armPlatforms.first();
+ } else {
+ defaultGcceArmVersion = QLatin1String("armv5");
+ }
- // For more specific builds, targets are in this form: build-platform, e.g. release-armv5
+ // For more specific builds, targets are in this form:
+ // release-armv5 - generic target, compiler version determined by toolchain or autodetection
+ // release-armv5-rvct4.0 - compiler version specific target
foreach(QString item, debugPlatforms) {
+ QString clause;
+ if (item.compare(winscwPlatform) == 0)
+ clause = configClause(item, debugBuild, QString(), winscwClause);
+ else if (item.compare(gccePlatform) == 0 )
+ clause = configClause(defaultGcceArmVersion, debugBuild, defaultGcceCompilerVersion, armClause);
+ else // use generic arm clause
+ clause = configClause(item, debugBuild, defaultRvctCompilerVersion, genericArmClause);
+
t << "debug-" << item << ": " << BLD_INF_FILENAME << endl;
- t << "\t$(SBS)";
- t << configClause(item, debugBuild, winscwClause, gcceClause, genericClause);
- t << endl;
+ t << "\t$(SBS)" << clause << endl;
+ t << "clean-debug-" << item << ": " << BLD_INF_FILENAME << endl;
+ t << "\t$(SBS) reallyclean" << clause << endl;
}
foreach(QString item, releasePlatforms) {
+ QString clause;
+ if (item.compare(gccePlatform) == 0 )
+ clause = configClause(defaultGcceArmVersion, releaseBuild, defaultGcceCompilerVersion, armClause);
+ else // use generic arm clause
+ clause = configClause(item, releaseBuild, defaultRvctCompilerVersion, genericArmClause);
+
t << "release-" << item << ": " << BLD_INF_FILENAME << endl;
- t << "\t$(SBS)";
- t << configClause(item, releaseBuild, winscwClause, gcceClause, genericClause);
- t << endl;
+ t << "\t$(SBS)" << clause << endl;
+ t << "clean-release-" << item << ": " << BLD_INF_FILENAME << endl;
+ t << "\t$(SBS) reallyclean" << clause << endl;
+ }
+
+ foreach(QString item, armPlatforms) {
+ foreach(QString compilerVersion, allArmCompilerVersions) {
+ QString debugClause = configClause(item, debugBuild, compilerVersion, armClause);
+ QString releaseClause = configClause(item, releaseBuild, compilerVersion, armClause);
+ t << "debug-" << item << "-" << compilerVersion << ": " << BLD_INF_FILENAME << endl;
+ t << "\t$(SBS)" << debugClause << endl;
+ t << "clean-debug-" << item << "-" << compilerVersion << ": " << BLD_INF_FILENAME << endl;
+ t << "\t$(SBS) reallyclean" << debugClause << endl;
+ t << "release-" << item << "-" << compilerVersion << ": " << BLD_INF_FILENAME << endl;
+ t << "\t$(SBS)" << releaseClause << endl;
+ t << "clean-release-" << item << "-" << compilerVersion << ": " << BLD_INF_FILENAME << endl;
+ t << "\t$(SBS) reallyclean" << releaseClause << endl;
+ }
}
t << endl;
@@ -344,7 +481,7 @@ void SymbianSbsv2MakefileGenerator::writeWrapperMakefile(QFile& wrapperFile, boo
t << endl << endl;
}
- // Add all extra targets including extra compiler targest also to wrapper makefile,
+ // Add all extra targets including extra compiler targets also to wrapper makefile,
// even though many of them may have already been added to bld.inf as FLMs.
// This is to enable use of targets like 'mocables', which call targets generated by extra compilers.
if (targetType != TypeSubdirs) {
@@ -365,32 +502,6 @@ void SymbianSbsv2MakefileGenerator::writeWrapperMakefile(QFile& wrapperFile, boo
}
t << endl << endl;
- t << "clean-debug: " << BLD_INF_FILENAME << endl;
- t << "\t$(SBS) reallyclean";
- foreach(QString clause, debugClauses) {
- t << clause;
- }
- t << endl << endl;
- t << "clean-release: " << BLD_INF_FILENAME << endl;
- t << "\t$(SBS) reallyclean";
- foreach(QString clause, releaseClauses) {
- t << clause;
- }
- t << endl << endl;
-
- // For more specific builds, targets are in this form: clean-build-platform, e.g. clean-release-armv5
- foreach(QString item, debugPlatforms) {
- t << "clean-debug-" << item << ": " << BLD_INF_FILENAME << endl;
- t << "\t$(SBS) reallyclean";
- t << configClause(item, debugBuild, winscwClause, gcceClause, genericClause);
- t << endl;
- }
- foreach(QString item, releasePlatforms) {
- t << "clean-release-" << item << ": " << BLD_INF_FILENAME << endl;
- t << "\t$(SBS) reallyclean";
- t << configClause(item, releaseBuild, winscwClause, gcceClause, genericClause);
- t << endl;
- }
t << endl;
}