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:
9 edited
3 copied

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/qmake/generators/symbian/initprojectdeploy_symbian.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)
     
    4848
    4949// Included from tools/shared
    50 #include <symbian/epocroot.h>
     50#include <symbian/epocroot_p.h>
    5151
    5252#define SYSBIN_DIR "/sys/bin"
     53#define HW_Z_DIR "epoc32/data/z"
    5354
    5455#define SUFFIX_DLL "dll"
     
    5960{
    6061    QString ret = Option::fixPathToTargetOS(src);
    61     return ret.replace('/', '\\');
     62
     63    bool pathHasDriveLetter = false;
     64    if (ret.size() > 1)
     65        pathHasDriveLetter = (ret.at(1) == QLatin1Char(':'));
     66
     67    return pathHasDriveLetter ? ret.replace('/', '\\') : QDir::toNativeSeparators(ret);
    6268}
    6369
     
    6672    // Libraries are plugins if deployment path is something else than
    6773    // SYSBIN_DIR with or without drive letter
    68     if (0 == info.suffix().compare(QLatin1String(SUFFIX_DLL), Qt::CaseInsensitive) &&
    69             (devicePath.size() < 8 ||
    70              (0 != devicePath.compare(QLatin1String(SYSBIN_DIR), Qt::CaseInsensitive) &&
    71               0 != devicePath.mid(1).compare(QLatin1String(":" SYSBIN_DIR), Qt::CaseInsensitive)))) {
     74    if (0 == info.suffix().compare(QLatin1String(SUFFIX_DLL), Qt::CaseInsensitive)
     75            && (devicePath.size() < 8
     76             || (0 != devicePath.compare(QLatin1String(SYSBIN_DIR), Qt::CaseInsensitive)
     77                && 0 != devicePath.mid(1).compare(QLatin1String(":" SYSBIN_DIR), Qt::CaseInsensitive)
     78                && 0 != devicePath.compare(qt_epocRoot() + QLatin1String(HW_Z_DIR SYSBIN_DIR))))) {
    7279        return true;
    7380    } else {
     
    9299                             QStringList& generatedFiles)
    93100{
    94     QDir().mkpath(QLatin1String(PLUGIN_STUB_DIR));
    95     if (!generatedDirs.contains(PLUGIN_STUB_DIR))
    96         generatedDirs << PLUGIN_STUB_DIR;
     101    QString pluginStubDir = Option::output_dir + QLatin1Char('/') + QLatin1String(PLUGIN_STUB_DIR);
     102    QDir().mkpath(pluginStubDir);
     103    if (!generatedDirs.contains(pluginStubDir))
     104        generatedDirs << pluginStubDir;
    97105    // Plugin stubs must have different name from the actual plugins, because
    98106    // the toolchain for creating ROM images cannot handle non-binary .dll files properly.
    99     QFile stubFile(QLatin1String(PLUGIN_STUB_DIR "/") + info.completeBaseName() + "." SUFFIX_QTPLUGIN);
     107    QFile stubFile(pluginStubDir + QLatin1Char('/') + info.completeBaseName() + QLatin1Char('.') + QLatin1String(SUFFIX_QTPLUGIN));
    100108    if (stubFile.open(QIODevice::WriteOnly)) {
    101109        if (!generatedFiles.contains(stubFile.fileName()))
     
    156164                              const QString &testPath,
    157165                              bool deployBinaries,
     166                              bool epocBuild,
    158167                              const QString &platform,
    159168                              const QString &build,
     
    171180        targetPathHasDriveLetter = targetPath.at(1) == QLatin1Char(':');
    172181    }
    173     QString deploymentDrive = targetPathHasDriveLetter ? targetPath.left(2) : QLatin1String("c:");
     182
     183    QString deploymentDrive;
     184    if (0 == platform.compare(QLatin1String(ROM_DEPLOYMENT_PLATFORM))) {
     185        deploymentDrive = qt_epocRoot() + HW_Z_DIR;
     186    } else {
     187        deploymentDrive = targetPathHasDriveLetter ? targetPath.left(2) : QLatin1String("c:");
     188    }
    174189
    175190    foreach(QString item, project->values("DEPLOYMENT")) {
     
    189204        }
    190205        if (!deployBinaries
     206                && 0 != platform.compare(QLatin1String(ROM_DEPLOYMENT_PLATFORM))
    191207                && !devicePathWithoutDrive.isEmpty()
    192208                && (0 == devicePathWithoutDrive.compare(project->values("APP_RESOURCE_DIR").join(""), Qt::CaseInsensitive)
     
    208224            devicePath = Option::fixPathToLocalOS(QDir::cleanPath(targetPath + QLatin1Char('/') + devicePath));
    209225        } else {
    210             if (!platform.compare(QLatin1String(EMULATOR_DEPLOYMENT_PLATFORM))) {
     226            if (0 == platform.compare(QLatin1String(EMULATOR_DEPLOYMENT_PLATFORM))) {
    211227                if (devicePathHasDriveLetter) {
    212                     devicePath = epocRoot() + "epoc32/winscw/" + devicePath.remove(1, 1);
     228                    devicePath = qt_epocRoot() + "epoc32/winscw/" + devicePath.remove(1, 1);
    213229                } else {
    214                     devicePath = epocRoot() + "epoc32/winscw/c" + devicePath;
     230                    devicePath = qt_epocRoot() + "epoc32/winscw/c" + devicePath;
    215231                }
    216232            } else {
    217                 if (!devicePathHasDriveLetter) {
    218                     if (!platform.compare(QLatin1String(ROM_DEPLOYMENT_PLATFORM))) {
    219                         //For plugin deployment under ARM no needed drive letter
    220                         devicePath = epocRoot() + "epoc32/data/z" + devicePath;
    221                     } else if (targetPathHasDriveLetter) {
    222                         // Drive letter needed if targetpath contains one and it is not already in
    223                         devicePath = deploymentDrive + devicePath;
    224                     }
    225                 } else {
    226                     //it is necessary to delete drive letter for ARM deployment
    227                     if (!platform.compare(QLatin1String(ROM_DEPLOYMENT_PLATFORM))) {
    228                         devicePath.remove(0,2);
    229                         devicePath = epocRoot() + "epoc32/data/z" + devicePath;
    230                     }
     233                if (devicePathHasDriveLetter
     234                    && 0 == platform.compare(QLatin1String(ROM_DEPLOYMENT_PLATFORM))) {
     235                    devicePath.remove(0,2);
     236                }
     237                if (0 == platform.compare(QLatin1String(ROM_DEPLOYMENT_PLATFORM))
     238                    || (!devicePathHasDriveLetter && targetPathHasDriveLetter)) {
     239                    devicePath = deploymentDrive + devicePath;
    231240                }
    232241            }
     
    235244        devicePath.replace(QLatin1String("\\"), QLatin1String("/"));
    236245
    237         if (!deployBinaries &&
    238                 0 == devicePath.right(8).compare(QLatin1String(SYSBIN_DIR), Qt::CaseInsensitive)) {
     246        if (!deployBinaries
     247                && 0 == devicePath.right(8).compare(QLatin1String(SYSBIN_DIR), Qt::CaseInsensitive)
     248                && 0 != platform.compare(QLatin1String(ROM_DEPLOYMENT_PLATFORM))) {
    239249            // Skip deploying to SYSBIN_DIR for anything but binary deployments
    240250            // Note: Deploying pre-built binaries also follow this rule, so emulator builds
     
    243253            continue;
    244254        }
     255
     256        QStringList flags = project->values(item + ".flags");
    245257
    246258        foreach(QString source, project->values(item + ".sources")) {
     
    265277                        if (deployBinaries) {
    266278                            // Executables and libraries are deployed to \sys\bin
    267                             QFileInfo targetPath(epocRoot() + "epoc32/release/" + platform + "/" + build + "/");
     279                            QFileInfo targetPath;
     280                            if (epocBuild)
     281                                targetPath.setFile(qt_epocRoot() + "epoc32/release/" + platform + "/" + build + "/");
     282                            else
     283                                targetPath.setFile(info.path() + QDir::separator());
    268284                            if(devicePathHasDriveLetter) {
    269285                                deploymentList.append(CopyItem(
     
    271287                                    false, true),
    272288                                    fixPathToEpocOS(devicePath.left(2) + QLatin1String(SYSBIN_DIR "/")
    273                                     + info.fileName())));
     289                                    + info.fileName()),
     290                                    flags));
    274291                            } else {
    275292                                deploymentList.append(CopyItem(
    276293                                    Option::fixPathToLocalOS(targetPath.absolutePath() + "/" + info.fileName(),
    277294                                    false, true),
    278                                     fixPathToEpocOS(deploymentDrive + QLatin1String(SYSBIN_DIR "/")
    279                                     + info.fileName())));
     295                                    fixPathToEpocOS(deploymentDrive + QLatin1String("/" SYSBIN_DIR "/")
     296                                    + info.fileName()),
     297                                    flags));
    280298                            }
    281299                        }
     
    288306                        // when generating .pkg files.
    289307                        deploymentList.append(CopyItem(Option::fixPathToLocalOS(info.absoluteFilePath()),
    290                                                        fixPathToEpocOS(devicePath + "/" + info.fileName())));
     308                                                       fixPathToEpocOS(devicePath + "/" + info.fileName()),
     309                                                       flags));
    291310                        continue;
    292311                    }
     
    309328                        // This deploys pre-built plugins. Other pre-built binaries will deploy normally,
    310329                        // as they have SYSBIN_DIR target path.
    311                         if (deployBinaries) {
     330                        if (deployBinaries
     331                            || (0 == platform.compare(QLatin1String(ROM_DEPLOYMENT_PLATFORM)))) {
    312332                            if (devicePathHasDriveLetter) {
    313333                                deploymentList.append(CopyItem(
    314334                                    Option::fixPathToLocalOS(absoluteItemPath + "/" + iterator.fileName()),
    315335                                    fixPathToEpocOS(devicePath.left(2) + QLatin1String(SYSBIN_DIR "/")
    316                                     + iterator.fileName())));
     336                                    + iterator.fileName()),
     337                                    flags));
    317338                            } else {
    318339                                deploymentList.append(CopyItem(
    319340                                    Option::fixPathToLocalOS(absoluteItemPath + "/" + iterator.fileName()),
    320                                     fixPathToEpocOS(deploymentDrive + QLatin1String(SYSBIN_DIR "/")
    321                                     + iterator.fileName())));
     341                                    fixPathToEpocOS(deploymentDrive + QLatin1String("/" SYSBIN_DIR "/")
     342                                    + iterator.fileName()),
     343                                    flags));
    322344                            }
    323345                        }
     
    329351                            Option::fixPathToLocalOS(absoluteItemPath + "/" + iterator.fileName()),
    330352                            fixPathToEpocOS(devicePath + "/" + absoluteItemPath.right(diffSize)
    331                             + "/" + iterator.fileName())));
     353                            + "/" + iterator.fileName()),
     354                            flags));
    332355                    }
    333356                }
     
    335358        }
    336359    }
    337 }
     360
     361    // Remove deployments that do not actually do anything
     362    if (0 == platform.compare(QLatin1String(EMULATOR_DEPLOYMENT_PLATFORM))
     363        || 0 == platform.compare(QLatin1String(ROM_DEPLOYMENT_PLATFORM))) {
     364        QMutableListIterator<CopyItem> i(deploymentList);
     365        while(i.hasNext()) {
     366            CopyItem &item = i.next();
     367            QFileInfo fromItem(item.from);
     368            QFileInfo toItem(item.to);
     369#if defined(Q_OS_WIN)
     370            if (0 == fromItem.absoluteFilePath().compare(toItem.absoluteFilePath(), Qt::CaseInsensitive))
     371#else
     372            if (0 == fromItem.absoluteFilePath().compare(toItem.absoluteFilePath()))
     373#endif
     374                i.remove();
     375        }
     376    }
     377}
  • trunk/qmake/generators/symbian/initprojectdeploy_symbian.h

    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)
     
    5757struct CopyItem
    5858{
    59     CopyItem(const QString& f, const QString& t) : from(f) , to(t) { }
     59    CopyItem(const QString& f, const QString& t)
     60        : from(f) , to(t) { }
     61    CopyItem(const QString& f, const QString& t, const QStringList& l)
     62        : from(f) , to(t), flags(l) { }
    6063    QString from;
    6164    QString to;
     65    QStringList flags;
    6266};
    6367typedef QList<CopyItem> DeploymentList;
     
    7074                              const QString &testPath,
    7175                              bool deployBinaries,
     76                              bool epocBuild,
    7277                              const QString &platform,
    7378                              const QString &build,
  • 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}
  • trunk/qmake/generators/symbian/symmake.h

    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)
     
    4444
    4545#include "initprojectdeploy_symbian.h"
     46#include "symbiancommon.h"
    4647#include <makefile.h>
    4748
     
    5455#define SYMBIAN_TEST_CONFIG "symbian_test"
    5556
    56 class SymbianMakefileGenerator : public MakefileGenerator
     57class SymbianMakefileGenerator : public MakefileGenerator, public SymbianCommonGenerator
    5758{
    5859protected:
    59     enum TargetType {
    60         TypeExe,
    61         TypeDll,
    62         TypeLib,
    63         TypePlugin,
    64         TypeSubdirs
    65     };
    66 
    6760    QString platform;
    6861    QString uid2;
    69     QString uid3;
    70     QString privateDirUid;
    71     TargetType targetType;
     62    QString mmpFileName;
    7263    QMap<QString, QStringList> sources;
    7364    QMap<QString, QStringList> systeminclude;
     
    7768    QStringList overriddenMmpKeywords;
    7869
    79     QStringList generatedFiles;
    80     QStringList generatedDirs;
    81     QHash<QString, QString> qt2S60LangMapTable;
    82 
    83     QString fixedTarget;
    84 
    85     void removeSpecialCharacters(QString& str);
    8670    QString fixPathForMmp(const QString& origPath, const QDir& parentDir);
    8771    QString absolutizePath(const QString& origPath);
    8872
    8973    virtual bool writeMakefile(QTextStream &t);
    90     void generatePkgFile(const QString &iconFile, DeploymentList &depList);
    91     bool containsStartWithItem(const QChar &c, const QStringList& src);
    9274
    9375    virtual void init();
     
    9880
    9981    void initMmpVariables();
     82    void generateMmpFileName();
    10083    void handleMmpRulesOverrides(QString &checkString,
    10184                                 bool &inResourceBlock,
     
    11093    void writeBldInfContent(QTextStream& t,
    11194                            bool addDeploymentExtension,
    112                             const QString &iconFile,
    113                             DeploymentList &depList);
     95                            const QString &iconFile);
    11496
    11597    static bool removeDuplicatedStrings(QStringList& stringList);
    11698
    11799    void writeMmpFileHeader(QTextStream &t);
    118     void writeMmpFile(QString &filename, QStringList &symbianLangCodes);
     100    void writeMmpFile(QString &filename, const SymbianLocalizationList &symbianLocalizationList);
    119101    void writeMmpFileMacrosPart(QTextStream& t);
    120102    void addMacro(QTextStream& t, const QString& value);
    121103    void writeMmpFileTargetPart(QTextStream& t);
    122     void writeMmpFileResourcePart(QTextStream& t, QStringList &symbianLangCodes);
     104    void writeMmpFileResourcePart(QTextStream& t, const SymbianLocalizationList &symbianLocalizationList);
    123105    void writeMmpFileSystemIncludePart(QTextStream& t);
    124106    void writeMmpFileIncludePart(QTextStream& t);
     
    138120    void writeMmpFileRulesPart(QTextStream& t);
    139121
    140     void writeCustomDefFile();
    141 
    142     void writeRegRssFile(QMap<QString, QStringList> &useritems);
    143     void writeRegRssList(QTextStream &t, QStringList &userList,
    144                          const QString &listTag,
    145                          const QString &listItem);
    146     void writeRssFile(QString &numberOfIcons, QString &iconfile);
    147     void writeLocFile(QStringList &symbianLangCodes);
    148     void readRssRules(QString &numberOfIcons,
    149                       QString &iconFile,
    150                       QMap<QString, QStringList> &userRssRules);
    151 
    152     QStringList symbianLangCodesFromTsFiles();
    153     void fillQt2S60LangMapTable();
    154 
    155122    void appendIfnotExist(QStringList &list, QString value);
    156123    void appendIfnotExist(QStringList &list, QStringList values);
    157124
    158     QString removePathSeparators(QString &file);
    159125    QString removeTrailingPathSeparators(QString &file);
    160126    void generateCleanCommands(QTextStream& t,
     
    165131                               const QString& itemSuffix);
    166132
    167     void writeSisTargets(QTextStream &t);
    168133    void generateDistcleanTargets(QTextStream& t);
    169     void generateExecutionTargets(QTextStream& t, const QStringList& platforms);
     134    QString generateLocFileTarget(QTextStream& t, const QString& locCmd);
    170135
    171136    // Subclass implements
  • trunk/qmake/generators/symbian/symmake_abld.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)
     
    5050
    5151// Included from tools/shared
    52 #include <symbian/epocroot.h>
     52#include <symbian/epocroot_p.h>
    5353
    5454#define DO_NOTHING_TARGET "do_nothing"
     
    7171void SymbianAbldMakefileGenerator::writeMkFile(const QString& wrapperFileName, bool deploymentOnly)
    7272{
    73     QString gnuMakefileName = QLatin1String("Makefile_") + uid3;
    74     removeSpecialCharacters(gnuMakefileName);
    75     gnuMakefileName.append(".mk");
    76 
    7773    QFile ft(gnuMakefileName);
    7874    if (ft.open(QIODevice::WriteOnly)) {
     
    189185    QTextStream t(&wrapperFile);
    190186
    191     t << "# ==============================================================================" << endl;
    192     t << "# Generated by qmake (" << qmake_version() << ") (Qt " << QT_VERSION_STR << ") on: ";
    193     t << QDateTime::currentDateTime().toString() << endl;
    194     t << "# This file is generated by qmake and should not be modified by the" << endl;
    195     t << "# user." << endl;
    196     t << "#  Name        : " << wrapperFile.fileName() << endl;
    197     t << "#  Description : Wrapper Makefile for calling Symbian build tools" << endl;
    198     t << "#" << endl;
    199     t << "# ==============================================================================" << "\n" << endl;
    200     t << endl;
    201 
    202     t << "MAKEFILE          = " << wrapperFile.fileName() << endl;
    203     t << "QMAKE             = " << Option::fixPathToTargetOS(var("QMAKE_QMAKE")) << endl;
     187    MakefileGenerator::writeHeader(t);
     188
     189    t << "MAKEFILE          = " << fileInfo(wrapperFile.fileName()).fileName() << endl;
     190    t << "QMAKE             = " << var("QMAKE_QMAKE") << endl;
    204191    t << "DEL_FILE          = " << var("QMAKE_DEL_FILE") << endl;
    205192    t << "DEL_DIR           = " << var("QMAKE_DEL_DIR") << endl;
     
    207194    t << "CHK_DIR_EXISTS    = " << var("QMAKE_CHK_DIR_EXISTS") << endl;
    208195    t << "MKDIR             = " << var("QMAKE_MKDIR") << endl;
     196#ifdef Q_OS_WIN32
    209197    t << "XCOPY             = xcopy /d /f /h /r /y /i" << endl;
    210198    t << "ABLD              = ABLD.BAT" << endl;
     199#elif defined(Q_OS_MAC)
     200    t << "XCOPY             = cp -R -v" << endl;
     201    t << "ABLD              = abld" << endl;
     202#else
     203    t << "XCOPY             = cp -R -u -v" << endl;
     204    t << "ABLD              = abld" << endl;
     205#endif
    211206    t << "DEBUG_PLATFORMS   = " << debugPlatforms.join(" ") << endl;
    212207    t << "RELEASE_PLATFORMS = " << releasePlatforms.join(" ") << endl;
     
    214209    t << endl;
    215210    t << "ifeq (WINS,$(findstring WINS, $(PLATFORM)))" << endl;
    216     t << "ZDIR=$(EPOCROOT)epoc32\\release\\$(PLATFORM)\\$(CFG)\\Z" << endl;
     211    t << "ZDIR=$(EPOCROOT)" << QDir::toNativeSeparators("epoc32/release/$(PLATFORM)/$(CFG)/z") << endl;
    217212    t << "else" << endl;
    218     t << "ZDIR=$(EPOCROOT)epoc32\\data\\z" << endl;
     213    t << "ZDIR=$(EPOCROOT)" << QDir::toNativeSeparators("epoc32/data/z") << endl;
    219214    t << "endif" << endl;
    220215    t << endl;
     
    249244        t << "all: debug release" << endl;
    250245        t << endl;
     246
     247        QString qmakeCmd = "\t$(QMAKE) \"" + project->projectFile() + "\" " + buildArgs();
     248
    251249        t << "qmake:" << endl;
    252         t << "\t$(QMAKE) -spec symbian-abld -o \"" << fileInfo(Option::output.fileName()).fileName()
    253           << "\" \"" << project->projectFile() << "\"" << endl;
    254         t << endl;
    255         t << BLD_INF_FILENAME ":" << endl;
    256         t << "\t$(QMAKE)" << endl;
    257         t << endl;
     250        t << qmakeCmd << endl;
     251        t << endl;
     252
     253        t << BLD_INF_FILENAME ": " << project->projectFile() << endl;
     254        t << qmakeCmd << endl;
     255        t << endl;
     256
    258257        t << "$(ABLD): " BLD_INF_FILENAME << endl;
    259258        t << "\tbldmake bldfiles" << endl;
    260259        t << endl;
    261260
    262         t << "debug: $(ABLD)" << endl;
     261        QString locFileDep = generateLocFileTarget(t, qmakeCmd);
     262
     263        t << "debug: " << locFileDep << "$(ABLD)" << endl;
    263264        foreach(QString item, debugPlatforms) {
    264265            t << "\t$(ABLD)" << testClause << " build " << item << " udeb" << endl;
    265266        }
    266267        t << endl;
    267         t << "release: $(ABLD)" << endl;
     268        t << "release: " << locFileDep << "$(ABLD)" << endl;
    268269        foreach(QString item, releasePlatforms) {
    269270            t << "\t$(ABLD)" << testClause << " build " << item << " urel" << endl;
     
    273274        // For more specific builds, targets are in this form: build-platform, e.g. release-armv5
    274275        foreach(QString item, debugPlatforms) {
    275             t << "debug-" << item << ": $(ABLD)" << endl;
     276            t << "debug-" << item << ": " << locFileDep << "$(ABLD)" << endl;
    276277            t << "\t$(ABLD)" << testClause << " build " << item << " udeb" << endl;
    277278        }
    278279
    279280        foreach(QString item, releasePlatforms) {
    280             t << "release-" << item << ": $(ABLD)" << endl;
     281            t << "release-" << item << ": " << locFileDep << "$(ABLD)" << endl;
    281282            t << "\t$(ABLD)" << testClause << " build " << item << " urel" << endl;
    282283        }
     
    310311        // -@ if NOT EXIST  ".\somedir"         mkdir ".\somedir"
    311312        QStringList dirsToClean;
     313        QString dirExists = var("QMAKE_CHK_DIR_EXISTS");
     314        QString mkdir = var("QMAKE_MKDIR");
    312315        for (QMap<QString, QStringList>::iterator it = systeminclude.begin(); it != systeminclude.end(); ++it) {
    313316            QStringList values = it.value();
     
    316319                    QString fixedValue(QDir::toNativeSeparators(values.at(i)));
    317320                    dirsToClean << fixedValue;
    318                     t << "\t-@ if NOT EXIST \""  << fixedValue << "\" mkdir \""
    319                       << fixedValue << "\"" << endl;
     321                    t << "\t-@ " << dirExists << " \""  << fixedValue << "\" "
     322                      << (isWindowsShell() ? "" : "|| ")
     323                      << mkdir << " \"" << fixedValue << "\"" << endl;
    320324                }
    321325            }
     
    326330        //       This is why the "2> NUL" gets appended to generated clean targets in makefile.cpp.
    327331        t << EXTENSION_CLEAN ": " COMPILER_CLEAN_TARGET << endl;
    328         generateCleanCommands(t, dirsToClean, var("QMAKE_DEL_DIR"), " /S /Q ", "", "");
     332        generateCleanCommands(t, dirsToClean, var("QMAKE_DEL_TREE"), "", "", "");
    329333        t << endl;
    330334
     
    375379    writeDeploymentTargets(t, true);
    376380
    377     writeSisTargets(t);
    378 
    379     writeStoreBuildTarget(t);
    380 
    381381    generateDistcleanTargets(t);
    382382
     
    408408    t << endl;
    409409
    410     generateExecutionTargets(t, debugPlatforms);
     410    t << "freeze: $(ABLD)" << endl;
     411    t << "\t$(ABLD)" << testClause << " freeze" << endl;
     412    t << endl;
     413
     414    // Abld toolchain doesn't differentiate between freezing release or debug
     415    t << "freeze-debug: freeze" << endl << endl;
     416    t << "freeze-release: freeze" << endl << endl;
     417
     418    // For more specific builds, targets are in this form: freeze-build-platform, e.g. freeze-release-armv5,
     419    // though note that debug and release targets of each platform are identical in symbian-abld.
     420    foreach(QString item, debugPlatforms) {
     421        t << "freeze-debug-" << item << ": $(ABLD)" << endl;
     422        t << "\t$(ABLD)" << testClause << " freeze " << item << endl;
     423    }
     424    foreach(QString item, releasePlatforms) {
     425        t << "freeze-release-" << item << ": $(ABLD)" << endl;
     426        t << "\t$(ABLD)" << testClause << " freeze " << item << endl;
     427    }
     428
     429    t << endl;
    411430}
    412431
     
    425444        t << WINSCW_DEPLOYMENT_TARGET ":" << endl;
    426445
    427     QString remoteTestPath = epocRoot()
    428         + QLatin1String(isRom ? "epoc32\\data\\z\\private\\" : "epoc32\\winscw\\c\\private\\")
     446    QString remoteTestPath = qt_epocRoot()
     447        + QDir::toNativeSeparators(QLatin1String(isRom ? "epoc32/data/z/private/"
     448                                                       : "epoc32/winscw/c/private/"))
    429449        + privateDirUid;
    430450    DeploymentList depList;
    431451
    432     initProjectDeploySymbian(project, depList, remoteTestPath, false,
     452    initProjectDeploySymbian(project, depList, remoteTestPath, false, true,
    433453        QLatin1String(isRom ? ROM_DEPLOYMENT_PLATFORM : EMULATOR_DEPLOYMENT_PLATFORM),
    434454        QString(), generatedDirs, generatedFiles);
     
    438458
    439459    for (int i = 0; i < depList.size(); ++i) {
     460#ifdef Q_OS_WIN32
    440461        // Xcopy prompts for selecting file or directory if target doesn't exist,
    441462        // and doesn't provide switch to force file selection. It does provide dir forcing, though,
     
    443464        t << "\t-$(XCOPY) \"" << depList.at(i).from << "\" \""
    444465          << depList.at(i).to.left(depList.at(i).to.lastIndexOf("\\") + 1) << "\"" << endl;
     466#else
     467        QString dirExists = var("QMAKE_CHK_DIR_EXISTS");
     468        QString mkdir = var("QMAKE_MKDIR");
     469        QString dir = QFileInfo(depList.at(i).to).dir().path();
     470        t << "\t-@ " << dirExists << " \""  << dir << "\" || "
     471                      << mkdir << " \"" << dir << "\"" << endl;
     472        t << "\t-$(XCOPY) \"" << QDir::toNativeSeparators(depList.at(i).from) << "\" \""
     473          << QDir::toNativeSeparators(depList.at(i).to) << "\"" << endl;
     474#endif
    445475    }
    446476
     
    454484    QStringList cleanList;
    455485    for (int i = 0; i < depList.size(); ++i) {
    456         cleanList.append(depList.at(i).to);
     486        cleanList.append(QDir::toNativeSeparators(depList.at(i).to));
    457487    }
    458488    generateCleanCommands(t, cleanList, "$(DEL_FILE)", "", "", "");
     
    464494
    465495    return true;
    466 }
    467 
    468 void SymbianAbldMakefileGenerator::writeStoreBuildTarget(QTextStream &t)
    469 {
    470     t << STORE_BUILD_TARGET ":" << endl;
    471     t << "\t@echo # ============================================================================== > " MAKE_CACHE_NAME << endl;
    472     t << "\t@echo # This file is generated by make and should not be modified by the user >> " MAKE_CACHE_NAME << endl;
    473     t << "\t@echo #  Name        : " << MAKE_CACHE_NAME << " >> " MAKE_CACHE_NAME << endl;
    474     t << "\t@echo #  Part of     : " << project->values("TARGET").join(" ") << " >> " MAKE_CACHE_NAME << endl;
    475     t << "\t@echo #  Description : This file is used to cache last build target for >> " MAKE_CACHE_NAME << endl;
    476     t << "\t@echo #                make sis target. >> " MAKE_CACHE_NAME << endl;
    477     t << "\t@echo #  Version     :  >> " MAKE_CACHE_NAME << endl;
    478     t << "\t@echo # >> " MAKE_CACHE_NAME << endl;
    479     t << "\t@echo # ============================================================================== >> " MAKE_CACHE_NAME <<  endl;
    480     t << "\t@echo. >> " MAKE_CACHE_NAME <<  endl;
    481     t << "\t@echo QT_SIS_TARGET ?= $(QT_SIS_TARGET) >> " MAKE_CACHE_NAME << endl;
    482     t << endl;
    483 
    484     generatedFiles << MAKE_CACHE_NAME;
    485496}
    486497
     
    490501    // do not get that, special deployment only makefile is generated for them if needed.
    491502    if (targetType != TypeSubdirs || addDeploymentExtension) {
    492         QString gnuMakefileName = QLatin1String("Makefile_") + uid3;
    493         removeSpecialCharacters(gnuMakefileName);
    494         gnuMakefileName.append(".mk");
     503        gnuMakefileName = QLatin1String("Makefile_") + fileInfo(mmpFileName).completeBaseName()
     504            + QLatin1String(".mk");
    495505        t << "gnumakefile " << gnuMakefileName << endl;
    496506    }
  • trunk/qmake/generators/symbian/symmake_abld.h

    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)
     
    5858    virtual void appendAbldTempDirs(QStringList& sysincspaths, QString includepath);
    5959
    60     void writeStoreBuildTarget(QTextStream &t);
    6160    bool writeDeploymentTargets(QTextStream &t, bool isRom);
    62 
     61    QString gnuMakefileName;
    6362public:
    6463
  • trunk/qmake/generators/symbian/symmake_sbsv2.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)
     
    5050
    5151// Included from tools/shared
    52 #include <symbian/epocroot.h>
     52#include <symbian/epocroot_p.h>
    5353
    5454SymbianSbsv2MakefileGenerator::SymbianSbsv2MakefileGenerator() : SymbianMakefileGenerator() { }
     
    5757#define FLM_DEST_DIR "epoc32/tools/makefile_templates/qt"
    5858#define FLM_SOURCE_DIR "/mkspecs/symbian-sbsv2/flm/qt"
     59#define PLATFORM_GCCE "gcce"
     60#define PLATFORM_WINSCW "winscw"
     61#define PLATFORM_ARM_PREFIX "arm"
     62#define BUILD_DEBUG "udeb"
     63#define BUILD_RELEASE "urel"
     64#define SBS_RVCT_PREFIX "rvct"
     65
     66static QString winscwPlatform;
     67static QString armPlatformPrefix;
     68static QString gccePlatform;
     69static QString sbsRvctPrefix;
     70
     71#if defined(Q_OS_UNIX)
     72    extern char **environ;
     73#endif
     74
     75static void fixFlmCmd(QString *cmdLine, const QMap<QString, QString> &commandsToReplace)
     76{
     77    // If commandItem starts with any $$QMAKE_* commands, do a replace for SBS equivalent.
     78    // Command replacement is done only for the start of the command or right after
     79    // concatenation operators (&& and ||), as otherwise unwanted replacements might occur.
     80    static QString cmdFind(QLatin1String("(^|&&\\s*|\\|\\|\\s*)%1"));
     81    static QString cmdReplace(QLatin1String("\\1%1"));
     82
     83    // $$escape_expand(\\n\\t) doesn't work for bld.inf files, but is often used as command
     84    // separator, so replace it with "&&" command concatenator.
     85    cmdLine->replace("\n\t", "&&");
     86
     87    // Iterate command replacements in reverse alphabetical order of keys so
     88    // that keys which are starts of other longer keys are iterated after longer keys.
     89    QMapIterator<QString, QString> cmdIter(commandsToReplace);
     90    cmdIter.toBack();
     91    while (cmdIter.hasPrevious()) {
     92        cmdIter.previous();
     93        if (cmdLine->contains(cmdIter.key()))
     94            cmdLine->replace(QRegExp(cmdFind.arg(cmdIter.key())), cmdReplace.arg(cmdIter.value()));
     95    }
     96
     97    // Sbsv2 toolchain strips all backslashes (even double ones) from option parameters, so just
     98    // assume all backslashes are directory separators and replace them with slashes.
     99    // Problem: If some command actually needs backslashes for something else than dir separator,
     100    // we are out of luck.
     101    cmdLine->replace("\\", "/");
     102}
    59103
    60104// Copies Qt FLMs to correct location under epocroot.
     
    68112        QFileInfoList sourceInfos = sourceDir.entryInfoList(QDir::Files);
    69113
    70         QDir destDir(epocRoot() + FLM_DEST_DIR);
     114        QDir destDir(qt_epocRoot() + FLM_DEST_DIR);
    71115        if (!destDir.exists()) {
    72116            if (destDir.mkpath(destDir.absolutePath()))
     
    91135}
    92136
     137void SymbianSbsv2MakefileGenerator::findInstalledCompilerVersions(const QString &matchExpression,
     138                                                                  const QString &versionPrefix,
     139                                                                  QStringList *versionList)
     140{
     141    // No need to be able to find env variables on other operating systems,
     142    // as only linux and windows have support for symbian-sbsv2 toolchain
     143#if defined(Q_OS_UNIX) || defined(Q_OS_WIN)
     144    char *entry = 0;
     145    int count = 0;
     146    QRegExp matcher(matchExpression);
     147    while ((entry = environ[count++])) {
     148        if (matcher.exactMatch(QString::fromLocal8Bit(entry))
     149            && fileInfo(matcher.cap(matcher.captureCount())).exists()) {
     150            // First capture (index 0) is the whole match, which is skipped.
     151            // Next n captures are version numbers, which are interesting.
     152            // Final capture is the env var value, which we already used, so that is skipped, too.
     153            int capture = 1;
     154            int finalCapture = matcher.captureCount() - 1;
     155            QString version = versionPrefix;
     156            while (capture <= finalCapture) {
     157                version.append(matcher.cap(capture));
     158                if (capture != finalCapture)
     159                    version.append(QLatin1Char('.'));
     160                capture++;
     161            }
     162            *versionList << version;
     163        }
     164    }
     165#endif
     166}
     167
     168void SymbianSbsv2MakefileGenerator::findGcceVersions(QStringList *gcceVersionList,
     169                                                     QString *defaultVersion)
     170{
     171    QString matchStr = QLatin1String("SBS_GCCE(\\d)(\\d)(\\d)BIN=(.*)");
     172    findInstalledCompilerVersions(matchStr, gccePlatform, gcceVersionList);
     173
     174    QString qtGcceVersion = QString::fromLocal8Bit(qgetenv("QT_GCCE_VERSION"));
     175
     176    if (!qtGcceVersion.isEmpty()) {
     177        if (QRegExp("\\d+\\.\\d+\\.\\d+").exactMatch(qtGcceVersion)) {
     178            *defaultVersion = gccePlatform + qtGcceVersion;
     179        } else {
     180            fprintf(stderr, "Warning: Variable QT_GCCE_VERSION ('%s') is in incorrect "
     181                    "format, expected format is: 'x.y.z'. Attempting to autodetect GCCE version.\n",
     182                    qPrintable(qtGcceVersion));
     183        }
     184    }
     185
     186    if (defaultVersion->isEmpty() && gcceVersionList->size()) {
     187        gcceVersionList->sort();
     188        *defaultVersion = gcceVersionList->last();
     189    }
     190}
     191
     192void SymbianSbsv2MakefileGenerator::findRvctVersions(QStringList *rvctVersionList,
     193                                                     QString *defaultVersion)
     194{
     195    QString matchStr = QLatin1String("RVCT(\\d)(\\d)BIN=(.*)");
     196    findInstalledCompilerVersions(matchStr, sbsRvctPrefix, rvctVersionList);
     197
     198    QString qtRvctVersion = QString::fromLocal8Bit(qgetenv("QT_RVCT_VERSION"));
     199
     200    if (!qtRvctVersion.isEmpty()) {
     201        if (QRegExp("\\d+\\.\\d+").exactMatch(qtRvctVersion)) {
     202            *defaultVersion = sbsRvctPrefix + qtRvctVersion;
     203        } else {
     204            fprintf(stderr, "Warning: Variable QT_RVCT_VERSION ('%s') is in incorrect "
     205                    "format, expected format is: 'x.y'.\n",
     206                    qPrintable(qtRvctVersion));
     207        }
     208    }
     209}
     210
     211QString SymbianSbsv2MakefileGenerator::configClause(const QString &platform,
     212                                                    const QString &build,
     213                                                    const QString &compilerVersion,
     214                                                    const QString &clauseTemplate)
     215{
     216    QString retval;
     217    if (QString::compare(platform, winscwPlatform) == 0) {
     218        retval = clauseTemplate.arg(build);
     219    } else if (platform.startsWith(armPlatformPrefix)) {
     220        QString fixedCompilerVersion = compilerVersion;
     221        fixedCompilerVersion.replace(".","_");
     222        retval = clauseTemplate.arg(platform.mid(sizeof(PLATFORM_ARM_PREFIX)-1))
     223                                  .arg(build)
     224                                  .arg(fixedCompilerVersion);
     225    } // else - Unsupported platform for makefile target, return empty clause
     226    return retval;
     227}
     228
    93229void SymbianSbsv2MakefileGenerator::writeSbsDeploymentList(const DeploymentList& depList, QTextStream& t)
    94230{
     
    100236        toItem.replace("\\", "/");
    101237#if defined(Q_OS_WIN)
    102         toItem.prepend(QDir::current().absolutePath().left(2)); // add drive
     238        // add drive if it doesn't have one yet
     239        if (toItem.size() > 1 && toItem[1] != QLatin1Char(':'))
     240            toItem.prepend(QDir::current().absolutePath().left(2));
    103241#endif
    104242        t << "OPTION DEPLOY_SOURCE " << fromItem << endl;
     
    117255void SymbianSbsv2MakefileGenerator::writeWrapperMakefile(QFile& wrapperFile, bool isPrimaryMakefile)
    118256{
     257    static QString debugBuild;
     258    static QString releaseBuild;
     259    static QString defaultGcceCompilerVersion;
     260    static QString defaultRvctCompilerVersion;
     261    static QStringList rvctVersions;
     262    static QStringList gcceVersions;
     263    static QStringList allArmCompilerVersions;
     264
     265    // Initialize static variables used in makefile creation
     266    if (debugBuild.isEmpty()) {
     267        debugBuild.append(QLatin1String(BUILD_DEBUG));
     268        releaseBuild.append(QLatin1String(BUILD_RELEASE));
     269        winscwPlatform.append(QLatin1String(PLATFORM_WINSCW));
     270        gccePlatform.append(QLatin1String(PLATFORM_GCCE));
     271        armPlatformPrefix.append(QLatin1String(PLATFORM_ARM_PREFIX));
     272        sbsRvctPrefix.append(QLatin1String(SBS_RVCT_PREFIX));
     273
     274        findGcceVersions(&gcceVersions, &defaultGcceCompilerVersion);
     275        findRvctVersions(&rvctVersions, &defaultRvctCompilerVersion);
     276
     277        allArmCompilerVersions << rvctVersions << gcceVersions;
     278
     279        if (!allArmCompilerVersions.size()) {
     280            fprintf(stderr, "Warning: No HW compilers detected. "
     281                    "Please install either GCCE or RVCT compiler to enable release builds.\n");
     282        }
     283    }
     284
    119285    QStringList allPlatforms;
    120286    foreach(QString platform, project->values("SYMBIAN_PLATFORMS")) {
     
    122288    }
    123289
    124     QStringList debugPlatforms = allPlatforms;
    125     QStringList releasePlatforms = allPlatforms;
    126     releasePlatforms.removeAll("winscw"); // No release for emulator
     290    if (!gcceVersions.size())
     291        allPlatforms.removeAll(gccePlatform);
    127292
    128293    QString testClause;
     
    132297        testClause = QLatin1String("");
    133298
     299    // Note: armClause is used for gcce, too, which has a side effect
     300    //       of requiring armv* platform(s) in SYMBIAN_PLATFORMS in order
     301    //       to get any compiler version specific targets.
     302    QString armClause = " -c " PLATFORM_ARM_PREFIX ".%1.%2.%3" + testClause;
     303    QString genericArmClause;
     304    if (defaultRvctCompilerVersion.isEmpty()) {
     305        // Note: Argument %3 needs to be empty string in this version of clause
     306        genericArmClause = " -c " PLATFORM_ARM_PREFIX "%1_%2%3" + testClause;
     307    } else {
     308        // If defaultRvctCompilerVersion is defined, use specific sbs clause for "generic" clause
     309        genericArmClause = armClause;
     310    }
     311    QString winscwClause = " -c " PLATFORM_WINSCW "_%1.mwccinc" + testClause;;
     312
     313    QStringList armPlatforms = allPlatforms.filter(QRegExp("^" PLATFORM_ARM_PREFIX));
     314
     315    if (!allArmCompilerVersions.size()) {
     316        foreach (QString item, armPlatforms) {
     317            allPlatforms.removeAll(item);
     318        }
     319        armPlatforms.clear();
     320    }
     321
     322    QStringList allClauses;
     323    QStringList debugClauses;
     324    QStringList releaseClauses;
     325
     326    // Only winscw and arm platforms are supported
     327    QStringList debugPlatforms = allPlatforms;
     328    QStringList releasePlatforms = allPlatforms;
     329    releasePlatforms.removeAll(winscwPlatform); // No release for emulator
     330
     331    if (!releasePlatforms.size()) {
     332        fprintf(stderr, "Warning: No valid release platforms in SYMBIAN_PLATFORMS (%s)\n"
     333                "Most likely required compiler(s) are not properly installed.\n",
     334                qPrintable(project->values("SYMBIAN_PLATFORMS").join(" ")));
     335    }
     336
     337    if (debugPlatforms.contains(winscwPlatform))
     338        debugClauses << configClause(winscwPlatform, debugBuild, QString(), winscwClause);
     339
     340    foreach(QString item, armPlatforms) {
     341        // Only use single clause per arm platform even if multiple compiler versions were found,
     342        // otherwise we get makefile target collisions from sbsv2 toolchain.
     343        if (rvctVersions.size()) {
     344            debugClauses << configClause(item, debugBuild, defaultRvctCompilerVersion, genericArmClause);
     345            releaseClauses << configClause(item, releaseBuild, defaultRvctCompilerVersion, genericArmClause);
     346        } else {
     347            debugClauses << configClause(item, debugBuild, defaultGcceCompilerVersion, armClause);
     348            releaseClauses << configClause(item, releaseBuild, defaultGcceCompilerVersion, armClause);
     349        }
     350    }
     351
     352    allClauses << debugClauses << releaseClauses;
     353
    134354    QTextStream t(&wrapperFile);
    135355
    136     t << "# ==============================================================================" << endl;
    137     t << "# Generated by qmake (" << qmake_version() << ") (Qt " << QT_VERSION_STR << ") on: ";
    138     t << QDateTime::currentDateTime().toString() << endl;
    139     t << "# This file is generated by qmake and should not be modified by the" << endl;
    140     t << "# user." << endl;
    141     t << "#  Name        : " << wrapperFile.fileName() << endl;
    142     t << "#  Description : Wrapper Makefile for calling Symbian build tools" << endl;
    143     t << "#" << endl;
    144     t << "# ==============================================================================" << "\n" << endl;
    145     t << endl;
    146     t << "MAKEFILE          = " << wrapperFile.fileName() << endl;
    147     t << "QMAKE             = " << Option::fixPathToTargetOS(var("QMAKE_QMAKE")) << endl;
     356    MakefileGenerator::writeHeader(t);
     357
     358    t << "MAKEFILE          = " << fileInfo(wrapperFile.fileName()).fileName() << endl;
     359    t << "QMAKE             = " << var("QMAKE_QMAKE") << endl;
    148360    t << "DEL_FILE          = " << var("QMAKE_DEL_FILE") << endl;
    149361    t << "DEL_DIR           = " << var("QMAKE_DEL_DIR") << endl;
     
    169381        }
    170382    }
     383
    171384    t << endl;
    172     t << "first: default" << endl;
    173     if (debugPlatforms.contains("winscw"))
    174         t << "default: debug-winscw";
    175     else if (debugPlatforms.contains("armv5"))
    176         t << "default: debug-armv5";
    177     else if (debugPlatforms.size())
    178         t << "default: debug-" << debugPlatforms.first();
    179     else
    180         t << "default: all";
    181 
    182     t << endl;
     385    t << "first: default" << endl << endl;
    183386    if (!isPrimaryMakefile) {
    184         t << "all:" << endl;
     387        t << "all:" << endl << endl;
     388        t << "default: all" << endl << endl;
    185389    } else {
    186         t << "all: debug release" << endl;
    187         t << endl;
     390        t << "all: debug release" << endl << endl;
     391        if (debugPlatforms.contains(winscwPlatform))
     392            t << "default: debug-winscw";
     393        else if (debugPlatforms.size())
     394            t << "default: debug-" << debugPlatforms.first();
     395        else
     396            t << "default: all";
     397        t << endl;
     398
     399        QString qmakeCmd = "\t$(QMAKE) \"" + project->projectFile() + "\" " + buildArgs();
     400
    188401        t << "qmake:" << endl;
    189         t << "\t$(QMAKE) -spec symbian-sbsv2 -o \"" << fileInfo(Option::output.fileName()).fileName()
    190           << "\" \"" << project->projectFile() << "\"" << endl;
    191         t << endl;
    192         t << BLD_INF_FILENAME ":" << endl;
    193         t << "\t$(QMAKE)" << endl;
    194         t << endl;
    195 
    196         QString winscw("winscw");
    197         t << "debug: " << BLD_INF_FILENAME << endl;
     402        t << qmakeCmd << endl;
     403        t << endl;
     404
     405        t << BLD_INF_FILENAME ": " << project->projectFile() << endl;
     406        t << qmakeCmd << endl;
     407        t << endl;
     408
     409        QString locFileDep = generateLocFileTarget(t, qmakeCmd);
     410
     411        t << "debug: " << locFileDep << BLD_INF_FILENAME << endl;
    198412        t << "\t$(SBS)";
     413        foreach(QString clause, debugClauses) {
     414            t << clause;
     415        }
     416        t << endl;
     417        t << "clean-debug: " << BLD_INF_FILENAME << endl;
     418        t << "\t$(SBS) reallyclean --toolcheck=off";
     419        foreach(QString clause, debugClauses) {
     420            t << clause;
     421        }
     422        t << endl;
     423
     424        t << "freeze-debug: " << BLD_INF_FILENAME << endl;
     425        t << "\t$(SBS) freeze";
     426        foreach(QString clause, debugClauses) {
     427            t << clause;
     428        }
     429        t << endl;
     430
     431        t << "release: " << locFileDep << BLD_INF_FILENAME << endl;
     432        t << "\t$(SBS)";
     433        foreach(QString clause, releaseClauses) {
     434            t << clause;
     435        }
     436        t << endl;
     437        t << "clean-release: " << BLD_INF_FILENAME << endl;
     438        t << "\t$(SBS) reallyclean --toolcheck=off";
     439        foreach(QString clause, releaseClauses) {
     440            t << clause;
     441        }
     442        t << endl;
     443
     444        t << "freeze-release: " << BLD_INF_FILENAME << endl;
     445        t << "\t$(SBS) freeze";
     446        foreach(QString clause, releaseClauses) {
     447            t << clause;
     448        }
     449        t << endl << endl;
     450
     451        QString defaultGcceArmVersion;
     452        if (armPlatforms.size()) {
     453            defaultGcceArmVersion = armPlatforms.first();
     454        } else {
     455            defaultGcceArmVersion = QLatin1String("armv5");
     456        }
     457
     458        // For more specific builds, targets are in this form:
     459        // release-armv5 - generic target, compiler version determined by toolchain or autodetection
     460        // release-armv5-rvct4.0 - compiler version specific target
    199461        foreach(QString item, debugPlatforms) {
    200             if(QString::compare(item, winscw) == 0)
    201                 t << " -c " << item << "_udeb.mwccinc" << testClause;
    202             else
    203                 t << " -c " << item << "_udeb" << testClause;
    204         }
    205         t << endl;
    206         t << "release: " << BLD_INF_FILENAME << endl;
    207         t << "\t$(SBS)";
     462            QString clause;
     463            if (item.compare(winscwPlatform) == 0)
     464                clause = configClause(item, debugBuild, QString(), winscwClause);
     465            else if (item.compare(gccePlatform) == 0 )
     466                clause = configClause(defaultGcceArmVersion, debugBuild, defaultGcceCompilerVersion, armClause);
     467            else // use generic arm clause
     468                clause = configClause(item, debugBuild, defaultRvctCompilerVersion, genericArmClause);
     469
     470            t << "debug-" << item << ": " << locFileDep << BLD_INF_FILENAME << endl;
     471            t << "\t$(SBS)" << clause << endl;
     472            t << "clean-debug-" << item << ": " << BLD_INF_FILENAME << endl;
     473            t << "\t$(SBS) reallyclean" << clause << endl;
     474            t << "freeze-debug-" << item << ": " << BLD_INF_FILENAME << endl;
     475            t << "\t$(SBS) freeze" << clause << endl;
     476        }
     477
    208478        foreach(QString item, releasePlatforms) {
    209             if(QString::compare(item, winscw) == 0)
    210                 t << " -c " << item << "_urel.mwccinc" << testClause;
    211             else
    212                 t << " -c " << item << "_urel" << testClause;
    213         }
    214         t << endl;
    215 
    216         // For more specific builds, targets are in this form: build-platform, e.g. release-armv5
    217         foreach(QString item, debugPlatforms) {
    218             t << "debug-" << item << ": " << BLD_INF_FILENAME << endl;
    219             if(QString::compare(item, winscw) == 0)
    220                 t << "\t$(SBS) -c " << item << "_udeb.mwccinc" << testClause << endl;
    221             else
    222                 t << "\t$(SBS) -c " << item << "_udeb" << testClause << endl;
    223         }
    224 
    225         foreach(QString item, releasePlatforms) {
    226             t << "release-" << item << ": " << BLD_INF_FILENAME << endl;
    227             if(QString::compare(item, winscw) == 0)
    228                 t << "\t$(SBS) -c " << item << "_urel.mwccinc" << testClause << endl;
    229             else
    230                 t << "\t$(SBS) -c " << item << "_urel" << testClause << endl;
     479            QString clause;
     480            if (item.compare(gccePlatform) == 0 )
     481                clause = configClause(defaultGcceArmVersion, releaseBuild, defaultGcceCompilerVersion, armClause);
     482            else // use generic arm clause
     483                clause = configClause(item, releaseBuild, defaultRvctCompilerVersion, genericArmClause);
     484
     485            t << "release-" << item << ": " << locFileDep << BLD_INF_FILENAME << endl;
     486            t << "\t$(SBS)" << clause << endl;
     487            t << "clean-release-" << item << ": " << BLD_INF_FILENAME << endl;
     488            t << "\t$(SBS) reallyclean" << clause << endl;
     489            t << "freeze-release-" << item << ": " << BLD_INF_FILENAME << endl;
     490            t << "\t$(SBS) freeze" << clause << endl;
     491        }
     492
     493        foreach(QString item, armPlatforms) {
     494            foreach(QString compilerVersion, allArmCompilerVersions) {
     495                QString debugClause = configClause(item, debugBuild, compilerVersion, armClause);
     496                QString releaseClause = configClause(item, releaseBuild, compilerVersion, armClause);
     497                t << "debug-" << item << "-" << compilerVersion << ": " << locFileDep << BLD_INF_FILENAME << endl;
     498                t << "\t$(SBS)" << debugClause << endl;
     499                t << "clean-debug-" << item << "-" << compilerVersion << ": " << BLD_INF_FILENAME << endl;
     500                t << "\t$(SBS) reallyclean" << debugClause << endl;
     501                t << "freeze-debug-" << item << "-" << compilerVersion << ": " << BLD_INF_FILENAME << endl;
     502                t << "\t$(SBS) freeze" << debugClause << endl;
     503                t << "release-" << item << "-" << compilerVersion << ": " << locFileDep << BLD_INF_FILENAME << endl;
     504                t << "\t$(SBS)" << releaseClause << endl;
     505                t << "clean-release-" << item << "-" << compilerVersion << ": " << BLD_INF_FILENAME << endl;
     506                t << "\t$(SBS) reallyclean" << releaseClause << endl;
     507                t << "freeze-release-" << item << "-" << compilerVersion << ": " << BLD_INF_FILENAME << endl;
     508                t << "\t$(SBS) freeze" << releaseClause << endl;
     509            }
    231510        }
    232511
    233512        t << endl;
    234513        t << "export: " << BLD_INF_FILENAME << endl;
    235         t << "\t$(SBS) export" << endl;
    236         t << endl;
     514        t << "\t$(SBS) export";
     515        foreach(QString clause, allClauses) {
     516            t << clause;
     517        }
     518        t << endl << endl;
    237519
    238520        t << "cleanexport: " << BLD_INF_FILENAME << endl;
    239         t << "\t$(SBS) cleanexport" << endl;
    240         t << endl;
    241 
    242     }
    243 
    244     // Add all extra targets including extra compiler targest also to wrapper makefile,
     521        t << "\t$(SBS) cleanexport";
     522        foreach(QString clause, allClauses) {
     523            t << clause;
     524        }
     525        t << endl << endl;
     526
     527        // Typically one wants to freeze release binaries, so make plain freeze target equal to
     528        // freeze-release. If freezing of debug binaries is needed for some reason, then
     529        // freeze-debug target should be used. There is no point to try freezing both with one
     530        // target as both produce the same def file.
     531        t << "freeze: freeze-release" << endl << endl;
     532    }
     533
     534    // Add all extra targets including extra compiler targets also to wrapper makefile,
    245535    // even though many of them may have already been added to bld.inf as FLMs.
    246536    // This is to enable use of targets like 'mocables', which call targets generated by extra compilers.
     
    254544    }
    255545
    256     writeSisTargets(t);
    257 
    258546    generateDistcleanTargets(t);
    259547
     548    // Do not check for tools when doing generic clean, as most tools are not actually needed for
     549    // cleaning. Mainly this is relevant for environments that do not have winscw compiler.
    260550    t << "clean: " << BLD_INF_FILENAME << endl;
    261     t << "\t-$(SBS) reallyclean" << endl;
     551    t << "\t-$(SBS) reallyclean --toolcheck=off";
     552    foreach(QString clause, allClauses) {
     553        t << clause;
     554    }
     555    t << endl << endl;
     556
    262557    t << endl;
    263 
    264     t << "clean-debug: " << BLD_INF_FILENAME << endl;
    265     t << "\t$(SBS) reallyclean";
    266     foreach(QString item, debugPlatforms) {
    267         t << " -c " << item << "_udeb" << testClause;
    268     }
    269     t << endl;
    270     t << "clean-release: " << BLD_INF_FILENAME << endl;
    271     t << "\t$(SBS) reallyclean";
    272     foreach(QString item, releasePlatforms) {
    273         t << " -c " << item << "_urel" << testClause;
    274     }
    275     t << endl;
    276 
    277     // For more specific builds, targets are in this form: clean-build-platform, e.g. clean-release-armv5
    278     foreach(QString item, debugPlatforms) {
    279         t << "clean-debug-" << item << ": " << BLD_INF_FILENAME << endl;
    280         t << "\t$(SBS) reallyclean -c " << item << "_udeb" << testClause << endl;
    281     }
    282     foreach(QString item, releasePlatforms) {
    283         t << "clean-release-" << item << ": " << BLD_INF_FILENAME << endl;
    284         t << "\t$(SBS) reallyclean -c " << item << "_urel" << testClause << endl;
    285     }
    286     t << endl;
    287 
    288     generateExecutionTargets(t, debugPlatforms);
    289558}
    290559
     
    308577    }
    309578
     579    QMap<QString, QString> commandsToReplace;
     580    commandsToReplace.insert(project->values("QMAKE_COPY").join(" "),
     581                             project->values("QMAKE_SBSV2_COPY").join(" "));
     582    commandsToReplace.insert(project->values("QMAKE_COPY_DIR").join(" "),
     583                             project->values("QMAKE_SBSV2_COPY_DIR").join(" "));
     584    commandsToReplace.insert(project->values("QMAKE_MOVE").join(" "),
     585                             project->values("QMAKE_SBSV2_MOVE").join(" "));
     586    commandsToReplace.insert(project->values("QMAKE_DEL_FILE").join(" "),
     587                             project->values("QMAKE_SBSV2_DEL_FILE").join(" "));
     588    commandsToReplace.insert(project->values("QMAKE_MKDIR").join(" "),
     589                             project->values("QMAKE_SBSV2_MKDIR").join(" "));
     590    commandsToReplace.insert(project->values("QMAKE_DEL_DIR").join(" "),
     591                             project->values("QMAKE_SBSV2_DEL_DIR").join(" "));
     592    commandsToReplace.insert(project->values("QMAKE_DEL_TREE").join(" "),
     593                             project->values("QMAKE_SBSV2_DEL_TREE").join(" "));
     594
    310595    // Write extra compilers and targets to initialize QMAKE_ET_* variables
    311596    // Cache results to avoid duplicate calls when creating wrapper makefile
     
    319604    QStringList allPreDeps;
    320605    foreach(QString item, project->values("PRE_TARGETDEPS")) {
    321         // Predeps get mangled in windows, so fix them to more sbsv2 friendly format
    322 #if defined(Q_OS_WIN)
    323         if (item.mid(1, 1) == ":")
    324             item = item.mid(0, 1).toUpper().append(item.mid(1)); // Fix drive to uppercase
    325 #endif
    326         item.replace("\\", "/");
    327         allPreDeps << escapeDependencyPath(item);
     606        allPreDeps.append(fileInfo(item).absoluteFilePath());
    328607    }
    329608
     
    355634                QString commandItem =  project->values(QLatin1String("QMAKE_INTERNAL_ET_PARSED_CMD.") + item + targetItem).join(" ");
    356635
    357 
    358636                // Make sure all deps paths are absolute
    359637                QString absoluteDeps;
     
    374652                    commandItem.replace("$(DEFINES)", defines.join(" "));
    375653
    376                 // Sbsv2 strips all backslashes (even doubles ones) from option parameters, so just replace them with slashes
    377                 // Problem: If some command actually needs backslashes for something else than dir separator, we are out of luck...
    378                 commandItem.replace("\\", "/");
     654                fixFlmCmd(&commandItem, commandsToReplace);
     655
    379656                t << "OPTION COMMAND " << commandItem << endl;
    380657                t << "END" << endl;
     
    386663
    387664    // Write deployment rules
    388     QString remoteTestPath = epocRoot() + QLatin1String("epoc32/winscw/c/private/") + privateDirUid;
     665    QString remoteTestPath = qt_epocRoot() + QLatin1String("epoc32/winscw/c/private/") + privateDirUid;
    389666    DeploymentList depList;
    390667
    391668    //write emulator deployment
    392669    t << "#if defined(WINSCW)" << endl;
    393     initProjectDeploySymbian(project, depList, remoteTestPath, false,
     670    initProjectDeploySymbian(project, depList, remoteTestPath, false, true,
    394671        QLatin1String(EMULATOR_DEPLOYMENT_PLATFORM), QString(), generatedDirs, generatedFiles);
    395672    writeSbsDeploymentList(depList, t);
     
    397674
    398675    //write ROM deployment
    399     remoteTestPath = epocRoot() + QLatin1String("epoc32/data/z/private/") + privateDirUid;
     676    remoteTestPath = qt_epocRoot() + QLatin1String("epoc32/data/z/private/") + privateDirUid;
    400677    depList.clear();
    401     initProjectDeploySymbian(project, depList, remoteTestPath, false,
     678    initProjectDeploySymbian(project, depList, remoteTestPath, false, true,
    402679        QLatin1String(ROM_DEPLOYMENT_PLATFORM), QString(), generatedDirs, generatedFiles);
    403680    writeSbsDeploymentList(depList, t);
     
    406683    // Write post link rules
    407684    if (!project->isEmpty("QMAKE_POST_LINK")) {
     685        QString postLinkCmd = var("QMAKE_POST_LINK");
     686        fixFlmCmd(&postLinkCmd, commandsToReplace);
    408687        t << "START EXTENSION qt/qmake_post_link" << endl;
    409         t << "OPTION POST_LINK_CMD " << var("QMAKE_POST_LINK") << endl;
    410         t << "OPTION LINK_TARGET " << removePathSeparators(escapeFilePath(fileFixify(project->first("TARGET"))).append(".").append(getTargetExtension())) << endl;
     688        t << "OPTION POST_LINK_CMD " << postLinkCmd << endl;
     689        t << "OPTION LINK_TARGET " << fixedTarget << QLatin1String(".") << getTargetExtension() << endl;
    411690        t << "END" << endl;
    412691        t << endl;
  • trunk/qmake/generators/symbian/symmake_sbsv2.h

    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)
     
    5757    virtual void writeWrapperMakefile(QFile& wrapperFile, bool isPrimaryMakefile);
    5858    virtual void appendAbldTempDirs(QStringList& sysincspaths, QString includepath);
     59    virtual bool isForSymbianSbsv2() const { return true; } // FIXME: killme - i'm ugly!
    5960
    6061public:
     
    6566private:
    6667    void exportFlm();
     68    void findGcceVersions(QStringList *gcceVersionList, QString *defaultVersion);
     69    void findRvctVersions(QStringList *rvctVersionList, QString *defaultVersion);
     70    void findInstalledCompilerVersions(const QString &matchExpression,
     71                                       const QString &versionPrefix,
     72                                       QStringList *versionList);
     73    QString configClause(const QString &platform,
     74                         const QString &build,
     75                         const QString &compilerVersion,
     76                         const QString &clauseTemplate);
     77
    6778    void writeSbsDeploymentList(const DeploymentList& depList, QTextStream& t);
    6879
Note: See TracChangeset for help on using the changeset viewer.