qmake/generators/symbian/symmake.cpp
branchRCL_3
changeset 7 3f74d0d4af4c
parent 5 d3bac044e0f0
child 13 c0432d11811c
equal deleted inserted replaced
6:dee5afe5301f 7:3f74d0d4af4c
    49 #include <stdlib.h>
    49 #include <stdlib.h>
    50 #include <qdebug.h>
    50 #include <qdebug.h>
    51 #include <qxmlstream.h>
    51 #include <qxmlstream.h>
    52 #include <QSettings>
    52 #include <QSettings>
    53 
    53 
       
    54 // Included from tools/shared
       
    55 #include <symbian/epocroot.h>
       
    56 
    54 #define RESOURCE_DIRECTORY_MMP "/resource/apps"
    57 #define RESOURCE_DIRECTORY_MMP "/resource/apps"
    55 #define RESOURCE_DIRECTORY_RESOURCE "\\\\resource\\\\apps\\\\"
    58 #define RESOURCE_DIRECTORY_RESOURCE "\\\\resource\\\\apps\\\\"
    56 #define REGISTRATION_RESOURCE_DIRECTORY_HW "/private/10003a3f/import/apps"
    59 #define REGISTRATION_RESOURCE_DIRECTORY_HW "/private/10003a3f/import/apps"
    57 #define PLUGIN_COMMON_DEF_FILE_FOR_MMP "./plugin_common.def"
    60 #define PLUGIN_COMMON_DEF_FILE_FOR_MMP "./plugin_common.def"
    58 #define PLUGIN_COMMON_DEF_FILE_ACTUAL "plugin_commonU.def"
    61 #define PLUGIN_COMMON_DEF_FILE_ACTUAL "plugin_commonU.def"
    60 #define BLD_INF_RULES_BASE "BLD_INF_RULES."
    63 #define BLD_INF_RULES_BASE "BLD_INF_RULES."
    61 #define BLD_INF_TAG_PLATFORMS "prj_platforms"
    64 #define BLD_INF_TAG_PLATFORMS "prj_platforms"
    62 #define BLD_INF_TAG_MMPFILES "prj_mmpfiles"
    65 #define BLD_INF_TAG_MMPFILES "prj_mmpfiles"
    63 #define BLD_INF_TAG_TESTMMPFILES "prj_testmmpfiles"
    66 #define BLD_INF_TAG_TESTMMPFILES "prj_testmmpfiles"
    64 #define BLD_INF_TAG_EXTENSIONS "prj_extensions"
    67 #define BLD_INF_TAG_EXTENSIONS "prj_extensions"
    65 #define BLD_INF_TAG_EXPORTS "prj_exports"
    68 #define BLD_INF_TAG_TESTEXTENSIONS "prj_testextensions"
    66 
    69 
    67 #define RSS_RULES "RSS_RULES"
    70 #define RSS_RULES "RSS_RULES"
    68 #define RSS_RULES_BASE "RSS_RULES."
    71 #define RSS_RULES_BASE "RSS_RULES."
    69 #define RSS_TAG_NBROFICONS "number_of_icons"
    72 #define RSS_TAG_NBROFICONS "number_of_icons"
    70 #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
    71 
    80 
    72 #define MMP_TARGET "TARGET"
    81 #define MMP_TARGET "TARGET"
    73 #define MMP_TARGETTYPE "TARGETTYPE"
    82 #define MMP_TARGETTYPE "TARGETTYPE"
    74 #define MMP_SECUREID "SECUREID"
    83 #define MMP_SECUREID "SECUREID"
    75 #define MMP_OPTION_CW "OPTION CW"
    84 #define MMP_OPTION_CW "OPTION CW"
    87 #define MMP_VERSION "VERSION"
    96 #define MMP_VERSION "VERSION"
    88 #define MMP_START_RESOURCE "START RESOURCE"
    97 #define MMP_START_RESOURCE "START RESOURCE"
    89 #define MMP_END_RESOURCE "END"
    98 #define MMP_END_RESOURCE "END"
    90 
    99 
    91 #define SIS_TARGET "sis"
   100 #define SIS_TARGET "sis"
       
   101 #define INSTALLER_SIS_TARGET "installer_sis"
       
   102 #define ROM_STUB_SIS_TARGET "stub_sis"
    92 #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"
    93 #define FAIL_SIS_NOPKG_TARGET "fail_sis_nopkg"
   106 #define FAIL_SIS_NOPKG_TARGET "fail_sis_nopkg"
    94 #define FAIL_SIS_NOCACHE_TARGET "fail_sis_nocache"
   107 #define FAIL_SIS_NOCACHE_TARGET "fail_sis_nocache"
    95 
   108 
    96 #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));
    97 
   110 
   102 
   115 
   103 QString SymbianMakefileGenerator::fixPathForMmp(const QString& origPath, const QDir& parentDir)
   116 QString SymbianMakefileGenerator::fixPathForMmp(const QString& origPath, const QDir& parentDir)
   104 {
   117 {
   105     static QString epocRootStr;
   118     static QString epocRootStr;
   106     if (epocRootStr.isEmpty()) {
   119     if (epocRootStr.isEmpty()) {
   107         QFileInfo efi(epocRoot());
   120         epocRootStr = epocRoot();
   108         epocRootStr = efi.canonicalFilePath();
   121         QFileInfo efi(epocRootStr);
   109         if (epocRootStr.isEmpty()) {
   122         if (!efi.exists() || epocRootStr.isEmpty()) {
   110             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()));
   111             epocRootStr = "/";
   124             epocRootStr = "/";
       
   125         } else {
       
   126             epocRootStr = efi.absoluteFilePath();
   112         }
   127         }
   113         if (!epocRootStr.endsWith("/"))
   128         if (!epocRootStr.endsWith("/"))
   114             epocRootStr += "/";
   129             epocRootStr += "/";
   115 
   130 
   116         epocRootStr += "epoc32/";
   131         epocRootStr += "epoc32/";
   130         resultPath = ".";
   145         resultPath = ".";
   131 
   146 
   132     return resultPath;
   147     return resultPath;
   133 }
   148 }
   134 
   149 
   135 QString SymbianMakefileGenerator::canonizePath(const QString& origPath)
   150 QString SymbianMakefileGenerator::absolutizePath(const QString& origPath)
   136 {
   151 {
   137     // Since current path gets appended almost always anyway, use it as default
       
   138     // for nonexisting paths.
       
   139     static QString defaultPath;
       
   140     if (defaultPath.isEmpty()) {
       
   141         QFileInfo fi(".");
       
   142         defaultPath = fi.canonicalFilePath();
       
   143     }
       
   144 
       
   145     // Prepend epocroot to any paths beginning with "/epoc32/"
   152     // Prepend epocroot to any paths beginning with "/epoc32/"
   146     QString resultPath = QDir::fromNativeSeparators(origPath);
   153     QString resultPath = QDir::fromNativeSeparators(origPath);
   147     QString tempPath(resultPath);
   154     if (resultPath.startsWith("/epoc32/", Qt::CaseInsensitive))
   148     bool isEpoc = false;
       
   149     if (resultPath.startsWith("/epoc32/", Qt::CaseInsensitive)) {
       
   150         isEpoc = true;
       
   151         resultPath = QDir::fromNativeSeparators(epocRoot()) + resultPath.mid(1);
   155         resultPath = QDir::fromNativeSeparators(epocRoot()) + resultPath.mid(1);
   152     }
       
   153 
   156 
   154     QFileInfo fi(fileInfo(resultPath));
   157     QFileInfo fi(fileInfo(resultPath));
   155     if(fi.isDir()) {
   158 
   156         if (isEpoc)
   159     // Since origPath can be something given in HEADERS, we need to check if we are dealing
   157             resultPath = fi.absoluteFilePath();//canonicalFilePath();
   160     // with a file or a directory. In case the origPath doesn't yet exist, isFile() returns
   158         else
   161     // false and we default to assuming it is a dir.
   159             resultPath = fi.canonicalFilePath();            
   162     if (fi.isFile()) {
       
   163         resultPath = fi.absolutePath();
   160     } else {
   164     } else {
   161         if (isEpoc)
   165         resultPath = fi.absoluteFilePath();
   162             resultPath = fi.absolutePath();//canonicalPath();
       
   163         else
       
   164             resultPath = fi.canonicalPath();
       
   165     }
       
   166     //some fix for the not existed EPOC32\include folder
       
   167     if (isEpoc) {
       
   168         int index = resultPath.lastIndexOf("/epoc32/"); 
       
   169         QString tmpRes = resultPath.mid(index);
       
   170         if (tmpRes != tempPath) {
       
   171             //we have the problems for not existed include directory
       
   172             //change the path
       
   173             resultPath.replace(tmpRes, tempPath);
       
   174             }
       
   175     }
   166     }
   176 
   167 
   177     resultPath = QDir::cleanPath(resultPath);
   168     resultPath = QDir::cleanPath(resultPath);
   178 
       
   179     if (resultPath.isEmpty())
       
   180         resultPath = defaultPath;
       
   181 
   169 
   182     return resultPath;
   170     return resultPath;
   183 }
   171 }
   184 
   172 
   185 SymbianMakefileGenerator::SymbianMakefileGenerator() : MakefileGenerator() { }
   173 SymbianMakefileGenerator::SymbianMakefileGenerator() : MakefileGenerator() { }
   218 {
   206 {
   219     writeHeader(t);
   207     writeHeader(t);
   220 
   208 
   221     QString numberOfIcons;
   209     QString numberOfIcons;
   222     QString iconFile;
   210     QString iconFile;
   223     QStringList userRssRules;
   211     QMap<QString, QStringList> userRssRules;
   224     readRssRules(numberOfIcons, iconFile, userRssRules);
   212     readRssRules(numberOfIcons, iconFile, userRssRules);
   225 
   213 
   226     // 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
   227     QStringList symbianLangCodes = symbianLangCodesFromTsFiles();
   215     QStringList symbianLangCodes = symbianLangCodesFromTsFiles();
   228 
   216 
   320     }
   308     }
   321     if (Option::mkfile::listgen) {
   309     if (Option::mkfile::listgen) {
   322         generatePrint(fileInfo(pkgFile.fileName()).absoluteFilePath());
   310         generatePrint(fileInfo(pkgFile.fileName()).absoluteFilePath());
   323     }
   311     }
   324     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);
   325 
   323 
   326     // Header info
   324     // Header info
   327     QTextStream t(&pkgFile);
   325     QString wrapperPkgFilename = QString("%1_installer.%2")
   328     t << QString("; %1 generated by qmake at %2").arg(pkgFilename).arg(QDateTime::currentDateTime().toString(Qt::ISODate))  << endl;
   326                                 .arg(fixedTarget)
   329     t << "; This file is generated by qmake and should not be modified by the user" << endl;
   327                                 .arg("pkg");
   330     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);
   331 
   333 
   332     // 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.
   333     QStringList rawPkgPreRules;
   337     QStringList rawPkgPreRules;
       
   338     QStringList languageRules;
       
   339     QStringList headerRules;
   334     foreach(QString deploymentItem, project->values("DEPLOYMENT")) {
   340     foreach(QString deploymentItem, project->values("DEPLOYMENT")) {
   335         foreach(QString pkgrulesItem, project->values(deploymentItem + ".pkg_prerules")) {
   341         foreach(QString pkgrulesItem, project->values(deploymentItem + ".pkg_prerules")) {
   336             QStringList pkgrulesValue = project->values(pkgrulesItem);
   342             QStringList pkgrulesValue = project->values(pkgrulesItem);
   337             // 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
   338             // This is convenience for defining single line mmp statements
   344             // This is convenience for defining single line mmp statements
   339             if (pkgrulesValue.isEmpty()) {
   345             if (pkgrulesValue.isEmpty()) {
   340                 rawPkgPreRules << pkgrulesItem;
   346                 if (pkgrulesItem.startsWith("&"))
       
   347                     languageRules << pkgrulesItem;
       
   348                 else if (pkgrulesItem.startsWith("#"))
       
   349                     headerRules << pkgrulesItem;
       
   350                 else
       
   351                     rawPkgPreRules << pkgrulesItem;
   341             } else {
   352             } else {
   342                 foreach(QString pkgrule, pkgrulesValue) {
   353                 if (containsStartWithItem('&', pkgrulesValue)) {
   343                     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                     }
   344                 }
   365                 }
   345             }
   366             }
   346         }
   367         }
   347     }
   368     }
   348 
   369 
   349     // 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
   350 
   371 
   351     if (!containsStartWithItem('&', rawPkgPreRules)) {
   372     if (languageRules.isEmpty()) {
   352         // language, (*** hardcoded to english atm, should be parsed from TRANSLATIONS)
   373         // language, (*** hardcoded to english atm, should be parsed from TRANSLATIONS)
   353         t << "; Language" << endl;
   374         languageRules << "; Language\n&EN\n\n";
   354         t << "&EN" << endl << endl;
   375     } else if (headerRules.isEmpty()) {
   355     } else {
       
   356         // 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
   357         if (!containsStartWithItem('#', rawPkgPreRules))
   377         fprintf(stderr, "Warning: If language is defined with DEPLOYMENT pkg_prerules, also the SIS header must be defined\n");
   358             fprintf(stderr, "Warning: If language is defined with DEPLOYMENT pkg_prerules, also the SIS header must be defined\n");
   378     }
   359     }
   379 
       
   380     t << languageRules.join("\n") << endl;
       
   381     tw << languageRules.join("\n") << endl;
   360 
   382 
   361     // name of application, UID and version
   383     // name of application, UID and version
   362     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('.', ',');
   363 
   385     QString sisHeader = "; SIS header: name, uid, version\n#{\"%1\"},(%2),%3\n\n";
   364     if (!containsStartWithItem('#', rawPkgPreRules)) {
   386     QString visualTarget = escapeFilePath(fileFixify(project->first("TARGET")));
   365         QString visualTarget = escapeFilePath(fileFixify(project->first("TARGET")));
   387     visualTarget = removePathSeparators(visualTarget);
   366         visualTarget = removePathSeparators(visualTarget);
   388     QString wrapperTarget = visualTarget + " installer";
   367 
   389 
   368         t << "; SIS header: name, uid, version" << endl;
   390     if (installerSisHeader.startsWith("0x", Qt::CaseInsensitive)) {
   369         t << QString("#{\"%1\"},(%2),%3").arg(visualTarget).arg(uid3).arg(applicationVersion) << endl << endl;
   391         tw << sisHeader.arg(wrapperTarget).arg(installerSisHeader).arg(applicationVersion);
   370     }
   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;
   371 
   400 
   372     // Localized vendor name
   401     // Localized vendor name
       
   402     QString vendorName;
   373     if (!containsStartWithItem('%', rawPkgPreRules)) {
   403     if (!containsStartWithItem('%', rawPkgPreRules)) {
   374         t << "; Localised Vendor name" << endl;
   404         vendorName += "; Localised Vendor name\n%{\"Vendor\"}\n\n";
   375         t << "%{\"Vendor\"}" << endl << endl;
       
   376     }
   405     }
   377 
   406 
   378     // Unique vendor name
   407     // Unique vendor name
   379     if (!containsStartWithItem(':', rawPkgPreRules)) {
   408     if (!containsStartWithItem(':', rawPkgPreRules)) {
   380         t << "; Unique Vendor name" << endl;
   409         vendorName += "; Unique Vendor name\n:\"Vendor\"\n\n";
   381         t << ":\"Vendor\"" << endl << endl;
   410     }
   382     }
   411 
       
   412     t << vendorName;
       
   413     tw << vendorName;
   383 
   414 
   384     // 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
   385     if (rawPkgPreRules.size()) {
   416     if (rawPkgPreRules.size()) {
   386         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 
   387         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             }
   388             t << item << endl;
   427             t << item << endl;
   389         }
   428         }
   390         t << endl;
   429         t << endl;
       
   430         tw << endl;
   391     }
   431     }
   392 
   432 
   393     // Begin Manufacturer block
   433     // Begin Manufacturer block
   394     if (!project->values("DEPLOYMENT.manufacturers").isEmpty()) {
   434     if (!project->values("DEPLOYMENT.manufacturers").isEmpty()) {
   395         QString manufacturerStr("IF ");
   435         QString manufacturerStr("IF ");
   407     QString installPathRegResource = "!:\\private\\10003a3f\\import\\apps";
   447     QString installPathRegResource = "!:\\private\\10003a3f\\import\\apps";
   408 
   448 
   409     // Find location of builds
   449     // Find location of builds
   410     QString epocReleasePath = QString("%1epoc32/release/$(PLATFORM)/$(TARGET)")
   450     QString epocReleasePath = QString("%1epoc32/release/$(PLATFORM)/$(TARGET)")
   411                               .arg(epocRoot());
   451                               .arg(epocRoot());
   412 
       
   413 
   452 
   414     if (targetType == TypeExe) {
   453     if (targetType == TypeExe) {
   415         // deploy .exe file
   454         // deploy .exe file
   416         t << "; Executable and default resource files" << endl;
   455         t << "; Executable and default resource files" << endl;
   417         QString exeFile = fixedTarget + ".exe";
   456         QString exeFile = fixedTarget + ".exe";
   445     }
   484     }
   446 
   485 
   447     // deploy any additional DEPLOYMENT  files
   486     // deploy any additional DEPLOYMENT  files
   448     QString remoteTestPath;
   487     QString remoteTestPath;
   449     remoteTestPath = QString("!:\\private\\%1").arg(privateDirUid);
   488     remoteTestPath = QString("!:\\private\\%1").arg(privateDirUid);
       
   489     QString zDir = epocRoot() + QLatin1String("epoc32/data/z");
   450 
   490 
   451     initProjectDeploySymbian(project, depList, remoteTestPath, true, "$(PLATFORM)", "$(TARGET)", generatedDirs, generatedFiles);
   491     initProjectDeploySymbian(project, depList, remoteTestPath, true, "$(PLATFORM)", "$(TARGET)", generatedDirs, generatedFiles);
   452     if (depList.size())
   492     if (depList.size())
   453         t << "; DEPLOYMENT" << endl;
   493         t << "; DEPLOYMENT" << endl;
   454     for (int i = 0; i < depList.size(); ++i)  {
   494     for (int i = 0; i < depList.size(); ++i)  {
   455         t << QString("\"%1\"    - \"%2\"")
   495         QString from = depList.at(i).from;
   456              .arg(QString(depList.at(i).from).replace('\\','/'))
   496         QString to = depList.at(i).to;
   457              .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;
   458     }
   512     }
   459     t << endl;
   513     t << endl;
   460 
   514 
   461     // 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
   462     t << "; Manual PKG post-rules from PRO files" << endl;
   516     t << "; Manual PKG post-rules from PRO files" << endl;
   497         t << "ELSEIF NOT(0) ; MANUFACTURER" << endl
   551         t << "ELSEIF NOT(0) ; MANUFACTURER" << endl
   498           << "\"" << fileInfo(manufacturerFailNoteFile).absoluteFilePath() << "\""
   552           << "\"" << fileInfo(manufacturerFailNoteFile).absoluteFilePath() << "\""
   499           << " - \"\", FILETEXT, TEXTEXIT" << endl
   553           << " - \"\", FILETEXT, TEXTEXIT" << endl
   500           << "ENDIF ; MANUFACTURER" << endl;
   554           << "ENDIF ; MANUFACTURER" << endl;
   501     }
   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     }
   502 }
   580 }
   503 
   581 
   504 bool SymbianMakefileGenerator::containsStartWithItem(const QChar &c, const QStringList& src)
   582 bool SymbianMakefileGenerator::containsStartWithItem(const QChar &c, const QStringList& src)
   505 {
   583 {
   506     bool result = false;
   584     bool result = false;
   673     srcpaths << project->values("SOURCES") << project->values("GENERATED_SOURCES");
   751     srcpaths << project->values("SOURCES") << project->values("GENERATED_SOURCES");
   674     srcpaths << project->values("UNUSED_SOURCES") << project->values("UI_SOURCES_DIR");
   752     srcpaths << project->values("UNUSED_SOURCES") << project->values("UI_SOURCES_DIR");
   675     srcpaths << project->values("UI_DIR");
   753     srcpaths << project->values("UI_DIR");
   676 
   754 
   677     QDir current = QDir::current();
   755     QDir current = QDir::current();
   678     QString canonizedCurrent = canonizePath(".");
   756     QString absolutizedCurrent = absolutizePath(".");
   679 
   757 
   680     for (int j = 0; j < srcpaths.size(); ++j) {
   758     for (int j = 0; j < srcpaths.size(); ++j) {
   681         QFileInfo fi(fileInfo(srcpaths.at(j)));
   759         QFileInfo fi(fileInfo(srcpaths.at(j)));
   682         // 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.
   683         if (fi.suffix().startsWith("c")) {
   761         if (fi.suffix().startsWith("c")) {
   684             if (fi.filePath().length() > fi.fileName().length()) {
   762             if (fi.filePath().length() > fi.fileName().length()) {
   685                 appendIfnotExist(srcincpaths, fi.path());
   763                 appendIfnotExist(srcincpaths, fi.path());
   686                 sources[canonizePath(fi.path())] += fi.fileName();
   764                 sources[absolutizePath(fi.path())] += fi.fileName();
   687             } else {
   765             } else {
   688                 sources[canonizedCurrent] += fi.fileName();
   766                 sources[absolutizedCurrent] += fi.fileName();
   689                 appendIfnotExist(srcincpaths, canonizedCurrent);
   767                 appendIfnotExist(srcincpaths, absolutizedCurrent);
   690             }
   768             }
   691         }
   769         }
   692     }
   770     }
   693 
   771 
   694     QStringList incpaths;
   772     QStringList incpaths;
   698     incpaths << srcincpaths;
   776     incpaths << srcincpaths;
   699     incpaths << project->values("UI_HEADERS_DIR");
   777     incpaths << project->values("UI_HEADERS_DIR");
   700     incpaths << project->values("UI_DIR");
   778     incpaths << project->values("UI_DIR");
   701 
   779 
   702     for (int j = 0; j < incpaths.size(); ++j) {
   780     for (int j = 0; j < incpaths.size(); ++j) {
   703         QString includepath = canonizePath(incpaths.at(j));
   781         QString includepath = absolutizePath(incpaths.at(j));
   704         appendIfnotExist(sysincspaths, includepath);
   782         appendIfnotExist(sysincspaths, includepath);
   705         appendAbldTempDirs(sysincspaths, includepath);
   783         appendAbldTempDirs(sysincspaths, includepath);
   706     }
   784     }
   707 
   785 
   708     // Remove duplicate include path entries
   786     // Remove duplicate include path entries
   740     QStringList overridableMmpKeywords;
   818     QStringList overridableMmpKeywords;
   741     QStringList restrictableMmpKeywords;
   819     QStringList restrictableMmpKeywords;
   742     QStringList restrictedMmpKeywords;
   820     QStringList restrictedMmpKeywords;
   743     bool inResourceBlock = false;
   821     bool inResourceBlock = false;
   744 
   822 
   745     overridableMmpKeywords << QLatin1String(MMP_TARGETTYPE);
   823     overridableMmpKeywords << QLatin1String(MMP_TARGETTYPE) << QLatin1String(MMP_EPOCHEAPSIZE);
   746     restrictableMmpKeywords << QLatin1String(MMP_TARGET) << QLatin1String(MMP_SECUREID)
   824     restrictableMmpKeywords << QLatin1String(MMP_TARGET) << QLatin1String(MMP_SECUREID)
   747        << QLatin1String(MMP_OPTION_CW) << QLatin1String(MMP_OPTION_ARMCC)
   825        << QLatin1String(MMP_LINKEROPTION_CW) << QLatin1String(MMP_LINKEROPTION_ARMCC)
   748        << QLatin1String(MMP_OPTION_GCCE) << QLatin1String(MMP_LINKEROPTION_CW)
   826        << QLatin1String(MMP_LINKEROPTION_GCCE)
   749        << QLatin1String(MMP_LINKEROPTION_ARMCC) << QLatin1String(MMP_LINKEROPTION_GCCE)
       
   750        << QLatin1String(MMP_CAPABILITY) << QLatin1String(MMP_EPOCALLOWDLLDATA)
   827        << QLatin1String(MMP_CAPABILITY) << QLatin1String(MMP_EPOCALLOWDLLDATA)
   751        << QLatin1String(MMP_EPOCHEAPSIZE) << QLatin1String(MMP_EPOCSTACKSIZE)
   828        << QLatin1String(MMP_EPOCSTACKSIZE) << QLatin1String(MMP_UID)
   752        << QLatin1String(MMP_UID) << QLatin1String(MMP_VENDORID)
   829        << QLatin1String(MMP_VENDORID) << QLatin1String(MMP_VERSION);
   753        << QLatin1String(MMP_VERSION);
       
   754 
   830 
   755     foreach (QString item, project->values("MMP_RULES")) {
   831     foreach (QString item, project->values("MMP_RULES")) {
   756         if (project->values(item).isEmpty()) {
   832         if (project->values(item).isEmpty()) {
   757             handleMmpRulesOverrides(item, inResourceBlock, restrictedMmpKeywords,
   833             handleMmpRulesOverrides(item, inResourceBlock, restrictedMmpKeywords,
   758                                     restrictableMmpKeywords, overridableMmpKeywords);
   834                                     restrictableMmpKeywords, overridableMmpKeywords);
   922 
   998 
   923 
   999 
   924 void SymbianMakefileGenerator::writeMmpFileTargetPart(QTextStream& t)
  1000 void SymbianMakefileGenerator::writeMmpFileTargetPart(QTextStream& t)
   925 {
  1001 {
   926     bool skipTargetType = overriddenMmpKeywords.contains(MMP_TARGETTYPE);
  1002     bool skipTargetType = overriddenMmpKeywords.contains(MMP_TARGETTYPE);
       
  1003     bool skipEpocHeapSize = overriddenMmpKeywords.contains(MMP_EPOCHEAPSIZE);
   927 
  1004 
   928     if (targetType == TypeExe) {
  1005     if (targetType == TypeExe) {
   929         t << MMP_TARGET "\t\t" << fixedTarget << ".exe" << endl;
  1006         t << MMP_TARGET "\t\t" << fixedTarget << ".exe" << endl;
   930         if (!skipTargetType) {
  1007         if (!skipTargetType) {
   931             if (project->isActiveConfig("stdbinary"))
  1008             if (project->isActiveConfig("stdbinary"))
   973 
  1050 
   974     t << endl;
  1051     t << endl;
   975 
  1052 
   976     if (0 != project->first("TARGET.EPOCSTACKSIZE").size())
  1053     if (0 != project->first("TARGET.EPOCSTACKSIZE").size())
   977         t << MMP_EPOCSTACKSIZE "\t\t" << project->first("TARGET.EPOCSTACKSIZE") << endl;
  1054         t << MMP_EPOCSTACKSIZE "\t\t" << project->first("TARGET.EPOCSTACKSIZE") << endl;
   978     if (0 != project->values("TARGET.EPOCHEAPSIZE").size())
  1055     if (!skipEpocHeapSize && 0 != project->values("TARGET.EPOCHEAPSIZE").size())
   979         t << MMP_EPOCHEAPSIZE "\t\t" << project->values("TARGET.EPOCHEAPSIZE").join(" ") << endl;
  1056         t << MMP_EPOCHEAPSIZE "\t\t" << project->values("TARGET.EPOCHEAPSIZE").join(" ") << endl;
   980     if (0 != project->values("TARGET.EPOCALLOWDLLDATA").size())
  1057     if (0 != project->values("TARGET.EPOCALLOWDLLDATA").size())
   981         t << MMP_EPOCALLOWDLLDATA << endl;
  1058         t << MMP_EPOCALLOWDLLDATA << endl;
   982 
  1059 
   983     if (targetType == TypePlugin && !project->isActiveConfig("stdbinary")) {
  1060     if (targetType == TypePlugin && !project->isActiveConfig("stdbinary")) {
  1201 
  1278 
  1202     if (!cw.isEmpty())
  1279     if (!cw.isEmpty())
  1203         t << MMP_OPTION_CW " " << cw <<  endl;
  1280         t << MMP_OPTION_CW " " << cw <<  endl;
  1204     if (!armcc.isEmpty())
  1281     if (!armcc.isEmpty())
  1205         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 
  1206     if (!gcce.isEmpty())
  1293     if (!gcce.isEmpty())
  1207         t << MMP_OPTION_GCCE " " << gcce <<  endl;
  1294         t << MMP_OPTION_GCCE " " << gcce <<  endl;
  1208 
  1295 
  1209     if (!cwlink.isEmpty())
  1296     if (!cwlink.isEmpty())
  1210         t << MMP_LINKEROPTION_CW " " << cwlink <<  endl;
  1297         t << MMP_LINKEROPTION_CW " " << cwlink <<  endl;
  1312         } else if (!project->isEmpty(item + ".subdir")) {
  1399         } else if (!project->isEmpty(item + ".subdir")) {
  1313             fixedItem = project->first(item + ".subdir");
  1400             fixedItem = project->first(item + ".subdir");
  1314         } else {
  1401         } else {
  1315             fixedItem = item;
  1402             fixedItem = item;
  1316         }
  1403         }
       
  1404 
       
  1405         QString condition;
       
  1406         if (!project->isEmpty(item + ".condition"))
       
  1407             condition = project->first(item + ".condition");
  1317 
  1408 
  1318         QFileInfo subdir(fileInfo(fixedItem));
  1409         QFileInfo subdir(fileInfo(fixedItem));
  1319         QString relativePath = directory.relativeFilePath(fixedItem);
  1410         QString relativePath = directory.relativeFilePath(fixedItem);
  1320         QString subdirFileName = subdir.completeBaseName();
  1411         QString subdirFileName = subdir.completeBaseName();
  1321         QString fullProName = subdir.absoluteFilePath();;
  1412         QString fullProName = subdir.absoluteFilePath();;
  1341         QString uid = generate_uid(fullProName);
  1432         QString uid = generate_uid(fullProName);
  1342         QString bldinfDefine = QString("BLD_INF_") + subdirFileName + QString("_") + uid;
  1433         QString bldinfDefine = QString("BLD_INF_") + subdirFileName + QString("_") + uid;
  1343         bldinfDefine = bldinfDefine.toUpper();
  1434         bldinfDefine = bldinfDefine.toUpper();
  1344         removeSpecialCharacters(bldinfDefine);
  1435         removeSpecialCharacters(bldinfDefine);
  1345 
  1436 
       
  1437         if (!condition.isEmpty())
       
  1438             t << "#if defined(" << condition << ")" << endl;
       
  1439 
  1346         t << "#ifndef " << bldinfDefine << endl;
  1440         t << "#ifndef " << bldinfDefine << endl;
  1347         t << "\t#include \"" << QDir::toNativeSeparators(bldinfFilename) << "\"" << endl;
  1441         t << "\t#include \"" << bldinfFilename << "\"" << endl;
  1348         t << "#endif // " << bldinfDefine << endl;
  1442         t << "#endif" << endl;
       
  1443 
       
  1444         if (!condition.isEmpty())
       
  1445             t << "#endif" << endl;
       
  1446 
  1349     }
  1447     }
  1350 
  1448 
  1351     // Add supported project platforms
  1449     // Add supported project platforms
  1352 
  1450 
  1353     t << endl << BLD_INF_TAG_PLATFORMS << endl << endl;
  1451     t << endl << BLD_INF_TAG_PLATFORMS << endl << endl;
  1361     t << endl;
  1459     t << endl;
  1362 
  1460 
  1363     // Add project mmps and old style extension makefiles
  1461     // Add project mmps and old style extension makefiles
  1364 
  1462 
  1365     QString mmpTag;
  1463     QString mmpTag;
  1366     if (project->isActiveConfig("symbian_test"))
  1464     if (project->isActiveConfig(SYMBIAN_TEST_CONFIG))
  1367         mmpTag = QLatin1String(BLD_INF_TAG_TESTMMPFILES);
  1465         mmpTag = QLatin1String(BLD_INF_TAG_TESTMMPFILES);
  1368     else
  1466     else
  1369         mmpTag = QLatin1String(BLD_INF_TAG_MMPFILES);
  1467         mmpTag = QLatin1String(BLD_INF_TAG_MMPFILES);
  1370 
  1468 
  1371     t << endl << mmpTag << endl << endl;
  1469     t << endl << mmpTag << endl << endl;
  1384     userItems = userBldInfRules.value(mmpTag);
  1482     userItems = userBldInfRules.value(mmpTag);
  1385     foreach(QString item, userItems)
  1483     foreach(QString item, userItems)
  1386         t << item << endl;
  1484         t << item << endl;
  1387     userBldInfRules.remove(mmpTag);
  1485     userBldInfRules.remove(mmpTag);
  1388 
  1486 
  1389     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;
  1390 
  1494 
  1391     // Generate extension rules
  1495     // Generate extension rules
  1392 
  1496 
  1393     writeBldInfExtensionRulesPart(t, iconFile);
  1497     writeBldInfExtensionRulesPart(t, iconFile);
  1394 
  1498 
  1395     userItems = userBldInfRules.value(BLD_INF_TAG_EXTENSIONS);
  1499     userItems = userBldInfRules.value(extensionTag);
  1396     foreach(QString item, userItems)
  1500     foreach(QString item, userItems)
  1397         t << item << endl;
  1501         t << item << endl;
  1398     userBldInfRules.remove(BLD_INF_TAG_EXTENSIONS);
  1502     userBldInfRules.remove(extensionTag);
  1399 
  1503 
  1400     // Add rest of the user defined content
  1504     // Add rest of the user defined content
  1401 
  1505 
  1402     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) {
  1403         t << endl << endl << it.key() << endl << endl;
  1507         t << endl << endl << it.key() << endl << endl;
  1404         userItems = it.value();
  1508         userItems = it.value();
  1405         foreach(QString item, userItems)
  1509         foreach(QString item, userItems)
  1406             t << item << endl;
  1510             t << item << endl;
  1407     }
  1511     }
  1408     if (project->values("CONFIG").contains("headerexport", Qt::CaseInsensitive)) {
  1512 }
  1409         writeExportPart(t);
  1513 
  1410     }
  1514 void SymbianMakefileGenerator::writeRegRssFile(QMap<QString, QStringList> &userItems)
  1411 }
       
  1412 
       
  1413 void SymbianMakefileGenerator::writeExportPart(QTextStream &t)
       
  1414 {
       
  1415     QDir currentDir = QDir::current();
       
  1416     t << "prj_exports" << endl;
       
  1417 
       
  1418     foreach(QString install, project->values("INSTALLS")) {
       
  1419         QString installDir = project->first(install + ".path");
       
  1420 
       
  1421         // Export macros are the recommended way, but might not be used
       
  1422         // in all cases (such as Qt headers). We handle it either way,
       
  1423         // macros or not. 
       
  1424         bool useLayerMacro = false;
       
  1425         if (installDir.startsWith("MW_LAYER_") ||
       
  1426             installDir.startsWith("APP_LAYER_") ||
       
  1427             installDir.startsWith("APP_LAYER_")) {
       
  1428             useLayerMacro = true;
       
  1429         } else {
       
  1430 #ifdef Q_OS_WIN
       
  1431             // If we are running on Windows, and the export target starts
       
  1432             // with a drive letter, we need to remove it, the build tools
       
  1433             // cannot handle drives in export paths
       
  1434 
       
  1435             if (installDir.length() > 2 && installDir[1] == ':') {
       
  1436                 installDir.remove(0, 2);
       
  1437             }
       
  1438 #endif
       
  1439             installDir.replace("\\", "/");
       
  1440             if (!installDir.endsWith("/")) {
       
  1441                 installDir.append("/");
       
  1442             }
       
  1443         }
       
  1444 
       
  1445         foreach(QString target, project->values(install + ".files")) {
       
  1446             // Handle glob targets (only in the current directory)
       
  1447             if (target.contains("*") || target.contains("?")) {
       
  1448                 QDir globber = QDir::current();
       
  1449                 globber.setNameFilters(QStringList(target));
       
  1450                 foreach(QString globbedTarget, globber.entryList()) {
       
  1451                     if (useLayerMacro) {
       
  1452                         QFileInfo globbedInfo(globbedTarget);
       
  1453                         t << globbedTarget << " " << installDir <<
       
  1454                             "(" << globbedInfo.fileName() << ")" << endl;
       
  1455                     } else {
       
  1456                         t << globbedTarget << " " << installDir << 
       
  1457                             globbedTarget << endl;
       
  1458                     }
       
  1459                 }
       
  1460             } else {
       
  1461                 target = currentDir.relativeFilePath(target);
       
  1462                 QFileInfo targetInfo(target);
       
  1463 
       
  1464                 // Not possible to export whole directories, extension makefile needed for this
       
  1465                 // Note that this check requires the file to be exported to exist in the qmake phase!
       
  1466                 if (targetInfo.isFile()) {
       
  1467                     if (useLayerMacro) {
       
  1468                         t << target << " " << installDir <<
       
  1469                             "(" << targetInfo.fileName() << ")" << endl;
       
  1470                     } else {
       
  1471                         t << target << " " << installDir <<
       
  1472                             targetInfo.fileName() << endl;
       
  1473                     }
       
  1474                 }
       
  1475             }
       
  1476         }
       
  1477     }
       
  1478     t << endl;
       
  1479 }
       
  1480 
       
  1481 void SymbianMakefileGenerator::writeRegRssFile(QStringList &userItems)
       
  1482 {
  1515 {
  1483     QString filename(fixedTarget);
  1516     QString filename(fixedTarget);
  1484     filename.append("_reg.rss");
  1517     filename.append("_reg.rss");
  1485     QFile ft(filename);
  1518     QFile ft(filename);
  1486     if (ft.open(QIODevice::WriteOnly)) {
  1519     if (ft.open(QIODevice::WriteOnly)) {
  1496         t << "// * user." << endl;
  1529         t << "// * user." << endl;
  1497         t << "// ============================================================================" << endl;
  1530         t << "// ============================================================================" << endl;
  1498         t << endl;
  1531         t << endl;
  1499         t << "#include <" << fixedTarget << ".rsg>" << endl;
  1532         t << "#include <" << fixedTarget << ".rsg>" << endl;
  1500         t << "#include <appinfo.rh>" << endl;
  1533         t << "#include <appinfo.rh>" << endl;
       
  1534         foreach(QString item, userItems[RSS_TAG_HEADER])
       
  1535             t << item << endl;
  1501         t << endl;
  1536         t << endl;
  1502         t << "UID2 KUidAppRegistrationResourceFile" << endl;
  1537         t << "UID2 KUidAppRegistrationResourceFile" << endl;
  1503         t << "UID3 " << uid3 << endl << endl;
  1538         t << "UID3 " << uid3 << endl << endl;
  1504         t << "RESOURCE APP_REGISTRATION_INFO" << endl;
  1539         t << "RESOURCE APP_REGISTRATION_INFO" << endl;
  1505         t << "\t{" << endl;
  1540         t << "\t{" << endl;
  1506         t << "\tapp_file=\"" << fixedTarget << "\";" << endl;
  1541         t << "\tapp_file=\"" << fixedTarget << "\";" << endl;
  1507         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"));
  1508         t << endl;
  1553         t << endl;
  1509 
  1554 
  1510         foreach(QString item, userItems)
  1555         foreach(QString item, userItems[RSS_TAG_DEFAULT])
  1511             t << "\t" << item << endl;
  1556             t << "\t" << item.replace("\n","\n\t") << endl;
  1512         t << "\t}" << endl;
  1557         t << "\t}" << endl;
       
  1558 
       
  1559         foreach(QString item, userItems[RSS_TAG_FOOTER])
       
  1560             t << item << endl;
  1513     } else {
  1561     } else {
  1514         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;
  1515     }
  1585     }
  1516 }
  1586 }
  1517 
  1587 
  1518 void SymbianMakefileGenerator::writeRssFile(QString &numberOfIcons, QString &iconFile)
  1588 void SymbianMakefileGenerator::writeRssFile(QString &numberOfIcons, QString &iconFile)
  1519 {
  1589 {
  1726             PRINT_FILE_CREATE_ERROR(locFilename);	
  1796             PRINT_FILE_CREATE_ERROR(locFilename);	
  1727 	    }
  1797 	    }
  1728     }
  1798     }
  1729 }
  1799 }
  1730 
  1800 
  1731 void SymbianMakefileGenerator::readRssRules(QString &numberOfIcons, QString &iconFile, QStringList &userRssRules)
  1801 void SymbianMakefileGenerator::readRssRules(QString &numberOfIcons,
       
  1802                                             QString &iconFile, QMap<QString,
       
  1803                                             QStringList> &userRssRules)
  1732 {
  1804 {
  1733     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) {
  1734         if (it.key().startsWith(RSS_RULES_BASE)) {
  1806         if (it.key().startsWith(RSS_RULES_BASE)) {
  1735             QString newKey = it.key().mid(sizeof(RSS_RULES_BASE) - 1);
  1807             QString newKey = it.key().mid(sizeof(RSS_RULES_BASE) - 1);
  1736             if (newKey.isEmpty()) {
  1808             if (newKey.isEmpty()) {
  1738                 continue;
  1810                 continue;
  1739             }
  1811             }
  1740             QStringList newValues;
  1812             QStringList newValues;
  1741             QStringList values = it.value();
  1813             QStringList values = it.value();
  1742             foreach(QString item, values) {
  1814             foreach(QString item, values) {
  1743                 // 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
  1744                 // This is convenience for defining single line statements
  1816                 // This is convenience for defining single line statements
  1745                 if (project->values(item).isEmpty()) {
  1817                 if (project->values(item).isEmpty()) {
  1746                     newValues << item;
  1818                     newValues << item;
  1747                 } else {
  1819                 } else {
       
  1820                     QStringList itemList;
  1748                     foreach(QString itemRow, project->values(item)) {
  1821                     foreach(QString itemRow, project->values(item)) {
  1749                         newValues << itemRow;
  1822                         itemList << itemRow;
  1750                     }
  1823                     }
       
  1824                     newValues << itemList.join("\n");
  1751                 }
  1825                 }
  1752             }
  1826             }
  1753             // Verify thet there is exactly one value in RSS_TAG_NBROFICONS
  1827             // Verify thet there is exactly one value in RSS_TAG_NBROFICONS
  1754             if (newKey == RSS_TAG_NBROFICONS) {
  1828             if (newKey == RSS_TAG_NBROFICONS) {
  1755                 if (newValues.count() == 1) {
  1829                 if (newValues.count() == 1) {
  1766                 } else {
  1840                 } else {
  1767                     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",
  1768                             RSS_RULES_BASE, RSS_TAG_ICONFILE);
  1842                             RSS_RULES_BASE, RSS_TAG_ICONFILE);
  1769                     continue;
  1843                     continue;
  1770                 }
  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;
  1771             } else {
  1853             } else {
  1772                 fprintf(stderr, "Warning: Unsupported key:'%s%s'\n",
  1854                 fprintf(stderr, "Warning: Unsupported key:'%s%s'\n",
  1773                         RSS_RULES_BASE, newKey.toLatin1().constData());
  1855                         RSS_RULES_BASE, newKey.toLatin1().constData());
  1774                 continue;
  1856                 continue;
  1775             }
  1857             }
  1776         }
  1858         }
  1777     }
  1859     }
  1778 
  1860 
       
  1861     QStringList newValues;
  1779     foreach(QString item, project->values(RSS_RULES)) {
  1862     foreach(QString item, project->values(RSS_RULES)) {
  1780         // 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
  1781         // This is convenience for defining single line mmp statements
  1864         // This is convenience for defining single line statements
  1782         if (project->values(item).isEmpty()) {
  1865         if (project->values(item).isEmpty()) {
  1783             userRssRules << item;
  1866             newValues << item;
  1784         } else {
  1867         } else {
  1785             userRssRules << project->values(item);
  1868             newValues << project->values(item);
  1786         }
  1869         }
  1787     }
  1870     }
       
  1871     userRssRules[RSS_TAG_DEFAULT] << newValues;
  1788 
  1872 
  1789     // 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
  1790     // or neither of them exist
  1874     // or neither of them exist
  1791     if (!((numberOfIcons.isEmpty() && iconFile.isEmpty()) ||
  1875     if (!((numberOfIcons.isEmpty() && iconFile.isEmpty()) ||
  1792             (!numberOfIcons.isEmpty() && !iconFile.isEmpty()))) {
  1876             (!numberOfIcons.isEmpty() && !iconFile.isEmpty()))) {
  2096 {
  2180 {
  2097     t << "-include " MAKE_CACHE_NAME << endl;
  2181     t << "-include " MAKE_CACHE_NAME << endl;
  2098     t << endl;
  2182     t << endl;
  2099 
  2183 
  2100     t << SIS_TARGET ":" << endl;
  2184     t << SIS_TARGET ":" << endl;
  2101     QString siscommand = QString("\t$(if $(wildcard %1_template.%2),$(if $(wildcard %3)," \
  2185     QString siscommand = QString::fromLatin1("\t$(if $(wildcard %1_template.%2),$(if $(wildcard %3)," \
  2102                                   "$(MAKE) -s -f $(MAKEFILE) %4," \
  2186                                   "$(MAKE) -s -f $(MAKEFILE) %4," \
  2103                                   "$(if $(QT_SIS_TARGET),$(MAKE) -s -f $(MAKEFILE) %4," \
  2187                                   "$(if $(QT_SIS_TARGET),$(MAKE) -s -f $(MAKEFILE) %4," \
  2104                                   "$(MAKE) -s -f $(MAKEFILE) %5))," \
  2188                                   "$(MAKE) -s -f $(MAKEFILE) %5))," \
  2105                                   "$(MAKE) -s -f $(MAKEFILE) %6)")
  2189                                   "$(MAKE) -s -f $(MAKEFILE) %6)")
  2106                           .arg(fixedTarget)
  2190                           .arg(fixedTarget)
  2112     t << siscommand << endl;
  2196     t << siscommand << endl;
  2113     t << endl;
  2197     t << endl;
  2114 
  2198 
  2115     t << OK_SIS_TARGET ":" << endl;
  2199     t << OK_SIS_TARGET ":" << endl;
  2116 
  2200 
  2117     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) " \
  2118                                  "$(QT_SIS_CERTIFICATE) $(QT_SIS_KEY) $(QT_SIS_PASSPHRASE)")
  2202                                  "$(QT_SIS_CERTIFICATE) $(QT_SIS_KEY) $(QT_SIS_PASSPHRASE)")
  2119                           .arg(fixedTarget)
  2203                           .arg(fixedTarget)
  2120                           .arg("pkg");
  2204                           .arg("pkg");
  2121     t << pkgcommand << endl;
  2205     t << pkgcommand << endl;
  2122     t << endl;
  2206     t << endl;
  2123 
  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 
  2124     t << FAIL_SIS_NOPKG_TARGET ":" << endl;
  2258     t << FAIL_SIS_NOPKG_TARGET ":" << endl;
  2125     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;
  2126     t << endl;
  2260     t << endl;
  2127 
  2261 
  2128     t << FAIL_SIS_NOCACHE_TARGET ":" << endl;
  2262     t << FAIL_SIS_NOCACHE_TARGET ":" << endl;
  2129     t << "\t$(error Project has to be built or QT_SIS_TARGET environment variable has to be set 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;
  2130     t << endl;
  2264     t << endl;
  2192         if (platforms.contains("winscw")) {
  2326         if (platforms.contains("winscw")) {
  2193             t << "run:" << endl;
  2327             t << "run:" << endl;
  2194             t << "\t-call " << epocRoot() << "epoc32/release/winscw/udeb/" << fixedTarget << ".exe " << "$(QT_RUN_OPTIONS)" << endl;
  2328             t << "\t-call " << epocRoot() << "epoc32/release/winscw/udeb/" << fixedTarget << ".exe " << "$(QT_RUN_OPTIONS)" << endl;
  2195         }
  2329         }
  2196         t << "runonphone: sis" << endl;
  2330         t << "runonphone: sis" << endl;
  2197         t << "\trunonphone $(QT_RUN_ON_PHONE_OPTIONS) --sis " << fixedTarget << "_$(QT_SIS_TARGET).sis " << fixedTarget << ".exe " << "$(QT_RUN_OPTIONS)" << endl;
  2331         t << "\trunonphone $(QT_RUN_ON_PHONE_OPTIONS) --sis " << fixedTarget << ".sis " << fixedTarget << ".exe " << "$(QT_RUN_OPTIONS)" << endl;
  2198         t << endl;
  2332         t << endl;
  2199     }
  2333     }
  2200 }
  2334 }