Ignore:
Timestamp:
May 5, 2011, 5:36:53 AM (14 years ago)
Author:
Dmitry A. Kuminov
Message:

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/qmake/generators/symbian/symmake.cpp

    r769 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
     
    5151
    5252// Included from tools/shared
    53 #include <symbian/epocroot.h>
     53#include <symbian/epocroot_p.h>
    5454
    5555#define RESOURCE_DIRECTORY_MMP "/resource/apps"
    56 #define RESOURCE_DIRECTORY_RESOURCE "\\\\resource\\\\apps\\\\"
    5756#define REGISTRATION_RESOURCE_DIRECTORY_HW "/private/10003a3f/import/apps"
    5857#define PLUGIN_COMMON_DEF_FILE_FOR_MMP "./plugin_common.def"
    59 #define PLUGIN_COMMON_DEF_FILE_ACTUAL "plugin_commonU.def"
     58#define BLD_INF_FILENAME_LEN (sizeof(BLD_INF_FILENAME) - 1)
    6059
    6160#define BLD_INF_RULES_BASE "BLD_INF_RULES."
     
    6564#define BLD_INF_TAG_EXTENSIONS "prj_extensions"
    6665#define BLD_INF_TAG_TESTEXTENSIONS "prj_testextensions"
    67 
    68 #define RSS_RULES "RSS_RULES"
    69 #define RSS_RULES_BASE "RSS_RULES."
    70 #define RSS_TAG_NBROFICONS "number_of_icons"
    71 #define RSS_TAG_ICONFILE "icon_file"
    72 #define RSS_TAG_HEADER "header"
    73 #define RSS_TAG_SERVICE_LIST "service_list"
    74 #define RSS_TAG_FILE_OWNERSHIP_LIST "file_ownership_list"
    75 #define RSS_TAG_DATATYPE_LIST "datatype_list"
    76 #define RSS_TAG_FOOTER "footer"
    77 #define RSS_TAG_DEFAULT "default_rules" // Same as just giving rules without tag
    7866
    7967#define MMP_TARGET "TARGET"
     
    9684#define VAR_LFLAGS "QMAKE_LFLAGS"
    9785
    98 #define SIS_TARGET "sis"
    99 #define INSTALLER_SIS_TARGET "installer_sis"
    100 #define ROM_STUB_SIS_TARGET "stub_sis"
    101 #define OK_SIS_TARGET "ok_sis"
    102 #define OK_INSTALLER_SIS_TARGET "ok_installer_sis"
    103 #define OK_ROM_STUB_SIS_TARGET "ok_stub_sis"
    104 #define FAIL_SIS_NOPKG_TARGET "fail_sis_nopkg"
    105 #define FAIL_SIS_NOCACHE_TARGET "fail_sis_nocache"
    106 
    107 #define PRINT_FILE_CREATE_ERROR(filename) fprintf(stderr, "Error: Could not create '%s'\n", qPrintable(filename));
    108 
    109 #define MANUFACTURER_NOTE_FILE "manufacturer_note.txt"
    110 #define DEFAULT_MANUFACTURER_NOTE \
    111     "The package is not supported for devices from this manufacturer. Please try the selfsigned " \
    112     "version of the package instead."
     86#define DEFINE_REPLACE_REGEXP "[^A-Z0-9_]"
    11387
    11488QString SymbianMakefileGenerator::fixPathForMmp(const QString& origPath, const QDir& parentDir)
     
    11690    static QString epocRootStr;
    11791    if (epocRootStr.isEmpty()) {
    118         epocRootStr = epocRoot();
     92        epocRootStr = qt_epocRoot();
    11993        QFileInfo efi(epocRootStr);
    12094        if (!efi.exists() || epocRootStr.isEmpty()) {
    121             fprintf(stderr, "Unable to resolve epocRoot '%s' to real dir on current drive, defaulting to '/' for mmp paths\n", qPrintable(epocRoot()));
     95            fprintf(stderr, "Unable to resolve epocRoot '%s' to real dir on current drive, defaulting to '/' for mmp paths\n", qPrintable(qt_epocRoot()));
    12296            epocRootStr = "/";
    12397        } else {
     
    151125    QString resultPath = QDir::fromNativeSeparators(origPath);
    152126    if (resultPath.startsWith("/epoc32/", Qt::CaseInsensitive))
    153         resultPath = QDir::fromNativeSeparators(epocRoot()) + resultPath.mid(1);
     127        resultPath = QDir::fromNativeSeparators(qt_epocRoot()) + resultPath.mid(1);
    154128
    155129    QFileInfo fi(fileInfo(resultPath));
     
    169143}
    170144
    171 SymbianMakefileGenerator::SymbianMakefileGenerator() : MakefileGenerator() { }
     145SymbianMakefileGenerator::SymbianMakefileGenerator() : MakefileGenerator(), SymbianCommonGenerator(this) { }
    172146SymbianMakefileGenerator::~SymbianMakefileGenerator() { }
    173147
     
    194168    bldinfDefine.append("_");
    195169    bldinfDefine.append(generate_uid(project->projectFile()));
     170    bldinfDefine = bldinfDefine.toUpper();
     171
     172    // replace anything not alphanumeric with underscore
     173    QRegExp replacementMask(DEFINE_REPLACE_REGEXP);
     174    bldinfDefine.replace(replacementMask, QLatin1String("_"));
    196175
    197176    bldinfDefine.prepend("BLD_INF_");
    198     removeSpecialCharacters(bldinfDefine);
    199 
    200     t << "#define " << bldinfDefine.toUpper() << endl << endl;
     177
     178    t << "#define " << bldinfDefine << endl << endl;
    201179}
    202180
    203181bool SymbianMakefileGenerator::writeMakefile(QTextStream &t)
    204182{
     183    if(!project->values("QMAKE_FAILED_REQUIREMENTS").isEmpty()) {
     184        fprintf(stderr, "Project files not generated because all requirements are not met:\n\t%s\n",
     185                qPrintable(var("QMAKE_FAILED_REQUIREMENTS")));
     186        return false;
     187    }
     188
    205189    writeHeader(t);
    206190
     
    210194    readRssRules(numberOfIcons, iconFile, userRssRules);
    211195
    212     // Get the application translations and convert to symbian OS lang code, i.e. decical number
    213     QStringList symbianLangCodes = symbianLangCodesFromTsFiles();
     196    SymbianLocalizationList symbianLocalizationList;
     197    parseTsFiles(&symbianLocalizationList);
    214198
    215199    // Generate pkg files if there are any actual files to deploy
    216200    bool generatePkg = false;
    217     DeploymentList depList;
    218201
    219202    if (targetType == TypeExe) {
     
    229212
    230213    if (generatePkg) {
    231         generatePkgFile(iconFile, depList);
    232     }
    233 
    234     writeBldInfContent(t, generatePkg, iconFile, depList);
     214        generatePkgFile(iconFile, true, symbianLocalizationList);
     215    }
     216
     217    writeBldInfContent(t, generatePkg, iconFile);
    235218
    236219    // Generate empty wrapper makefile here, because wrapper makefile must exist before writeMkFile,
    237220    // but all required data is not yet available.
    238221    bool isPrimaryMakefile = true;
    239     QString wrapperFileName("Makefile");
     222    QString wrapperFileName = Option::output_dir + QLatin1Char('/') + QLatin1String("Makefile");
    240223    QString outputFileName = fileInfo(Option::output.fileName()).fileName();
    241224    if (outputFileName != BLD_INF_FILENAME) {
     
    265248    writeMkFile(wrapperFileName, false);
    266249
    267     QString shortProFilename = project->projectFile();
    268     shortProFilename.replace(0, shortProFilename.lastIndexOf("/") + 1, QString(""));
    269     shortProFilename.replace(Option::pro_ext, QString(""));
    270 
    271     QString mmpFilename = shortProFilename;
    272     mmpFilename.append("_");
    273     mmpFilename.append(uid3);
    274     mmpFilename.append(Option::mmp_ext);
    275     writeMmpFile(mmpFilename, symbianLangCodes);
     250    QString absoluteMmpFileName = Option::output_dir + QLatin1Char('/') + mmpFileName;
     251    writeMmpFile(absoluteMmpFileName, symbianLocalizationList);
    276252
    277253    if (targetType == TypeExe) {
     
    279255            writeRegRssFile(userRssRules);
    280256            writeRssFile(numberOfIcons, iconFile);
    281             writeLocFile(symbianLangCodes);
     257            writeLocFile(symbianLocalizationList);
    282258        }
    283259    }
     
    289265}
    290266
    291 void SymbianMakefileGenerator::generatePkgFile(const QString &iconFile, DeploymentList &depList)
    292 {
    293     QString pkgFilename = QString("%1_template.%2")
    294                           .arg(fixedTarget)
    295                           .arg("pkg");
    296     QFile pkgFile(pkgFilename);
    297     if (!pkgFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
    298         PRINT_FILE_CREATE_ERROR(pkgFilename);
    299         return;
    300     }
    301 
    302     generatedFiles << pkgFile.fileName();
    303     QTextStream t(&pkgFile);
    304 
    305     QString installerSisHeader = project->values("DEPLOYMENT.installer_header").join("\n");
    306     if (installerSisHeader.isEmpty())
    307         installerSisHeader = "0xA000D7CE"; // Use default self-signable UID if not defined
    308 
    309     QString wrapperStreamBuffer;
    310     QTextStream tw(&wrapperStreamBuffer);
    311 
    312     QString dateStr = QDateTime::currentDateTime().toString(Qt::ISODate);
    313 
    314     // Header info
    315     QString wrapperPkgFilename = QString("%1_installer.%2")
    316                                 .arg(fixedTarget)
    317                                 .arg("pkg");
    318     QString headerComment = "; %1 generated by qmake at %2\n"
    319         "; This file is generated by qmake and should not be modified by the user\n"
    320         ";\n\n";
    321     t << headerComment.arg(pkgFilename).arg(dateStr);
    322     tw << headerComment.arg(wrapperPkgFilename).arg(dateStr);
    323 
    324     // Construct QStringList from pkg_prerules since we need search it before printed to file
    325     // Note: Though there can't be more than one language or header line, use stringlists
    326     // in case user wants comments to go with the rules.
    327     QStringList rawPkgPreRules;
    328     QStringList languageRules;
    329     QStringList headerRules;
    330     foreach(QString deploymentItem, project->values("DEPLOYMENT")) {
    331         foreach(QString pkgrulesItem, project->values(deploymentItem + ".pkg_prerules")) {
    332             QStringList pkgrulesValue = project->values(pkgrulesItem);
    333             // If there is no stringlist defined for a rule, use rule name directly
    334             // This is convenience for defining single line mmp statements
    335             if (pkgrulesValue.isEmpty()) {
    336                 if (pkgrulesItem.startsWith("&"))
    337                     languageRules << pkgrulesItem;
    338                 else if (pkgrulesItem.startsWith("#"))
    339                     headerRules << pkgrulesItem;
    340                 else
    341                     rawPkgPreRules << pkgrulesItem;
    342             } else {
    343                 if (containsStartWithItem('&', pkgrulesValue)) {
    344                     foreach(QString pkgrule, pkgrulesValue) {
    345                         languageRules << pkgrule;
    346                     }
    347                 } else if (containsStartWithItem('#', pkgrulesValue)) {
    348                     foreach(QString pkgrule, pkgrulesValue) {
    349                         headerRules << pkgrule;
    350                     }
    351                 } else {
    352                     foreach(QString pkgrule, pkgrulesValue) {
    353                         rawPkgPreRules << pkgrule;
    354                     }
    355                 }
    356             }
    357         }
    358     }
    359 
    360     // Apply some defaults if specific data does not exist in PKG pre-rules
    361 
    362     if (languageRules.isEmpty()) {
    363         // language, (*** hardcoded to english atm, should be parsed from TRANSLATIONS)
    364         languageRules << "; Language\n&EN\n\n";
    365     } else if (headerRules.isEmpty()) {
    366         // In case user defines langs, he must take care also about SIS header
    367         fprintf(stderr, "Warning: If language is defined with DEPLOYMENT pkg_prerules, also the SIS header must be defined\n");
    368     }
    369 
    370     t << languageRules.join("\n") << endl;
    371     tw << languageRules.join("\n") << endl;
    372 
    373     // name of application, UID and version
    374     QString applicationVersion = project->first("VERSION").isEmpty() ? "1,0,0" : project->first("VERSION").replace('.', ',');
    375     QString sisHeader = "; SIS header: name, uid, version\n#{\"%1\"},(%2),%3\n\n";
    376     QString visualTarget = escapeFilePath(fileFixify(project->first("TARGET")));
    377     visualTarget = removePathSeparators(visualTarget);
    378     QString wrapperTarget = visualTarget + " installer";
    379 
    380     if (installerSisHeader.startsWith("0x", Qt::CaseInsensitive)) {
    381         tw << sisHeader.arg(wrapperTarget).arg(installerSisHeader).arg(applicationVersion);
    382     } else {
    383         tw << installerSisHeader << endl;
    384     }
    385 
    386     if (headerRules.isEmpty())
    387         t << sisHeader.arg(visualTarget).arg(uid3).arg(applicationVersion);
    388     else
    389         t << headerRules.join("\n") << endl;
    390 
    391     // Localized vendor name
    392     QString vendorName;
    393     if (!containsStartWithItem('%', rawPkgPreRules)) {
    394         vendorName += "; Localised Vendor name\n%{\"Vendor\"}\n\n";
    395     }
    396 
    397     // Unique vendor name
    398     if (!containsStartWithItem(':', rawPkgPreRules)) {
    399         vendorName += "; Unique Vendor name\n:\"Vendor\"\n\n";
    400     }
    401 
    402     t << vendorName;
    403     tw << vendorName;
    404 
    405     // PKG pre-rules - these are added before actual file installations i.e. SIS package body
    406     if (rawPkgPreRules.size()) {
    407         QString comment = "\n; Manual PKG pre-rules from PRO files\n";
    408         t << comment;
    409         tw << comment;
    410 
    411         foreach(QString item, rawPkgPreRules) {
    412             // Only regular pkg file should have package dependencies or pkg header if that is
    413             // defined using prerules.
    414             if (!item.startsWith("(") && !item.startsWith("#")) {
    415                 tw << item << endl;
    416             }
    417             t << item << endl;
    418         }
    419         t << endl;
    420         tw << endl;
    421     }
    422 
    423     // Begin Manufacturer block
    424     if (!project->values("DEPLOYMENT.manufacturers").isEmpty()) {
    425         QString manufacturerStr("IF ");
    426         foreach(QString manufacturer, project->values("DEPLOYMENT.manufacturers")) {
    427             manufacturerStr.append(QString("(MANUFACTURER)=(%1) OR \n   ").arg(manufacturer));
    428         }
    429         // Remove the final OR
    430         manufacturerStr.chop(8);
    431         t << manufacturerStr << endl;
    432     }
    433 
    434     // Install paths on the phone *** should be dynamic at some point
    435     QString installPathBin = "!:\\sys\\bin";
    436     QString installPathResource = "!:\\resource\\apps";
    437     QString installPathRegResource = "!:\\private\\10003a3f\\import\\apps";
    438 
    439     // Find location of builds
    440     QString epocReleasePath = QString("%1epoc32/release/$(PLATFORM)/$(TARGET)")
    441                               .arg(epocRoot());
    442 
    443     if (targetType == TypeExe) {
    444         // deploy .exe file
    445         t << "; Executable and default resource files" << endl;
    446         QString exeFile = fixedTarget + ".exe";
    447         t << QString("\"%1/%2\"    - \"%3\\%4\"")
    448              .arg(epocReleasePath)
    449              .arg(exeFile)
    450              .arg(installPathBin)
    451              .arg(exeFile) << endl;
    452 
    453         // deploy rsc & reg_rsc file
    454         if (!project->isActiveConfig("no_icon")) {
    455             t << QString("\"%1epoc32/data/z/resource/apps/%2\"    - \"%3\\%4\"")
    456                  .arg(epocRoot())
    457                  .arg(fixedTarget + ".rsc")
    458                  .arg(installPathResource)
    459                  .arg(fixedTarget + ".rsc") << endl;
    460 
    461             t << QString("\"%1epoc32/data/z/private/10003a3f/import/apps/%2\"    - \"%3\\%4\"")
    462                  .arg(epocRoot())
    463                  .arg(fixedTarget + "_reg.rsc")
    464                  .arg(installPathRegResource)
    465                  .arg(fixedTarget + "_reg.rsc") << endl;
    466 
    467             if (!iconFile.isEmpty())  {
    468                 t << QString("\"%1epoc32/data/z%2\"    - \"!:%3\"")
    469                      .arg(epocRoot())
    470                      .arg(iconFile)
    471                      .arg(QDir::toNativeSeparators(iconFile)) << endl << endl;
    472             }
    473         }
    474     }
    475 
    476     // deploy any additional DEPLOYMENT  files
    477     QString remoteTestPath;
    478     remoteTestPath = QString("!:\\private\\%1").arg(privateDirUid);
    479     QString zDir = epocRoot() + QLatin1String("epoc32/data/z");
    480 
    481     initProjectDeploySymbian(project, depList, remoteTestPath, true, "$(PLATFORM)", "$(TARGET)", generatedDirs, generatedFiles);
    482     if (depList.size())
    483         t << "; DEPLOYMENT" << endl;
    484     for (int i = 0; i < depList.size(); ++i)  {
    485         QString from = depList.at(i).from;
    486         QString to = depList.at(i).to;
    487 
    488         // Deploy anything not already deployed from under epoc32 instead from under
    489         // \epoc32\data\z\ to enable using pkg file without rebuilding
    490         // the project, which can be useful for some binary only distributions.
    491         if (!from.contains(QLatin1String("epoc32"), Qt::CaseInsensitive)) {
    492             from = to;
    493             if (from.size() > 1 && from.at(1) == QLatin1Char(':'))
    494                 from = from.mid(2);
    495             from.prepend(zDir);
    496         } else {
    497             if (from.size() > 1 && from.at(1) == QLatin1Char(':'))
    498                 from = from.mid(2);
    499         }
    500 
    501         t << QString("\"%1\"    - \"%2\"").arg(from.replace('\\','/')).arg(to) << endl;
    502     }
    503     t << endl;
    504 
    505     // PKG post-rules - these are added after actual file installations i.e. SIS package body
    506     t << "; Manual PKG post-rules from PRO files" << endl;
    507     foreach(QString deploymentItem, project->values("DEPLOYMENT")) {
    508         foreach(QString pkgrulesItem, project->values(deploymentItem + ".pkg_postrules")) {
    509             QStringList pkgrulesValue = project->values(pkgrulesItem);
    510             // If there is no stringlist defined for a rule, use rule name directly
    511             // This is convenience for defining single line statements
    512             if (pkgrulesValue.isEmpty()) {
    513                 t << pkgrulesItem << endl;
    514             } else {
    515                 foreach(QString pkgrule, pkgrulesValue) {
    516                     t << pkgrule << endl;
    517                 }
    518             }
    519             t << endl;
    520         }
    521     }
    522 
    523     // Close Manufacturer block
    524     if (!project->values("DEPLOYMENT.manufacturers").isEmpty()) {
    525         QString manufacturerFailNoteFile;
    526         if (project->values("DEPLOYMENT.manufacturers.fail_note").isEmpty()) {
    527             manufacturerFailNoteFile = QString("%1_" MANUFACTURER_NOTE_FILE).arg(uid3);
    528             QFile ft(manufacturerFailNoteFile);
    529             if (ft.open(QIODevice::WriteOnly)) {
    530                 generatedFiles << ft.fileName();
    531                 QTextStream t2(&ft);
    532 
    533                 t2 << QString(DEFAULT_MANUFACTURER_NOTE) << endl;
    534             } else {
    535                 PRINT_FILE_CREATE_ERROR(manufacturerFailNoteFile)
    536             }
    537         } else {
    538             manufacturerFailNoteFile = project->values("DEPLOYMENT.manufacturers.fail_note").join("");
    539         }
    540 
    541         t << "ELSEIF NOT(0) ; MANUFACTURER" << endl
    542           << "\"" << fileInfo(manufacturerFailNoteFile).absoluteFilePath() << "\""
    543           << " - \"\", FILETEXT, TEXTEXIT" << endl
    544           << "ENDIF ; MANUFACTURER" << endl;
    545     }
    546 
    547     // Write wrapper pkg
    548     if (!installerSisHeader.isEmpty()) {
    549         QFile wrapperPkgFile(wrapperPkgFilename);
    550         if (!wrapperPkgFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
    551             PRINT_FILE_CREATE_ERROR(wrapperPkgFilename);
    552             return;
    553         }
    554 
    555         generatedFiles << wrapperPkgFile.fileName();
    556         QTextStream twf(&wrapperPkgFile);
    557 
    558         twf << wrapperStreamBuffer << endl;
    559 
    560         // Wrapped files deployment
    561         QString currentPath = qmake_getpwd();
    562         QString sisName = QString("%1.sis").arg(fixedTarget);
    563         twf << "\"" << currentPath << "/" << sisName << "\" - \"c:\\adm\\" << sisName << "\"" << endl;
    564 
    565         QString bootStrapPath = QLibraryInfo::location(QLibraryInfo::PrefixPath);
    566         bootStrapPath.append("/smartinstaller.sis");
    567         QFileInfo fi(fileInfo(bootStrapPath));
    568         twf << "@\"" << fi.absoluteFilePath() << "\",(0x2002CCCD)" << endl;
    569     }
    570 }
    571 
    572 bool SymbianMakefileGenerator::containsStartWithItem(const QChar &c, const QStringList& src)
    573 {
    574     bool result = false;
    575     foreach(QString str, src) {
    576         if (str.startsWith(c)) {
    577             result =  true;
    578             break;
    579         }
    580     }
    581     return result;
    582 }
    583 
    584 void SymbianMakefileGenerator::writeCustomDefFile()
    585 {
    586     if (targetType == TypePlugin && !project->isActiveConfig("stdbinary")) {
    587         // Create custom def file for plugin
    588         QFile ft(QLatin1String(PLUGIN_COMMON_DEF_FILE_ACTUAL));
    589 
    590         if (ft.open(QIODevice::WriteOnly)) {
    591             generatedFiles << ft.fileName();
    592             QTextStream t(&ft);
    593 
    594             t << "; ==============================================================================" << endl;
    595             t << "; Generated by qmake (" << qmake_version() << ") (Qt " QT_VERSION_STR ") on: ";
    596             t << QDateTime::currentDateTime().toString(Qt::ISODate) << endl;
    597             t << "; This file is generated by qmake and should not be modified by the" << endl;
    598             t << "; user." << endl;
    599             t << ";  Name        : " PLUGIN_COMMON_DEF_FILE_ACTUAL << endl;
    600             t << ";  Part of     : " << project->values("TARGET").join(" ") << endl;
    601             t << ";  Description : Fixes common plugin symbols to known ordinals" << endl;
    602             t << ";  Version     : " << endl;
    603             t << ";" << endl;
    604             t << "; ==============================================================================" << "\n" << endl;
    605 
    606             t << endl;
    607 
    608             t << "EXPORTS" << endl;
    609             t << "\tqt_plugin_query_verification_data @ 1 NONAME" << endl;
    610             t << "\tqt_plugin_instance @ 2 NONAME" << endl;
    611             t << endl;
    612         } else {
    613             PRINT_FILE_CREATE_ERROR(QString(PLUGIN_COMMON_DEF_FILE_ACTUAL))
    614         }
    615     }
    616 }
    617 
    618267void SymbianMakefileGenerator::init()
    619268{
    620269    MakefileGenerator::init();
    621     fixedTarget = escapeFilePath(fileFixify(project->first("TARGET")));
    622     fixedTarget = removePathSeparators(fixedTarget);
    623     removeSpecialCharacters(fixedTarget);
     270    SymbianCommonGenerator::init();
    624271
    625272    if (0 != project->values("QMAKE_PLATFORM").size())
     
    632279    project->values("QMAKE_LIBS_PRIVATE") += escapeFilePaths(project->values("LIBS_PRIVATE"));
    633280
    634     // bld.inf
     281    // Disallow renaming of bld.inf.
     282    project->values("MAKEFILE").clear();
    635283    project->values("MAKEFILE") += BLD_INF_FILENAME;
    636284
    637285    // .mmp
     286    mmpFileName = fixedTarget;
     287    if (targetType == TypeExe)
     288        mmpFileName.append("_exe");
     289    else if (targetType == TypeDll || targetType == TypePlugin)
     290        mmpFileName.append("_dll");
     291    else if (targetType == TypeLib)
     292        mmpFileName.append("_lib");
     293    mmpFileName.append(Option::mmp_ext);
     294
    638295    initMmpVariables();
    639296
    640     // Check TARGET.UID3 presence
    641     if (0 != project->values("TARGET.UID3").size()) {
    642         uid3 = project->first("TARGET.UID3");
    643     } else {
    644         uid3 = generateUID3();
    645     }
    646 
    647     if ((project->values("TEMPLATE")).contains("app"))
    648         targetType = TypeExe;
    649     else if ((project->values("TEMPLATE")).contains("lib")) {
    650         // Check CONFIG to see if we are to build staticlib or dll
    651         if (project->isActiveConfig("staticlib") || project->isActiveConfig("static"))
    652             targetType = TypeLib;
    653         else if (project->isActiveConfig("plugin"))
    654             targetType = TypePlugin;
    655         else
    656             targetType = TypeDll;
    657     } else {
    658         targetType = TypeSubdirs;
    659     }
    660 
    661     if (0 != project->values("TARGET.UID2").size()) {
    662         uid2 = project->first("TARGET.UID2");
    663     } else if (project->isActiveConfig("stdbinary")) {
    664         uid2 = "0x20004C45";
    665     } else {
    666         if (targetType == TypeExe) {
    667             if (project->values("QT").contains("gui", Qt::CaseInsensitive)) {
    668                 // exe and gui -> uid2 needed
    669                 uid2 = "0x100039CE";
    670             } else {
    671                 // exe but not gui: uid2 is ignored anyway -> set it to 0
    672                 uid2 = "0";
    673             }
    674         } else if (targetType == TypeDll || targetType == TypeLib || targetType == TypePlugin) {
    675             uid2 = "0x1000008d";
    676         }
    677     }
     297    uid2 = project->first("TARGET.UID2");
    678298
    679299    uid2 = uid2.trimmed();
    680     uid3 = uid3.trimmed();
    681 
    682     // UID is valid as either hex or decimal, so just convert it to number and back to hex
    683     // to get proper string for private dir
    684     bool conversionOk = false;
    685     uint uidNum = uid3.toUInt(&conversionOk, 0);
    686 
    687     if (!conversionOk) {
    688         fprintf(stderr, "Error: Invalid UID \"%s\".\n", uid3.toUtf8().constData());
    689     } else {
    690         privateDirUid.setNum(uidNum, 16);
    691         while (privateDirUid.length() < 8)
    692             privateDirUid.insert(0, QLatin1Char('0'));
    693     }
    694300}
    695301
     
    886492    t << "// This file is generated by qmake and should not be modified by the" << endl;
    887493    t << "// user." << endl;
    888     t << "//  Name        : " << escapeFilePath(fileFixify(project->projectFile().remove(project->projectFile().length() - 4, 4))) << Option::mmp_ext << endl;
     494    t << "//  Name        : " << mmpFileName << endl;
    889495    t << "// ==============================================================================" << endl << endl;
    890496}
    891497
    892 void SymbianMakefileGenerator::writeMmpFile(QString &filename, QStringList &symbianLangCodes)
     498void SymbianMakefileGenerator::writeMmpFile(QString &filename, const SymbianLocalizationList &symbianLocalizationList)
    893499{
    894500    QFile ft(filename);
     
    902508        writeMmpFileTargetPart(t);
    903509
    904         writeMmpFileResourcePart(t, symbianLangCodes);
     510        writeMmpFileResourcePart(t, symbianLocalizationList);
    905511
    906512        writeMmpFileMacrosPart(t);
     
    1044650    \private\10003a3f\import\apps directory.
    1045651*/
    1046 void SymbianMakefileGenerator::writeMmpFileResourcePart(QTextStream& t, QStringList &symbianLangCodes)
     652void SymbianMakefileGenerator::writeMmpFileResourcePart(QTextStream& t, const SymbianLocalizationList &symbianLocalizationList)
    1047653{
    1048654    if ((targetType == TypeExe) &&
     
    1054660        t << "SOURCEPATH\t\t\t. " << endl;
    1055661        t << "LANG SC ";    // no endl
    1056         foreach(QString lang, symbianLangCodes) {
    1057             t << lang << " "; // no endl
     662        SymbianLocalizationListIterator iter(symbianLocalizationList);
     663        while (iter.hasNext()) {
     664            const SymbianLocalization &loc = iter.next();
     665            t << loc.symbianLanguageCode << " "; // no endl
    1058666        }
    1059667        t << endl;
     
    1118726                // ARMV5 build directory for library type. We default to shared
    1119727                // library, since that is more common.
    1120                 QString udebStaticLibLocation(epocRoot());
     728                QString udebStaticLibLocation(qt_epocRoot());
    1121729                QString urelStaticLibLocation(udebStaticLibLocation);
    1122730                udebStaticLibLocation += QString("epoc32/release/armv5/udeb/%1.lib").arg(lib);
     
    1265873}
    1266874
    1267 void SymbianMakefileGenerator::writeBldInfContent(QTextStream &t, bool addDeploymentExtension, const QString &iconFile, DeploymentList &depList)
     875void SymbianMakefileGenerator::writeBldInfContent(QTextStream &t, bool addDeploymentExtension, const QString &iconFile)
    1268876{
    1269877    // Read user defined bld inf rules
     
    1296904    // Add includes of subdirs bld.inf files
    1297905
    1298     QString mmpfilename = escapeFilePath(fileFixify(project->projectFile()));
    1299     mmpfilename = mmpfilename.replace(mmpfilename.lastIndexOf("."), 4, Option::mmp_ext);
    1300906    QString currentPath = qmake_getpwd();
    1301907    QDir directory(currentPath);
     
    1303909    const QStringList &subdirs = project->values("SUBDIRS");
    1304910    foreach(QString item, subdirs) {
     911        bool fromFile = false;
    1305912        QString fixedItem;
    1306913        if (!project->isEmpty(item + ".file")) {
    1307914            fixedItem = project->first(item + ".file");
     915            fromFile = true;
    1308916        } else if (!project->isEmpty(item + ".subdir")) {
    1309917            fixedItem = project->first(item + ".subdir");
     918            fromFile = false;
    1310919        } else {
    1311920            fixedItem = item;
     921            fromFile = item.endsWith(Option::pro_ext);
    1312922        }
    1313923
     
    1318928        QFileInfo subdir(fileInfo(fixedItem));
    1319929        QString relativePath = directory.relativeFilePath(fixedItem);
    1320         QString subdirFileName = subdir.completeBaseName();
    1321         QString fullProName = subdir.absoluteFilePath();;
     930        QString fullProName = subdir.absoluteFilePath();
    1322931        QString bldinfFilename;
     932        QString subdirFileName;
     933
     934        if (fromFile) {
     935            subdirFileName = subdir.completeBaseName();
     936        } else {
     937            subdirFileName = subdir.fileName();
     938        }
    1323939
    1324940        if (subdir.isDir()) {
     
    1342958        QString bldinfDefine = QString("BLD_INF_") + subdirFileName + QString("_") + uid;
    1343959        bldinfDefine = bldinfDefine.toUpper();
    1344         removeSpecialCharacters(bldinfDefine);
     960
     961        // replace anything not alphanumeric with underscore
     962        QRegExp replacementMask(DEFINE_REPLACE_REGEXP);
     963        bldinfDefine.replace(replacementMask, QLatin1String("_"));
    1345964
    1346965        if (!condition.isEmpty())
     
    1379998
    1380999    writeBldInfMkFilePart(t, addDeploymentExtension);
    1381     if (targetType != TypeSubdirs) {
    1382         QString shortProFilename = project->projectFile();
    1383         shortProFilename.replace(0, shortProFilename.lastIndexOf("/") + 1, QString(""));
    1384         shortProFilename.replace(Option::pro_ext, QString(""));
    1385 
    1386         QString mmpFilename = shortProFilename + QString("_") + uid3 + Option::mmp_ext;
    1387 
    1388         t << mmpFilename << endl;
    1389     }
     1000    if (targetType != TypeSubdirs)
     1001        t << mmpFileName << endl;
    13901002
    13911003    userItems = userBldInfRules.value(mmpTag);
     
    14211033}
    14221034
    1423 void SymbianMakefileGenerator::writeRegRssFile(QMap<QString, QStringList> &userItems)
    1424 {
    1425     QString filename(fixedTarget);
    1426     filename.append("_reg.rss");
    1427     QFile ft(filename);
    1428     if (ft.open(QIODevice::WriteOnly)) {
    1429         generatedFiles << ft.fileName();
    1430         QTextStream t(&ft);
    1431         t << "// ============================================================================" << endl;
    1432         t << "// * Generated by qmake (" << qmake_version() << ") (Qt " QT_VERSION_STR ") on: ";
    1433         t << QDateTime::currentDateTime().toString(Qt::ISODate) << endl;
    1434         t << "// * This file is generated by qmake and should not be modified by the" << endl;
    1435         t << "// * user." << endl;
    1436         t << "// ============================================================================" << endl;
    1437         t << endl;
    1438         t << "#include <" << fixedTarget << ".rsg>" << endl;
    1439         t << "#include <appinfo.rh>" << endl;
    1440         foreach(QString item, userItems[RSS_TAG_HEADER])
    1441             t << item << endl;
    1442         t << endl;
    1443         t << "UID2 KUidAppRegistrationResourceFile" << endl;
    1444         t << "UID3 " << uid3 << endl << endl;
    1445         t << "RESOURCE APP_REGISTRATION_INFO" << endl;
    1446         t << "\t{" << endl;
    1447         t << "\tapp_file=\"" << fixedTarget << "\";" << endl;
    1448         t << "\tlocalisable_resource_file=\"" RESOURCE_DIRECTORY_RESOURCE << fixedTarget << "\";" << endl;
    1449 
    1450         writeRegRssList(t, userItems[RSS_TAG_SERVICE_LIST],
    1451                         QLatin1String(RSS_TAG_SERVICE_LIST),
    1452                         QLatin1String("SERVICE_INFO"));
    1453         writeRegRssList(t, userItems[RSS_TAG_FILE_OWNERSHIP_LIST],
    1454                         QLatin1String(RSS_TAG_FILE_OWNERSHIP_LIST),
    1455                         QLatin1String("FILE_OWNERSHIP_INFO"));
    1456         writeRegRssList(t, userItems[RSS_TAG_DATATYPE_LIST],
    1457                         QLatin1String(RSS_TAG_DATATYPE_LIST),
    1458                         QLatin1String("DATATYPE"));
    1459         t << endl;
    1460 
    1461         foreach(QString item, userItems[RSS_TAG_DEFAULT])
    1462             t << "\t" << item.replace("\n","\n\t") << endl;
    1463         t << "\t}" << endl;
    1464 
    1465         foreach(QString item, userItems[RSS_TAG_FOOTER])
    1466             t << item << endl;
    1467     } else {
    1468         PRINT_FILE_CREATE_ERROR(filename)
    1469     }
    1470 }
    1471 
    1472 void SymbianMakefileGenerator::writeRegRssList(QTextStream &t,
    1473                                                QStringList &userList,
    1474                                                const QString &listTag,
    1475                                                const QString &listItem)
    1476 {
    1477     int itemCount = userList.count();
    1478     if (itemCount) {
    1479         t << "\t" << listTag << " ="<< endl;
    1480         t << "\t\t{" << endl;
    1481         foreach(QString item, userList) {
    1482             t << "\t\t" << listItem << endl;
    1483             t << "\t\t\t{" << endl;
    1484             t << "\t\t\t" << item.replace("\n","\n\t\t\t") << endl;
    1485             t << "\t\t\t}";
    1486             if (--itemCount)
    1487                 t << ",";
    1488             t << endl;
    1489         }
    1490         t << "\t\t}; "<< endl;
    1491     }
    1492 }
    1493 
    1494 void SymbianMakefileGenerator::writeRssFile(QString &numberOfIcons, QString &iconFile)
    1495 {
    1496     QString filename(fixedTarget);
    1497     filename.append(".rss");
    1498     QFile ft(filename);
    1499     if (ft.open(QIODevice::WriteOnly)) {
    1500         generatedFiles << ft.fileName();
    1501         QTextStream t(&ft);
    1502         t << "// ============================================================================" << endl;
    1503         t << "// * Generated by qmake (" << qmake_version() << ") (Qt " QT_VERSION_STR ") on: ";
    1504         t << QDateTime::currentDateTime().toString(Qt::ISODate) << endl;
    1505         t << "// * This file is generated by qmake and should not be modified by the" << endl;
    1506         t << "// * user." << endl;
    1507         t << "// ============================================================================" << endl;
    1508         t << endl;
    1509         t << "#include <appinfo.rh>" << endl;
    1510         t << "#include \"" << fixedTarget << ".loc\"" << endl;
    1511         t << endl;
    1512         t << "RESOURCE LOCALISABLE_APP_INFO r_localisable_app_info" << endl;
    1513         t << "\t{" << endl;
    1514         t << "\tshort_caption = STRING_r_short_caption;" << endl;
    1515         t << "\tcaption_and_icon =" << endl;
    1516         t << "\tCAPTION_AND_ICON_INFO" << endl;
    1517         t << "\t\t{" << endl;
    1518         t << "\t\tcaption = STRING_r_caption;" << endl;
    1519 
    1520         QString rssIconFile = iconFile;
    1521         rssIconFile = rssIconFile.replace("/", "\\\\");
    1522 
    1523         if (numberOfIcons.isEmpty() || rssIconFile.isEmpty()) {
    1524             // There can be maximum one item in this tag, validated when parsed
    1525             t << "\t\tnumber_of_icons = 0;" << endl;
    1526             t << "\t\ticon_file = \"\";" << endl;
    1527         } else {
    1528             // There can be maximum one item in this tag, validated when parsed
    1529             t << "\t\tnumber_of_icons = " << numberOfIcons << ";" << endl;
    1530             t << "\t\ticon_file = \"" << rssIconFile << "\";" << endl;
    1531         }
    1532         t << "\t\t};" << endl;
    1533         t << "\t}" << endl;
    1534         t << endl;
    1535     } else {
    1536         PRINT_FILE_CREATE_ERROR(filename);
    1537     }
    1538 }
    1539 
    1540 void SymbianMakefileGenerator::writeLocFile(QStringList &symbianLangCodes)
    1541 {
    1542     QString filename(fixedTarget);
    1543     filename.append(".loc");
    1544     QFile ft(filename);
    1545     if (ft.open(QIODevice::WriteOnly)) {
    1546         generatedFiles << ft.fileName();
    1547         QTextStream t(&ft);
    1548         t << "// ============================================================================" << endl;
    1549         t << "// * Generated by qmake (" << qmake_version() << ") (Qt " QT_VERSION_STR ") on: ";
    1550         t << QDateTime::currentDateTime().toString(Qt::ISODate) << endl;
    1551         t << "// * This file is generated by qmake and should not be modified by the" << endl;
    1552         t << "// * user." << endl;
    1553         t << "// ============================================================================" << endl;
    1554         t << endl;
    1555         t << "#ifdef LANGUAGE_SC" << endl;
    1556         t << "#define STRING_r_short_caption \"" << fixedTarget  << "\"" << endl;
    1557         t << "#define STRING_r_caption \"" << fixedTarget  << "\"" << endl;
    1558         foreach(QString lang, symbianLangCodes) {
    1559             t << "#elif defined LANGUAGE_" << lang << endl;
    1560             t << "#define STRING_r_short_caption \"" << fixedTarget  << "\"" << endl;
    1561             t << "#define STRING_r_caption \"" << fixedTarget  << "\"" << endl;
    1562         }
    1563         t << "#else" << endl;
    1564         t << "#define STRING_r_short_caption \"" << fixedTarget  << "\"" << endl;
    1565         t << "#define STRING_r_caption \"" << fixedTarget  << "\"" << endl;
    1566         t << "#endif" << endl;
    1567     } else {
    1568         PRINT_FILE_CREATE_ERROR(filename);
    1569     }
    1570 }
    1571 
    1572 void SymbianMakefileGenerator::readRssRules(QString &numberOfIcons,
    1573                                             QString &iconFile, QMap<QString,
    1574                                             QStringList> &userRssRules)
    1575 {
    1576     for (QMap<QString, QStringList>::iterator it = project->variables().begin(); it != project->variables().end(); ++it) {
    1577         if (it.key().startsWith(RSS_RULES_BASE)) {
    1578             QString newKey = it.key().mid(sizeof(RSS_RULES_BASE) - 1);
    1579             if (newKey.isEmpty()) {
    1580                 fprintf(stderr, "Warning: Empty RSS_RULES_BASE key encountered\n");
    1581                 continue;
    1582             }
    1583             QStringList newValues;
    1584             QStringList values = it.value();
    1585             foreach(QString item, values) {
    1586                 // If there is no stringlist defined for a rule, use rule value directly
    1587                 // This is convenience for defining single line statements
    1588                 if (project->values(item).isEmpty()) {
    1589                     newValues << item;
    1590                 } else {
    1591                     QStringList itemList;
    1592                     foreach(QString itemRow, project->values(item)) {
    1593                         itemList << itemRow;
    1594                     }
    1595                     newValues << itemList.join("\n");
    1596                 }
    1597             }
    1598             // Verify thet there is exactly one value in RSS_TAG_NBROFICONS
    1599             if (newKey == RSS_TAG_NBROFICONS) {
    1600                 if (newValues.count() == 1) {
    1601                     numberOfIcons = newValues[0];
    1602                 } else {
    1603                     fprintf(stderr, "Warning: There must be exactly one value in '%s%s'\n",
    1604                             RSS_RULES_BASE, RSS_TAG_NBROFICONS);
    1605                     continue;
    1606                 }
    1607             // Verify thet there is exactly one value in RSS_TAG_ICONFILE
    1608             } else if (newKey == RSS_TAG_ICONFILE) {
    1609                 if (newValues.count() == 1) {
    1610                     iconFile = newValues[0];
    1611                 } else {
    1612                     fprintf(stderr, "Warning: There must be exactly one value in '%s%s'\n",
    1613                             RSS_RULES_BASE, RSS_TAG_ICONFILE);
    1614                     continue;
    1615                 }
    1616             } else if (newKey == RSS_TAG_HEADER
    1617                        || newKey == RSS_TAG_SERVICE_LIST
    1618                        || newKey == RSS_TAG_FILE_OWNERSHIP_LIST
    1619                        || newKey == RSS_TAG_DATATYPE_LIST
    1620                        || newKey == RSS_TAG_FOOTER
    1621                        || newKey == RSS_TAG_DEFAULT) {
    1622                 userRssRules[newKey] = newValues;
    1623                 continue;
    1624             } else {
    1625                 fprintf(stderr, "Warning: Unsupported key:'%s%s'\n",
    1626                         RSS_RULES_BASE, newKey.toLatin1().constData());
    1627                 continue;
    1628             }
    1629         }
    1630     }
    1631 
    1632     QStringList newValues;
    1633     foreach(QString item, project->values(RSS_RULES)) {
    1634         // If there is no stringlist defined for a rule, use rule value directly
    1635         // This is convenience for defining single line statements
    1636         if (project->values(item).isEmpty()) {
    1637             newValues << item;
    1638         } else {
    1639             newValues << project->values(item);
    1640         }
    1641     }
    1642     userRssRules[RSS_TAG_DEFAULT] << newValues;
    1643 
    1644     // Validate that either both RSS_TAG_NBROFICONS and RSS_TAG_ICONFILE keys exist
    1645     // or neither of them exist
    1646     if (!((numberOfIcons.isEmpty() && iconFile.isEmpty()) ||
    1647             (!numberOfIcons.isEmpty() && !iconFile.isEmpty()))) {
    1648         numberOfIcons.clear();
    1649         iconFile.clear();
    1650         fprintf(stderr, "Warning: Both or neither of '%s%s' and '%s%s' keys must exist.\n",
    1651                 RSS_RULES_BASE, RSS_TAG_NBROFICONS, RSS_RULES_BASE, RSS_TAG_ICONFILE);
    1652     }
    1653 
    1654     // Validate that RSS_TAG_NBROFICONS contains only numbers
    1655     if (!numberOfIcons.isEmpty()) {
    1656         bool ok;
    1657         numberOfIcons = numberOfIcons.simplified();
    1658         numberOfIcons.toInt(&ok);
    1659         if (!ok) {
    1660             numberOfIcons.clear();
    1661             iconFile.clear();
    1662             fprintf(stderr, "Warning: '%s%s' must be integer in decimal format.\n",
    1663                     RSS_RULES_BASE, RSS_TAG_NBROFICONS);
    1664         }
    1665     }
    1666 }
    1667 
    1668 QStringList SymbianMakefileGenerator::symbianLangCodesFromTsFiles()
    1669 {
    1670     QStringList tsfiles;
    1671     QStringList symbianLangCodes;
    1672     tsfiles << project->values("TRANSLATIONS");
    1673 
    1674     fillQt2S60LangMapTable();
    1675 
    1676     foreach(QString file, tsfiles) {
    1677         int extIndex = file.lastIndexOf(".");
    1678         int langIndex = file.lastIndexOf("_", (extIndex - file.length()));
    1679         langIndex += 1;
    1680         QString qtlang = file.mid(langIndex, extIndex - langIndex);
    1681         QString s60lang = qt2S60LangMapTable.value(qtlang, QString("SC"));
    1682 
    1683         if (!symbianLangCodes.contains(s60lang) && s60lang != "SC")
    1684             symbianLangCodes += s60lang;
    1685     }
    1686 
    1687     return symbianLangCodes;
    1688 }
    1689 
    1690 void SymbianMakefileGenerator::fillQt2S60LangMapTable()
    1691 {
    1692     qt2S60LangMapTable.reserve(170); // 165 items at time of writing.
    1693     qt2S60LangMapTable.insert("ab", "SC");            //Abkhazian                     //
    1694     qt2S60LangMapTable.insert("om", "SC");            //Afan                          //
    1695     qt2S60LangMapTable.insert("aa", "SC");            //Afar                          //
    1696     qt2S60LangMapTable.insert("af", "34");            //Afrikaans                     //Afrikaans
    1697     qt2S60LangMapTable.insert("sq", "35");            //Albanian                      //Albanian
    1698     qt2S60LangMapTable.insert("am", "36");            //Amharic                       //Amharic
    1699     qt2S60LangMapTable.insert("ar", "37");            //Arabic                        //Arabic
    1700     qt2S60LangMapTable.insert("hy", "38");            //Armenian                      //Armenian
    1701     qt2S60LangMapTable.insert("as", "SC");            //Assamese                      //
    1702     qt2S60LangMapTable.insert("ay", "SC");            //Aymara                        //
    1703     qt2S60LangMapTable.insert("az", "SC");            //Azerbaijani                   //
    1704     qt2S60LangMapTable.insert("ba", "SC");            //Bashkir                       //
    1705     qt2S60LangMapTable.insert("eu", "SC");            //Basque                        //
    1706     qt2S60LangMapTable.insert("bn", "41");            //Bengali                       //Bengali
    1707     qt2S60LangMapTable.insert("dz", "SC");            //Bhutani                       //
    1708     qt2S60LangMapTable.insert("bh", "SC");            //Bihari                        //
    1709     qt2S60LangMapTable.insert("bi", "SC");            //Bislama                       //
    1710     qt2S60LangMapTable.insert("br", "SC");            //Breton                        //
    1711     qt2S60LangMapTable.insert("bg", "42");            //Bulgarian                     //Bulgarian
    1712     qt2S60LangMapTable.insert("my", "43");            //Burmese                       //Burmese
    1713     qt2S60LangMapTable.insert("be", "40");            //Byelorussian                  //Belarussian
    1714     qt2S60LangMapTable.insert("km", "SC");            //Cambodian                     //
    1715     qt2S60LangMapTable.insert("ca", "44");            //Catalan                       //Catalan
    1716     qt2S60LangMapTable.insert("zh", "SC");            //Chinese                       //
    1717     qt2S60LangMapTable.insert("co", "SC");            //Corsican                      //
    1718     qt2S60LangMapTable.insert("hr", "45");            //Croatian                      //Croatian
    1719     qt2S60LangMapTable.insert("cs", "25");            //Czech                         //Czech
    1720     qt2S60LangMapTable.insert("da", "07");            //Danish                        //Danish
    1721     qt2S60LangMapTable.insert("nl", "18");            //Dutch                         //Dutch
    1722     qt2S60LangMapTable.insert("en", "01");            //English                       //English(UK)
    1723     qt2S60LangMapTable.insert("eo", "SC");            //Esperanto                     //
    1724     qt2S60LangMapTable.insert("et", "49");            //Estonian                      //Estonian
    1725     qt2S60LangMapTable.insert("fo", "SC");            //Faroese                       //
    1726     qt2S60LangMapTable.insert("fj", "SC");            //Fiji                          //
    1727     qt2S60LangMapTable.insert("fi", "09");            //Finnish                       //Finnish
    1728     qt2S60LangMapTable.insert("fr", "02");            //French                        //French
    1729     qt2S60LangMapTable.insert("fy", "SC");            //Frisian                       //
    1730     qt2S60LangMapTable.insert("gd", "52");            //Gaelic                        //Gaelic
    1731     qt2S60LangMapTable.insert("gl", "SC");            //Galician                      //
    1732     qt2S60LangMapTable.insert("ka", "53");            //Georgian                      //Georgian
    1733     qt2S60LangMapTable.insert("de", "03");            //German                        //German
    1734     qt2S60LangMapTable.insert("el", "54");            //Greek                         //Greek
    1735     qt2S60LangMapTable.insert("kl", "SC");            //Greenlandic                   //
    1736     qt2S60LangMapTable.insert("gn", "SC");            //Guarani                       //
    1737     qt2S60LangMapTable.insert("gu", "56");            //Gujarati                      //Gujarati
    1738     qt2S60LangMapTable.insert("ha", "SC");            //Hausa                         //
    1739     qt2S60LangMapTable.insert("he", "57");            //Hebrew                        //Hebrew
    1740     qt2S60LangMapTable.insert("hi", "58");            //Hindi                         //Hindi
    1741     qt2S60LangMapTable.insert("hu", "17");            //Hungarian                     //Hungarian
    1742     qt2S60LangMapTable.insert("is", "15");            //Icelandic                     //Icelandic
    1743     qt2S60LangMapTable.insert("id", "59");            //Indonesian                    //Indonesian
    1744     qt2S60LangMapTable.insert("ia", "SC");            //Interlingua                   //
    1745     qt2S60LangMapTable.insert("ie", "SC");            //Interlingue                   //
    1746     qt2S60LangMapTable.insert("iu", "SC");            //Inuktitut                     //
    1747     qt2S60LangMapTable.insert("ik", "SC");            //Inupiak                       //
    1748     qt2S60LangMapTable.insert("ga", "60");            //Irish                         //Irish
    1749     qt2S60LangMapTable.insert("it", "05");            //Italian                       //Italian
    1750     qt2S60LangMapTable.insert("ja", "32");            //Japanese                      //Japanese
    1751     qt2S60LangMapTable.insert("jv", "SC");            //Javanese                      //
    1752     qt2S60LangMapTable.insert("kn", "62");            //Kannada                       //Kannada
    1753     qt2S60LangMapTable.insert("ks", "SC");            //Kashmiri                      //
    1754     qt2S60LangMapTable.insert("kk", "63");            //Kazakh                        //Kazakh
    1755     qt2S60LangMapTable.insert("rw", "SC");            //Kinyarwanda                   //
    1756     qt2S60LangMapTable.insert("ky", "SC");            //Kirghiz                       //
    1757     qt2S60LangMapTable.insert("ko", "65");            //Korean                        //Korean
    1758     qt2S60LangMapTable.insert("ku", "SC");            //Kurdish                       //
    1759     qt2S60LangMapTable.insert("rn", "SC");            //Kurundi                       //
    1760     qt2S60LangMapTable.insert("lo", "66");            //Laothian                      //Laothian
    1761     qt2S60LangMapTable.insert("la", "SC");            //Latin                         //
    1762     qt2S60LangMapTable.insert("lv", "67");            //Latvian                       //Latvian
    1763     qt2S60LangMapTable.insert("ln", "SC");            //Lingala                       //
    1764     qt2S60LangMapTable.insert("lt", "68");            //Lithuanian                    //Lithuanian
    1765     qt2S60LangMapTable.insert("mk", "69");            //Macedonian                    //Macedonian
    1766     qt2S60LangMapTable.insert("mg", "SC");            //Malagasy                      //
    1767     qt2S60LangMapTable.insert("ms", "70");            //Malay                         //Malay
    1768     qt2S60LangMapTable.insert("ml", "71");            //Malayalam                     //Malayalam
    1769     qt2S60LangMapTable.insert("mt", "SC");            //Maltese                       //
    1770     qt2S60LangMapTable.insert("mi", "SC");            //Maori                         //
    1771     qt2S60LangMapTable.insert("mr", "72");            //Marathi                       //Marathi
    1772     qt2S60LangMapTable.insert("mo", "73");            //Moldavian                     //Moldovian
    1773     qt2S60LangMapTable.insert("mn", "74");            //Mongolian                     //Mongolian
    1774     qt2S60LangMapTable.insert("na", "SC");            //Nauru                         //
    1775     qt2S60LangMapTable.insert("ne", "SC");            //Nepali                        //
    1776     qt2S60LangMapTable.insert("nb", "08");            //Norwegian                     //Norwegian
    1777     qt2S60LangMapTable.insert("oc", "SC");            //Occitan                       //
    1778     qt2S60LangMapTable.insert("or", "SC");            //Oriya                         //
    1779     qt2S60LangMapTable.insert("ps", "SC");            //Pashto                        //
    1780     qt2S60LangMapTable.insert("fa", "SC");            //Persian                       //
    1781     qt2S60LangMapTable.insert("pl", "27");            //Polish                        //Polish
    1782     qt2S60LangMapTable.insert("pt", "13");            //Portuguese                    //Portuguese
    1783     qt2S60LangMapTable.insert("pa", "77");            //Punjabi                       //Punjabi
    1784     qt2S60LangMapTable.insert("qu", "SC");            //Quechua                       //
    1785     qt2S60LangMapTable.insert("rm", "SC");            //RhaetoRomance                 //
    1786     qt2S60LangMapTable.insert("ro", "78");            //Romanian                      //Romanian
    1787     qt2S60LangMapTable.insert("ru", "16");            //Russian                       //Russian
    1788     qt2S60LangMapTable.insert("sm", "SC");            //Samoan                        //
    1789     qt2S60LangMapTable.insert("sg", "SC");            //Sangho                        //
    1790     qt2S60LangMapTable.insert("sa", "SC");            //Sanskrit                      //
    1791     qt2S60LangMapTable.insert("sr", "79");            //Serbian                       //Serbian
    1792     qt2S60LangMapTable.insert("sh", "SC");            //SerboCroatian                 //
    1793     qt2S60LangMapTable.insert("st", "SC");            //Sesotho                       //
    1794     qt2S60LangMapTable.insert("tn", "SC");            //Setswana                      //
    1795     qt2S60LangMapTable.insert("sn", "SC");            //Shona                         //
    1796     qt2S60LangMapTable.insert("sd", "SC");            //Sindhi                        //
    1797     qt2S60LangMapTable.insert("si", "80");            //Singhalese                    //Sinhalese
    1798     qt2S60LangMapTable.insert("ss", "SC");            //Siswati                       //
    1799     qt2S60LangMapTable.insert("sk", "26");            //Slovak                        //Slovak
    1800     qt2S60LangMapTable.insert("sl", "28");            //Slovenian                     //Slovenian
    1801     qt2S60LangMapTable.insert("so", "81");            //Somali                        //Somali
    1802     qt2S60LangMapTable.insert("es", "04");            //Spanish                       //Spanish
    1803     qt2S60LangMapTable.insert("su", "SC");            //Sundanese                     //
    1804     qt2S60LangMapTable.insert("sw", "84");            //Swahili                       //Swahili
    1805     qt2S60LangMapTable.insert("sv", "06");            //Swedish                       //Swedish
    1806     qt2S60LangMapTable.insert("tl", "39");            //Tagalog                       //Tagalog
    1807     qt2S60LangMapTable.insert("tg", "SC");            //Tajik                         //
    1808     qt2S60LangMapTable.insert("ta", "87");            //Tamil                         //Tamil
    1809     qt2S60LangMapTable.insert("tt", "SC");            //Tatar                         //
    1810     qt2S60LangMapTable.insert("te", "88");            //Telugu                        //Telugu
    1811     qt2S60LangMapTable.insert("th", "33");            //Thai                          //Thai
    1812     qt2S60LangMapTable.insert("bo", "89");            //Tibetan                       //Tibetan
    1813     qt2S60LangMapTable.insert("ti", "90");            //Tigrinya                      //Tigrinya
    1814     qt2S60LangMapTable.insert("to", "SC");            //Tonga                         //
    1815     qt2S60LangMapTable.insert("ts", "SC");            //Tsonga                        //
    1816     qt2S60LangMapTable.insert("tr", "14");            //Turkish                       //Turkish
    1817     qt2S60LangMapTable.insert("tk", "92");            //Turkmen                       //Turkmen
    1818     qt2S60LangMapTable.insert("tw", "SC");            //Twi                           //
    1819     qt2S60LangMapTable.insert("ug", "SC");            //Uigur                         //
    1820     qt2S60LangMapTable.insert("uk", "93");            //Ukrainian                     //Ukrainian
    1821     qt2S60LangMapTable.insert("ur", "94");            //Urdu                          //Urdu
    1822     qt2S60LangMapTable.insert("uz", "SC");            //Uzbek                         //
    1823     qt2S60LangMapTable.insert("vi", "96");            //Vietnamese                    //Vietnamese
    1824     qt2S60LangMapTable.insert("vo", "SC");            //Volapuk                       //
    1825     qt2S60LangMapTable.insert("cy", "97");            //Welsh                         //Welsh
    1826     qt2S60LangMapTable.insert("wo", "SC");            //Wolof                         //
    1827     qt2S60LangMapTable.insert("xh", "SC");            //Xhosa                         //
    1828     qt2S60LangMapTable.insert("yi", "SC");            //Yiddish                       //
    1829     qt2S60LangMapTable.insert("yo", "SC");            //Yoruba                        //
    1830     qt2S60LangMapTable.insert("za", "SC");            //Zhuang                        //
    1831     qt2S60LangMapTable.insert("zu", "98");            //Zulu                          //Zulu
    1832     qt2S60LangMapTable.insert("nn", "75");            //Nynorsk                       //NorwegianNynorsk
    1833     qt2S60LangMapTable.insert("bs", "SC");            //Bosnian                       //
    1834     qt2S60LangMapTable.insert("dv", "SC");            //Divehi                        //
    1835     qt2S60LangMapTable.insert("gv", "SC");            //Manx                          //
    1836     qt2S60LangMapTable.insert("kw", "SC");            //Cornish                       //
    1837     qt2S60LangMapTable.insert("ak", "SC");            //Akan                          //
    1838     qt2S60LangMapTable.insert("kok", "SC");           //Konkani                       //
    1839     qt2S60LangMapTable.insert("gaa", "SC");           //Ga                            //
    1840     qt2S60LangMapTable.insert("ig", "SC");            //Igbo                          //
    1841     qt2S60LangMapTable.insert("kam", "SC");           //Kamba                         //
    1842     qt2S60LangMapTable.insert("syr", "SC");           //Syriac                        //
    1843     qt2S60LangMapTable.insert("byn", "SC");           //Blin                          //
    1844     qt2S60LangMapTable.insert("gez", "SC");           //Geez                          //
    1845     qt2S60LangMapTable.insert("kfo", "SC");           //Koro                          //
    1846     qt2S60LangMapTable.insert("sid", "SC");           //Sidamo                        //
    1847     qt2S60LangMapTable.insert("cch", "SC");           //Atsam                         //
    1848     qt2S60LangMapTable.insert("tig", "SC");           //Tigre                         //
    1849     qt2S60LangMapTable.insert("kaj", "SC");           //Jju                           //
    1850     qt2S60LangMapTable.insert("fur", "SC");           //Friulian                      //
    1851     qt2S60LangMapTable.insert("ve", "SC");            //Venda                         //
    1852     qt2S60LangMapTable.insert("ee", "SC");            //Ewe                           //
    1853     qt2S60LangMapTable.insert("wa", "SC");            //Walamo                        //
    1854     qt2S60LangMapTable.insert("haw", "SC");           //Hawaiian                      //
    1855     qt2S60LangMapTable.insert("kcg", "SC");           //Tyap                          //
    1856     qt2S60LangMapTable.insert("ny", "SC");            //Chewa                         //
    1857 }
    1858 
    18591035void SymbianMakefileGenerator::appendIfnotExist(QStringList &list, QString value)
    18601036{
     
    18671043    foreach(QString item, values)
    18681044        appendIfnotExist(list, item);
    1869 }
    1870 
    1871 QString SymbianMakefileGenerator::removePathSeparators(QString &file)
    1872 {
    1873     QString ret = file;
    1874     while (ret.indexOf(QDir::separator()) > 0) {
    1875         ret.remove(0, ret.indexOf(QDir::separator()) + 1);
    1876     }
    1877 
    1878     return ret;
    18791045}
    18801046
     
    19041070        t << cmd << " " << cmdOptions << " \"" << QDir::toNativeSeparators(item) << "\"" << endl;
    19051071#else
    1906         t << "\t-if test -f " << QDir::toNativeSeparators(item) << "; then ";
     1072        t << "\t-if test -e " << QDir::toNativeSeparators(item) << "; then ";
    19071073        t << cmd << " " << cmdOptions << " " << QDir::toNativeSeparators(item) << "; fi" << endl;
    19081074#endif
    19091075    }
    1910 }
    1911 
    1912 void SymbianMakefileGenerator::removeSpecialCharacters(QString& str)
    1913 {
    1914     // When modifying this method check also application_icon.prf
    1915     str.replace(QString("/"), QString("_"));
    1916     str.replace(QString("\\"), QString("_"));
    1917     str.replace(QString("-"), QString("_"));
    1918     str.replace(QString(":"), QString("_"));
    1919     str.replace(QString("."), QString("_"));
    1920     str.replace(QString(" "), QString("_"));
    1921 }
    1922 
    1923 void SymbianMakefileGenerator::writeSisTargets(QTextStream &t)
    1924 {
    1925     t << "-include " MAKE_CACHE_NAME << endl;
    1926     t << endl;
    1927 
    1928     t << SIS_TARGET ":" << endl;
    1929     QString siscommand = QString::fromLatin1("\t$(if $(wildcard %1_template.%2),$(if $(wildcard %3)," \
    1930                                   "$(MAKE) -s -f $(MAKEFILE) %4," \
    1931                                   "$(if $(QT_SIS_TARGET),$(MAKE) -s -f $(MAKEFILE) %4," \
    1932                                   "$(MAKE) -s -f $(MAKEFILE) %5))," \
    1933                                   "$(MAKE) -s -f $(MAKEFILE) %6)")
    1934                           .arg(fixedTarget)
    1935                           .arg("pkg")
    1936                           .arg(MAKE_CACHE_NAME)
    1937                           .arg(OK_SIS_TARGET)
    1938                           .arg(FAIL_SIS_NOCACHE_TARGET)
    1939                           .arg(FAIL_SIS_NOPKG_TARGET);
    1940     t << siscommand << endl;
    1941     t << endl;
    1942 
    1943     t << OK_SIS_TARGET ":" << endl;
    1944 
    1945     QString pkgcommand = QString::fromLatin1("\tcreatepackage.bat $(QT_SIS_OPTIONS) %1_template.%2 $(QT_SIS_TARGET) " \
    1946                                  "$(QT_SIS_CERTIFICATE) $(QT_SIS_KEY) $(QT_SIS_PASSPHRASE)")
    1947                           .arg(fixedTarget)
    1948                           .arg("pkg");
    1949     t << pkgcommand << endl;
    1950     t << endl;
    1951 
    1952     QString sisName = fixedTarget;
    1953     sisName += ".sis";
    1954 
    1955     t << sisName << ":" << endl;
    1956     t << "\t$(MAKE) -s -f $(MAKEFILE) " SIS_TARGET << endl << endl;
    1957 
    1958     t << ROM_STUB_SIS_TARGET ":" << endl;
    1959     QString stubsiscommand = QString::fromLatin1("\t$(if $(wildcard %1_template.%2),$(if $(wildcard %3)," \
    1960                                   "$(MAKE) -s -f $(MAKEFILE) %4," \
    1961                                   "$(if $(QT_SIS_TARGET),$(MAKE) -s -f $(MAKEFILE) %4," \
    1962                                   "$(MAKE) -s -f $(MAKEFILE) %5))," \
    1963                                   "$(MAKE) -s -f $(MAKEFILE) %6)")
    1964                           .arg(fixedTarget)
    1965                           .arg("pkg")
    1966                           .arg(MAKE_CACHE_NAME)
    1967                           .arg(OK_ROM_STUB_SIS_TARGET)
    1968                           .arg(FAIL_SIS_NOCACHE_TARGET)
    1969                           .arg(FAIL_SIS_NOPKG_TARGET);
    1970     t << stubsiscommand << endl;
    1971     t << endl;
    1972 
    1973     t << OK_ROM_STUB_SIS_TARGET ":" << endl;
    1974 
    1975     QString stubpkgcommand = QString::fromLatin1("\tcreatepackage.bat -s $(QT_SIS_OPTIONS) %1_template.%2 $(QT_SIS_TARGET) " \
    1976                                  "$(QT_SIS_CERTIFICATE) $(QT_SIS_KEY) $(QT_SIS_PASSPHRASE)")
    1977                           .arg(fixedTarget)
    1978                           .arg("pkg");
    1979     t << stubpkgcommand << endl;
    1980     t << endl;
    1981 
    1982     t << INSTALLER_SIS_TARGET ": " << sisName << endl;
    1983     siscommand = QString::fromLatin1("\t$(if $(wildcard %1_installer.%2)," \
    1984                                   "$(MAKE) -s -f $(MAKEFILE) %3," \
    1985                                   "$(MAKE) -s -f $(MAKEFILE) %4)")
    1986                           .arg(fixedTarget)
    1987                           .arg("pkg")
    1988                           .arg(OK_INSTALLER_SIS_TARGET)
    1989                           .arg(FAIL_SIS_NOPKG_TARGET);
    1990     t << siscommand << endl;
    1991     t << endl;
    1992 
    1993     t << OK_INSTALLER_SIS_TARGET ": " << endl;
    1994 
    1995     pkgcommand = QString::fromLatin1("\tcreatepackage.bat $(QT_SIS_OPTIONS) %1_installer.%2 - " \
    1996                          "$(QT_SIS_CERTIFICATE) $(QT_SIS_KEY) $(QT_SIS_PASSPHRASE)")
    1997                   .arg(fixedTarget)
    1998                   .arg("pkg");
    1999     t << pkgcommand << endl;
    2000     t << endl;
    2001 
    2002     t << FAIL_SIS_NOPKG_TARGET ":" << endl;
    2003     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;
    2004     t << endl;
    2005 
    2006     t << FAIL_SIS_NOCACHE_TARGET ":" << endl;
    2007     t << "\t$(error Project has to be built or QT_SIS_TARGET environment variable has to be set before calling 'SIS' target)" << endl;
    2008     t << endl;
    20091076}
    20101077
     
    20641131}
    20651132
    2066 void SymbianMakefileGenerator::generateExecutionTargets(QTextStream& t, const QStringList& platforms)
    2067 {
    2068     // create execution targets
    2069     if (targetType == TypeExe) {
    2070         if (platforms.contains("winscw")) {
    2071             t << "run:" << endl;
    2072             t << "\t-call " << epocRoot() << "epoc32/release/winscw/udeb/" << fixedTarget << ".exe " << "$(QT_RUN_OPTIONS)" << endl;
    2073         }
    2074         t << "runonphone: sis" << endl;
    2075         t << "\trunonphone $(QT_RUN_ON_PHONE_OPTIONS) --sis " << fixedTarget << ".sis " << fixedTarget << ".exe " << "$(QT_RUN_OPTIONS)" << endl;
     1133// Returns a string that can be used as a dependency to loc file on other targets
     1134QString SymbianMakefileGenerator::generateLocFileTarget(QTextStream& t, const QString& locCmd)
     1135{
     1136    QString locFile;
     1137    if (targetType == TypeExe && !project->isActiveConfig("no_icon")) {
     1138        locFile = Option::fixPathToLocalOS(generateLocFileName());
     1139        t << locFile << QLatin1String(": ") << project->values("SYMBIAN_MATCHED_TRANSLATIONS").join(" ") << endl;
     1140        t << locCmd << endl;
    20761141        t << endl;
    2077     }
    2078 }
     1142        locFile += QLatin1Char(' ');
     1143    }
     1144
     1145    return locFile;
     1146}
Note: See TracChangeset for help on using the changeset viewer.