qmake/generators/symbian/symmake.cpp
changeset 7 f7bc934e204c
parent 3 41300fa6a67c
equal deleted inserted replaced
3:41300fa6a67c 7:f7bc934e204c
     1 /****************************************************************************
     1 /****************************************************************************
     2 **
     2 **
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
     3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     4 ** All rights reserved.
     4 ** All rights reserved.
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
     6 **
     6 **
     7 ** This file is part of the qmake application of the Qt Toolkit.
     7 ** This file is part of the qmake application of the Qt Toolkit.
     8 **
     8 **
    38 ** $QT_END_LICENSE$
    38 ** $QT_END_LICENSE$
    39 **
    39 **
    40 ****************************************************************************/
    40 ****************************************************************************/
    41 
    41 
    42 #include "symmake.h"
    42 #include "symmake.h"
    43 #include "initprojectdeploy_symbian.h"
       
    44 
    43 
    45 #include <qstring.h>
    44 #include <qstring.h>
    46 #include <qhash.h>
    45 #include <qhash.h>
    47 #include <qstringlist.h>
    46 #include <qstringlist.h>
    48 #include <qdir.h>
    47 #include <qdir.h>
    49 #include <qdatetime.h>
    48 #include <qdatetime.h>
    50 #include <stdlib.h>
    49 #include <stdlib.h>
    51 #include <qdebug.h>
    50 #include <qdebug.h>
    52 #include <qxmlstream.h>
    51 #include <qxmlstream.h>
    53 #include <qsettings>
    52 #include <QSettings>
       
    53 
       
    54 // Included from tools/shared
       
    55 #include <symbian/epocroot.h>
    54 
    56 
    55 #define RESOURCE_DIRECTORY_MMP "/resource/apps"
    57 #define RESOURCE_DIRECTORY_MMP "/resource/apps"
    56 #define RESOURCE_DIRECTORY_RESOURCE "\\\\resource\\\\apps\\\\"
    58 #define RESOURCE_DIRECTORY_RESOURCE "\\\\resource\\\\apps\\\\"
    57 #define REGISTRATION_RESOURCE_DIRECTORY_HW "/private/10003a3f/import/apps"
    59 #define REGISTRATION_RESOURCE_DIRECTORY_HW "/private/10003a3f/import/apps"
    58 #define PLUGIN_COMMON_DEF_FILE_FOR_MMP "./plugin_common.def"
    60 #define PLUGIN_COMMON_DEF_FILE_FOR_MMP "./plugin_common.def"
    59 #define PLUGIN_COMMON_DEF_FILE_ACTUAL "plugin_commonU.def"
    61 #define PLUGIN_COMMON_DEF_FILE_ACTUAL "plugin_commonU.def"
    60 #define BLD_INF_FILENAME_LEN (sizeof(BLD_INF_FILENAME) - 1)
       
    61 
    62 
    62 #define BLD_INF_RULES_BASE "BLD_INF_RULES."
    63 #define BLD_INF_RULES_BASE "BLD_INF_RULES."
    63 #define BLD_INF_TAG_PLATFORMS "prj_platforms"
    64 #define BLD_INF_TAG_PLATFORMS "prj_platforms"
    64 #define BLD_INF_TAG_MMPFILES "prj_mmpfiles"
    65 #define BLD_INF_TAG_MMPFILES "prj_mmpfiles"
    65 #define BLD_INF_TAG_TESTMMPFILES "prj_testmmpfiles"
    66 #define BLD_INF_TAG_TESTMMPFILES "prj_testmmpfiles"
    66 #define BLD_INF_TAG_EXTENSIONS "prj_extensions"
    67 #define BLD_INF_TAG_EXTENSIONS "prj_extensions"
       
    68 #define BLD_INF_TAG_TESTEXTENSIONS "prj_testextensions"
    67 
    69 
    68 #define RSS_RULES "RSS_RULES"
    70 #define RSS_RULES "RSS_RULES"
    69 #define RSS_RULES_BASE "RSS_RULES."
    71 #define RSS_RULES_BASE "RSS_RULES."
    70 #define RSS_TAG_NBROFICONS "number_of_icons"
    72 #define RSS_TAG_NBROFICONS "number_of_icons"
    71 #define RSS_TAG_ICONFILE "icon_file"
    73 #define RSS_TAG_ICONFILE "icon_file"
       
    74 #define RSS_TAG_HEADER "header"
       
    75 #define RSS_TAG_SERVICE_LIST "service_list"
       
    76 #define RSS_TAG_FILE_OWNERSHIP_LIST "file_ownership_list"
       
    77 #define RSS_TAG_DATATYPE_LIST "datatype_list"
       
    78 #define RSS_TAG_FOOTER "footer"
       
    79 #define RSS_TAG_DEFAULT "default_rules" // Same as just giving rules without tag
    72 
    80 
    73 #define MMP_TARGET "TARGET"
    81 #define MMP_TARGET "TARGET"
    74 #define MMP_TARGETTYPE "TARGETTYPE"
    82 #define MMP_TARGETTYPE "TARGETTYPE"
    75 #define MMP_SECUREID "SECUREID"
    83 #define MMP_SECUREID "SECUREID"
    76 #define MMP_OPTION_CW "OPTION CW"
    84 #define MMP_OPTION_CW "OPTION CW"
    88 #define MMP_VERSION "VERSION"
    96 #define MMP_VERSION "VERSION"
    89 #define MMP_START_RESOURCE "START RESOURCE"
    97 #define MMP_START_RESOURCE "START RESOURCE"
    90 #define MMP_END_RESOURCE "END"
    98 #define MMP_END_RESOURCE "END"
    91 
    99 
    92 #define SIS_TARGET "sis"
   100 #define SIS_TARGET "sis"
       
   101 #define INSTALLER_SIS_TARGET "installer_sis"
       
   102 #define ROM_STUB_SIS_TARGET "stub_sis"
    93 #define OK_SIS_TARGET "ok_sis"
   103 #define OK_SIS_TARGET "ok_sis"
       
   104 #define OK_INSTALLER_SIS_TARGET "ok_installer_sis"
       
   105 #define OK_ROM_STUB_SIS_TARGET "ok_stub_sis"
    94 #define FAIL_SIS_NOPKG_TARGET "fail_sis_nopkg"
   106 #define FAIL_SIS_NOPKG_TARGET "fail_sis_nopkg"
    95 #define FAIL_SIS_NOCACHE_TARGET "fail_sis_nocache"
   107 #define FAIL_SIS_NOCACHE_TARGET "fail_sis_nocache"
    96 #define RESTORE_BUILD_TARGET "restore_build"
       
    97 
   108 
    98 #define PRINT_FILE_CREATE_ERROR(filename) fprintf(stderr, "Error: Could not create '%s'\n", qPrintable(filename));
   109 #define PRINT_FILE_CREATE_ERROR(filename) fprintf(stderr, "Error: Could not create '%s'\n", qPrintable(filename));
       
   110 
       
   111 #define MANUFACTURER_NOTE_FILE "manufacturer_note.txt"
       
   112 #define DEFAULT_MANUFACTURER_NOTE \
       
   113     "The package is not supported for devices from this manufacturer. Please try the selfsigned " \
       
   114     "version of the package instead."
    99 
   115 
   100 QString SymbianMakefileGenerator::fixPathForMmp(const QString& origPath, const QDir& parentDir)
   116 QString SymbianMakefileGenerator::fixPathForMmp(const QString& origPath, const QDir& parentDir)
   101 {
   117 {
   102     static QString epocRootStr;
   118     static QString epocRootStr;
   103     if (epocRootStr.isEmpty()) {
   119     if (epocRootStr.isEmpty()) {
   104         QFileInfo efi(epocRoot());
   120         epocRootStr = epocRoot();
   105         epocRootStr = efi.canonicalFilePath();
   121         QFileInfo efi(epocRootStr);
   106         if (epocRootStr.isEmpty()) {
   122         if (!efi.exists() || epocRootStr.isEmpty()) {
   107             fprintf(stderr, "Unable to resolve epocRoot '%s' to real dir on current drive, defaulting to '/' for mmp paths\n", qPrintable(epocRoot()));
   123             fprintf(stderr, "Unable to resolve epocRoot '%s' to real dir on current drive, defaulting to '/' for mmp paths\n", qPrintable(epocRoot()));
   108             epocRootStr = "/";
   124             epocRootStr = "/";
       
   125         } else {
       
   126             epocRootStr = efi.absoluteFilePath();
   109         }
   127         }
   110         if (!epocRootStr.endsWith("/"))
   128         if (!epocRootStr.endsWith("/"))
   111             epocRootStr += "/";
   129             epocRootStr += "/";
   112 
   130 
   113         epocRootStr += "epoc32/";
   131         epocRootStr += "epoc32/";
   127         resultPath = ".";
   145         resultPath = ".";
   128 
   146 
   129     return resultPath;
   147     return resultPath;
   130 }
   148 }
   131 
   149 
   132 QString SymbianMakefileGenerator::canonizePath(const QString& origPath)
   150 QString SymbianMakefileGenerator::absolutizePath(const QString& origPath)
   133 {
   151 {
   134     // Since current path gets appended almost always anyway, use it as default
       
   135     // for nonexisting paths.
       
   136     static QString defaultPath;
       
   137     if (defaultPath.isEmpty()) {
       
   138         QFileInfo fi(".");
       
   139         defaultPath = fi.canonicalFilePath();
       
   140     }
       
   141 
       
   142     // Prepend epocroot to any paths beginning with "/epoc32/"
   152     // Prepend epocroot to any paths beginning with "/epoc32/"
   143     QString resultPath = QDir::fromNativeSeparators(origPath);
   153     QString resultPath = QDir::fromNativeSeparators(origPath);
   144     QString tempPath(resultPath);
   154     if (resultPath.startsWith("/epoc32/", Qt::CaseInsensitive))
   145     bool isEpoc = false;
       
   146     if (resultPath.startsWith("/epoc32/", Qt::CaseInsensitive)) {
       
   147         isEpoc = true;
       
   148         resultPath = QDir::fromNativeSeparators(epocRoot()) + resultPath.mid(1);
   155         resultPath = QDir::fromNativeSeparators(epocRoot()) + resultPath.mid(1);
   149     }
       
   150 
   156 
   151     QFileInfo fi(fileInfo(resultPath));
   157     QFileInfo fi(fileInfo(resultPath));
   152     if(fi.isDir()) {
   158 
   153         if (isEpoc)
   159     // Since origPath can be something given in HEADERS, we need to check if we are dealing
   154             resultPath = fi.absoluteFilePath();//canonicalFilePath();
   160     // with a file or a directory. In case the origPath doesn't yet exist, isFile() returns
   155         else
   161     // false and we default to assuming it is a dir.
   156             resultPath = fi.canonicalFilePath();            
   162     if (fi.isFile()) {
       
   163         resultPath = fi.absolutePath();
   157     } else {
   164     } else {
   158         if (isEpoc)
   165         resultPath = fi.absoluteFilePath();
   159             resultPath = fi.absolutePath();//canonicalPath();
       
   160         else
       
   161             resultPath = fi.canonicalPath();
       
   162     }
       
   163     //some fix for the not existed EPOC32\include folder
       
   164     if (isEpoc) {
       
   165         int index = resultPath.lastIndexOf("/epoc32/"); 
       
   166         QString tmpRes = resultPath.mid(index);
       
   167         if (tmpRes != tempPath) {
       
   168             //we have the problems for not existed include directory
       
   169             //change the path
       
   170             resultPath.replace(tmpRes, tempPath);
       
   171             }
       
   172     }
   166     }
   173 
   167 
   174     resultPath = QDir::cleanPath(resultPath);
   168     resultPath = QDir::cleanPath(resultPath);
   175 
       
   176     if (resultPath.isEmpty())
       
   177         resultPath = defaultPath;
       
   178 
   169 
   179     return resultPath;
   170     return resultPath;
   180 }
   171 }
   181 
   172 
   182 SymbianMakefileGenerator::SymbianMakefileGenerator() : MakefileGenerator() { }
   173 SymbianMakefileGenerator::SymbianMakefileGenerator() : MakefileGenerator() { }
   215 {
   206 {
   216     writeHeader(t);
   207     writeHeader(t);
   217 
   208 
   218     QString numberOfIcons;
   209     QString numberOfIcons;
   219     QString iconFile;
   210     QString iconFile;
   220     QStringList userRssRules;
   211     QMap<QString, QStringList> userRssRules;
   221     readRssRules(numberOfIcons, iconFile, userRssRules);
   212     readRssRules(numberOfIcons, iconFile, userRssRules);
   222 
   213 
   223     // Get the application translations and convert to symbian OS lang code, i.e. decical number
   214     // Get the application translations and convert to symbian OS lang code, i.e. decical number
   224     QStringList symbianLangCodes = symbianLangCodesFromTsFiles();
   215     QStringList symbianLangCodes = symbianLangCodesFromTsFiles();
   225 
   216 
   226     // Generate pkg files if there are any actual files to deploy
   217     // Generate pkg files if there are any actual files to deploy
   227     bool generatePkg = false;
   218     bool generatePkg = false;
       
   219     DeploymentList depList;
       
   220 
   228     if (targetType == TypeExe) {
   221     if (targetType == TypeExe) {
   229         generatePkg = true;
   222         generatePkg = true;
   230     } else {
   223     } else {
   231         foreach(QString item, project->values("DEPLOYMENT")) {
   224         foreach(QString item, project->values("DEPLOYMENT")) {
   232             if (!project->values(item + ".sources").isEmpty()) {
   225             if (!project->values(item + ".sources").isEmpty()) {
   235             }
   228             }
   236         }
   229         }
   237     }
   230     }
   238 
   231 
   239     if (generatePkg) {
   232     if (generatePkg) {
   240         generatePkgFile(iconFile);
   233         generatePkgFile(iconFile, depList);
   241     }
   234     }
   242 
   235 
   243     writeBldInfContent(t, generatePkg, iconFile);
   236     writeBldInfContent(t, generatePkg, iconFile, depList);
   244 
   237 
   245     // Generate empty wrapper makefile here, because wrapper makefile must exist before writeMkFile,
   238     // Generate empty wrapper makefile here, because wrapper makefile must exist before writeMkFile,
   246     // but all required data is not yet available.
   239     // but all required data is not yet available.
   247     bool isPrimaryMakefile = true;
   240     bool isPrimaryMakefile = true;
   248     QString wrapperFileName("Makefile");
   241     QString wrapperFileName("Makefile");
   249     QString outputFileName = fileInfo(Option::output.fileName()).fileName();
   242     QString outputFileName = fileInfo(Option::output.fileName()).fileName();
   250     if (outputFileName != BLD_INF_FILENAME) {
   243     if (outputFileName != BLD_INF_FILENAME) {
   251         wrapperFileName.append(".").append((outputFileName.size() > BLD_INF_FILENAME_LEN && outputFileName.left(BLD_INF_FILENAME_LEN) == BLD_INF_FILENAME) ? outputFileName.mid(8) : outputFileName);
   244         wrapperFileName.append(".").append(outputFileName.startsWith(BLD_INF_FILENAME)
       
   245                                            ? outputFileName.mid(sizeof(BLD_INF_FILENAME))
       
   246                                            : outputFileName);
   252         isPrimaryMakefile = false;
   247         isPrimaryMakefile = false;
   253     }
   248     }
   254 
   249 
   255     QFile wrapperMakefile(wrapperFileName);
   250     QFile wrapperMakefile(wrapperFileName);
   256     if (wrapperMakefile.open(QIODevice::WriteOnly)) {
   251     if (wrapperMakefile.open(QIODevice::WriteOnly)) {
   284     mmpFilename.append(uid3);
   279     mmpFilename.append(uid3);
   285     mmpFilename.append(Option::mmp_ext);
   280     mmpFilename.append(Option::mmp_ext);
   286     writeMmpFile(mmpFilename, symbianLangCodes);
   281     writeMmpFile(mmpFilename, symbianLangCodes);
   287 
   282 
   288     if (targetType == TypeExe) {
   283     if (targetType == TypeExe) {
   289         if (!project->values("CONFIG").contains("no_icon", Qt::CaseInsensitive)) {
   284         if (!project->isActiveConfig("no_icon")) {
   290             writeRegRssFile(userRssRules);
   285             writeRegRssFile(userRssRules);
   291             writeRssFile(numberOfIcons, iconFile);
   286             writeRssFile(numberOfIcons, iconFile);
   292             writeLocFile(symbianLangCodes);
   287             writeLocFile(symbianLangCodes);
   293             if (!project->values("SYMBIANTRANSLATIONS").isEmpty())
   288             if (!project->values("SYMBIANTRANSLATIONS").isEmpty())
   294                 writeSymbianLocFile(symbianLangCodes);        
   289                 writeSymbianLocFile(symbianLangCodes);        
   299     writeWrapperMakefile(wrapperMakefile, isPrimaryMakefile);
   294     writeWrapperMakefile(wrapperMakefile, isPrimaryMakefile);
   300 
   295 
   301     return true;
   296     return true;
   302 }
   297 }
   303 
   298 
   304 void SymbianMakefileGenerator::generatePkgFile(const QString &iconFile)
   299 void SymbianMakefileGenerator::generatePkgFile(const QString &iconFile, DeploymentList &depList)
   305 {
   300 {
   306     QString pkgFilename = QString("%1_template.%2")
   301     QString pkgFilename = QString("%1_template.%2")
   307                           .arg(fixedTarget)
   302                           .arg(fixedTarget)
   308                           .arg("pkg");
   303                           .arg("pkg");
   309     QFile pkgFile(pkgFilename);
   304     QFile pkgFile(pkgFilename);
   313     }
   308     }
   314     if (Option::mkfile::listgen) {
   309     if (Option::mkfile::listgen) {
   315         generatePrint(fileInfo(pkgFile.fileName()).absoluteFilePath());
   310         generatePrint(fileInfo(pkgFile.fileName()).absoluteFilePath());
   316     }
   311     }
   317     generatedFiles << pkgFile.fileName();
   312     generatedFiles << pkgFile.fileName();
       
   313     QTextStream t(&pkgFile);
       
   314 
       
   315     QString installerSisHeader = project->values("DEPLOYMENT.installer_header").join("\n");
       
   316     if (installerSisHeader.isEmpty())
       
   317         installerSisHeader = "0xA000D7CE"; // Use default self-signable UID if not defined
       
   318 
       
   319     QString wrapperStreamBuffer;
       
   320     QTextStream tw(&wrapperStreamBuffer);
       
   321 
       
   322     QString dateStr = QDateTime::currentDateTime().toString(Qt::ISODate);
   318 
   323 
   319     // Header info
   324     // Header info
   320     QTextStream t(&pkgFile);
   325     QString wrapperPkgFilename = QString("%1_installer.%2")
   321     t << QString("; %1 generated by qmake at %2").arg(pkgFilename).arg(QDateTime::currentDateTime().toString(Qt::ISODate))  << endl;
   326                                 .arg(fixedTarget)
   322     t << "; This file is generated by qmake and should not be modified by the user" << endl;
   327                                 .arg("pkg");
   323     t << ";" << endl << endl;
   328     QString headerComment = "; %1 generated by qmake at %2\n"
       
   329         "; This file is generated by qmake and should not be modified by the user\n"
       
   330         ";\n\n";
       
   331     t << headerComment.arg(pkgFilename).arg(dateStr);
       
   332     tw << headerComment.arg(wrapperPkgFilename).arg(dateStr);
   324 
   333 
   325     // Construct QStringList from pkg_prerules since we need search it before printed to file
   334     // Construct QStringList from pkg_prerules since we need search it before printed to file
       
   335     // Note: Though there can't be more than one language or header line, use stringlists
       
   336     // in case user wants comments to go with the rules.
   326     QStringList rawPkgPreRules;
   337     QStringList rawPkgPreRules;
       
   338     QStringList languageRules;
       
   339     QStringList headerRules;
   327     foreach(QString deploymentItem, project->values("DEPLOYMENT")) {
   340     foreach(QString deploymentItem, project->values("DEPLOYMENT")) {
   328         foreach(QString pkgrulesItem, project->values(deploymentItem + ".pkg_prerules")) {
   341         foreach(QString pkgrulesItem, project->values(deploymentItem + ".pkg_prerules")) {
   329             QStringList pkgrulesValue = project->values(pkgrulesItem);
   342             QStringList pkgrulesValue = project->values(pkgrulesItem);
   330             // If there is no stringlist defined for a rule, use rule name directly
   343             // If there is no stringlist defined for a rule, use rule name directly
   331             // This is convenience for defining single line mmp statements
   344             // This is convenience for defining single line mmp statements
   332             if (pkgrulesValue.isEmpty()) {
   345             if (pkgrulesValue.isEmpty()) {
   333                 rawPkgPreRules << pkgrulesItem;
   346                 if (pkgrulesItem.startsWith("&"))
       
   347                     languageRules << pkgrulesItem;
       
   348                 else if (pkgrulesItem.startsWith("#"))
       
   349                     headerRules << pkgrulesItem;
       
   350                 else
       
   351                     rawPkgPreRules << pkgrulesItem;
   334             } else {
   352             } else {
   335                 foreach(QString pkgrule, pkgrulesValue) {
   353                 if (containsStartWithItem('&', pkgrulesValue)) {
   336                     rawPkgPreRules << pkgrule;
   354                     foreach(QString pkgrule, pkgrulesValue) {
       
   355                         languageRules << pkgrule;
       
   356                     }
       
   357                 } else if (containsStartWithItem('#', pkgrulesValue)) {
       
   358                     foreach(QString pkgrule, pkgrulesValue) {
       
   359                         headerRules << pkgrule;
       
   360                     }
       
   361                 } else {
       
   362                     foreach(QString pkgrule, pkgrulesValue) {
       
   363                         rawPkgPreRules << pkgrule;
       
   364                     }
   337                 }
   365                 }
   338             }
   366             }
   339         }
   367         }
   340     }
   368     }
   341 
   369 
   342     // Apply some defaults if specific data does not exist in PKG pre-rules
   370     // Apply some defaults if specific data does not exist in PKG pre-rules
   343 
   371 
   344     if (!containsStartWithItem('&', rawPkgPreRules)) {
   372     if (languageRules.isEmpty()) {
   345         // language, (*** hardcoded to english atm, should be parsed from TRANSLATIONS)
   373         // language, (*** hardcoded to english atm, should be parsed from TRANSLATIONS)
   346         t << "; Language" << endl;
   374         languageRules << "; Language\n&EN\n\n";
   347         t << "&EN" << endl << endl;
   375     } else if (headerRules.isEmpty()) {
   348     } else {
       
   349         // In case user defines langs, he must take care also about SIS header
   376         // In case user defines langs, he must take care also about SIS header
   350         if (!containsStartWithItem('#', rawPkgPreRules))
   377         fprintf(stderr, "Warning: If language is defined with DEPLOYMENT pkg_prerules, also the SIS header must be defined\n");
   351             fprintf(stderr, "Warning: If language is defined with DEPLOYMENT pkg_prerules, also the SIS header must be defined\n");
   378     }
   352     }
   379 
       
   380     t << languageRules.join("\n") << endl;
       
   381     tw << languageRules.join("\n") << endl;
   353 
   382 
   354     // name of application, UID and version
   383     // name of application, UID and version
   355     QString applicationVersion = project->first("VERSION").isEmpty() ? "1,0,0" : project->first("VERSION").replace('.', ',');
   384     QString applicationVersion = project->first("VERSION").isEmpty() ? "1,0,0" : project->first("VERSION").replace('.', ',');
   356 
   385     QString sisHeader = "; SIS header: name, uid, version\n#{\"%1\"},(%2),%3\n\n";
   357     if (!containsStartWithItem('#', rawPkgPreRules)) {
   386     QString visualTarget = escapeFilePath(fileFixify(project->first("TARGET")));
   358         QString visualTarget = escapeFilePath(fileFixify(project->first("TARGET")));
   387     visualTarget = removePathSeparators(visualTarget);
   359         visualTarget = removePathSeparators(visualTarget);
   388     QString wrapperTarget = visualTarget + " installer";
   360 
   389 
   361         t << "; SIS header: name, uid, version" << endl;
   390     if (installerSisHeader.startsWith("0x", Qt::CaseInsensitive)) {
   362         t << QString("#{\"%1\"},(%2),%3").arg(visualTarget).arg(uid3).arg(applicationVersion) << endl << endl;
   391         tw << sisHeader.arg(wrapperTarget).arg(installerSisHeader).arg(applicationVersion);
   363     }
   392     } else {
       
   393         tw << installerSisHeader << endl;
       
   394     }
       
   395 
       
   396     if (headerRules.isEmpty())
       
   397         t << sisHeader.arg(visualTarget).arg(uid3).arg(applicationVersion);
       
   398     else
       
   399         t << headerRules.join("\n") << endl;
   364 
   400 
   365     // Localized vendor name
   401     // Localized vendor name
       
   402     QString vendorName;
   366     if (!containsStartWithItem('%', rawPkgPreRules)) {
   403     if (!containsStartWithItem('%', rawPkgPreRules)) {
   367         t << "; Localised Vendor name" << endl;
   404         vendorName += "; Localised Vendor name\n%{\"Vendor\"}\n\n";
   368         t << "%{\"Vendor\"}" << endl << endl;
       
   369     }
   405     }
   370 
   406 
   371     // Unique vendor name
   407     // Unique vendor name
   372     if (!containsStartWithItem(':', rawPkgPreRules)) {
   408     if (!containsStartWithItem(':', rawPkgPreRules)) {
   373         t << "; Unique Vendor name" << endl;
   409         vendorName += "; Unique Vendor name\n:\"Vendor\"\n\n";
   374         t << ":\"Vendor\"" << endl << endl;
   410     }
   375     }
   411 
       
   412     t << vendorName;
       
   413     tw << vendorName;
   376 
   414 
   377     // PKG pre-rules - these are added before actual file installations i.e. SIS package body
   415     // PKG pre-rules - these are added before actual file installations i.e. SIS package body
   378     if (rawPkgPreRules.size()) {
   416     if (rawPkgPreRules.size()) {
   379         t << "; Manual PKG pre-rules from PRO files" << endl;
   417         QString comment = "\n; Manual PKG pre-rules from PRO files\n";
       
   418         t << comment;
       
   419         tw << comment;
       
   420 
   380         foreach(QString item, rawPkgPreRules) {
   421         foreach(QString item, rawPkgPreRules) {
       
   422             // Only regular pkg file should have package dependencies or pkg header if that is
       
   423             // defined using prerules.
       
   424             if (!item.startsWith("(") && !item.startsWith("#")) {
       
   425                 tw << item << endl;
       
   426             }
   381             t << item << endl;
   427             t << item << endl;
   382         }
   428         }
   383         t << endl;
   429         t << endl;
       
   430         tw << endl;
       
   431     }
       
   432 
       
   433     // Begin Manufacturer block
       
   434     if (!project->values("DEPLOYMENT.manufacturers").isEmpty()) {
       
   435         QString manufacturerStr("IF ");
       
   436         foreach(QString manufacturer, project->values("DEPLOYMENT.manufacturers")) {
       
   437             manufacturerStr.append(QString("(MANUFACTURER)=(%1) OR \n   ").arg(manufacturer));
       
   438         }
       
   439         // Remove the final OR
       
   440         manufacturerStr.chop(8);
       
   441         t << manufacturerStr << endl;
   384     }
   442     }
   385 
   443 
   386     // Install paths on the phone *** should be dynamic at some point
   444     // Install paths on the phone *** should be dynamic at some point
   387     QString installPathBin = "!:\\sys\\bin";
   445     QString installPathBin = "!:\\sys\\bin";
   388     QString installPathResource = "!:\\resource\\apps";
   446     QString installPathResource = "!:\\resource\\apps";
   389     QString installPathRegResource = "!:\\private\\10003a3f\\import\\apps";
   447     QString installPathRegResource = "!:\\private\\10003a3f\\import\\apps";
   390 
   448 
   391     // Find location of builds
   449     // Find location of builds
   392     QString epocReleasePath = QString("%1epoc32/release/$(PLATFORM)/$(TARGET)")
   450     QString epocReleasePath = QString("%1epoc32/release/$(PLATFORM)/$(TARGET)")
   393                               .arg(epocRoot());
   451                               .arg(epocRoot());
   394 
       
   395 
   452 
   396     if (targetType == TypeExe) {
   453     if (targetType == TypeExe) {
   397         // deploy .exe file
   454         // deploy .exe file
   398         t << "; Executable and default resource files" << endl;
   455         t << "; Executable and default resource files" << endl;
   399         QString exeFile = fixedTarget + ".exe";
   456         QString exeFile = fixedTarget + ".exe";
   402              .arg(exeFile)
   459              .arg(exeFile)
   403              .arg(installPathBin)
   460              .arg(installPathBin)
   404              .arg(exeFile) << endl;
   461              .arg(exeFile) << endl;
   405 
   462 
   406         // deploy rsc & reg_rsc file
   463         // deploy rsc & reg_rsc file
   407         if (!project->values("CONFIG").contains("no_icon", Qt::CaseInsensitive)) {
   464         if (!project->isActiveConfig("no_icon")) {
   408             t << QString("\"%1epoc32/data/z/resource/apps/%2\"    - \"%3\\%4\"")
   465             t << QString("\"%1epoc32/data/z/resource/apps/%2\"    - \"%3\\%4\"")
   409                  .arg(epocRoot())
   466                  .arg(epocRoot())
   410                  .arg(fixedTarget + ".rsc")
   467                  .arg(fixedTarget + ".rsc")
   411                  .arg(installPathResource)
   468                  .arg(installPathResource)
   412                  .arg(fixedTarget + ".rsc") << endl;
   469                  .arg(fixedTarget + ".rsc") << endl;
   425             }
   482             }
   426         }
   483         }
   427     }
   484     }
   428 
   485 
   429     // deploy any additional DEPLOYMENT  files
   486     // deploy any additional DEPLOYMENT  files
   430     DeploymentList depList;
       
   431     QString remoteTestPath;
   487     QString remoteTestPath;
   432     remoteTestPath = QString("!:\\private\\%1").arg(privateDirUid);
   488     remoteTestPath = QString("!:\\private\\%1").arg(privateDirUid);
       
   489     QString zDir = epocRoot() + QLatin1String("epoc32/data/z");
   433 
   490 
   434     initProjectDeploySymbian(project, depList, remoteTestPath, true, "$(PLATFORM)", "$(TARGET)", generatedDirs, generatedFiles);
   491     initProjectDeploySymbian(project, depList, remoteTestPath, true, "$(PLATFORM)", "$(TARGET)", generatedDirs, generatedFiles);
   435     if (depList.size())
   492     if (depList.size())
   436         t << "; DEPLOYMENT" << endl;
   493         t << "; DEPLOYMENT" << endl;
   437     for (int i = 0; i < depList.size(); ++i)  {
   494     for (int i = 0; i < depList.size(); ++i)  {
   438         t << QString("\"%1\"    - \"%2\"")
   495         QString from = depList.at(i).from;
   439              .arg(QString(depList.at(i).from).replace('\\','/'))
   496         QString to = depList.at(i).to;
   440              .arg(depList.at(i).to) << endl;
   497 
       
   498         // Deploy anything not already deployed from under epoc32 instead from under
       
   499         // \epoc32\data\z\ to enable using pkg file without rebuilding
       
   500         // the project, which can be useful for some binary only distributions.
       
   501         if (!from.contains(QLatin1String("epoc32"), Qt::CaseInsensitive)) {
       
   502             from = to;
       
   503             if (from.size() > 1 && from.at(1) == QLatin1Char(':'))
       
   504                 from = from.mid(2);
       
   505             from.prepend(zDir);
       
   506         } else {
       
   507             if (from.size() > 1 && from.at(1) == QLatin1Char(':'))
       
   508                 from = from.mid(2);
       
   509         }
       
   510 
       
   511         t << QString("\"%1\"    - \"%2\"").arg(from.replace('\\','/')).arg(to) << endl;
   441     }
   512     }
   442     t << endl;
   513     t << endl;
   443 
   514 
   444     // PKG post-rules - these are added after actual file installations i.e. SIS package body
   515     // PKG post-rules - these are added after actual file installations i.e. SIS package body
   445     t << "; Manual PKG post-rules from PRO files" << endl;
   516     t << "; Manual PKG post-rules from PRO files" << endl;
   456                 }
   527                 }
   457             }
   528             }
   458             t << endl;
   529             t << endl;
   459         }
   530         }
   460     }
   531     }
       
   532 
       
   533     // Close Manufacturer block
       
   534     if (!project->values("DEPLOYMENT.manufacturers").isEmpty()) {
       
   535         QString manufacturerFailNoteFile;
       
   536         if (project->values("DEPLOYMENT.manufacturers.fail_note").isEmpty()) {
       
   537             manufacturerFailNoteFile = QString("%1_" MANUFACTURER_NOTE_FILE).arg(uid3);
       
   538             QFile ft(manufacturerFailNoteFile);
       
   539             if (ft.open(QIODevice::WriteOnly)) {
       
   540                 generatedFiles << ft.fileName();
       
   541                 QTextStream t2(&ft);
       
   542 
       
   543                 t2 << QString(DEFAULT_MANUFACTURER_NOTE) << endl;
       
   544             } else {
       
   545                 PRINT_FILE_CREATE_ERROR(manufacturerFailNoteFile)
       
   546             }
       
   547         } else {
       
   548             manufacturerFailNoteFile = project->values("DEPLOYMENT.manufacturers.fail_note").join("");
       
   549         }
       
   550 
       
   551         t << "ELSEIF NOT(0) ; MANUFACTURER" << endl
       
   552           << "\"" << fileInfo(manufacturerFailNoteFile).absoluteFilePath() << "\""
       
   553           << " - \"\", FILETEXT, TEXTEXIT" << endl
       
   554           << "ENDIF ; MANUFACTURER" << endl;
       
   555     }
       
   556 
       
   557     // Write wrapper pkg
       
   558     if (!installerSisHeader.isEmpty()) {
       
   559         QFile wrapperPkgFile(wrapperPkgFilename);
       
   560         if (!wrapperPkgFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
       
   561             PRINT_FILE_CREATE_ERROR(wrapperPkgFilename);
       
   562             return;
       
   563         }
       
   564 
       
   565         generatedFiles << wrapperPkgFile.fileName();
       
   566         QTextStream twf(&wrapperPkgFile);
       
   567 
       
   568         twf << wrapperStreamBuffer << endl;
       
   569 
       
   570         // Wrapped files deployment
       
   571         QString currentPath = qmake_getpwd();
       
   572         QString sisName = QString("%1.sis").arg(fixedTarget);
       
   573         twf << "\"" << currentPath << "/" << sisName << "\" - \"c:\\adm\\" << sisName << "\"" << endl;
       
   574 
       
   575         QString bootStrapPath = QLibraryInfo::location(QLibraryInfo::PrefixPath);
       
   576         bootStrapPath.append("/smartinstaller.sis");
       
   577         QFileInfo fi(fileInfo(bootStrapPath));
       
   578         twf << "@\"" << fi.absoluteFilePath() << "\",(0x2002CCCD)" << endl;
       
   579     }
   461 }
   580 }
   462 
   581 
   463 bool SymbianMakefileGenerator::containsStartWithItem(const QChar &c, const QStringList& src)
   582 bool SymbianMakefileGenerator::containsStartWithItem(const QChar &c, const QStringList& src)
   464 {
   583 {
   465     bool result = false;
   584     bool result = false;
   472     return result;
   591     return result;
   473 }
   592 }
   474 
   593 
   475 void SymbianMakefileGenerator::writeCustomDefFile()
   594 void SymbianMakefileGenerator::writeCustomDefFile()
   476 {
   595 {
   477     if (targetType == TypePlugin && !project->values("CONFIG").contains("stdbinary", Qt::CaseInsensitive)) {
   596     if (targetType == TypePlugin && !project->isActiveConfig("stdbinary")) {
   478         // Create custom def file for plugin
   597         // Create custom def file for plugin
   479         QFile ft(QLatin1String(PLUGIN_COMMON_DEF_FILE_ACTUAL));
   598         QFile ft(QLatin1String(PLUGIN_COMMON_DEF_FILE_ACTUAL));
   480 
   599 
   481         if (ft.open(QIODevice::WriteOnly)) {
   600         if (ft.open(QIODevice::WriteOnly)) {
   482             if (Option::mkfile::listgen) {
   601             if (Option::mkfile::listgen) {
   513 {
   632 {
   514     MakefileGenerator::init();
   633     MakefileGenerator::init();
   515     fixedTarget = escapeFilePath(fileFixify(project->first("TARGET")));
   634     fixedTarget = escapeFilePath(fileFixify(project->first("TARGET")));
   516     fixedTarget = removePathSeparators(fixedTarget);
   635     fixedTarget = removePathSeparators(fixedTarget);
   517     removeSpecialCharacters(fixedTarget);
   636     removeSpecialCharacters(fixedTarget);
       
   637     
       
   638  		translationFileName = escapeFilePath(fileFixify(project->first("TRANSLATIONS")));
       
   639  		if (!translationFileName.isEmpty()){
       
   640  		 		translationFileName.chop(3);
       
   641  				translationFileName = removePathSeparators(translationFileName);
       
   642  				removeSpecialCharacters(translationFileName);
       
   643  			}
       
   644  			else
       
   645  				translationFileName = fixedTarget;
   518 
   646 
   519     if (0 != project->values("QMAKE_PLATFORM").size())
   647     if (0 != project->values("QMAKE_PLATFORM").size())
   520         platform = varGlue("QMAKE_PLATFORM", "", " ", "");
   648         platform = varGlue("QMAKE_PLATFORM", "", " ", "");
   521 
   649 
   522     if (0 == project->values("QMAKESPEC").size())
   650     if (0 == project->values("QMAKESPEC").size())
   540 
   668 
   541     if ((project->values("TEMPLATE")).contains("app"))
   669     if ((project->values("TEMPLATE")).contains("app"))
   542         targetType = TypeExe;
   670         targetType = TypeExe;
   543     else if ((project->values("TEMPLATE")).contains("lib")) {
   671     else if ((project->values("TEMPLATE")).contains("lib")) {
   544         // Check CONFIG to see if we are to build staticlib or dll
   672         // Check CONFIG to see if we are to build staticlib or dll
   545         if (project->values("CONFIG").contains("staticlib") || project->values("CONFIG").contains("static"))
   673         if (project->isActiveConfig("staticlib") || project->isActiveConfig("static"))
   546             targetType = TypeLib;
   674             targetType = TypeLib;
   547         else if (project->values("CONFIG").contains("plugin"))
   675         else if (project->isActiveConfig("plugin"))
   548             targetType = TypePlugin;
   676             targetType = TypePlugin;
   549         else
   677         else
   550             targetType = TypeDll;
   678             targetType = TypeDll;
   551     } else {
   679     } else {
   552         targetType = TypeSubdirs;
   680         targetType = TypeSubdirs;
   553     }
   681     }
   554 
   682 
   555     if (0 != project->values("TARGET.UID2").size()) {
   683     if (0 != project->values("TARGET.UID2").size()) {
   556         uid2 = project->first("TARGET.UID2");
   684         uid2 = project->first("TARGET.UID2");
   557     } else if (project->values("CONFIG").contains("stdbinary", Qt::CaseInsensitive)) {
   685     } else if (project->isActiveConfig("stdbinary")) {
   558         uid2 = "0x20004C45";
   686         uid2 = "0x20004C45";
   559     } else {
   687     } else {
   560         if (targetType == TypeExe) {
   688         if (targetType == TypeExe) {
   561             if (project->values("QT").contains("gui", Qt::CaseInsensitive)) {
   689             if (project->values("QT").contains("gui", Qt::CaseInsensitive)) {
   562                 // exe and gui -> uid2 needed
   690                 // exe and gui -> uid2 needed
   623     srcpaths << project->values("SOURCES") << project->values("GENERATED_SOURCES");
   751     srcpaths << project->values("SOURCES") << project->values("GENERATED_SOURCES");
   624     srcpaths << project->values("UNUSED_SOURCES") << project->values("UI_SOURCES_DIR");
   752     srcpaths << project->values("UNUSED_SOURCES") << project->values("UI_SOURCES_DIR");
   625     srcpaths << project->values("UI_DIR");
   753     srcpaths << project->values("UI_DIR");
   626 
   754 
   627     QDir current = QDir::current();
   755     QDir current = QDir::current();
   628     QString canonizedCurrent = canonizePath(".");
   756     QString absolutizedCurrent = absolutizePath(".");
   629 
   757 
   630     for (int j = 0; j < srcpaths.size(); ++j) {
   758     for (int j = 0; j < srcpaths.size(); ++j) {
   631         QFileInfo fi(fileInfo(srcpaths.at(j)));
   759         QFileInfo fi(fileInfo(srcpaths.at(j)));
   632         // Sometimes sources have other than *.c* files (e.g. *.moc); prune them.
   760         // Sometimes sources have other than *.c* files (e.g. *.moc); prune them.
   633         if (fi.suffix().startsWith("c")) {
   761         if (fi.suffix().startsWith("c")) {
   634             if (fi.filePath().length() > fi.fileName().length()) {
   762             if (fi.filePath().length() > fi.fileName().length()) {
   635                 appendIfnotExist(srcincpaths, fi.path());
   763                 appendIfnotExist(srcincpaths, fi.path());
   636                 sources[canonizePath(fi.path())] += fi.fileName();
   764                 sources[absolutizePath(fi.path())] += fi.fileName();
   637             } else {
   765             } else {
   638                 sources[canonizedCurrent] += fi.fileName();
   766                 sources[absolutizedCurrent] += fi.fileName();
   639                 appendIfnotExist(srcincpaths, canonizedCurrent);
   767                 appendIfnotExist(srcincpaths, absolutizedCurrent);
   640             }
   768             }
   641         }
   769         }
   642     }
   770     }
   643 
   771 
   644     QStringList incpaths;
   772     QStringList incpaths;
   648     incpaths << srcincpaths;
   776     incpaths << srcincpaths;
   649     incpaths << project->values("UI_HEADERS_DIR");
   777     incpaths << project->values("UI_HEADERS_DIR");
   650     incpaths << project->values("UI_DIR");
   778     incpaths << project->values("UI_DIR");
   651 
   779 
   652     for (int j = 0; j < incpaths.size(); ++j) {
   780     for (int j = 0; j < incpaths.size(); ++j) {
   653         QString includepath = canonizePath(incpaths.at(j));
   781         QString includepath = absolutizePath(incpaths.at(j));
   654         appendIfnotExist(sysincspaths, includepath);
   782         appendIfnotExist(sysincspaths, includepath);
   655         appendAbldTempDirs(sysincspaths, includepath);
   783         appendAbldTempDirs(sysincspaths, includepath);
   656     }
   784     }
   657 
   785 
   658     // Remove duplicate include path entries
   786     // Remove duplicate include path entries
   690     QStringList overridableMmpKeywords;
   818     QStringList overridableMmpKeywords;
   691     QStringList restrictableMmpKeywords;
   819     QStringList restrictableMmpKeywords;
   692     QStringList restrictedMmpKeywords;
   820     QStringList restrictedMmpKeywords;
   693     bool inResourceBlock = false;
   821     bool inResourceBlock = false;
   694 
   822 
   695     overridableMmpKeywords << QLatin1String(MMP_TARGETTYPE);
   823     overridableMmpKeywords << QLatin1String(MMP_TARGETTYPE) << QLatin1String(MMP_EPOCHEAPSIZE);
   696     restrictableMmpKeywords << QLatin1String(MMP_TARGET) << QLatin1String(MMP_SECUREID)
   824     restrictableMmpKeywords << QLatin1String(MMP_TARGET) << QLatin1String(MMP_SECUREID)
   697        << QLatin1String(MMP_OPTION_CW) << QLatin1String(MMP_OPTION_ARMCC)
   825        << QLatin1String(MMP_LINKEROPTION_CW) << QLatin1String(MMP_LINKEROPTION_ARMCC)
   698        << QLatin1String(MMP_OPTION_GCCE) << QLatin1String(MMP_LINKEROPTION_CW)
   826        << QLatin1String(MMP_LINKEROPTION_GCCE)
   699        << QLatin1String(MMP_LINKEROPTION_ARMCC) << QLatin1String(MMP_LINKEROPTION_GCCE)
       
   700        << QLatin1String(MMP_CAPABILITY) << QLatin1String(MMP_EPOCALLOWDLLDATA)
   827        << QLatin1String(MMP_CAPABILITY) << QLatin1String(MMP_EPOCALLOWDLLDATA)
   701        << QLatin1String(MMP_EPOCHEAPSIZE) << QLatin1String(MMP_EPOCSTACKSIZE)
   828        << QLatin1String(MMP_EPOCSTACKSIZE) << QLatin1String(MMP_UID)
   702        << QLatin1String(MMP_UID) << QLatin1String(MMP_VENDORID)
   829        << QLatin1String(MMP_VENDORID) << QLatin1String(MMP_VERSION);
   703        << QLatin1String(MMP_VERSION);
       
   704 
   830 
   705     foreach (QString item, project->values("MMP_RULES")) {
   831     foreach (QString item, project->values("MMP_RULES")) {
   706         if (project->values(item).isEmpty()) {
   832         if (project->values(item).isEmpty()) {
   707             handleMmpRulesOverrides(item, inResourceBlock, restrictedMmpKeywords,
   833             handleMmpRulesOverrides(item, inResourceBlock, restrictedMmpKeywords,
   708                                     restrictableMmpKeywords, overridableMmpKeywords);
   834                                     restrictableMmpKeywords, overridableMmpKeywords);
   823             }
   949             }
   824             t << endl;
   950             t << endl;
   825         }
   951         }
   826         t << endl;
   952         t << endl;
   827 
   953 
   828         if (!project->values("CONFIG").contains("static") && !project->values("CONFIG").contains("staticlib")) {
   954         if (!project->isActiveConfig("static") && !project->isActiveConfig("staticlib")) {
   829             writeMmpFileLibraryPart(t);
   955             writeMmpFileLibraryPart(t);
   830         }
   956         }
   831 
   957 
   832         writeMmpFileCapabilityPart(t);
   958         writeMmpFileCapabilityPart(t);
   833 
   959 
   872 
   998 
   873 
   999 
   874 void SymbianMakefileGenerator::writeMmpFileTargetPart(QTextStream& t)
  1000 void SymbianMakefileGenerator::writeMmpFileTargetPart(QTextStream& t)
   875 {
  1001 {
   876     bool skipTargetType = overriddenMmpKeywords.contains(MMP_TARGETTYPE);
  1002     bool skipTargetType = overriddenMmpKeywords.contains(MMP_TARGETTYPE);
       
  1003     bool skipEpocHeapSize = overriddenMmpKeywords.contains(MMP_EPOCHEAPSIZE);
   877 
  1004 
   878     if (targetType == TypeExe) {
  1005     if (targetType == TypeExe) {
   879         t << MMP_TARGET "\t\t" << fixedTarget << ".exe" << endl;
  1006         t << MMP_TARGET "\t\t" << fixedTarget << ".exe" << endl;
   880         if (!skipTargetType) {
  1007         if (!skipTargetType) {
   881             if (project->values("CONFIG").contains("stdbinary", Qt::CaseInsensitive))
  1008             if (project->isActiveConfig("stdbinary"))
   882                 t << MMP_TARGETTYPE "\t\tSTDEXE" << endl;
  1009                 t << MMP_TARGETTYPE "\t\tSTDEXE" << endl;
   883             else
  1010             else
   884                 t << MMP_TARGETTYPE "\t\tEXE" << endl;
  1011                 t << MMP_TARGETTYPE "\t\tEXE" << endl;
   885         }
  1012         }
   886     } else if (targetType == TypeDll || targetType == TypePlugin) {
  1013     } else if (targetType == TypeDll || targetType == TypePlugin) {
   887         t << MMP_TARGET "\t\t" << fixedTarget << ".dll" << endl;
  1014         t << MMP_TARGET "\t\t" << fixedTarget << ".dll" << endl;
   888         if (!skipTargetType) {
  1015         if (!skipTargetType) {
   889             if (project->values("CONFIG").contains("stdbinary", Qt::CaseInsensitive))
  1016             if (project->isActiveConfig("stdbinary"))
   890                 t << MMP_TARGETTYPE "\t\tSTDDLL" << endl;
  1017                 t << MMP_TARGETTYPE "\t\tSTDDLL" << endl;
   891             else
  1018             else
   892                 t << MMP_TARGETTYPE "\t\tDLL" << endl;
  1019                 t << MMP_TARGETTYPE "\t\tDLL" << endl;
   893         }
  1020         }
   894     } else if (targetType == TypeLib) {
  1021     } else if (targetType == TypeLib) {
   895         t << MMP_TARGET "\t\t" << fixedTarget << ".lib" << endl;
  1022         t << MMP_TARGET "\t\t" << fixedTarget << ".lib" << endl;
   896         if (!skipTargetType) {
  1023         if (!skipTargetType) {
   897             if (project->values("CONFIG").contains("stdbinary", Qt::CaseInsensitive))
  1024             if (project->isActiveConfig("stdbinary"))
   898                 t << MMP_TARGETTYPE "\t\tSTDLIB" << endl;
  1025                 t << MMP_TARGETTYPE "\t\tSTDLIB" << endl;
   899             else
  1026             else
   900                 t << MMP_TARGETTYPE "\t\tLIB" << endl;
  1027                 t << MMP_TARGETTYPE "\t\tLIB" << endl;
   901         }
  1028         }
   902     } else {
  1029     } else {
   923 
  1050 
   924     t << endl;
  1051     t << endl;
   925 
  1052 
   926     if (0 != project->first("TARGET.EPOCSTACKSIZE").size())
  1053     if (0 != project->first("TARGET.EPOCSTACKSIZE").size())
   927         t << MMP_EPOCSTACKSIZE "\t\t" << project->first("TARGET.EPOCSTACKSIZE") << endl;
  1054         t << MMP_EPOCSTACKSIZE "\t\t" << project->first("TARGET.EPOCSTACKSIZE") << endl;
   928     if (0 != project->values("TARGET.EPOCHEAPSIZE").size())
  1055     if (!skipEpocHeapSize && 0 != project->values("TARGET.EPOCHEAPSIZE").size())
   929         t << MMP_EPOCHEAPSIZE "\t\t" << project->values("TARGET.EPOCHEAPSIZE").join(" ") << endl;
  1056         t << MMP_EPOCHEAPSIZE "\t\t" << project->values("TARGET.EPOCHEAPSIZE").join(" ") << endl;
   930     if (0 != project->values("TARGET.EPOCALLOWDLLDATA").size())
  1057     if (0 != project->values("TARGET.EPOCALLOWDLLDATA").size())
   931         t << MMP_EPOCALLOWDLLDATA << endl;
  1058         t << MMP_EPOCALLOWDLLDATA << endl;
   932 
  1059 
   933     if (targetType == TypePlugin && !project->values("CONFIG").contains("stdbinary", Qt::CaseInsensitive)) {
  1060     if (targetType == TypePlugin && !project->isActiveConfig("stdbinary")) {
   934         // Use custom def file for Qt plugins
  1061         // Use custom def file for Qt plugins
   935         t << "DEFFILE " PLUGIN_COMMON_DEF_FILE_FOR_MMP << endl;
  1062         t << "DEFFILE " PLUGIN_COMMON_DEF_FILE_FOR_MMP << endl;
   936     }
  1063     }
   937 
  1064 
   938     t << endl;
  1065     t << endl;
   944     \private\10003a3f\import\apps directory.
  1071     \private\10003a3f\import\apps directory.
   945 */
  1072 */
   946 void SymbianMakefileGenerator::writeMmpFileResourcePart(QTextStream& t, QStringList &symbianLangCodes)
  1073 void SymbianMakefileGenerator::writeMmpFileResourcePart(QTextStream& t, QStringList &symbianLangCodes)
   947 {
  1074 {
   948     if ((targetType == TypeExe) &&
  1075     if ((targetType == TypeExe) &&
   949             !project->values("CONFIG").contains("no_icon", Qt::CaseInsensitive)) {
  1076             !project->isActiveConfig("no_icon")) {
   950 
  1077 
   951         QString locTarget = fixedTarget;
  1078         QString locTarget = fixedTarget;
   952         locTarget.append(".rss");
  1079         locTarget.append(".rss");
   953 
  1080 
   954         t << "SOURCEPATH\t\t\t. " << endl;
  1081         t << "SOURCEPATH\t\t\t. " << endl;
  1151 
  1278 
  1152     if (!cw.isEmpty())
  1279     if (!cw.isEmpty())
  1153         t << MMP_OPTION_CW " " << cw <<  endl;
  1280         t << MMP_OPTION_CW " " << cw <<  endl;
  1154     if (!armcc.isEmpty())
  1281     if (!armcc.isEmpty())
  1155         t << MMP_OPTION_ARMCC " " << armcc <<  endl;
  1282         t << MMP_OPTION_ARMCC " " << armcc <<  endl;
       
  1283 
       
  1284     foreach(QString armccVersion, project->values("VERSION_FLAGS.ARMCC")) {
       
  1285         QStringList currentValues = project->values("QMAKE_CXXFLAGS." + armccVersion);
       
  1286         if (currentValues.size()) {
       
  1287             t << "#if defined(" << armccVersion << ")" << endl;
       
  1288             t << MMP_OPTION_ARMCC " " << currentValues.join(" ") <<  endl;
       
  1289             t << "#endif" << endl;
       
  1290         }
       
  1291     }
       
  1292 
  1156     if (!gcce.isEmpty())
  1293     if (!gcce.isEmpty())
  1157         t << MMP_OPTION_GCCE " " << gcce <<  endl;
  1294         t << MMP_OPTION_GCCE " " << gcce <<  endl;
  1158 
  1295 
  1159     if (!cwlink.isEmpty())
  1296     if (!cwlink.isEmpty())
  1160         t << MMP_LINKEROPTION_CW " " << cwlink <<  endl;
  1297         t << MMP_LINKEROPTION_CW " " << cwlink <<  endl;
  1216             }
  1353             }
  1217         }
  1354         }
  1218     }
  1355     }
  1219 }
  1356 }
  1220 
  1357 
  1221 void SymbianMakefileGenerator::writeBldInfContent(QTextStream &t, bool addDeploymentExtension, const QString &iconFile)
  1358 void SymbianMakefileGenerator::writeBldInfContent(QTextStream &t, bool addDeploymentExtension, const QString &iconFile, DeploymentList &depList)
  1222 {
  1359 {
  1223     // Read user defined bld inf rules
  1360     // Read user defined bld inf rules
  1224 
  1361 
  1225     QMap<QString, QStringList> userBldInfRules;
  1362     QMap<QString, QStringList> userBldInfRules;
  1226     for (QMap<QString, QStringList>::iterator it = project->variables().begin(); it != project->variables().end(); ++it) {
  1363     for (QMap<QString, QStringList>::iterator it = project->variables().begin(); it != project->variables().end(); ++it) {
  1262         } else if (!project->isEmpty(item + ".subdir")) {
  1399         } else if (!project->isEmpty(item + ".subdir")) {
  1263             fixedItem = project->first(item + ".subdir");
  1400             fixedItem = project->first(item + ".subdir");
  1264         } else {
  1401         } else {
  1265             fixedItem = item;
  1402             fixedItem = item;
  1266         }
  1403         }
       
  1404 
       
  1405         QString condition;
       
  1406         if (!project->isEmpty(item + ".condition"))
       
  1407             condition = project->first(item + ".condition");
  1267 
  1408 
  1268         QFileInfo subdir(fileInfo(fixedItem));
  1409         QFileInfo subdir(fileInfo(fixedItem));
  1269         QString relativePath = directory.relativeFilePath(fixedItem);
  1410         QString relativePath = directory.relativeFilePath(fixedItem);
  1270         QString subdirFileName = subdir.completeBaseName();
  1411         QString subdirFileName = subdir.completeBaseName();
  1271         QString fullProName = subdir.absoluteFilePath();;
  1412         QString fullProName = subdir.absoluteFilePath();;
  1291         QString uid = generate_uid(fullProName);
  1432         QString uid = generate_uid(fullProName);
  1292         QString bldinfDefine = QString("BLD_INF_") + subdirFileName + QString("_") + uid;
  1433         QString bldinfDefine = QString("BLD_INF_") + subdirFileName + QString("_") + uid;
  1293         bldinfDefine = bldinfDefine.toUpper();
  1434         bldinfDefine = bldinfDefine.toUpper();
  1294         removeSpecialCharacters(bldinfDefine);
  1435         removeSpecialCharacters(bldinfDefine);
  1295 
  1436 
       
  1437         if (!condition.isEmpty())
       
  1438             t << "#if defined(" << condition << ")" << endl;
       
  1439 
  1296         t << "#ifndef " << bldinfDefine << endl;
  1440         t << "#ifndef " << bldinfDefine << endl;
  1297         t << "\t#include \"" << QDir::toNativeSeparators(bldinfFilename) << "\"" << endl;
  1441         t << "\t#include \"" << bldinfFilename << "\"" << endl;
  1298         t << "#endif // " << bldinfDefine << endl;
  1442         t << "#endif" << endl;
       
  1443 
       
  1444         if (!condition.isEmpty())
       
  1445             t << "#endif" << endl;
       
  1446 
  1299     }
  1447     }
  1300 
  1448 
  1301     // Add supported project platforms
  1449     // Add supported project platforms
  1302 
  1450 
  1303     t << endl << BLD_INF_TAG_PLATFORMS << endl << endl;
  1451     t << endl << BLD_INF_TAG_PLATFORMS << endl << endl;
  1311     t << endl;
  1459     t << endl;
  1312 
  1460 
  1313     // Add project mmps and old style extension makefiles
  1461     // Add project mmps and old style extension makefiles
  1314 
  1462 
  1315     QString mmpTag;
  1463     QString mmpTag;
  1316     if (project->values("CONFIG").contains("symbian_test", Qt::CaseInsensitive))
  1464     if (project->isActiveConfig(SYMBIAN_TEST_CONFIG))
  1317         mmpTag = QLatin1String(BLD_INF_TAG_TESTMMPFILES);
  1465         mmpTag = QLatin1String(BLD_INF_TAG_TESTMMPFILES);
  1318     else
  1466     else
  1319         mmpTag = QLatin1String(BLD_INF_TAG_MMPFILES);
  1467         mmpTag = QLatin1String(BLD_INF_TAG_MMPFILES);
  1320 
  1468 
  1321     t << endl << mmpTag << endl << endl;
  1469     t << endl << mmpTag << endl << endl;
  1334     userItems = userBldInfRules.value(mmpTag);
  1482     userItems = userBldInfRules.value(mmpTag);
  1335     foreach(QString item, userItems)
  1483     foreach(QString item, userItems)
  1336         t << item << endl;
  1484         t << item << endl;
  1337     userBldInfRules.remove(mmpTag);
  1485     userBldInfRules.remove(mmpTag);
  1338 
  1486 
  1339     t << endl << BLD_INF_TAG_EXTENSIONS << endl << endl;
  1487     QString extensionTag;
       
  1488     if (project->isActiveConfig(SYMBIAN_TEST_CONFIG))
       
  1489         extensionTag = QLatin1String(BLD_INF_TAG_TESTEXTENSIONS);
       
  1490     else
       
  1491         extensionTag = QLatin1String(BLD_INF_TAG_EXTENSIONS);
       
  1492 
       
  1493     t << endl << extensionTag << endl << endl;
  1340 
  1494 
  1341     // Generate extension rules
  1495     // Generate extension rules
  1342 
  1496 
  1343     writeBldInfExtensionRulesPart(t, iconFile);
  1497     writeBldInfExtensionRulesPart(t, iconFile);
  1344 
  1498 
  1345     userItems = userBldInfRules.value(BLD_INF_TAG_EXTENSIONS);
  1499     userItems = userBldInfRules.value(extensionTag);
  1346     foreach(QString item, userItems)
  1500     foreach(QString item, userItems)
  1347         t << item << endl;
  1501         t << item << endl;
  1348     userBldInfRules.remove(BLD_INF_TAG_EXTENSIONS);
  1502     userBldInfRules.remove(extensionTag);
  1349 
  1503 
  1350     // Add rest of the user defined content
  1504     // Add rest of the user defined content
  1351 
  1505 
  1352     for (QMap<QString, QStringList>::iterator it = userBldInfRules.begin(); it != userBldInfRules.end(); ++it) {
  1506     for (QMap<QString, QStringList>::iterator it = userBldInfRules.begin(); it != userBldInfRules.end(); ++it) {
  1353         t << endl << endl << it.key() << endl << endl;
  1507         t << endl << endl << it.key() << endl << endl;
  1354         userItems = it.value();
  1508         userItems = it.value();
  1355         foreach(QString item, userItems)
  1509         foreach(QString item, userItems)
  1356             t << item << endl;
  1510             t << item << endl;
  1357     }
  1511     }
  1358     if (project->values("CONFIG").contains("headerexport", Qt::CaseInsensitive)) {
  1512 }
  1359         writeExportPart(t);
  1513 
  1360     }
  1514 void SymbianMakefileGenerator::writeRegRssFile(QMap<QString, QStringList> &userItems)
  1361 }
       
  1362 
       
  1363 void SymbianMakefileGenerator::writeExportPart(QTextStream &t)
       
  1364 {
       
  1365     QDir currentDir = QDir::current();
       
  1366     t << "prj_exports" << endl;
       
  1367 
       
  1368     foreach(QString install, project->values("INSTALLS")) {
       
  1369         QString installDir = project->first(install + ".path");
       
  1370 
       
  1371         // Export macros are the recommended way, but might not be used
       
  1372         // in all cases (such as Qt headers). We handle it either way,
       
  1373         // macros or not. 
       
  1374         bool useLayerMacro = false;
       
  1375         if (installDir.startsWith("MW_LAYER_") ||
       
  1376             installDir.startsWith("APP_LAYER_") ||
       
  1377             installDir.startsWith("APP_LAYER_")) {
       
  1378             useLayerMacro = true;
       
  1379         } else {
       
  1380 #ifdef Q_OS_WIN
       
  1381             // If we are running on Windows, and the export target starts
       
  1382             // with a drive letter, we need to remove it, the build tools
       
  1383             // cannot handle drives in export paths
       
  1384 
       
  1385             if (installDir.length() > 2 && installDir[1] == ':') {
       
  1386                 installDir.remove(0, 2);
       
  1387             }
       
  1388 #endif
       
  1389             installDir.replace("\\", "/");
       
  1390             if (!installDir.endsWith("/")) {
       
  1391                 installDir.append("/");
       
  1392             }
       
  1393         }
       
  1394 
       
  1395         foreach(QString target, project->values(install + ".files")) {
       
  1396             // Handle glob targets (only in the current directory)
       
  1397             if (target.contains("*") || target.contains("?")) {
       
  1398                 QDir globber = QDir::current();
       
  1399                 globber.setNameFilters(QStringList(target));
       
  1400                 foreach(QString globbedTarget, globber.entryList()) {
       
  1401                     if (useLayerMacro) {
       
  1402                         QFileInfo globbedInfo(globbedTarget);
       
  1403                         t << globbedTarget << " " << installDir <<
       
  1404                             "(" << globbedInfo.fileName() << ")" << endl;
       
  1405                     } else {
       
  1406                         t << globbedTarget << " " << installDir << 
       
  1407                             globbedTarget << endl;
       
  1408                     }
       
  1409                 }
       
  1410             } else {
       
  1411                 target = currentDir.relativeFilePath(target);
       
  1412                 QFileInfo targetInfo(target);
       
  1413 
       
  1414                 // Not possible to export whole directories, extension makefile needed for this
       
  1415                 // Note that this check requires the file to be exported to exist in the qmake phase!
       
  1416                 if (targetInfo.isFile()) {
       
  1417                     if (useLayerMacro) {
       
  1418                         t << target << " " << installDir <<
       
  1419                             "(" << targetInfo.fileName() << ")" << endl;
       
  1420                     } else {
       
  1421                         t << target << " " << installDir <<
       
  1422                             targetInfo.fileName() << endl;
       
  1423                     }
       
  1424                 }
       
  1425             }
       
  1426         }
       
  1427     }
       
  1428     t << endl;
       
  1429 }
       
  1430 
       
  1431 void SymbianMakefileGenerator::writeRegRssFile(QStringList &userItems)
       
  1432 {
  1515 {
  1433     QString filename(fixedTarget);
  1516     QString filename(fixedTarget);
  1434     filename.append("_reg.rss");
  1517     filename.append("_reg.rss");
  1435     QFile ft(filename);
  1518     QFile ft(filename);
  1436     if (ft.open(QIODevice::WriteOnly)) {
  1519     if (ft.open(QIODevice::WriteOnly)) {
  1446         t << "// * user." << endl;
  1529         t << "// * user." << endl;
  1447         t << "// ============================================================================" << endl;
  1530         t << "// ============================================================================" << endl;
  1448         t << endl;
  1531         t << endl;
  1449         t << "#include <" << fixedTarget << ".rsg>" << endl;
  1532         t << "#include <" << fixedTarget << ".rsg>" << endl;
  1450         t << "#include <appinfo.rh>" << endl;
  1533         t << "#include <appinfo.rh>" << endl;
       
  1534         foreach(QString item, userItems[RSS_TAG_HEADER])
       
  1535             t << item << endl;
  1451         t << endl;
  1536         t << endl;
  1452         t << "UID2 KUidAppRegistrationResourceFile" << endl;
  1537         t << "UID2 KUidAppRegistrationResourceFile" << endl;
  1453         t << "UID3 " << uid3 << endl << endl;
  1538         t << "UID3 " << uid3 << endl << endl;
  1454         t << "RESOURCE APP_REGISTRATION_INFO" << endl;
  1539         t << "RESOURCE APP_REGISTRATION_INFO" << endl;
  1455         t << "\t{" << endl;
  1540         t << "\t{" << endl;
  1456         t << "\tapp_file=\"" << fixedTarget << "\";" << endl;
  1541         t << "\tapp_file=\"" << fixedTarget << "\";" << endl;
  1457         t << "\tlocalisable_resource_file=\"" RESOURCE_DIRECTORY_RESOURCE << fixedTarget << "\";" << endl;
  1542         t << "\tlocalisable_resource_file=\"" RESOURCE_DIRECTORY_RESOURCE << fixedTarget << "\";" << endl;
       
  1543 
       
  1544         writeRegRssList(t, userItems[RSS_TAG_SERVICE_LIST],
       
  1545                         QLatin1String(RSS_TAG_SERVICE_LIST),
       
  1546                         QLatin1String("SERVICE_INFO"));
       
  1547         writeRegRssList(t, userItems[RSS_TAG_FILE_OWNERSHIP_LIST],
       
  1548                         QLatin1String(RSS_TAG_FILE_OWNERSHIP_LIST),
       
  1549                         QLatin1String("FILE_OWNERSHIP_INFO"));
       
  1550         writeRegRssList(t, userItems[RSS_TAG_DATATYPE_LIST],
       
  1551                         QLatin1String(RSS_TAG_DATATYPE_LIST),
       
  1552                         QLatin1String("DATATYPE"));
  1458         t << endl;
  1553         t << endl;
  1459 
  1554 
  1460         foreach(QString item, userItems)
  1555         foreach(QString item, userItems[RSS_TAG_DEFAULT])
  1461             t << "\t" << item << endl;
  1556             t << "\t" << item.replace("\n","\n\t") << endl;
  1462         t << "\t}" << endl;
  1557         t << "\t}" << endl;
       
  1558 
       
  1559         foreach(QString item, userItems[RSS_TAG_FOOTER])
       
  1560             t << item << endl;
  1463     } else {
  1561     } else {
  1464         PRINT_FILE_CREATE_ERROR(filename)
  1562         PRINT_FILE_CREATE_ERROR(filename)
       
  1563     }
       
  1564 }
       
  1565 
       
  1566 void SymbianMakefileGenerator::writeRegRssList(QTextStream &t,
       
  1567                                                QStringList &userList,
       
  1568                                                const QString &listTag,
       
  1569                                                const QString &listItem)
       
  1570 {
       
  1571     int itemCount = userList.count();
       
  1572     if (itemCount) {
       
  1573         t << "\t" << listTag << " ="<< endl;
       
  1574         t << "\t\t{" << endl;
       
  1575         foreach(QString item, userList) {
       
  1576             t << "\t\t" << listItem << endl;
       
  1577             t << "\t\t\t{" << endl;
       
  1578             t << "\t\t\t" << item.replace("\n","\n\t\t\t") << endl;
       
  1579             t << "\t\t\t}";
       
  1580             if (--itemCount)
       
  1581                 t << ",";
       
  1582             t << endl;
       
  1583         }
       
  1584         t << "\t\t}; "<< endl;
  1465     }
  1585     }
  1466 }
  1586 }
  1467 
  1587 
  1468 void SymbianMakefileGenerator::writeRssFile(QString &numberOfIcons, QString &iconFile)
  1588 void SymbianMakefileGenerator::writeRssFile(QString &numberOfIcons, QString &iconFile)
  1469 {
  1589 {
  1482         t << "// * This file is generated by qmake and should not be modified by the" << endl;
  1602         t << "// * This file is generated by qmake and should not be modified by the" << endl;
  1483         t << "// * user." << endl;
  1603         t << "// * user." << endl;
  1484         t << "// ============================================================================" << endl;
  1604         t << "// ============================================================================" << endl;
  1485         t << endl;
  1605         t << endl;
  1486         t << "#include <appinfo.rh>" << endl;
  1606         t << "#include <appinfo.rh>" << endl;
  1487         if (!project->values("SYMBIANTRANSLATIONS").isEmpty())
  1607         t << "#include <" << translationFileName << ".loc>" << endl;
  1488             t << "#include <" << fixedTarget << ".loc>" << endl;
       
  1489         else
       
  1490             t << "#include \"" << fixedTarget << ".loc\"" << endl;
       
  1491         t << endl;
  1608         t << endl;
  1492         t << "RESOURCE LOCALISABLE_APP_INFO r_localisable_app_info" << endl;
  1609         t << "RESOURCE LOCALISABLE_APP_INFO r_localisable_app_info" << endl;
  1493         t << "\t{" << endl;
  1610         t << "\t{" << endl;
  1494         t << "\tshort_caption = STRING_r_short_caption;" << endl;
  1611         t << "\tshort_caption = STRING_r_short_caption;" << endl;
  1495         t << "\tcaption_and_icon =" << endl;
  1612         t << "\tcaption_and_icon =" << endl;
  1517     }
  1634     }
  1518 }
  1635 }
  1519 
  1636 
  1520 void SymbianMakefileGenerator::writeLocFile(QStringList &symbianLangCodes)
  1637 void SymbianMakefileGenerator::writeLocFile(QStringList &symbianLangCodes)
  1521 {
  1638 {
  1522     QString filename(fixedTarget);
  1639     QString filename(translationFileName);
  1523     if (project->values("SYMBIANTRANSLATIONS").isEmpty()) {
  1640     if (project->values("SYMBIANTRANSLATIONS").isEmpty()) {
  1524         filename.append(".loc");
  1641         filename.append(".loc");
  1525     } else { 
  1642     } else { 
  1526         if (!project->first("SYMBIANLOCFILESDIR").isEmpty()) { 
  1643         if (!project->first("SYMBIANLOCFILESDIR").isEmpty()) { 
  1527             filename.insert(0,project->first("SYMBIANLOCFILESDIR"));         
  1644             filename.insert(0,project->first("SYMBIANLOCFILESDIR"));         
  1528         } else {	
  1645         } else {	
  1529             filename.insert(0,"/epoc32/include/platform/app/loc/");    
  1646             filename.insert(0,"/epoc32/include/platform/mw/loc/");    
  1530         }
  1647         }
  1531         filename.append(".loc");
  1648         filename.append(".loc");
  1532     }
  1649     }
  1533     
  1650     
  1534     QFile ft(filename);
  1651     QFile ft(filename);
  1558         t << "#define STRING_r_short_caption \"" << fixedTarget  << "\"" << endl;
  1675         t << "#define STRING_r_short_caption \"" << fixedTarget  << "\"" << endl;
  1559         t << "#define STRING_r_caption \"" << fixedTarget  << "\"" << endl;
  1676         t << "#define STRING_r_caption \"" << fixedTarget  << "\"" << endl;
  1560         t << "#endif" << endl;
  1677         t << "#endif" << endl;
  1561     } else {
  1678     } else {
  1562             t << "#if LANGUAGE_01" << endl;    
  1679             t << "#if LANGUAGE_01" << endl;    
  1563             t << "#include <" << "01/" << fixedTarget  << "_01.loc>" << endl;
  1680             t << "#include <" << "01/" << translationFileName  << "_01.loc>" << endl;
  1564             foreach(QString lang, symbianLangCodes) {
  1681             foreach(QString lang, symbianLangCodes) {
  1565                 if (lang.localeAwareCompare("01") != 0) {
  1682                 if (lang.localeAwareCompare("01") != 0) {
  1566                     t << "#elif LANGUAGE_" << lang << endl;
  1683                     t << "#elif LANGUAGE_" << lang << endl;
  1567                     t << "#include <" << lang << "/" << fixedTarget  << "_" << lang << ".loc>" << ">" << endl;
  1684                     t << "#include <" << lang << "/" << translationFileName  << "_" << lang << ".loc" << ">" << endl;
  1568                 }
  1685                 }
  1569             }
  1686             }
  1570             t << "#endif" << endl;
  1687             t << "#endif" << endl;
  1571         }
  1688         }
  1572     } else {
  1689     } else {
  1574     }
  1691     }
  1575 }
  1692 }
  1576 
  1693 
  1577 void SymbianMakefileGenerator::writeSymbianLocFile(QStringList &symbianLangCodes)
  1694 void SymbianMakefileGenerator::writeSymbianLocFile(QStringList &symbianLangCodes)
  1578 {	
  1695 {	
  1579 	QString filename(fixedTarget); 
  1696 	QString filename(translationFileName); 
  1580 	foreach(QString lang, symbianLangCodes) {
  1697 	foreach(QString lang, symbianLangCodes) {
  1581         
  1698         
  1582 		QString tsFilename(filename);  
  1699 		QString tsFilename(filename);  
  1583 		QString language = qt2S60LangMapTable.key(lang, QString("en"));
  1700 		QString language = qt2S60LangMapTable.key(lang, QString("en"));
  1584 		tsFilename.append("_"+language+".ts");
  1701 		tsFilename.append("_"+language+".ts");
  1585 		tsFilename.insert(0,project->first("SYMBIANTRANSLATIONDIR")); 	
  1702 	
       
  1703 		tsFilename.insert(0,project->first("SYMBIANTRANSLATIONSRCDIR")); 	
  1586 		
  1704 		
  1587         QString locFilename(filename); 
  1705         QString locFilename(filename); 
  1588         locFilename.append("_"+lang+".loc");
  1706         locFilename.append("_"+lang+".loc");
  1589         if (!project->first("SYMBIANLOCFILESDIR").isEmpty()) {    
  1707         if (!project->first("SYMBIANLOCFILESDIR").isEmpty()) {    
  1590             locFilename.insert(0,lang+"/");
  1708             locFilename.insert(0,lang+"/");
  1591             locFilename.insert(0,project->first("SYMBIANLOCFILESDIR"));
  1709             locFilename.insert(0,project->first("SYMBIANLOCFILESDIR"));
  1592         } else {	
  1710         } else {	
  1593             locFilename.insert(0,"/epoc32/include/platform/app/loc/"+lang+"/");
  1711             locFilename.insert(0,"/epoc32/include/platform/mw/loc/"+lang+"/");
  1594         }
  1712         }
  1595                 
  1713                 
  1596         QString shortCaption;
  1714         QString shortCaption;
  1597         QString longCaption;
  1715         QString longCaption;
  1598         
  1716         
  1631                                 }
  1749                                 }
  1632                             }
  1750                             }
  1633                         }
  1751                         }
  1634                     }         
  1752                     }         
  1635                 }
  1753                 }
  1636                 if (shortCaption.isEmpty())
  1754                 if (shortCaption.isEmpty()){
  1637                     fprintf(stderr, "Warning: STRING_r_short_caption not generated from file '%s'.\n", qPrintable(tsFilename));
  1755                     fprintf(stderr, "Warning: STRING_r_short_caption not generated from file '%s'.\n", qPrintable(tsFilename));
  1638                 if (longCaption.isEmpty())
  1756                     fprintf(stderr, "       : short caption generated from target name '#%s'.\n", qPrintable(fixedTarget));
       
  1757                   }
       
  1758                 if (longCaption.isEmpty()){
  1639                     fprintf(stderr, "Warning: STRING_r_caption not generated from file '%s'.\n", qPrintable(tsFilename));
  1759                     fprintf(stderr, "Warning: STRING_r_caption not generated from file '%s'.\n", qPrintable(tsFilename));
       
  1760                     fprintf(stderr, "       : caption generated from target name '#%s'.\n", qPrintable(fixedTarget));
       
  1761                   }
  1640                 if (xml.hasError())
  1762                 if (xml.hasError())
  1641                     fprintf(stderr, "ERROR: \"%s\" when parsing ts file\n", qPrintable(xml.errorString()));
  1763                     fprintf(stderr, "ERROR: \"%s\" when parsing ts file\n", qPrintable(xml.errorString()));
  1642             } else {
  1764             } else {
  1643                 fprintf(stderr, "Could not open ts file (%s)\n", qPrintable(tsFilename));
  1765                 fprintf(stderr, "Could not open ts file (%s)\n", qPrintable(tsFilename));
  1644             }
  1766             }
  1645         } else {
  1767         } else {
  1646             fprintf(stderr, "ts file does not exist: (%s)\n", qPrintable(tsFilename));
  1768             fprintf(stderr, "Warning: ts file does not exist: (%s)\n", qPrintable(tsFilename));
       
  1769             fprintf(stderr, "       : short and long caption generated from target name '#%s'.\n", qPrintable(fixedTarget));
  1647         }
  1770         }
  1648 
  1771 
  1649         // generate language specific caption loc file
  1772         // generate language specific caption loc file
  1650         QFile ft(locFilename);
  1773         QFile ft(locFilename);
  1651         if (ft.open(QIODevice::WriteOnly)) {
  1774         if (ft.open(QIODevice::WriteOnly)) {
  1659             t << "// ============================================================================" << endl;
  1782             t << "// ============================================================================" << endl;
  1660             t << endl;
  1783             t << endl;
  1661             if (!shortCaption.isEmpty()) {
  1784             if (!shortCaption.isEmpty()) {
  1662                 t << "#define STRING_r_short_caption \"" << shortCaption  << "\"" << endl;    
  1785                 t << "#define STRING_r_short_caption \"" << shortCaption  << "\"" << endl;    
  1663             } else {
  1786             } else {
  1664                 t << "#define STRING_r_short_caption \"" << fixedTarget  << "\"" << endl;
  1787                 t << "#define STRING_r_short_caption \"" "#"<< fixedTarget  << "\"" << endl;
  1665             }    
  1788             }    
  1666             if (!longCaption.isEmpty()) {
  1789             if (!longCaption.isEmpty()) {
  1667                 t << "#define STRING_r_caption \"" << longCaption  << "\"" << endl;  
  1790                 t << "#define STRING_r_caption \"" << longCaption  << "\"" << endl;  
  1668             } else {    
  1791             } else {    
  1669                 t << "#define STRING_r_caption \"" << fixedTarget  << "\"" << endl;
  1792                 t << "#define STRING_r_caption \"" "#"<< fixedTarget  << "\"" << endl;
  1670             }
  1793             }
  1671             ft.close();
  1794             ft.close();
  1672         } else {
  1795         } else {
  1673             PRINT_FILE_CREATE_ERROR(locFilename);	
  1796             PRINT_FILE_CREATE_ERROR(locFilename);	
  1674 	    }
  1797 	    }
  1675     }
  1798     }
  1676 }
  1799 }
  1677 
  1800 
  1678 void SymbianMakefileGenerator::readRssRules(QString &numberOfIcons, QString &iconFile, QStringList &userRssRules)
  1801 void SymbianMakefileGenerator::readRssRules(QString &numberOfIcons,
       
  1802                                             QString &iconFile, QMap<QString,
       
  1803                                             QStringList> &userRssRules)
  1679 {
  1804 {
  1680     for (QMap<QString, QStringList>::iterator it = project->variables().begin(); it != project->variables().end(); ++it) {
  1805     for (QMap<QString, QStringList>::iterator it = project->variables().begin(); it != project->variables().end(); ++it) {
  1681         if (it.key().startsWith(RSS_RULES_BASE)) {
  1806         if (it.key().startsWith(RSS_RULES_BASE)) {
  1682             QString newKey = it.key().mid(sizeof(RSS_RULES_BASE) - 1);
  1807             QString newKey = it.key().mid(sizeof(RSS_RULES_BASE) - 1);
  1683             if (newKey.isEmpty()) {
  1808             if (newKey.isEmpty()) {
  1685                 continue;
  1810                 continue;
  1686             }
  1811             }
  1687             QStringList newValues;
  1812             QStringList newValues;
  1688             QStringList values = it.value();
  1813             QStringList values = it.value();
  1689             foreach(QString item, values) {
  1814             foreach(QString item, values) {
  1690                 // If there is no stringlist defined for a rule, use rule name directly
  1815                 // If there is no stringlist defined for a rule, use rule value directly
  1691                 // This is convenience for defining single line statements
  1816                 // This is convenience for defining single line statements
  1692                 if (project->values(item).isEmpty()) {
  1817                 if (project->values(item).isEmpty()) {
  1693                     newValues << item;
  1818                     newValues << item;
  1694                 } else {
  1819                 } else {
       
  1820                     QStringList itemList;
  1695                     foreach(QString itemRow, project->values(item)) {
  1821                     foreach(QString itemRow, project->values(item)) {
  1696                         newValues << itemRow;
  1822                         itemList << itemRow;
  1697                     }
  1823                     }
       
  1824                     newValues << itemList.join("\n");
  1698                 }
  1825                 }
  1699             }
  1826             }
  1700             // Verify thet there is exactly one value in RSS_TAG_NBROFICONS
  1827             // Verify thet there is exactly one value in RSS_TAG_NBROFICONS
  1701             if (newKey == RSS_TAG_NBROFICONS) {
  1828             if (newKey == RSS_TAG_NBROFICONS) {
  1702                 if (newValues.count() == 1) {
  1829                 if (newValues.count() == 1) {
  1713                 } else {
  1840                 } else {
  1714                     fprintf(stderr, "Warning: There must be exactly one value in '%s%s'\n",
  1841                     fprintf(stderr, "Warning: There must be exactly one value in '%s%s'\n",
  1715                             RSS_RULES_BASE, RSS_TAG_ICONFILE);
  1842                             RSS_RULES_BASE, RSS_TAG_ICONFILE);
  1716                     continue;
  1843                     continue;
  1717                 }
  1844                 }
       
  1845             } else if (newKey == RSS_TAG_HEADER
       
  1846                        || newKey == RSS_TAG_SERVICE_LIST
       
  1847                        || newKey == RSS_TAG_FILE_OWNERSHIP_LIST
       
  1848                        || newKey == RSS_TAG_DATATYPE_LIST
       
  1849                        || newKey == RSS_TAG_FOOTER
       
  1850                        || newKey == RSS_TAG_DEFAULT) {
       
  1851                 userRssRules[newKey] = newValues;
       
  1852                 continue;
  1718             } else {
  1853             } else {
  1719                 fprintf(stderr, "Warning: Unsupported key:'%s%s'\n",
  1854                 fprintf(stderr, "Warning: Unsupported key:'%s%s'\n",
  1720                         RSS_RULES_BASE, newKey.toLatin1().constData());
  1855                         RSS_RULES_BASE, newKey.toLatin1().constData());
  1721                 continue;
  1856                 continue;
  1722             }
  1857             }
  1723         }
  1858         }
  1724     }
  1859     }
  1725 
  1860 
       
  1861     QStringList newValues;
  1726     foreach(QString item, project->values(RSS_RULES)) {
  1862     foreach(QString item, project->values(RSS_RULES)) {
  1727         // If there is no stringlist defined for a rule, use rule name directly
  1863         // If there is no stringlist defined for a rule, use rule value directly
  1728         // This is convenience for defining single line mmp statements
  1864         // This is convenience for defining single line statements
  1729         if (project->values(item).isEmpty()) {
  1865         if (project->values(item).isEmpty()) {
  1730             userRssRules << item;
  1866             newValues << item;
  1731         } else {
  1867         } else {
  1732             userRssRules << project->values(item);
  1868             newValues << project->values(item);
  1733         }
  1869         }
  1734     }
  1870     }
       
  1871     userRssRules[RSS_TAG_DEFAULT] << newValues;
  1735 
  1872 
  1736     // Validate that either both RSS_TAG_NBROFICONS and RSS_TAG_ICONFILE keys exist
  1873     // Validate that either both RSS_TAG_NBROFICONS and RSS_TAG_ICONFILE keys exist
  1737     // or neither of them exist
  1874     // or neither of them exist
  1738     if (!((numberOfIcons.isEmpty() && iconFile.isEmpty()) ||
  1875     if (!((numberOfIcons.isEmpty() && iconFile.isEmpty()) ||
  1739             (!numberOfIcons.isEmpty() && !iconFile.isEmpty()))) {
  1876             (!numberOfIcons.isEmpty() && !iconFile.isEmpty()))) {
  1745 
  1882 
  1746     // Validate that RSS_TAG_NBROFICONS contains only numbers
  1883     // Validate that RSS_TAG_NBROFICONS contains only numbers
  1747     if (!numberOfIcons.isEmpty()) {
  1884     if (!numberOfIcons.isEmpty()) {
  1748         bool ok;
  1885         bool ok;
  1749         numberOfIcons = numberOfIcons.simplified();
  1886         numberOfIcons = numberOfIcons.simplified();
  1750         int tmp = numberOfIcons.toInt(&ok);
  1887         numberOfIcons.toInt(&ok);
  1751         if (!ok) {
  1888         if (!ok) {
  1752             numberOfIcons.clear();
  1889             numberOfIcons.clear();
  1753             iconFile.clear();
  1890             iconFile.clear();
  1754             fprintf(stderr, "Warning: '%s%s' must be integer in decimal format.\n",
  1891             fprintf(stderr, "Warning: '%s%s' must be integer in decimal format.\n",
  1755                     RSS_RULES_BASE, RSS_TAG_NBROFICONS);
  1892                     RSS_RULES_BASE, RSS_TAG_NBROFICONS);
  2039     str.replace(QString(" "), QString("_"));
  2176     str.replace(QString(" "), QString("_"));
  2040 }
  2177 }
  2041 
  2178 
  2042 void SymbianMakefileGenerator::writeSisTargets(QTextStream &t)
  2179 void SymbianMakefileGenerator::writeSisTargets(QTextStream &t)
  2043 {
  2180 {
  2044     t << SIS_TARGET ": " RESTORE_BUILD_TARGET << endl;
  2181     t << "-include " MAKE_CACHE_NAME << endl;
  2045     QString siscommand = QString("\t$(if $(wildcard %1_template.%2),$(if $(wildcard %3)," \
  2182     t << endl;
  2046                                   "$(MAKE) -s -f $(MAKEFILE) %4,$(MAKE) -s -f $(MAKEFILE) %5)," \
  2183 
       
  2184     t << SIS_TARGET ":" << endl;
       
  2185     QString siscommand = QString::fromLatin1("\t$(if $(wildcard %1_template.%2),$(if $(wildcard %3)," \
       
  2186                                   "$(MAKE) -s -f $(MAKEFILE) %4," \
       
  2187                                   "$(if $(QT_SIS_TARGET),$(MAKE) -s -f $(MAKEFILE) %4," \
       
  2188                                   "$(MAKE) -s -f $(MAKEFILE) %5))," \
  2047                                   "$(MAKE) -s -f $(MAKEFILE) %6)")
  2189                                   "$(MAKE) -s -f $(MAKEFILE) %6)")
  2048                           .arg(fixedTarget)
  2190                           .arg(fixedTarget)
  2049                           .arg("pkg")
  2191                           .arg("pkg")
  2050                           .arg(MAKE_CACHE_NAME)
  2192                           .arg(MAKE_CACHE_NAME)
  2051                           .arg(OK_SIS_TARGET)
  2193                           .arg(OK_SIS_TARGET)
  2054     t << siscommand << endl;
  2196     t << siscommand << endl;
  2055     t << endl;
  2197     t << endl;
  2056 
  2198 
  2057     t << OK_SIS_TARGET ":" << endl;
  2199     t << OK_SIS_TARGET ":" << endl;
  2058 
  2200 
  2059     QString pkgcommand = QString("\tcreatepackage.bat $(QT_SIS_OPTIONS) %1_template.%2 $(QT_SIS_TARGET) " \
  2201     QString pkgcommand = QString::fromLatin1("\tcreatepackage.bat $(QT_SIS_OPTIONS) %1_template.%2 $(QT_SIS_TARGET) " \
  2060                                  "$(QT_SIS_CERTIFICATE) $(QT_SIS_KEY) $(QT_SIS_PASSPHRASE)")
  2202                                  "$(QT_SIS_CERTIFICATE) $(QT_SIS_KEY) $(QT_SIS_PASSPHRASE)")
  2061                           .arg(fixedTarget)
  2203                           .arg(fixedTarget)
  2062                           .arg("pkg");
  2204                           .arg("pkg");
  2063     t << pkgcommand << endl;
  2205     t << pkgcommand << endl;
  2064     t << endl;
  2206     t << endl;
  2065 
  2207 
       
  2208     QString sisName = fixedTarget;
       
  2209     sisName += ".sis";
       
  2210 
       
  2211     t << sisName << ":" << endl;
       
  2212     t << "\t$(MAKE) -s -f $(MAKEFILE) " SIS_TARGET << endl << endl;
       
  2213 
       
  2214     t << ROM_STUB_SIS_TARGET ":" << endl;
       
  2215     QString stubsiscommand = QString::fromLatin1("\t$(if $(wildcard %1_template.%2),$(if $(wildcard %3)," \
       
  2216                                   "$(MAKE) -s -f $(MAKEFILE) %4," \
       
  2217                                   "$(if $(QT_SIS_TARGET),$(MAKE) -s -f $(MAKEFILE) %4," \
       
  2218                                   "$(MAKE) -s -f $(MAKEFILE) %5))," \
       
  2219                                   "$(MAKE) -s -f $(MAKEFILE) %6)")
       
  2220                           .arg(fixedTarget)
       
  2221                           .arg("pkg")
       
  2222                           .arg(MAKE_CACHE_NAME)
       
  2223                           .arg(OK_ROM_STUB_SIS_TARGET)
       
  2224                           .arg(FAIL_SIS_NOCACHE_TARGET)
       
  2225                           .arg(FAIL_SIS_NOPKG_TARGET);
       
  2226     t << stubsiscommand << endl;
       
  2227     t << endl;
       
  2228 
       
  2229     t << OK_ROM_STUB_SIS_TARGET ":" << endl;
       
  2230 
       
  2231     QString stubpkgcommand = QString::fromLatin1("\tcreatepackage.bat -s $(QT_SIS_OPTIONS) %1_template.%2 $(QT_SIS_TARGET) " \
       
  2232                                  "$(QT_SIS_CERTIFICATE) $(QT_SIS_KEY) $(QT_SIS_PASSPHRASE)")
       
  2233                           .arg(fixedTarget)
       
  2234                           .arg("pkg");
       
  2235     t << stubpkgcommand << endl;
       
  2236     t << endl;
       
  2237 
       
  2238     t << INSTALLER_SIS_TARGET ": " << sisName << endl;
       
  2239     siscommand = QString::fromLatin1("\t$(if $(wildcard %1_installer.%2)," \
       
  2240                                   "$(MAKE) -s -f $(MAKEFILE) %3," \
       
  2241                                   "$(MAKE) -s -f $(MAKEFILE) %4)")
       
  2242                           .arg(fixedTarget)
       
  2243                           .arg("pkg")
       
  2244                           .arg(OK_INSTALLER_SIS_TARGET)
       
  2245                           .arg(FAIL_SIS_NOPKG_TARGET);
       
  2246     t << siscommand << endl;
       
  2247     t << endl;
       
  2248 
       
  2249     t << OK_INSTALLER_SIS_TARGET ": " << endl;
       
  2250 
       
  2251     pkgcommand = QString::fromLatin1("\tcreatepackage.bat $(QT_SIS_OPTIONS) %1_installer.%2 - " \
       
  2252                          "$(QT_SIS_CERTIFICATE) $(QT_SIS_KEY) $(QT_SIS_PASSPHRASE)")
       
  2253                   .arg(fixedTarget)
       
  2254                   .arg("pkg");
       
  2255     t << pkgcommand << endl;
       
  2256     t << endl;
       
  2257 
  2066     t << FAIL_SIS_NOPKG_TARGET ":" << endl;
  2258     t << FAIL_SIS_NOPKG_TARGET ":" << endl;
  2067     t << "\t$(error PKG file does not exist, 'SIS' target is only supported for executables or projects with DEPLOYMENT statement)" << endl;
  2259     t << "\t$(error PKG file does not exist, '" SIS_TARGET "' and '" INSTALLER_SIS_TARGET "' target are only supported for executables or projects with DEPLOYMENT statement)" << endl;
  2068     t << endl;
  2260     t << endl;
  2069 
  2261 
  2070     t << FAIL_SIS_NOCACHE_TARGET ":" << endl;
  2262     t << FAIL_SIS_NOCACHE_TARGET ":" << endl;
  2071     t << "\t$(error Project has to be build before calling 'SIS' target)" << endl;
  2263     t << "\t$(error Project has to be built or QT_SIS_TARGET environment variable has to be set before calling 'SIS' target)" << endl;
  2072     t << endl;
       
  2073 
       
  2074 
       
  2075     t << RESTORE_BUILD_TARGET ":" << endl;
       
  2076     t << "-include " MAKE_CACHE_NAME << endl;
       
  2077     t << endl;
  2264     t << endl;
  2078 }
  2265 }
  2079 
  2266 
  2080 void SymbianMakefileGenerator::generateDistcleanTargets(QTextStream& t)
  2267 void SymbianMakefileGenerator::generateDistcleanTargets(QTextStream& t)
  2081 {
  2268 {
  2129     t << endl;
  2316     t << endl;
  2130 
  2317 
  2131     t << "distclean: clean dodistclean" << endl;
  2318     t << "distclean: clean dodistclean" << endl;
  2132     t << endl;
  2319     t << endl;
  2133 }
  2320 }
       
  2321 
       
  2322 void SymbianMakefileGenerator::generateExecutionTargets(QTextStream& t, const QStringList& platforms)
       
  2323 {
       
  2324     // create execution targets
       
  2325     if (targetType == TypeExe) {
       
  2326         if (platforms.contains("winscw")) {
       
  2327             t << "run:" << endl;
       
  2328             t << "\t-call " << epocRoot() << "epoc32/release/winscw/udeb/" << fixedTarget << ".exe " << "$(QT_RUN_OPTIONS)" << endl;
       
  2329         }
       
  2330         t << "runonphone: sis" << endl;
       
  2331         t << "\trunonphone $(QT_RUN_ON_PHONE_OPTIONS) --sis " << fixedTarget << ".sis " << fixedTarget << ".exe " << "$(QT_RUN_OPTIONS)" << endl;
       
  2332         t << endl;
       
  2333     }
       
  2334 }