--- a/qmake/generators/symbian/symmake_sbsv2.cpp Fri Sep 17 08:34:18 2010 +0300
+++ b/qmake/generators/symbian/symmake_sbsv2.cpp Mon Oct 04 01:19:32 2010 +0300
@@ -56,6 +56,12 @@
#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 BUILD_DEBUG "udeb"
+#define BUILD_RELEASE "urel"
// Copies Qt FLMs to correct location under epocroot.
// This is not done by configure as it is possible to change epocroot after configure.
@@ -94,6 +100,67 @@
}
}
+QString SymbianSbsv2MakefileGenerator::gcceVersion()
+{
+ 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());
+ }
+ }
+ // 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;
+ }
+ }
+ }
+ }
+ }
+
+ // Indicate undetected version to avoid rechecking multiple times
+ if (gcceVersionStr.isEmpty())
+ gcceVersionStr = UNDETECTED_GCCE_VERSION;
+
+ return gcceVersionStr;
+}
+
+QString SymbianSbsv2MakefileGenerator::configClause(QString &platform,
+ QString &build,
+ QString &winscwClauseTemplate,
+ QString &gcceClauseTemplate,
+ QString &genericClauseTemplate)
+{
+ 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);
+ return retval;
+}
+
void SymbianSbsv2MakefileGenerator::writeSbsDeploymentList(const DeploymentList& depList, QTextStream& t)
{
for (int i = 0; i < depList.size(); ++i) {
@@ -123,21 +190,54 @@
void SymbianSbsv2MakefileGenerator::writeWrapperMakefile(QFile& wrapperFile, bool isPrimaryMakefile)
{
+ static QString debugBuild(BUILD_DEBUG);
+ static QString releaseBuild(BUILD_RELEASE);
+
QStringList allPlatforms;
foreach(QString platform, project->values("SYMBIAN_PLATFORMS")) {
allPlatforms << platform.toLower();
}
- QStringList debugPlatforms = allPlatforms;
- QStringList releasePlatforms = allPlatforms;
- releasePlatforms.removeAll("winscw"); // No release for emulator
-
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;
+
+ 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 allClauses;
+ QStringList debugClauses;
+ QStringList releaseClauses;
+
+ QStringList debugPlatforms = allPlatforms;
+ QStringList releasePlatforms = allPlatforms;
+ releasePlatforms.removeAll(PLATFORM_WINSCW); // No release for emulator
+
+ foreach(QString item, debugPlatforms) {
+ if (item != PLATFORM_ARMV5 || !stripArmv5)
+ debugClauses << configClause(item, debugBuild, winscwClause, gcceClause, genericClause);
+ }
+ foreach(QString item, releasePlatforms) {
+ if (item != PLATFORM_ARMV5 || !stripArmv5)
+ releaseClauses << configClause(item, releaseBuild, winscwClause, gcceClause, genericClause);
+ }
+ allClauses << debugClauses << releaseClauses;
+
QTextStream t(&wrapperFile);
t << "# ==============================================================================" << endl;
@@ -177,9 +277,9 @@
}
t << endl;
t << "first: default" << endl;
- if (debugPlatforms.contains("winscw"))
+ if (debugPlatforms.contains(PLATFORM_WINSCW))
t << "default: debug-winscw";
- else if (debugPlatforms.contains("armv5"))
+ else if (debugPlatforms.contains(PLATFORM_ARMV5))
t << "default: debug-armv5";
else if (debugPlatforms.size())
t << "default: debug-" << debugPlatforms.first();
@@ -192,60 +292,61 @@
} else {
t << "all: debug release" << endl;
t << endl;
+
+ QString qmakeCmd = "\t$(QMAKE) \"" + project->projectFile() + "\" " + buildArgs();
+
t << "qmake:" << endl;
- t << "\t$(QMAKE) -spec symbian-sbsv2 -o \"" << fileInfo(Option::output.fileName()).fileName()
- << "\" \"" << project->projectFile() << "\"" << endl;
- t << endl;
- t << BLD_INF_FILENAME ":" << endl;
- t << "\t$(QMAKE)" << endl;
+ t << qmakeCmd << endl;
t << endl;
- QString winscw("winscw");
+ t << BLD_INF_FILENAME ": " << project->projectFile() << endl;
+ t << qmakeCmd << endl;
+ t << endl;
+
+ QString currentClause;
+
t << "debug: " << BLD_INF_FILENAME << endl;
t << "\t$(SBS)";
- foreach(QString item, debugPlatforms) {
- if(QString::compare(item, winscw) == 0)
- t << " -c " << item << "_udeb.mwccinc" << testClause;
- else
- t << " -c " << item << "_udeb" << testClause;
+ foreach(QString item, debugClauses) {
+ t << item;
}
t << endl;
t << "release: " << BLD_INF_FILENAME << endl;
t << "\t$(SBS)";
- foreach(QString item, releasePlatforms) {
- if(QString::compare(item, winscw) == 0)
- t << " -c " << item << "_urel.mwccinc" << testClause;
- else
- t << " -c " << item << "_urel" << testClause;
+ foreach(QString item, releaseClauses) {
+ t << item;
}
t << endl;
// For more specific builds, targets are in this form: build-platform, e.g. release-armv5
foreach(QString item, debugPlatforms) {
t << "debug-" << item << ": " << BLD_INF_FILENAME << endl;
- if(QString::compare(item, winscw) == 0)
- t << "\t$(SBS) -c " << item << "_udeb.mwccinc" << testClause << endl;
- else
- t << "\t$(SBS) -c " << item << "_udeb" << testClause << endl;
+ t << "\t$(SBS)";
+ t << configClause(item, debugBuild, winscwClause, gcceClause, genericClause);
+ t << endl;
}
foreach(QString item, releasePlatforms) {
t << "release-" << item << ": " << BLD_INF_FILENAME << endl;
- if(QString::compare(item, winscw) == 0)
- t << "\t$(SBS) -c " << item << "_urel.mwccinc" << testClause << endl;
- else
- t << "\t$(SBS) -c " << item << "_urel" << testClause << endl;
+ t << "\t$(SBS)";
+ t << configClause(item, releaseBuild, winscwClause, gcceClause, genericClause);
+ t << endl;
}
t << endl;
t << "export: " << BLD_INF_FILENAME << endl;
- t << "\t$(SBS) export" << endl;
- t << endl;
+ t << "\t$(SBS) export";
+ foreach(QString clause, allClauses) {
+ t << clause;
+ }
+ t << endl << endl;
t << "cleanexport: " << BLD_INF_FILENAME << endl;
- t << "\t$(SBS) cleanexport" << endl;
- t << endl;
-
+ t << "\t$(SBS) cleanexport";
+ foreach(QString clause, allClauses) {
+ t << clause;
+ }
+ t << endl << endl;
}
// Add all extra targets including extra compiler targest also to wrapper makefile,
@@ -263,30 +364,37 @@
generateDistcleanTargets(t);
t << "clean: " << BLD_INF_FILENAME << endl;
- t << "\t-$(SBS) reallyclean" << endl;
- t << endl;
+ t << "\t-$(SBS) reallyclean";
+ foreach(QString clause, allClauses) {
+ t << clause;
+ }
+ t << endl << endl;
t << "clean-debug: " << BLD_INF_FILENAME << endl;
t << "\t$(SBS) reallyclean";
- foreach(QString item, debugPlatforms) {
- t << " -c " << item << "_udeb" << testClause;
+ foreach(QString clause, debugClauses) {
+ t << clause;
}
- t << endl;
+ t << endl << endl;
t << "clean-release: " << BLD_INF_FILENAME << endl;
t << "\t$(SBS) reallyclean";
- foreach(QString item, releasePlatforms) {
- t << " -c " << item << "_urel" << testClause;
+ foreach(QString clause, releaseClauses) {
+ t << clause;
}
- t << endl;
+ 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 -c " << item << "_udeb" << testClause << 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 -c " << item << "_urel" << testClause << endl;
+ t << "\t$(SBS) reallyclean";
+ t << configClause(item, releaseBuild, winscwClause, gcceClause, genericClause);
+ t << endl;
}
t << endl;
}
@@ -310,6 +418,28 @@
}
}
+ QMap<QString, QString> commandsToReplace;
+ commandsToReplace.insert(project->values("QMAKE_COPY").join(" "),
+ project->values("QMAKE_SBSV2_COPY").join(" "));
+ commandsToReplace.insert(project->values("QMAKE_COPY_DIR").join(" "),
+ project->values("QMAKE_SBSV2_COPY_DIR").join(" "));
+ commandsToReplace.insert(project->values("QMAKE_MOVE").join(" "),
+ project->values("QMAKE_SBSV2_MOVE").join(" "));
+ commandsToReplace.insert(project->values("QMAKE_DEL_FILE").join(" "),
+ project->values("QMAKE_SBSV2_DEL_FILE").join(" "));
+ commandsToReplace.insert(project->values("QMAKE_MKDIR").join(" "),
+ project->values("QMAKE_SBSV2_MKDIR").join(" "));
+ commandsToReplace.insert(project->values("QMAKE_DEL_DIR").join(" "),
+ project->values("QMAKE_SBSV2_DEL_DIR").join(" "));
+ commandsToReplace.insert(project->values("QMAKE_DEL_TREE").join(" "),
+ project->values("QMAKE_SBSV2_DEL_TREE").join(" "));
+
+ // If commandItem starts with any $$QMAKE_* commands, do a replace for SBS equivalent
+ // Command replacement is done only for the start of the command or right after
+ // concatenation operators (&& and ||), as otherwise unwanted replacements might occur.
+ static QString cmdFind("(^|&&\\s*|\\|\\|\\s*)%1");
+ static QString cmdReplace("\\1%1");
+
// Write extra compilers and targets to initialize QMAKE_ET_* variables
// Cache results to avoid duplicate calls when creating wrapper makefile
QTextStream extraCompilerStream(&extraCompilersCache);
@@ -321,13 +451,7 @@
// are not necessary.
QStringList allPreDeps;
foreach(QString item, project->values("PRE_TARGETDEPS")) {
- // Predeps get mangled in windows, so fix them to more sbsv2 friendly format
-#if defined(Q_OS_WIN)
- if (item.mid(1, 1) == ":")
- item = item.mid(0, 1).toUpper().append(item.mid(1)); // Fix drive to uppercase
-#endif
- item.replace("\\", "/");
- allPreDeps << escapeDependencyPath(item);
+ allPreDeps.append(fileInfo(item).absoluteFilePath());
}
foreach (QString item, project->values("GENERATED_SOURCES")) {
@@ -357,7 +481,6 @@
QStringList deps = project->values(QLatin1String("QMAKE_INTERNAL_ET_PARSED_DEPS.") + item + targetItem);
QString commandItem = project->values(QLatin1String("QMAKE_INTERNAL_ET_PARSED_CMD.") + item + targetItem).join(" ");
-
// Make sure all deps paths are absolute
QString absoluteDeps;
foreach (QString depItem, deps) {
@@ -371,6 +494,18 @@
t << "OPTION PREDEP_TARGET " << absoluteTarget << endl;
t << "OPTION DEPS " << absoluteDeps << endl;
+ // Iterate command replacements in reverse alphabetical order of keys so
+ // that keys which are starts of other longer keys are iterated after longer keys.
+ QMapIterator<QString, QString> cmdIter(commandsToReplace);
+ cmdIter.toBack();
+ while (cmdIter.hasPrevious()) {
+ cmdIter.previous();
+ if (commandItem.contains(cmdIter.key())) {
+ commandItem.replace(QRegExp(cmdFind.arg(cmdIter.key())),
+ cmdReplace.arg(cmdIter.value()));
+ }
+ }
+
if (commandItem.indexOf("$(INCPATH)") != -1)
commandItem.replace("$(INCPATH)", incPath.join(" "));
if (commandItem.indexOf("$(DEFINES)") != -1)
@@ -388,8 +523,10 @@
t << endl;
//loc change starts
- QString translationFilename = project->first("TRANSLATIONS");
- if (!project->values("SYMBIANTRANSLATIONS").isEmpty() && !translationFilename.isEmpty()) {
+ //QString translationFilename = project->first("TRANSLATIONS");
+ if (!project->values("SYMBIANTRANSLATIONS").isEmpty() && !project->first("TRANSLATIONS").isEmpty()) {
+ QStringList translationFilenames = project->values("TRANSLATIONS");
+ foreach (const QString &translationFilename, translationFilenames) {
QStringList symbianTranslations = project->values("SYMBIANTRANSLATIONS");
QString symbianTrPath = project->first("SYMBIANTRANSLATIONDIR");
QString symbianTrSrcPath = project->first("SYMBIANTRANSLATIONSRCDIR");
@@ -451,6 +588,7 @@
t << endl;
}
}
+ }
//QTP: loc change end
// Write deployment rules