qmake/generators/symbian/symmake.cpp
changeset 3 41300fa6a67c
parent 0 1918ee327afb
child 4 3b1da2848fc7
child 7 f7bc934e204c
child 18 2f34d5167611
equal deleted inserted replaced
2:56cd8111b7f7 3:41300fa6a67c
    47 #include <qstringlist.h>
    47 #include <qstringlist.h>
    48 #include <qdir.h>
    48 #include <qdir.h>
    49 #include <qdatetime.h>
    49 #include <qdatetime.h>
    50 #include <stdlib.h>
    50 #include <stdlib.h>
    51 #include <qdebug.h>
    51 #include <qdebug.h>
       
    52 #include <qxmlstream.h>
       
    53 #include <qsettings>
    52 
    54 
    53 #define RESOURCE_DIRECTORY_MMP "/resource/apps"
    55 #define RESOURCE_DIRECTORY_MMP "/resource/apps"
    54 #define RESOURCE_DIRECTORY_RESOURCE "\\\\resource\\\\apps\\\\"
    56 #define RESOURCE_DIRECTORY_RESOURCE "\\\\resource\\\\apps\\\\"
    55 #define REGISTRATION_RESOURCE_DIRECTORY_HW "/private/10003a3f/import/apps"
    57 #define REGISTRATION_RESOURCE_DIRECTORY_HW "/private/10003a3f/import/apps"
    56 #define PLUGIN_COMMON_DEF_FILE_FOR_MMP "./plugin_common.def"
    58 #define PLUGIN_COMMON_DEF_FILE_FOR_MMP "./plugin_common.def"
    72 #define MMP_TARGETTYPE "TARGETTYPE"
    74 #define MMP_TARGETTYPE "TARGETTYPE"
    73 #define MMP_SECUREID "SECUREID"
    75 #define MMP_SECUREID "SECUREID"
    74 #define MMP_OPTION_CW "OPTION CW"
    76 #define MMP_OPTION_CW "OPTION CW"
    75 #define MMP_OPTION_ARMCC "OPTION ARMCC"
    77 #define MMP_OPTION_ARMCC "OPTION ARMCC"
    76 #define MMP_OPTION_GCCE "OPTION GCCE"
    78 #define MMP_OPTION_GCCE "OPTION GCCE"
       
    79 #define MMP_LINKEROPTION_CW "LINKEROPTION CW"
       
    80 #define MMP_LINKEROPTION_ARMCC "LINKEROPTION ARMCC"
       
    81 #define MMP_LINKEROPTION_GCCE "LINKEROPTION GCCE"
       
    82 #define MMP_CAPABILITY "CAPABILITY"
       
    83 #define MMP_EPOCALLOWDLLDATA "EPOCALLOWDLLDATA"
       
    84 #define MMP_EPOCHEAPSIZE "EPOCHEAPSIZE"
       
    85 #define MMP_EPOCSTACKSIZE "EPOCSTACKSIZE"
       
    86 #define MMP_UID "UID"
       
    87 #define MMP_VENDORID "VENDORID"
       
    88 #define MMP_VERSION "VERSION"
       
    89 #define MMP_START_RESOURCE "START RESOURCE"
       
    90 #define MMP_END_RESOURCE "END"
    77 
    91 
    78 #define SIS_TARGET "sis"
    92 #define SIS_TARGET "sis"
    79 #define OK_SIS_TARGET "ok_sis"
    93 #define OK_SIS_TARGET "ok_sis"
    80 #define FAIL_SIS_NOPKG_TARGET "fail_sis_nopkg"
    94 #define FAIL_SIS_NOPKG_TARGET "fail_sis_nopkg"
    81 #define FAIL_SIS_NOCACHE_TARGET "fail_sis_nocache"
    95 #define FAIL_SIS_NOCACHE_TARGET "fail_sis_nocache"
   170 
   184 
   171 void SymbianMakefileGenerator::writeHeader(QTextStream &t)
   185 void SymbianMakefileGenerator::writeHeader(QTextStream &t)
   172 {
   186 {
   173     t << "// ============================================================================" << endl;
   187     t << "// ============================================================================" << endl;
   174     t << "// * Makefile for building: " << escapeFilePath(var("TARGET")) << endl;
   188     t << "// * Makefile for building: " << escapeFilePath(var("TARGET")) << endl;
   175     t << "// * Generated by qmake (" << qmake_version() << ") (Qt " << QT_VERSION_STR << ") on: ";
   189     t << "// * Generated by qmake (" << qmake_version() << ") (Qt " QT_VERSION_STR ") on: ";
   176     t << QDateTime::currentDateTime().toString(Qt::ISODate) << endl;
   190     t << QDateTime::currentDateTime().toString(Qt::ISODate) << endl;
   177     t << "// * This file is generated by qmake and should not be modified by the" << endl;
   191     t << "// * This file is generated by qmake and should not be modified by the" << endl;
   178     t << "// * user." << endl;
   192     t << "// * user." << endl;
   179     t << "// * Project:  " << fileFixify(project->projectFile()) << endl;
   193     t << "// * Project:  " << fileFixify(project->projectFile()) << endl;
   180     t << "// * Template: " << var("TEMPLATE") << endl;
   194     t << "// * Template: " << var("TEMPLATE") << endl;
   224 
   238 
   225     if (generatePkg) {
   239     if (generatePkg) {
   226         generatePkgFile(iconFile);
   240         generatePkgFile(iconFile);
   227     }
   241     }
   228 
   242 
   229     writeBldInfContent(t, generatePkg);
   243     writeBldInfContent(t, generatePkg, iconFile);
   230 
   244 
   231     // Generate empty wrapper makefile here, because wrapper makefile must exist before writeMkFile,
   245     // Generate empty wrapper makefile here, because wrapper makefile must exist before writeMkFile,
   232     // but all required data is not yet available.
   246     // but all required data is not yet available.
   233     bool isPrimaryMakefile = true;
   247     bool isPrimaryMakefile = true;
   234     QString wrapperFileName("Makefile");
   248     QString wrapperFileName("Makefile");
   274     if (targetType == TypeExe) {
   288     if (targetType == TypeExe) {
   275         if (!project->values("CONFIG").contains("no_icon", Qt::CaseInsensitive)) {
   289         if (!project->values("CONFIG").contains("no_icon", Qt::CaseInsensitive)) {
   276             writeRegRssFile(userRssRules);
   290             writeRegRssFile(userRssRules);
   277             writeRssFile(numberOfIcons, iconFile);
   291             writeRssFile(numberOfIcons, iconFile);
   278             writeLocFile(symbianLangCodes);
   292             writeLocFile(symbianLangCodes);
       
   293             if (!project->values("SYMBIANTRANSLATIONS").isEmpty())
       
   294                 writeSymbianLocFile(symbianLangCodes);        
   279         }
   295         }
   280     }
   296     }
   281 
   297 
   282     writeCustomDefFile();
   298     writeCustomDefFile();
   283     writeWrapperMakefile(wrapperMakefile, isPrimaryMakefile);
   299     writeWrapperMakefile(wrapperMakefile, isPrimaryMakefile);
   399                  .arg(epocRoot())
   415                  .arg(epocRoot())
   400                  .arg(fixedTarget + "_reg.rsc")
   416                  .arg(fixedTarget + "_reg.rsc")
   401                  .arg(installPathRegResource)
   417                  .arg(installPathRegResource)
   402                  .arg(fixedTarget + "_reg.rsc") << endl;
   418                  .arg(fixedTarget + "_reg.rsc") << endl;
   403 
   419 
   404             QString myIconFile = iconFile;
       
   405             myIconFile = myIconFile.replace("\\\\", "\\");
       
   406 
       
   407             if (!iconFile.isEmpty())  {
   420             if (!iconFile.isEmpty())  {
   408                 t << QString("\"%1epoc32/data/z%2\"    - \"!:%3\"")
   421                 t << QString("\"%1epoc32/data/z%2\"    - \"!:%3\"")
   409                      .arg(epocRoot())
   422                      .arg(epocRoot())
   410                      .arg(QString(myIconFile).replace('\\','/'))
   423                      .arg(iconFile)
   411                      .arg(myIconFile) << endl << endl;
   424                      .arg(QDir::toNativeSeparators(iconFile)) << endl << endl;
   412             }
   425             }
   413         }
   426         }
   414     }
   427     }
   415 
   428 
   416     // deploy any additional DEPLOYMENT  files
   429     // deploy any additional DEPLOYMENT  files
   471             }
   484             }
   472             generatedFiles << ft.fileName();
   485             generatedFiles << ft.fileName();
   473             QTextStream t(&ft);
   486             QTextStream t(&ft);
   474 
   487 
   475             t << "; ==============================================================================" << endl;
   488             t << "; ==============================================================================" << endl;
   476             t << "; Generated by qmake (" << qmake_version() << ") (Qt " << QT_VERSION_STR << ") on: ";
   489             t << "; Generated by qmake (" << qmake_version() << ") (Qt " QT_VERSION_STR ") on: ";
   477             t << QDateTime::currentDateTime().toString(Qt::ISODate) << endl;
   490             t << QDateTime::currentDateTime().toString(Qt::ISODate) << endl;
   478             t << "; This file is generated by qmake and should not be modified by the" << endl;
   491             t << "; This file is generated by qmake and should not be modified by the" << endl;
   479             t << "; user." << endl;
   492             t << "; user." << endl;
   480             t << ";  Name        : " PLUGIN_COMMON_DEF_FILE_ACTUAL << endl;
   493             t << ";  Name        : " PLUGIN_COMMON_DEF_FILE_ACTUAL << endl;
   481             t << ";  Part of     : " << project->values("TARGET").join(" ") << endl;
   494             t << ";  Part of     : " << project->values("TARGET").join(" ") << endl;
   634     incpaths << project->values("HEADERS");
   647     incpaths << project->values("HEADERS");
   635     incpaths << srcincpaths;
   648     incpaths << srcincpaths;
   636     incpaths << project->values("UI_HEADERS_DIR");
   649     incpaths << project->values("UI_HEADERS_DIR");
   637     incpaths << project->values("UI_DIR");
   650     incpaths << project->values("UI_DIR");
   638 
   651 
   639     QString epocPath("epoc32");
       
   640     for (int j = 0; j < incpaths.size(); ++j) {
   652     for (int j = 0; j < incpaths.size(); ++j) {
   641         QString includepath = canonizePath(incpaths.at(j));
   653         QString includepath = canonizePath(incpaths.at(j));
   642         appendIfnotExist(sysincspaths, includepath);
   654         appendIfnotExist(sysincspaths, includepath);
   643         // As a workaround for Symbian toolchain insistence to treat include
   655         appendAbldTempDirs(sysincspaths, includepath);
   644         // statements as relative to source file rather than the file they appear in,
       
   645         // we generate extra temporary include directories to make
       
   646         // relative include paths used in various headers to work properly.
       
   647         // Note that this is not a fix-all solution; it's just a stop-gap measure
       
   648         // to make Qt itself build until toolchain can support relative includes in
       
   649         // a way that Qt expects.
       
   650         if (!includepath.contains(epocPath)) // No temp dirs for epoc includes
       
   651             appendIfnotExist(sysincspaths, includepath + QString("/" QT_EXTRA_INCLUDE_DIR));
       
   652     }
   656     }
   653 
   657 
   654     // Remove duplicate include path entries
   658     // Remove duplicate include path entries
   655     QStringList temporary;
   659     QStringList temporary;
   656     for (int i = 0; i < sysincspaths.size(); ++i) {
   660     for (int i = 0; i < sysincspaths.size(); ++i) {
   682 
   686 
   683     systeminclude.insert("SYSTEMINCLUDE", sysincspaths);
   687     systeminclude.insert("SYSTEMINCLUDE", sysincspaths);
   684 
   688 
   685     // Check MMP_RULES for singleton keywords that are overridden
   689     // Check MMP_RULES for singleton keywords that are overridden
   686     QStringList overridableMmpKeywords;
   690     QStringList overridableMmpKeywords;
   687     overridableMmpKeywords << QLatin1String(MMP_TARGETTYPE) << QLatin1String(MMP_OPTION_CW)
   691     QStringList restrictableMmpKeywords;
   688         << QLatin1String(MMP_OPTION_ARMCC) << QLatin1String(MMP_OPTION_GCCE);
   692     QStringList restrictedMmpKeywords;
       
   693     bool inResourceBlock = false;
       
   694 
       
   695     overridableMmpKeywords << QLatin1String(MMP_TARGETTYPE);
       
   696     restrictableMmpKeywords << QLatin1String(MMP_TARGET) << QLatin1String(MMP_SECUREID)
       
   697        << QLatin1String(MMP_OPTION_CW) << QLatin1String(MMP_OPTION_ARMCC)
       
   698        << QLatin1String(MMP_OPTION_GCCE) << QLatin1String(MMP_LINKEROPTION_CW)
       
   699        << QLatin1String(MMP_LINKEROPTION_ARMCC) << QLatin1String(MMP_LINKEROPTION_GCCE)
       
   700        << QLatin1String(MMP_CAPABILITY) << QLatin1String(MMP_EPOCALLOWDLLDATA)
       
   701        << QLatin1String(MMP_EPOCHEAPSIZE) << QLatin1String(MMP_EPOCSTACKSIZE)
       
   702        << QLatin1String(MMP_UID) << QLatin1String(MMP_VENDORID)
       
   703        << QLatin1String(MMP_VERSION);
   689 
   704 
   690     foreach (QString item, project->values("MMP_RULES")) {
   705     foreach (QString item, project->values("MMP_RULES")) {
   691         if (project->values(item).isEmpty()) {
   706         if (project->values(item).isEmpty()) {
   692             checkOverridability(overridableMmpKeywords, item);
   707             handleMmpRulesOverrides(item, inResourceBlock, restrictedMmpKeywords,
       
   708                                     restrictableMmpKeywords, overridableMmpKeywords);
   693         } else {
   709         } else {
   694             foreach (QString itemRow, project->values(item)) {
   710             foreach (QString itemRow, project->values(item)) {
   695                 checkOverridability(overridableMmpKeywords, itemRow);
   711                 handleMmpRulesOverrides(itemRow, inResourceBlock, restrictedMmpKeywords,
   696             }
   712                                         restrictableMmpKeywords, overridableMmpKeywords);
   697         }
   713             }
   698     }
   714         }
   699 }
   715     }
   700 
   716 
   701 void SymbianMakefileGenerator::checkOverridability(QStringList &overridableKeywords, QString &checkString)
   717     if (restrictedMmpKeywords.size()) {
   702 {
   718         fprintf(stderr, "Warning: Restricted statements detected in MMP_RULES:\n"
   703     // Check if checkString contains overridable keyword and
   719                 "         (%s)\n"
   704     // add the keyword to overridden keywords list if so.
   720                 "         Use corresponding qmake variable(s) instead.\n",
       
   721                 qPrintable(restrictedMmpKeywords.join(", ")));
       
   722         }
       
   723 }
       
   724 
       
   725 void SymbianMakefileGenerator::handleMmpRulesOverrides(QString &checkString,
       
   726                                                        bool &inResourceBlock,
       
   727                                                        QStringList &restrictedMmpKeywords,
       
   728                                                        const QStringList &restrictableMmpKeywords,
       
   729                                                        const QStringList &overridableMmpKeywords)
       
   730 {
   705     QString simplifiedString = checkString.simplified();
   731     QString simplifiedString = checkString.simplified();
   706     foreach (QString item, overridableKeywords) {
   732 
   707         if (simplifiedString.startsWith(item))
   733     if (!inResourceBlock && simplifiedString.startsWith(MMP_START_RESOURCE, Qt::CaseInsensitive))
   708             appendIfnotExist(overriddenMmpKeywords, item);
   734         inResourceBlock = true;
   709     }
   735     else if (inResourceBlock && simplifiedString.startsWith(MMP_END_RESOURCE, Qt::CaseInsensitive))
   710 }
   736         inResourceBlock = false;
       
   737 
       
   738     // Allow restricted and overridable items in RESOURCE blocks as those do not actually
       
   739     // override anything.
       
   740     if (!inResourceBlock) {
       
   741         appendKeywordIfMatchFound(overriddenMmpKeywords, overridableMmpKeywords, simplifiedString);
       
   742         appendKeywordIfMatchFound(restrictedMmpKeywords, restrictableMmpKeywords, simplifiedString);
       
   743     }
       
   744 }
       
   745 
       
   746 void SymbianMakefileGenerator::appendKeywordIfMatchFound(QStringList &list,
       
   747                                                          const QStringList &keywordList,
       
   748                                                          QString &checkString)
       
   749 {
       
   750     // Check if checkString starts with any supplied keyword and
       
   751     // add the found keyword to list if it does.
       
   752     foreach (QString item, keywordList) {
       
   753         if (checkString.startsWith(QString(item).append(" "), Qt::CaseInsensitive)
       
   754             || checkString.compare(item, Qt::CaseInsensitive) == 0) {
       
   755             appendIfnotExist(list, item);
       
   756         }
       
   757     }
       
   758 }
       
   759 
   711 
   760 
   712 bool SymbianMakefileGenerator::removeDuplicatedStrings(QStringList &stringList)
   761 bool SymbianMakefileGenerator::removeDuplicatedStrings(QStringList &stringList)
   713 {
   762 {
   714     QStringList tmpStringList;
   763     QStringList tmpStringList;
   715 
   764 
   727 }
   776 }
   728 
   777 
   729 void SymbianMakefileGenerator::writeMmpFileHeader(QTextStream &t)
   778 void SymbianMakefileGenerator::writeMmpFileHeader(QTextStream &t)
   730 {
   779 {
   731     t << "// ==============================================================================" << endl;
   780     t << "// ==============================================================================" << endl;
   732     t << "// Generated by qmake (" << qmake_version() << ") (Qt " << QT_VERSION_STR << ") on: ";
   781     t << "// Generated by qmake (" << qmake_version() << ") (Qt " QT_VERSION_STR ") on: ";
   733     t << QDateTime::currentDateTime().toString(Qt::ISODate) << endl;
   782     t << QDateTime::currentDateTime().toString(Qt::ISODate) << endl;
   734     t << "// This file is generated by qmake and should not be modified by the" << endl;
   783     t << "// This file is generated by qmake and should not be modified by the" << endl;
   735     t << "// user." << endl;
   784     t << "// user." << endl;
   736     t << "//  Name        : " << escapeFilePath(fileFixify(project->projectFile().remove(project->projectFile().length() - 4, 4))) << Option::mmp_ext << endl;
   785     t << "//  Name        : " << escapeFilePath(fileFixify(project->projectFile().remove(project->projectFile().length() - 4, 4))) << Option::mmp_ext << endl;
   737     t << "// ==============================================================================" << endl << endl;
   786     t << "// ==============================================================================" << endl << endl;
   816     t << endl;
   865     t << endl;
   817 }
   866 }
   818 
   867 
   819 void SymbianMakefileGenerator::addMacro(QTextStream& t, const QString& value)
   868 void SymbianMakefileGenerator::addMacro(QTextStream& t, const QString& value)
   820 {
   869 {
   821     t << "MACRO" << "\t\t" <<  value << endl;
   870     t << "MACRO\t\t" <<  value << endl;
   822 }
   871 }
   823 
   872 
   824 
   873 
   825 void SymbianMakefileGenerator::writeMmpFileTargetPart(QTextStream& t)
   874 void SymbianMakefileGenerator::writeMmpFileTargetPart(QTextStream& t)
   826 {
   875 {
   827     bool skipTargetType = overriddenMmpKeywords.contains(MMP_TARGETTYPE);
   876     bool skipTargetType = overriddenMmpKeywords.contains(MMP_TARGETTYPE);
   828 
   877 
   829     if (targetType == TypeExe) {
   878     if (targetType == TypeExe) {
   830         t << MMP_TARGET << "\t\t" << fixedTarget << ".exe" << endl;
   879         t << MMP_TARGET "\t\t" << fixedTarget << ".exe" << endl;
   831         if (!skipTargetType) {
   880         if (!skipTargetType) {
   832             if (project->values("CONFIG").contains("stdbinary", Qt::CaseInsensitive))
   881             if (project->values("CONFIG").contains("stdbinary", Qt::CaseInsensitive))
   833                 t << MMP_TARGETTYPE << "\t\t" << "STDEXE" << endl;
   882                 t << MMP_TARGETTYPE "\t\tSTDEXE" << endl;
   834             else
   883             else
   835                 t << MMP_TARGETTYPE << "\t\t" << "EXE" << endl;
   884                 t << MMP_TARGETTYPE "\t\tEXE" << endl;
   836         }
   885         }
   837     } else if (targetType == TypeDll || targetType == TypePlugin) {
   886     } else if (targetType == TypeDll || targetType == TypePlugin) {
   838         t << MMP_TARGET << "\t\t" << fixedTarget << ".dll" << endl;
   887         t << MMP_TARGET "\t\t" << fixedTarget << ".dll" << endl;
   839         if (!skipTargetType) {
   888         if (!skipTargetType) {
   840             if (project->values("CONFIG").contains("stdbinary", Qt::CaseInsensitive))
   889             if (project->values("CONFIG").contains("stdbinary", Qt::CaseInsensitive))
   841                 t << MMP_TARGETTYPE << "\t\t" << "STDDLL" << endl;
   890                 t << MMP_TARGETTYPE "\t\tSTDDLL" << endl;
   842             else
   891             else
   843                 t << MMP_TARGETTYPE << "\t\t" << "DLL" << endl;
   892                 t << MMP_TARGETTYPE "\t\tDLL" << endl;
   844         }
   893         }
   845     } else if (targetType == TypeLib) {
   894     } else if (targetType == TypeLib) {
   846         t << MMP_TARGET << "\t\t" << fixedTarget << ".lib" << endl;
   895         t << MMP_TARGET "\t\t" << fixedTarget << ".lib" << endl;
   847         if (!skipTargetType) {
   896         if (!skipTargetType) {
   848             if (project->values("CONFIG").contains("stdbinary", Qt::CaseInsensitive))
   897             if (project->values("CONFIG").contains("stdbinary", Qt::CaseInsensitive))
   849                 t << MMP_TARGETTYPE << "\t\t" << "STDLIB" << endl;
   898                 t << MMP_TARGETTYPE "\t\tSTDLIB" << endl;
   850             else
   899             else
   851                 t << MMP_TARGETTYPE << "\t\t" << "LIB" << endl;
   900                 t << MMP_TARGETTYPE "\t\tLIB" << endl;
   852         }
   901         }
   853     } else {
   902     } else {
   854         fprintf(stderr, "Error: Unexpected targettype (%d) in SymbianMakefileGenerator::writeMmpFileTargetPart\n", targetType);
   903         fprintf(stderr, "Error: Unexpected targettype (%d) in SymbianMakefileGenerator::writeMmpFileTargetPart\n", targetType);
   855     }
   904     }
   856 
   905 
   857     t << endl;
   906     t << endl;
   858 
   907 
   859     t << "UID" << "\t\t" << uid2 << " " << uid3 << endl;
   908     t << MMP_UID "\t\t" << uid2 << " " << uid3 << endl;
   860 
   909 
   861     if (0 != project->values("TARGET.SID").size()) {
   910     if (0 != project->values("TARGET.SID").size()) {
   862         t << MMP_SECUREID << "\t\t" << project->values("TARGET.SID").join(" ") << endl;
   911         t << MMP_SECUREID "\t\t" << project->values("TARGET.SID").join(" ") << endl;
   863     } else {
   912     } else {
   864         if (0 == uid3.size())
   913         if (0 == uid3.size())
   865             t << MMP_SECUREID << "\t\t" << "0" << endl;
   914             t << MMP_SECUREID "\t\t0" << endl;
   866         else
   915         else
   867             t << MMP_SECUREID << "\t\t" << uid3 << endl;
   916             t << MMP_SECUREID "\t\t" << uid3 << endl;
   868     }
   917     }
   869 
   918 
   870     // default value used from mkspecs is 0
   919     // default value used from mkspecs is 0
   871     if (0 != project->values("TARGET.VID").size()) {
   920     if (0 != project->values("TARGET.VID").size()) {
   872         t << "VENDORID" << "\t\t" << project->values("TARGET.VID").join(" ") << endl;
   921         t << MMP_VENDORID "\t\t" << project->values("TARGET.VID").join(" ") << endl;
   873     }
   922     }
   874 
   923 
   875     t << endl;
   924     t << endl;
   876 
   925 
   877     if (0 != project->first("TARGET.EPOCSTACKSIZE").size())
   926     if (0 != project->first("TARGET.EPOCSTACKSIZE").size())
   878         t << "EPOCSTACKSIZE" << "\t\t" << project->first("TARGET.EPOCSTACKSIZE") << endl;
   927         t << MMP_EPOCSTACKSIZE "\t\t" << project->first("TARGET.EPOCSTACKSIZE") << endl;
   879     if (0 != project->values("TARGET.EPOCHEAPSIZE").size())
   928     if (0 != project->values("TARGET.EPOCHEAPSIZE").size())
   880         t << "EPOCHEAPSIZE" << "\t\t" << project->values("TARGET.EPOCHEAPSIZE").join(" ") << endl;
   929         t << MMP_EPOCHEAPSIZE "\t\t" << project->values("TARGET.EPOCHEAPSIZE").join(" ") << endl;
   881     if (0 != project->values("TARGET.EPOCALLOWDLLDATA").size())
   930     if (0 != project->values("TARGET.EPOCALLOWDLLDATA").size())
   882         t << "EPOCALLOWDLLDATA" << endl;
   931         t << MMP_EPOCALLOWDLLDATA << endl;
   883 
   932 
   884     if (targetType == TypePlugin && !project->values("CONFIG").contains("stdbinary", Qt::CaseInsensitive)) {
   933     if (targetType == TypePlugin && !project->values("CONFIG").contains("stdbinary", Qt::CaseInsensitive)) {
   885         // Use custom def file for Qt plugins
   934         // Use custom def file for Qt plugins
   886         t << "DEFFILE " PLUGIN_COMMON_DEF_FILE_FOR_MMP << endl;
   935         t << "DEFFILE " PLUGIN_COMMON_DEF_FILE_FOR_MMP << endl;
   887     }
   936     }
   901 
   950 
   902         QString locTarget = fixedTarget;
   951         QString locTarget = fixedTarget;
   903         locTarget.append(".rss");
   952         locTarget.append(".rss");
   904 
   953 
   905         t << "SOURCEPATH\t\t\t. " << endl;
   954         t << "SOURCEPATH\t\t\t. " << endl;
   906         t << "LANG SC ";    // no endl
   955 
   907         foreach(QString lang, symbianLangCodes) {
   956         if (!project->values("SYMBIANTRANSLATIONS").isEmpty()) {
   908             t << lang << " "; // no endl
   957             t << MMP_START_RESOURCE "\t\t" << locTarget << endl;
   909         }
   958             t << "LANGUAGE_IDS" << endl;
   910         t << endl;
   959             t << "HEADER" << endl;
   911         t << "START RESOURCE\t\t" << locTarget << endl;
   960             t << "TARGETPATH\t\t\t" RESOURCE_DIRECTORY_MMP << endl;
   912         t << "HEADER" << endl;
   961             t << MMP_END_RESOURCE << endl << endl;
   913         t << "TARGETPATH\t\t\t" RESOURCE_DIRECTORY_MMP << endl;
   962         } else {
   914         t << "END" << endl << endl;
   963             t << "LANG SC ";    // no endl
       
   964             foreach(QString lang, symbianLangCodes) {
       
   965                 t << lang << " "; // no endl
       
   966             }
       
   967             t << endl;
       
   968             t << MMP_START_RESOURCE "\t\t" << locTarget << endl;
       
   969             t << "HEADER" << endl;
       
   970             t << "TARGETPATH\t\t\t" RESOURCE_DIRECTORY_MMP << endl;
       
   971             t << MMP_END_RESOURCE << endl << endl;
       
   972         }
   915 
   973 
   916         QString regTarget = fixedTarget;
   974         QString regTarget = fixedTarget;
   917         regTarget.append("_reg.rss");
   975         regTarget.append("_reg.rss");
   918 
   976 
   919         t << "SOURCEPATH\t\t\t." << endl;
   977         t << "SOURCEPATH\t\t\t." << endl;
   920         t << "START RESOURCE\t\t" << regTarget << endl;
   978         t << MMP_START_RESOURCE "\t\t" << regTarget << endl;
   921         if (isForSymbianSbsv2())
   979         if (isForSymbianSbsv2())
   922             t << "DEPENDS " << fixedTarget << ".rsg" << endl;
   980             t << "DEPENDS " << fixedTarget << ".rsg" << endl;
   923         t << "TARGETPATH\t\t" REGISTRATION_RESOURCE_DIRECTORY_HW << endl;
   981         t << "TARGETPATH\t\t" REGISTRATION_RESOURCE_DIRECTORY_HW << endl;
   924         t << "END" << endl << endl;
   982         t << MMP_END_RESOURCE << endl << endl;
   925     }
   983     }
   926 }
   984 }
   927 
   985 
   928 void SymbianMakefileGenerator::writeMmpFileSystemIncludePart(QTextStream& t)
   986 void SymbianMakefileGenerator::writeMmpFileSystemIncludePart(QTextStream& t)
   929 {
   987 {
   931 
   989 
   932     for (QMap<QString, QStringList>::iterator it = systeminclude.begin(); it != systeminclude.end(); ++it) {
   990     for (QMap<QString, QStringList>::iterator it = systeminclude.begin(); it != systeminclude.end(); ++it) {
   933         QStringList values = it.value();
   991         QStringList values = it.value();
   934         for (int i = 0; i < values.size(); ++i) {
   992         for (int i = 0; i < values.size(); ++i) {
   935             QString handledPath = values.at(i);
   993             QString handledPath = values.at(i);
   936             t << "SYSTEMINCLUDE" << "\t\t" << fixPathForMmp(handledPath, current) << endl;
   994             t << "SYSTEMINCLUDE\t\t" << fixPathForMmp(handledPath, current) << endl;
   937         }
   995         }
   938     }
   996     }
   939 
   997 
   940     t << endl;
   998     t << endl;
   941 }
   999 }
   987 
  1045 
   988 void SymbianMakefileGenerator::writeMmpFileCapabilityPart(QTextStream& t)
  1046 void SymbianMakefileGenerator::writeMmpFileCapabilityPart(QTextStream& t)
   989 {
  1047 {
   990     if (0 != project->first("TARGET.CAPABILITY").size()) {
  1048     if (0 != project->first("TARGET.CAPABILITY").size()) {
   991         QStringList &capabilities = project->values("TARGET.CAPABILITY");
  1049         QStringList &capabilities = project->values("TARGET.CAPABILITY");
   992         t << "CAPABILITY" << "\t\t";
  1050         t << MMP_CAPABILITY "\t\t";
   993 
  1051 
   994         for (int i = 0; i < capabilities.size(); ++i) {
  1052         for (int i = 0; i < capabilities.size(); ++i) {
   995             QString cap = capabilities.at(i);
  1053             QString cap = capabilities.at(i);
   996             t << cap << " ";
  1054             t << cap << " ";
   997         }
  1055         }
   998     } else {
  1056     } else {
   999         t << "CAPABILITY" << "\t\t" << "None";
  1057         t << MMP_CAPABILITY "\t\tNone";
  1000     }
  1058     }
  1001     t << endl << endl;
  1059     t << endl << endl;
  1002 }
  1060 }
  1003 
  1061 
  1004 void SymbianMakefileGenerator::writeMmpFileCompilerOptionPart(QTextStream& t)
  1062 void SymbianMakefileGenerator::writeMmpFileCompilerOptionPart(QTextStream& t)
  1005 {
  1063 {
  1006     QString cw, armcc, gcce;
  1064     QString cw, armcc, gcce;
       
  1065     QString cwlink, armlink, gccelink;
  1007 
  1066 
  1008     if (0 != project->values("QMAKE_CXXFLAGS.CW").size()) {
  1067     if (0 != project->values("QMAKE_CXXFLAGS.CW").size()) {
  1009         cw.append(project->values("QMAKE_CXXFLAGS.CW").join(" "));
  1068         cw.append(project->values("QMAKE_CXXFLAGS.CW").join(" "));
  1010         cw.append(" ");
  1069         cw.append(" ");
  1011     }
  1070     }
  1051         armcc.append(" ");
  1110         armcc.append(" ");
  1052         gcce.append(project->values("QMAKE_CFLAGS").join(" "));
  1111         gcce.append(project->values("QMAKE_CFLAGS").join(" "));
  1053         gcce.append(" ");
  1112         gcce.append(" ");
  1054     }
  1113     }
  1055 
  1114 
       
  1115     if (0 != project->values("QMAKE_LFLAGS.CW").size()) {
       
  1116         cwlink.append(project->values("QMAKE_LFLAGS.CW").join(" "));
       
  1117         cwlink.append(" ");
       
  1118     }
       
  1119 
       
  1120     if (0 != project->values("QMAKE_LFLAGS.ARMCC").size()) {
       
  1121         armlink.append(project->values("QMAKE_LFLAGS.ARMCC").join(" "));
       
  1122         armlink.append(" ");
       
  1123     }
       
  1124 
       
  1125     if (0 != project->values("QMAKE_LFLAGS.GCCE").size()) {
       
  1126         gccelink.append(project->values("QMAKE_LFLAGS.GCCE").join(" "));
       
  1127         gccelink.append(" ");
       
  1128     }
       
  1129 
       
  1130     if (0 != project->values("QMAKE_LFLAGS").size()) {
       
  1131         cwlink.append(project->values("QMAKE_LFLAGS").join(" "));
       
  1132         cwlink.append(" ");
       
  1133         armlink.append(project->values("QMAKE_LFLAGS").join(" "));
       
  1134         armlink.append(" ");
       
  1135         gccelink.append(project->values("QMAKE_LFLAGS").join(" "));
       
  1136         gccelink.append(" ");
       
  1137     }
       
  1138 
  1056     if (!cw.isEmpty() && cw[cw.size()-1] == ' ')
  1139     if (!cw.isEmpty() && cw[cw.size()-1] == ' ')
  1057         cw.chop(1);
  1140         cw.chop(1);
  1058     if (!armcc.isEmpty() && armcc[armcc.size()-1] == ' ')
  1141     if (!armcc.isEmpty() && armcc[armcc.size()-1] == ' ')
  1059         armcc.chop(1);
  1142         armcc.chop(1);
  1060     if (!gcce.isEmpty() && gcce[gcce.size()-1] == ' ')
  1143     if (!gcce.isEmpty() && gcce[gcce.size()-1] == ' ')
  1061         gcce.chop(1);
  1144         gcce.chop(1);
  1062 
  1145     if (!cwlink.isEmpty() && cwlink[cwlink.size()-1] == ' ')
  1063     if (!cw.isEmpty() && !overriddenMmpKeywords.contains(MMP_OPTION_CW))
  1146         cwlink.chop(1);
       
  1147     if (!armlink.isEmpty() && armlink[armlink.size()-1] == ' ')
       
  1148         armlink.chop(1);
       
  1149     if (!gccelink.isEmpty() && gccelink[gccelink.size()-1] == ' ')
       
  1150         gccelink.chop(1);
       
  1151 
       
  1152     if (!cw.isEmpty())
  1064         t << MMP_OPTION_CW " " << cw <<  endl;
  1153         t << MMP_OPTION_CW " " << cw <<  endl;
  1065     if (!armcc.isEmpty() && !overriddenMmpKeywords.contains(MMP_OPTION_ARMCC))
  1154     if (!armcc.isEmpty())
  1066         t << MMP_OPTION_ARMCC " " << armcc <<  endl;
  1155         t << MMP_OPTION_ARMCC " " << armcc <<  endl;
  1067     if (!gcce.isEmpty() && !overriddenMmpKeywords.contains(MMP_OPTION_GCCE))
  1156     if (!gcce.isEmpty())
  1068         t << MMP_OPTION_GCCE " " << gcce <<  endl;
  1157         t << MMP_OPTION_GCCE " " << gcce <<  endl;
  1069 
  1158 
  1070     t <<  endl;
  1159     if (!cwlink.isEmpty())
       
  1160         t << MMP_LINKEROPTION_CW " " << cwlink <<  endl;
       
  1161     if (!armlink.isEmpty())
       
  1162         t << MMP_LINKEROPTION_ARMCC " " << armlink <<  endl;
       
  1163     if (!gccelink.isEmpty())
       
  1164         t << MMP_LINKEROPTION_GCCE " " << gccelink <<  endl;
       
  1165 
       
  1166     t << endl;
  1071 }
  1167 }
  1072 
  1168 
  1073 void SymbianMakefileGenerator::writeMmpFileBinaryVersionPart(QTextStream& t)
  1169 void SymbianMakefileGenerator::writeMmpFileBinaryVersionPart(QTextStream& t)
  1074 {
  1170 {
  1075     QString applicationVersion = project->first("VERSION");
  1171     QString applicationVersion = project->first("VERSION");
  1101         if (!applicationVersion.isEmpty())
  1197         if (!applicationVersion.isEmpty())
  1102             fprintf(stderr, "Invalid VERSION string: %s\n", qPrintable(applicationVersion));
  1198             fprintf(stderr, "Invalid VERSION string: %s\n", qPrintable(applicationVersion));
  1103         mmpVersion = "10.0"; // Default binary version for symbian is 10.0
  1199         mmpVersion = "10.0"; // Default binary version for symbian is 10.0
  1104     }
  1200     }
  1105 
  1201 
  1106     t << "VERSION " << mmpVersion  << endl;
  1202     t << MMP_VERSION " " << mmpVersion  << endl;
  1107 }
  1203 }
  1108 
  1204 
  1109 void SymbianMakefileGenerator::writeMmpFileRulesPart(QTextStream& t)
  1205 void SymbianMakefileGenerator::writeMmpFileRulesPart(QTextStream& t)
  1110 {
  1206 {
  1111     foreach(QString item, project->values("MMP_RULES")) {
  1207     foreach(QString item, project->values("MMP_RULES")) {
  1120             }
  1216             }
  1121         }
  1217         }
  1122     }
  1218     }
  1123 }
  1219 }
  1124 
  1220 
  1125 void SymbianMakefileGenerator::writeBldInfContent(QTextStream &t, bool addDeploymentExtension)
  1221 void SymbianMakefileGenerator::writeBldInfContent(QTextStream &t, bool addDeploymentExtension, const QString &iconFile)
  1126 {
  1222 {
  1127     // Read user defined bld inf rules
  1223     // Read user defined bld inf rules
  1128 
  1224 
  1129     QMap<QString, QStringList> userBldInfRules;
  1225     QMap<QString, QStringList> userBldInfRules;
  1130     for (QMap<QString, QStringList>::iterator it = project->variables().begin(); it != project->variables().end(); ++it) {
  1226     for (QMap<QString, QStringList>::iterator it = project->variables().begin(); it != project->variables().end(); ++it) {
  1242 
  1338 
  1243     t << endl << BLD_INF_TAG_EXTENSIONS << endl << endl;
  1339     t << endl << BLD_INF_TAG_EXTENSIONS << endl << endl;
  1244 
  1340 
  1245     // Generate extension rules
  1341     // Generate extension rules
  1246 
  1342 
  1247     writeBldInfExtensionRulesPart(t);
  1343     writeBldInfExtensionRulesPart(t, iconFile);
  1248 
  1344 
  1249     userItems = userBldInfRules.value(BLD_INF_TAG_EXTENSIONS);
  1345     userItems = userBldInfRules.value(BLD_INF_TAG_EXTENSIONS);
  1250     foreach(QString item, userItems)
  1346     foreach(QString item, userItems)
  1251         t << item << endl;
  1347         t << item << endl;
  1252     userBldInfRules.remove(BLD_INF_TAG_EXTENSIONS);
  1348     userBldInfRules.remove(BLD_INF_TAG_EXTENSIONS);
  1342             generatePrint(fileInfo(ft.fileName()).absoluteFilePath());
  1438             generatePrint(fileInfo(ft.fileName()).absoluteFilePath());
  1343             }
  1439             }
  1344         generatedFiles << ft.fileName();
  1440         generatedFiles << ft.fileName();
  1345         QTextStream t(&ft);
  1441         QTextStream t(&ft);
  1346         t << "// ============================================================================" << endl;
  1442         t << "// ============================================================================" << endl;
  1347         t << "// * Generated by qmake (" << qmake_version() << ") (Qt " << QT_VERSION_STR << ") on: ";
  1443         t << "// * Generated by qmake (" << qmake_version() << ") (Qt " QT_VERSION_STR ") on: ";
  1348         t << QDateTime::currentDateTime().toString(Qt::ISODate) << endl;
  1444         t << QDateTime::currentDateTime().toString(Qt::ISODate) << endl;
  1349         t << "// * This file is generated by qmake and should not be modified by the" << endl;
  1445         t << "// * This file is generated by qmake and should not be modified by the" << endl;
  1350         t << "// * user." << endl;
  1446         t << "// * user." << endl;
  1351         t << "// ============================================================================" << endl;
  1447         t << "// ============================================================================" << endl;
  1352         t << endl;
  1448         t << endl;
  1353         t << "#include <" << fixedTarget << ".rsg>" << endl;
  1449         t << "#include <" << fixedTarget << ".rsg>" << endl;
  1354         t << "#include <appinfo.rh>" << endl;
  1450         t << "#include <appinfo.rh>" << endl;
  1355         t << endl;
  1451         t << endl;
  1356         //t << "#include <data_caging_paths.hrh>" << "\n" << endl;
  1452         t << "UID2 KUidAppRegistrationResourceFile" << endl;
  1357         t << "UID2 " << "KUidAppRegistrationResourceFile" << endl;
       
  1358         t << "UID3 " << uid3 << endl << endl;
  1453         t << "UID3 " << uid3 << endl << endl;
  1359         t << "RESOURCE APP_REGISTRATION_INFO" << endl;
  1454         t << "RESOURCE APP_REGISTRATION_INFO" << endl;
  1360         t << "\t{" << endl;
  1455         t << "\t{" << endl;
  1361         t << "\tapp_file=\"" << fixedTarget << "\";" << endl;
  1456         t << "\tapp_file=\"" << fixedTarget << "\";" << endl;
  1362         t << "\tlocalisable_resource_file=\"" RESOURCE_DIRECTORY_RESOURCE << fixedTarget << "\";" << endl;
  1457         t << "\tlocalisable_resource_file=\"" RESOURCE_DIRECTORY_RESOURCE << fixedTarget << "\";" << endl;
  1380             generatePrint(fileInfo(ft.fileName()).absoluteFilePath());
  1475             generatePrint(fileInfo(ft.fileName()).absoluteFilePath());
  1381             }
  1476             }
  1382         generatedFiles << ft.fileName();
  1477         generatedFiles << ft.fileName();
  1383         QTextStream t(&ft);
  1478         QTextStream t(&ft);
  1384         t << "// ============================================================================" << endl;
  1479         t << "// ============================================================================" << endl;
  1385         t << "// * Generated by qmake (" << qmake_version() << ") (Qt " << QT_VERSION_STR << ") on: ";
  1480         t << "// * Generated by qmake (" << qmake_version() << ") (Qt " QT_VERSION_STR ") on: ";
  1386         t << QDateTime::currentDateTime().toString(Qt::ISODate) << endl;
  1481         t << QDateTime::currentDateTime().toString(Qt::ISODate) << endl;
  1387         t << "// * This file is generated by qmake and should not be modified by the" << endl;
  1482         t << "// * This file is generated by qmake and should not be modified by the" << endl;
  1388         t << "// * user." << endl;
  1483         t << "// * user." << endl;
  1389         t << "// ============================================================================" << endl;
  1484         t << "// ============================================================================" << endl;
  1390         t << endl;
  1485         t << endl;
  1391         t << "#include <appinfo.rh>" << endl;
  1486         t << "#include <appinfo.rh>" << endl;
  1392         t << "#include \"" << fixedTarget << ".loc\"" << endl;
  1487         if (!project->values("SYMBIANTRANSLATIONS").isEmpty())
       
  1488             t << "#include <" << fixedTarget << ".loc>" << endl;
       
  1489         else
       
  1490             t << "#include \"" << fixedTarget << ".loc\"" << endl;
  1393         t << endl;
  1491         t << endl;
  1394         t << "RESOURCE LOCALISABLE_APP_INFO r_localisable_app_info" << endl;
  1492         t << "RESOURCE LOCALISABLE_APP_INFO r_localisable_app_info" << endl;
  1395         t << "\t{" << endl;
  1493         t << "\t{" << endl;
  1396         t << "\tshort_caption = STRING_r_short_caption;" << endl;
  1494         t << "\tshort_caption = STRING_r_short_caption;" << endl;
  1397         t << "\tcaption_and_icon =" << endl;
  1495         t << "\tcaption_and_icon =" << endl;
  1398         t << "\tCAPTION_AND_ICON_INFO" << endl;
  1496         t << "\tCAPTION_AND_ICON_INFO" << endl;
  1399         t << "\t\t{" << endl;
  1497         t << "\t\t{" << endl;
  1400         t << "\t\tcaption = STRING_r_caption;" << endl;
  1498         t << "\t\tcaption = STRING_r_caption;" << endl;
  1401 
  1499 
  1402         if (numberOfIcons.isEmpty() || iconFile.isEmpty()) {
  1500         QString rssIconFile = iconFile;
       
  1501         rssIconFile = rssIconFile.replace("/", "\\\\");
       
  1502 
       
  1503         if (numberOfIcons.isEmpty() || rssIconFile.isEmpty()) {
  1403             // There can be maximum one item in this tag, validated when parsed
  1504             // There can be maximum one item in this tag, validated when parsed
  1404             t << "\t\tnumber_of_icons = 0;" << endl;
  1505             t << "\t\tnumber_of_icons = 0;" << endl;
  1405             t << "\t\ticon_file = \"\";" << endl;
  1506             t << "\t\ticon_file = \"\";" << endl;
  1406         } else {
  1507         } else {
  1407             // There can be maximum one item in this tag, validated when parsed
  1508             // There can be maximum one item in this tag, validated when parsed
  1408             t << "\t\tnumber_of_icons = " << numberOfIcons << ";" << endl;
  1509             t << "\t\tnumber_of_icons = " << numberOfIcons << ";" << endl;
  1409             t << "\t\ticon_file = \"" << iconFile << "\";" << endl;
  1510             t << "\t\ticon_file = \"" << rssIconFile << "\";" << endl;
  1410         }
  1511         }
  1411         t << "\t\t};" << endl;
  1512         t << "\t\t};" << endl;
  1412         t << "\t}" << endl;
  1513         t << "\t}" << endl;
  1413         t << endl;
  1514         t << endl;
  1414     } else {
  1515     } else {
  1417 }
  1518 }
  1418 
  1519 
  1419 void SymbianMakefileGenerator::writeLocFile(QStringList &symbianLangCodes)
  1520 void SymbianMakefileGenerator::writeLocFile(QStringList &symbianLangCodes)
  1420 {
  1521 {
  1421     QString filename(fixedTarget);
  1522     QString filename(fixedTarget);
  1422     filename.append(".loc");
  1523     if (project->values("SYMBIANTRANSLATIONS").isEmpty()) {
       
  1524         filename.append(".loc");
       
  1525     } else { 
       
  1526         if (!project->first("SYMBIANLOCFILESDIR").isEmpty()) { 
       
  1527             filename.insert(0,project->first("SYMBIANLOCFILESDIR"));         
       
  1528         } else {	
       
  1529             filename.insert(0,"/epoc32/include/platform/app/loc/");    
       
  1530         }
       
  1531         filename.append(".loc");
       
  1532     }
       
  1533     
  1423     QFile ft(filename);
  1534     QFile ft(filename);
  1424     if (ft.open(QIODevice::WriteOnly)) {
  1535     if (ft.open(QIODevice::WriteOnly)) {
  1425         if (Option::mkfile::listgen) {
  1536         if (Option::mkfile::listgen) {
  1426             generatePrint(fileInfo(ft.fileName()).absoluteFilePath());
  1537             generatePrint(fileInfo(ft.fileName()).absoluteFilePath());
  1427         }
  1538         }
  1428         generatedFiles << ft.fileName();
  1539         generatedFiles << ft.fileName();
  1429         QTextStream t(&ft);
  1540         QTextStream t(&ft);
  1430         t << "// ============================================================================" << endl;
  1541         t << "// ============================================================================" << endl;
  1431         t << "// * Generated by qmake (" << qmake_version() << ") (Qt " << QT_VERSION_STR << ") on: ";
  1542         t << "// * Generated by qmake (" << qmake_version() << ") (Qt " QT_VERSION_STR ") on: ";
  1432         t << QDateTime::currentDateTime().toString(Qt::ISODate) << endl;
  1543         t << QDateTime::currentDateTime().toString(Qt::ISODate) << endl;
  1433         t << "// * This file is generated by qmake and should not be modified by the" << endl;
  1544         t << "// * This file is generated by qmake and should not be modified by the" << endl;
  1434         t << "// * user." << endl;
  1545         t << "// * user." << endl;
  1435         t << "// ============================================================================" << endl;
  1546         t << "// ============================================================================" << endl;
  1436         t << endl;
  1547         t << endl;
       
  1548         if (project->values("SYMBIANTRANSLATIONS").isEmpty()) {
  1437         t << "#ifdef LANGUAGE_SC" << endl;
  1549         t << "#ifdef LANGUAGE_SC" << endl;
  1438         t << "#define STRING_r_short_caption \"" << fixedTarget  << "\"" << endl;
  1550         t << "#define STRING_r_short_caption \"" << fixedTarget  << "\"" << endl;
  1439         t << "#define STRING_r_caption \"" << fixedTarget  << "\"" << endl;
  1551         t << "#define STRING_r_caption \"" << fixedTarget  << "\"" << endl;
  1440         foreach(QString lang, symbianLangCodes) {
  1552         foreach(QString lang, symbianLangCodes) {
  1441             t << "#elif defined LANGUAGE_" << lang << endl;
  1553             t << "#elif defined LANGUAGE_" << lang << endl;
  1445         t << "#else" << endl;
  1557         t << "#else" << endl;
  1446         t << "#define STRING_r_short_caption \"" << fixedTarget  << "\"" << endl;
  1558         t << "#define STRING_r_short_caption \"" << fixedTarget  << "\"" << endl;
  1447         t << "#define STRING_r_caption \"" << fixedTarget  << "\"" << endl;
  1559         t << "#define STRING_r_caption \"" << fixedTarget  << "\"" << endl;
  1448         t << "#endif" << endl;
  1560         t << "#endif" << endl;
  1449     } else {
  1561     } else {
       
  1562             t << "#if LANGUAGE_01" << endl;    
       
  1563             t << "#include <" << "01/" << fixedTarget  << "_01.loc>" << endl;
       
  1564             foreach(QString lang, symbianLangCodes) {
       
  1565                 if (lang.localeAwareCompare("01") != 0) {
       
  1566                     t << "#elif LANGUAGE_" << lang << endl;
       
  1567                     t << "#include <" << lang << "/" << fixedTarget  << "_" << lang << ".loc>" << ">" << endl;
       
  1568                 }
       
  1569             }
       
  1570             t << "#endif" << endl;
       
  1571         }
       
  1572     } else {
  1450         PRINT_FILE_CREATE_ERROR(filename);
  1573         PRINT_FILE_CREATE_ERROR(filename);
       
  1574     }
       
  1575 }
       
  1576 
       
  1577 void SymbianMakefileGenerator::writeSymbianLocFile(QStringList &symbianLangCodes)
       
  1578 {	
       
  1579 	QString filename(fixedTarget); 
       
  1580 	foreach(QString lang, symbianLangCodes) {
       
  1581         
       
  1582 		QString tsFilename(filename);  
       
  1583 		QString language = qt2S60LangMapTable.key(lang, QString("en"));
       
  1584 		tsFilename.append("_"+language+".ts");
       
  1585 		tsFilename.insert(0,project->first("SYMBIANTRANSLATIONDIR")); 	
       
  1586 		
       
  1587         QString locFilename(filename); 
       
  1588         locFilename.append("_"+lang+".loc");
       
  1589         if (!project->first("SYMBIANLOCFILESDIR").isEmpty()) {    
       
  1590             locFilename.insert(0,lang+"/");
       
  1591             locFilename.insert(0,project->first("SYMBIANLOCFILESDIR"));
       
  1592         } else {	
       
  1593             locFilename.insert(0,"/epoc32/include/platform/app/loc/"+lang+"/");
       
  1594         }
       
  1595                 
       
  1596         QString shortCaption;
       
  1597         QString longCaption;
       
  1598         
       
  1599         // get captions from ts file
       
  1600         QFile tsFile(tsFilename);
       
  1601         if (tsFile.exists()) {
       
  1602             if (tsFile.open(QIODevice::ReadOnly)) {
       
  1603                 QString shortCaptionId = QLatin1String("txt_short_caption_");
       
  1604                 shortCaptionId.append(filename);
       
  1605                 QString longCaptionId = QLatin1String("txt_long_caption_");
       
  1606                 longCaptionId.append(filename);
       
  1607                 QXmlStreamReader xml(&tsFile);
       
  1608                 while (!xml.atEnd()) {
       
  1609                     xml.readNext();
       
  1610                     if (xml.isStartElement() && xml.name() == "context") {
       
  1611                         while (!(xml.isEndElement() && xml.name() == "context") && !xml.atEnd()) {
       
  1612                             xml.readNext();  
       
  1613                             if (xml.isStartElement() && xml.name() == "message" && 
       
  1614                                 xml.attributes().value("numerus") == "no" && 
       
  1615                                 xml.attributes().value("id") == shortCaptionId) {
       
  1616                                 while (!(xml.isEndElement() && xml.name() == "message") && !xml.atEnd()) {
       
  1617                                     xml.readNext();
       
  1618                                     if (xml.isStartElement() && xml.name() == "translation") {
       
  1619                             		   shortCaption = xml.readElementText();
       
  1620                                     }
       
  1621                                 }
       
  1622                             }
       
  1623                             if (xml.isStartElement() && xml.name() == "message" && 
       
  1624                                 xml.attributes().value("numerus") == "no" && 
       
  1625                                 xml.attributes().value("id") == longCaptionId) {
       
  1626                                 while (!(xml.isEndElement() && xml.name() == "message") && !xml.atEnd()) {   
       
  1627                                     xml.readNext();
       
  1628                                     if (xml.isStartElement() && xml.name() == "translation") {
       
  1629                                         longCaption = xml.readElementText();
       
  1630                                     }
       
  1631                                 }
       
  1632                             }
       
  1633                         }
       
  1634                     }         
       
  1635                 }
       
  1636                 if (shortCaption.isEmpty())
       
  1637                     fprintf(stderr, "Warning: STRING_r_short_caption not generated from file '%s'.\n", qPrintable(tsFilename));
       
  1638                 if (longCaption.isEmpty())
       
  1639                     fprintf(stderr, "Warning: STRING_r_caption not generated from file '%s'.\n", qPrintable(tsFilename));
       
  1640                 if (xml.hasError())
       
  1641                     fprintf(stderr, "ERROR: \"%s\" when parsing ts file\n", qPrintable(xml.errorString()));
       
  1642             } else {
       
  1643                 fprintf(stderr, "Could not open ts file (%s)\n", qPrintable(tsFilename));
       
  1644             }
       
  1645         } else {
       
  1646             fprintf(stderr, "ts file does not exist: (%s)\n", qPrintable(tsFilename));
       
  1647         }
       
  1648 
       
  1649         // generate language specific caption loc file
       
  1650         QFile ft(locFilename);
       
  1651         if (ft.open(QIODevice::WriteOnly)) {
       
  1652             generatedFiles << ft.fileName();
       
  1653             QTextStream t(&ft);
       
  1654             t << "// ============================================================================" << endl;
       
  1655             t << "// * Generated by qmake (" << qmake_version() << ") (Qt " << QT_VERSION_STR << ") on: ";
       
  1656             t << QDateTime::currentDateTime().toString(Qt::ISODate) << endl;
       
  1657             t << "// * This file is generated by qmake and should not be modified by the" << endl;
       
  1658             t << "// * user." << endl;
       
  1659             t << "// ============================================================================" << endl;
       
  1660             t << endl;
       
  1661             if (!shortCaption.isEmpty()) {
       
  1662                 t << "#define STRING_r_short_caption \"" << shortCaption  << "\"" << endl;    
       
  1663             } else {
       
  1664                 t << "#define STRING_r_short_caption \"" << fixedTarget  << "\"" << endl;
       
  1665             }    
       
  1666             if (!longCaption.isEmpty()) {
       
  1667                 t << "#define STRING_r_caption \"" << longCaption  << "\"" << endl;  
       
  1668             } else {    
       
  1669                 t << "#define STRING_r_caption \"" << fixedTarget  << "\"" << endl;
       
  1670             }
       
  1671             ft.close();
       
  1672         } else {
       
  1673             PRINT_FILE_CREATE_ERROR(locFilename);	
       
  1674 	    }
  1451     }
  1675     }
  1452 }
  1676 }
  1453 
  1677 
  1454 void SymbianMakefileGenerator::readRssRules(QString &numberOfIcons, QString &iconFile, QStringList &userRssRules)
  1678 void SymbianMakefileGenerator::readRssRules(QString &numberOfIcons, QString &iconFile, QStringList &userRssRules)
  1455 {
  1679 {
  1539     QStringList symbianLangCodes;
  1763     QStringList symbianLangCodes;
  1540     tsfiles << project->values("TRANSLATIONS");
  1764     tsfiles << project->values("TRANSLATIONS");
  1541 
  1765 
  1542     fillQt2S60LangMapTable();
  1766     fillQt2S60LangMapTable();
  1543 
  1767 
  1544     foreach(QString file, tsfiles) {
  1768     if (project->values("SYMBIANTRANSLATIONS").isEmpty()) {
  1545         int extIndex = file.lastIndexOf(".");
  1769         foreach(QString file, tsfiles) {
  1546         int langIndex = file.lastIndexOf("_", (extIndex - file.length()));
  1770             int extIndex = file.lastIndexOf(".");
  1547         langIndex += 1;
  1771             int langIndex = file.lastIndexOf("_", (extIndex - file.length()));
  1548         QString qtlang = file.mid(langIndex, extIndex - langIndex);
  1772             langIndex += 1;
  1549         QString s60lang = qt2S60LangMapTable.value(qtlang, QString("SC"));
  1773             QString qtlang = file.mid(langIndex, extIndex - langIndex);
  1550 
  1774             QString s60lang = qt2S60LangMapTable.value(qtlang, QString("SC"));
  1551         if (!symbianLangCodes.contains(s60lang) && s60lang != "SC")
  1775             if (!symbianLangCodes.contains(s60lang) && s60lang != "SC")
  1552             symbianLangCodes += s60lang;
  1776                 symbianLangCodes += s60lang;
  1553     }
  1777         }
  1554 
  1778     } else {
       
  1779         modifyQt2S60LangMapTable(); // Modify the table according to the system_languages.ini file 
       
  1780         foreach(QString symbianTranslation, project->values("SYMBIANTRANSLATIONS")) {
       
  1781             QString s60lang = qt2S60LangMapTable.value(symbianTranslation, QString("SC"));
       
  1782 
       
  1783             if (!symbianLangCodes.contains(s60lang) && s60lang != "SC")
       
  1784                 symbianLangCodes += s60lang;
       
  1785         }
       
  1786     }
       
  1787         
  1555     return symbianLangCodes;
  1788     return symbianLangCodes;
  1556 }
  1789 }
  1557 
  1790 
  1558 void SymbianMakefileGenerator::fillQt2S60LangMapTable()
  1791 void SymbianMakefileGenerator::fillQt2S60LangMapTable()
  1559 {
  1792 {
  1722     qt2S60LangMapTable.insert("haw", "SC");           //Hawaiian                      //
  1955     qt2S60LangMapTable.insert("haw", "SC");           //Hawaiian                      //
  1723     qt2S60LangMapTable.insert("kcg", "SC");           //Tyap                          //
  1956     qt2S60LangMapTable.insert("kcg", "SC");           //Tyap                          //
  1724     qt2S60LangMapTable.insert("ny", "SC");            //Chewa                         //
  1957     qt2S60LangMapTable.insert("ny", "SC");            //Chewa                         //
  1725 }
  1958 }
  1726 
  1959 
       
  1960 void SymbianMakefileGenerator::modifyQt2S60LangMapTable()
       
  1961 {
       
  1962 	QString systemLanguagesIniFile = project->first("SYMBIANTRANSLATIONDIR").
       
  1963                                      append(QLatin1String("system_languages.ini"));
       
  1964     QFileInfo systemLangFileInfo(systemLanguagesIniFile);
       
  1965     if (systemLangFileInfo.exists()) {
       
  1966         QSettings systemLanguages(systemLanguagesIniFile, QSettings::IniFormat);
       
  1967         QStringList keys = systemLanguages.allKeys();
       
  1968         foreach (const QString &qtlang, keys){
       
  1969             QString s60lang = systemLanguages.value(qtlang).toString();
       
  1970             if (s60lang.localeAwareCompare(qt2S60LangMapTable.value(qtlang, QString("SC"))) != 0) {
       
  1971                 qt2S60LangMapTable.insert(qtlang, s60lang);
       
  1972                 fprintf(stderr, "Inserted: s60lang '%s' for qtlang '%s'.\n", qPrintable(s60lang), qPrintable(qtlang));
       
  1973             }
       
  1974         }
       
  1975     }
       
  1976 }
       
  1977 
  1727 void SymbianMakefileGenerator::appendIfnotExist(QStringList &list, QString value)
  1978 void SymbianMakefileGenerator::appendIfnotExist(QStringList &list, QString value)
  1728 {
  1979 {
  1729     if (!list.contains(value))
  1980     if (!list.contains(value))
  1730         list += value;
  1981         list += value;
  1731 }
  1982 }
  1777     }
  2028     }
  1778 }
  2029 }
  1779 
  2030 
  1780 void SymbianMakefileGenerator::removeSpecialCharacters(QString& str)
  2031 void SymbianMakefileGenerator::removeSpecialCharacters(QString& str)
  1781 {
  2032 {
       
  2033     // When modifying this method check also application_icon.prf
  1782     str.replace(QString("/"), QString("_"));
  2034     str.replace(QString("/"), QString("_"));
  1783     str.replace(QString("\\"), QString("_"));
  2035     str.replace(QString("\\"), QString("_"));
  1784     str.replace(QString("-"), QString("_"));
  2036     str.replace(QString("-"), QString("_"));
  1785     str.replace(QString(":"), QString("_"));
  2037     str.replace(QString(":"), QString("_"));
  1786     str.replace(QString("."), QString("_"));
  2038     str.replace(QString("."), QString("_"));