Changeset 846 for trunk/qmake/generators


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

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

Location:
trunk
Files:
2 deleted
36 edited
7 copied

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/qmake/generators/mac/pbuilder_pbx.cpp

    r651 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)
     
    524524            QTextStream mkt(&mkf);
    525525            writeHeader(mkt);
    526             mkt << "QMAKE    = "        << (project->isEmpty("QMAKE_QMAKE") ?
    527                                             QString((QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmake")) :
    528                                             var("QMAKE_QMAKE")) << endl;
     526            mkt << "QMAKE    = " << var("QMAKE_QMAKE") << endl;
    529527            writeMakeQmake(mkt);
    530528            mkt.flush();
     
    543541          << "\t\t\t" << writeSettings("neededFileNames", QStringList(), SettingsAsList, 4) << ";" << "\n"
    544542          << "\t\t\t" << writeSettings("shellPath", "/bin/sh") << ";" << "\n"
    545           << "\t\t\t" << writeSettings("shellScript", fixForOutput("make -C " + escapeFilePath(qmake_getpwd()) + " -f " + escapeFilePath(mkfile))) << ";" << "\n"
     543          << "\t\t\t" << writeSettings("shellScript", fixForOutput("make -C " + escapeFilePath(qmake_getpwd()) + " -f '" + escapeFilePath(mkfile) + "'")) << ";" << "\n"
    546544          << "\t\t" << "};" << "\n";
    547545    }
     
    792790          << "\t\t\t" << writeSettings("neededFileNames", fixListForOutput("QMAKE_PBX_OBJ"), SettingsAsList, 4) << ";" << "\n"
    793791          << "\t\t\t" << writeSettings("shellPath", "/bin/sh") << ";" << "\n"
    794           << "\t\t\t" << writeSettings("shellScript", fixForOutput("make -C " + escapeFilePath(qmake_getpwd()) + " -f " + escapeFilePath(mkfile))) << ";" << "\n"
     792          << "\t\t\t" << writeSettings("shellScript", fixForOutput("make -C " + escapeFilePath(qmake_getpwd()) + " -f '" + escapeFilePath(mkfile) + "'")) << ";" << "\n"
    795793          << "\t\t" << "};" << "\n";
    796794   }
     
    971969          << "\t\t\t" << writeSettings("neededFileNames", QStringList(), SettingsAsList, 4) << ";" << "\n"
    972970          << "\t\t\t" << writeSettings("shellPath", "/bin/sh") << "\n"
    973           << "\t\t\t" << writeSettings("shellScript", fixForOutput("make -C " + escapeFilePath(qmake_getpwd()) + " -f " + escapeFilePath(mkfile))) << ";" << "\n"
     971          << "\t\t\t" << writeSettings("shellScript", fixForOutput("make -C " + escapeFilePath(qmake_getpwd()) + " -f '" + escapeFilePath(mkfile) + "'")) << ";" << "\n"
    974972          << "\t\t" << "};" << "\n";
    975973    }
  • trunk/qmake/generators/mac/pbuilder_pbx.h

    r651 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)
  • trunk/qmake/generators/makefile.cpp

    r773 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)
     
    467467        const QStringList &subs = v["QMAKE_SUBSTITUTES"];
    468468        for(int i = 0; i < subs.size(); ++i) {
    469             if(!subs.at(i).endsWith(".in")) {
    470                 warn_msg(WarnLogic, "Substitute '%s' does not end with '.in'",
    471                          subs.at(i).toLatin1().constData());
    472                 continue;
    473             }
    474             QFile in(fileFixify(subs.at(i))), out(fileInfo(subs.at(i)).fileName());
    475             if(out.fileName().endsWith(".in"))
    476                 out.setFileName(out.fileName().left(out.fileName().length()-3));
     469            QString inn = subs.at(i) + ".input", outn = subs.at(i) + ".output";
     470            if (v.contains(inn) || v.contains(outn)) {
     471                if (!v.contains(inn) || !v.contains(outn)) {
     472                    warn_msg(WarnLogic, "Substitute '%s' has only one of .input and .output",
     473                             subs.at(i).toLatin1().constData());
     474                    continue;
     475                }
     476                const QStringList &tinn = v[inn], &toutn = v[outn];
     477                if (tinn.length() != 1) {
     478                    warn_msg(WarnLogic, "Substitute '%s.input' does not have exactly one value",
     479                             subs.at(i).toLatin1().constData());
     480                    continue;
     481                }
     482                if (toutn.length() != 1) {
     483                    warn_msg(WarnLogic, "Substitute '%s.output' does not have exactly one value",
     484                             subs.at(i).toLatin1().constData());
     485                    continue;
     486                }
     487                inn = tinn.first();
     488                outn = toutn.first();
     489            } else {
     490                inn = subs.at(i);
     491                if(!inn.endsWith(".in")) {
     492                    warn_msg(WarnLogic, "Substitute '%s' does not end with '.in'",
     493                             inn.toLatin1().constData());
     494                    continue;
     495                }
     496                outn = inn.left(inn.length()-3);
     497            }
     498            QFile in(fileFixify(inn));
     499            QFile out(fileFixify(outn, qmake_getpwd(), Option::output_dir));
    477500            if(in.open(QFile::ReadOnly)) {
    478501                QString contents;
     
    529552                    QString old = QString::fromUtf8(out.readAll());
    530553                    if(contents == old) {
    531                         v["QMAKE_INTERNAL_INCLUDED_FILES"].append(subs.at(i));
     554                        v["QMAKE_INTERNAL_INCLUDED_FILES"].append(in.fileName());
    532555                        continue;
    533556                    }
     
    539562                    }
    540563                }
     564                mkdir(QFileInfo(out).absolutePath());
    541565                if(out.open(QFile::WriteOnly)) {
    542                     v["QMAKE_INTERNAL_INCLUDED_FILES"].append(subs.at(i));
     566                    v["QMAKE_INTERNAL_INCLUDED_FILES"].append(in.fileName());
    543567                    out.write(contents.toUtf8());
    544568                } else {
     
    807831
    808832    // escape qmake command
    809     if (!project->isEmpty("QMAKE_QMAKE")) {
    810         project->values("QMAKE_QMAKE") = escapeFilePaths(project->values("QMAKE_QMAKE"));
    811     }
     833    QStringList &qmk = project->values("QMAKE_QMAKE");
     834    qmk = escapeFilePaths(qmk);
    812835}
    813836
     
    9821005                libs << "QMAKE_LIBS_PRIVATE";
    9831006            for(QStringList::Iterator it = libs.begin(); it != libs.end(); ++it)
    984                 t << project->values((*it)).join(" ") << " ";
     1007                t << project->values((*it)).join(" ").replace('\\', "\\\\") << " ";
    9851008        }
    9861009        t << endl;
     
    12761299                if(!dirstr.endsWith(Option::dir_sep))
    12771300                    dirstr += Option::dir_sep;
    1278                 if(exists(wild)) { //real file
     1301                bool is_target = (wild == fileFixify(var("TARGET"), FileFixifyAbsolute));
     1302                if(is_target || exists(wild)) { //real file or target
    12791303                    QString file = wild;
    12801304                    QFileInfo fi(fileInfo(wild));
     
    12901314                    if (fi.isDir())
    12911315                       cmd = inst_prefix + "$(INSTALL_DIR)";
    1292                     else if (fi.isExecutable())
     1316                    else if (is_target || fi.isExecutable())
    12931317                       cmd = inst_prefix + "$(INSTALL_PROGRAM)";
    12941318                    else
     
    17861810        QStringList tmp_dep = project->values((*it) + ".depends");
    17871811        QString tmp_dep_cmd;
     1812        QString dep_cd_cmd;
    17881813        if(!project->isEmpty((*it) + ".depend_command")) {
    17891814            int argv0 = -1;
     
    17991824                if(exists(c)) {
    18001825                    cmdline[argv0] = escapeFilePath(Option::fixPathToLocalOS(cmdline.at(argv0), false));
    1801                     tmp_dep_cmd = cmdline.join(" ");
    18021826                } else {
    18031827                    cmdline[argv0] = escapeFilePath(cmdline.at(argv0));
    18041828                }
    1805             }
     1829                QFileInfo cmdFileInfo(cmdline[argv0]);
     1830                if (!cmdFileInfo.isAbsolute() || cmdFileInfo.exists())
     1831                    tmp_dep_cmd = cmdline.join(" ");
     1832            }
     1833            dep_cd_cmd = QLatin1String("cd ")
     1834                 + escapeFilePath(Option::fixPathToLocalOS(Option::output_dir, false))
     1835                 + QLatin1String(" && ");
    18061836        }
    18071837        QStringList &vars = project->values((*it) + ".variables");
     
    18601890            if(tmp_clean.indexOf("${QMAKE_") == -1) {
    18611891                t << "\n\t" << del_statement << " " << tmp_clean << del_suffix;
    1862                 if (isForSymbian())
    1863                     t << " 2> NUL"; // Eliminate unnecessary warnings
    18641892                wrote_clean = true;
    18651893            }
     
    19191947                    QString dep_cmd = replaceExtraCompilerVariables(tmp_dep_cmd, (*input),
    19201948                                                                    tmp_out);
    1921                     dep_cmd = fixEnvVariables(dep_cmd);
     1949                    dep_cmd = dep_cd_cmd + fixEnvVariables(dep_cmd);
    19221950                    if(FILE *proc = QT_POPEN(dep_cmd.toLatin1().constData(), "r")) {
    19231951                        QString indeps;
     
    20172045                char buff[256];
    20182046                QString dep_cmd = replaceExtraCompilerVariables(tmp_dep_cmd, (*input), out);
    2019                 dep_cmd = fixEnvVariables(dep_cmd);
     2047                dep_cmd = dep_cd_cmd + fixEnvVariables(dep_cmd);
    20202048                if(FILE *proc = QT_POPEN(dep_cmd.toLatin1().constData(), "r")) {
    20212049                    QString indeps;
     
    21542182MakefileGenerator::writeStubMakefile(QTextStream &t)
    21552183{
    2156     t << "QMAKE    = "        << (project->isEmpty("QMAKE_QMAKE") ? QString("qmake") : var("QMAKE_QMAKE")) << endl;
     2184    t << "QMAKE    = " << var("QMAKE_QMAKE") << endl;
    21572185    QStringList &qut = project->values("QMAKE_EXTRA_TARGETS");
    21582186    for(QStringList::ConstIterator it = qut.begin(); it != qut.end(); ++it)
     
    22092237    if(!Option::mkfile::qmakespec_commandline.isEmpty())
    22102238        ret += " -spec " + specdir(outdir);
    2211     if(Option::target_mode == Option::TARG_MAC9_MODE)
    2212         ret += " -mac9";
    2213     else if(Option::target_mode == Option::TARG_MACX_MODE)
    2214         ret += " -macx";
    2215     else if(Option::target_mode == Option::TARG_UNIX_MODE)
    2216         ret += " -unix";
    2217     else if(Option::target_mode == Option::TARG_WIN_MODE)
    2218         ret += " -win32";
     2239    if (Option::target_mode_overridden) {
     2240        if (Option::target_mode == Option::TARG_MACX_MODE)
     2241            ret += " -macx";
     2242        else if (Option::target_mode == Option::TARG_UNIX_MODE)
     2243            ret += " -unix";
     2244        else if (Option::target_mode == Option::TARG_WIN_MODE)
     2245            ret += " -win32";
     2246    }
    22192247    else if(Option::target_mode == Option::TARG_OS2_MODE)
    22202248        ret += " -os2";
     
    22712299    t << "# Template: " << var("TEMPLATE") << endl;
    22722300    if(!project->isActiveConfig("build_pass"))
    2273         t << "# Command: " << build_args().replace("$(QMAKE)",
    2274                       (project->isEmpty("QMAKE_QMAKE") ? QString("qmake") : var("QMAKE_QMAKE"))) << endl;
     2301        t << "# Command: " << build_args().replace("$(QMAKE)", var("QMAKE_QMAKE")) << endl;
    22752302    t << "#############################################################################" << endl;
    22762303    t << endl;
     
    24052432        /* Calling Option::fixPathToTargetOS() is necessary for MinGW/MSYS, which requires
    24062433         * back-slashes to be turned into slashes. */
    2407         t << "QMAKE         = " << Option::fixPathToTargetOS(var("QMAKE_QMAKE")) << endl;
     2434        t << "QMAKE         = " << var("QMAKE_QMAKE") << endl;
    24082435        t << "DEL_FILE      = " << var("QMAKE_DEL_FILE") << endl;
    24092436        t << "CHK_DIR_EXISTS= " << var("QMAKE_CHK_DIR_EXISTS") << endl;
     
    27332760                if(exists(Option::fixPathToLocalOS(specdir()+QDir::separator()+"qmake.conf")))
    27342761                    t << escapeDependencyPath(specdir() + Option::dir_sep + "qmake.conf") << " ";
    2735                 else if(exists(Option::fixPathToLocalOS(specdir()+QDir::separator()+"tmake.conf")))
    2736                     t << escapeDependencyPath(specdir() + Option::dir_sep + "tmake.conf") << " ";
    27372762            }
    27382763            const QStringList &included = project->values("QMAKE_INTERNAL_INCLUDED_FILES");
  • trunk/qmake/generators/makefile.h

    r651 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)
     
    248248    virtual bool mergeBuildProject(MakefileGenerator * /*other*/) { return false; }
    249249    virtual bool openOutput(QFile &, const QString &build) const;
    250     virtual bool isDosLikeShell() const { return Option::target_mode == Option::TARG_WIN_MODE ||
    251                                                  Option::target_mode == Option::TARG_OS2_MODE; }
     250    virtual bool isDosLikeShell() const { return Option::host_mode == Option::HOST_WIN_MODE ||
     251                                                 Option::host_mode == Option::HOST_OS2_MODE; }
     252    virtual bool isForSymbianSbsv2() const { return false; } // FIXME: killme - i'm ugly!
     253
     254    /* The next one is to avoid having SymbianCommonGenerator as a virtually
     255       inherited class of this class. Instead it is without a base class
     256       (avoiding the virtual inheritance problem), and is allowed to use
     257       functions defined in here.
     258
     259       To illustrate:
     260                               +-------------------+
     261                               | MakefileGenerator |
     262                               +-------------------+
     263                                 ^            ^
     264                                 |            |
     265                                 |            X <-- Avoid this inheritance
     266                                 |            |
     267              +------------------------+  +------------------------+
     268              | UnixMakefileGenerator  |  | SymbianCommonGenerator |
     269              |         or             |  |                        |
     270              | NmakeMakefileGenerator |  |                        |
     271              +------------------------+  +------------------------+
     272                                 ^            ^
     273                                 |            |
     274                                 |            |
     275                                 |            |
     276                           +-----------------------------+
     277                           | SymbianMakefileTemplate<>   |
     278                           +-----------------------------+
     279
     280       We want to avoid the famous diamond problem, because if we have that, we need
     281       virtual inheritance, which not all compilers like. Therefore, we break the
     282       link as illustrated. Instead, we have a pointer to MakefileGenerator inside
     283       SymbianCommonGenerator, and allows full access by making it a friend here.
     284    */
     285    friend class SymbianCommonGenerator;
    252286};
    253287
  • trunk/qmake/generators/makefiledeps.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)
  • trunk/qmake/generators/makefiledeps.h

    r651 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)
  • trunk/qmake/generators/metamakefile.cpp

    r651 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        delete project;
    5959}
     60
     61#ifndef QT_QMAKE_PARSER_ONLY
    6062
    6163class BuildsMetaMakefileGenerator : public MetaMakefileGenerator
     
    294296    bool hasError = false;
    295297
    296     if(Option::recursive) {
     298    // It might make sense to bequeath the CONFIG option to the recursed
     299    // projects. OTOH, one would most likely have it in all projects anyway -
     300    // either through a qmakespec, a .qmake.cache or explicitly - as otherwise
     301    // running qmake in a subdirectory would have a different auto-recurse
     302    // setting than in parent directories.
     303    bool recurse = Option::recursive == Option::QMAKE_RECURSIVE_YES
     304                   || (Option::recursive == Option::QMAKE_RECURSIVE_DEFAULT
     305                       && project->isRecursive());
     306    if(recurse) {
    297307        QString old_output_dir = Option::output_dir;
    298308        QString old_output = Option::output.fileName();
     
    376386    self->input_dir = qmake_getpwd();
    377387    self->output_dir = Option::output_dir;
    378     if(!Option::recursive || (!Option::output.fileName().endsWith(Option::dir_sep) && !QFileInfo(Option::output).isDir()))
     388    if(!recurse || (!Option::output.fileName().endsWith(Option::dir_sep) && !QFileInfo(Option::output).isDir()))
    379389        self->output_file = Option::output.fileName();
    380390    self->makefile = new BuildsMetaMakefileGenerator(project, name, false);
     
    434444#include "msvc_nmake.h"
    435445#include "borland_bmake.h"
    436 #include "msvc_dsp.h"
    437446#include "msvc_vcproj.h"
     447#include "msvc_vcxproj.h"
    438448#include "symmake_abld.h"
    439449#include "symmake_sbsv2.h"
     450#include "symbian_makefile.h"
    440451QT_END_INCLUDE_NAMESPACE
    441452
     
    462473    } else if(gen == "PROJECTBUILDER" || gen == "XCODE") {
    463474        mkfile = new ProjectBuilderMakefileGenerator;
    464     } else if(gen == "MSVC") {
    465         // Visual Studio =< v6.0
    466         if(proj->first("TEMPLATE").indexOf(QRegExp("^vc.*")) != -1)
    467             mkfile = new DspMakefileGenerator;
     475    } else if(gen == "MSVC.NET") {
     476        if (proj->first("TEMPLATE").startsWith("vc"))
     477            mkfile = new VcprojGenerator;
    468478        else
    469479            mkfile = new NmakeMakefileGenerator;
    470     } else if(gen == "MSVC.NET") {
    471         // Visual Studio >= v7.0
    472         if(proj->first("TEMPLATE").indexOf(QRegExp("^vc.*")) != -1 || proj->first("TEMPLATE").indexOf(QRegExp("^ce.*")) != -1)
    473             mkfile = new VcprojGenerator;
     480    } else if(gen == "MSBUILD") {
     481        // Visual Studio >= v11.0
     482        if (proj->first("TEMPLATE").startsWith("vc"))
     483            mkfile = new VcxprojGenerator;
    474484        else
    475485            mkfile = new NmakeMakefileGenerator;
     
    480490    } else if(gen == "SYMBIAN_SBSV2") {
    481491        mkfile = new SymbianSbsv2MakefileGenerator;
     492    } else if(gen == "SYMBIAN_UNIX") {
     493        mkfile = new SymbianMakefileTemplate<UnixMakefileGenerator>;
    482494    } else {
    483495        fprintf(stderr, "Unknown generator specified: %s\n", gen.toLatin1().constData());
     
    507519}
    508520
     521#endif // QT_QMAKE_PARSER_ONLY
     522
     523bool
     524MetaMakefileGenerator::modesForGenerator(const QString &gen,
     525        Option::HOST_MODE *host_mode, Option::TARG_MODE *target_mode)
     526{
     527    if (gen == "UNIX") {
     528#ifdef Q_OS_MAC
     529        *host_mode = Option::HOST_MACX_MODE;
     530        *target_mode = Option::TARG_MACX_MODE;
     531#else
     532        *host_mode = Option::HOST_UNIX_MODE;
     533        *target_mode = Option::TARG_UNIX_MODE;
     534#endif
     535    } else if (gen == "MSVC.NET" || gen == "BMAKE" || gen == "MSBUILD") {
     536        *host_mode = Option::HOST_WIN_MODE;
     537        *target_mode = Option::TARG_WIN_MODE;
     538    } else if (gen == "MINGW") {
     539#if defined(Q_OS_MAC)
     540        *host_mode = Option::HOST_MACX_MODE;
     541#elif defined(Q_OS_UNIX)
     542        *host_mode = Option::HOST_UNIX_MODE;
     543#else
     544        *host_mode = Option::HOST_WIN_MODE;
     545#endif
     546        *target_mode = Option::TARG_WIN_MODE;
     547    } else if (gen == "PROJECTBUILDER" || gen == "XCODE") {
     548        *host_mode = Option::HOST_MACX_MODE;
     549        *target_mode = Option::TARG_MACX_MODE;
     550    } else if (gen == "SYMBIAN_ABLD" || gen == "SYMBIAN_SBSV2" || gen == "SYMBIAN_UNIX") {
     551#if defined(Q_OS_MAC)
     552        *host_mode = Option::HOST_MACX_MODE;
     553#elif defined(Q_OS_UNIX)
     554        *host_mode = Option::HOST_UNIX_MODE;
     555#else
     556        *host_mode = Option::HOST_WIN_MODE;
     557#endif
     558        *target_mode = Option::TARG_SYMBIAN_MODE;
     559    } else {
     560        fprintf(stderr, "Unknown generator specified: %s\n", gen.toLatin1().constData());
     561        return false;
     562    }
     563    return true;
     564}
     565
    509566QT_END_NAMESPACE
  • trunk/qmake/generators/metamakefile.h

    r651 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)
     
    4343#define METAMAKEFILE_H
    4444
     45#include <option.h>
     46
    4547#include <qlist.h>
    4648#include <qstring.h>
     
    6668    static MakefileGenerator *createMakefileGenerator(QMakeProject *proj, bool noIO = false);
    6769
     70    static bool modesForGenerator(const QString &generator,
     71                                  Option::HOST_MODE *host_mode, Option::TARG_MODE *target_mode);
     72
    6873    inline QMakeProject *projectFile() const { return project; }
    6974
  • trunk/qmake/generators/projectgenerator.cpp

    r651 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)
     
    112112                    if(dir.right(1) != Option::dir_sep)
    113113                        dir += Option::dir_sep;
    114                     if(Option::recursive) {
     114                    if(Option::recursive == Option::QMAKE_RECURSIVE_YES) {
    115115                        QStringList files = QDir(dir).entryList(QDir::Files);
    116116                        for(int i = 0; i < (int)files.count(); i++) {
     
    139139                    regex = regex.right(regex.length() - (s+1));
    140140                }
    141                 if(Option::recursive) {
     141                if(Option::recursive == Option::QMAKE_RECURSIVE_YES) {
    142142                    QStringList entries = QDir(dir).entryList(QDir::Dirs);
    143143                    for(int i = 0; i < (int)entries.count(); i++) {
     
    194194                        }
    195195                    }
    196                     if(Option::recursive) {
     196                    if(Option::recursive == Option::QMAKE_RECURSIVE_YES) {
    197197                        QStringList dirs = QDir(newdir).entryList(QDir::Dirs);
    198198                        for(int i = 0; i < (int)dirs.count(); i++) {
     
    231231                            }
    232232                        }
    233                         if(Option::recursive && !knownDirs.contains(newdir, Qt::CaseInsensitive))
     233                        if(Option::recursive == Option::QMAKE_RECURSIVE_YES
     234                           && !knownDirs.contains(newdir, Qt::CaseInsensitive))
    234235                            knownDirs.append(newdir);
    235236                    }
  • trunk/qmake/generators/projectgenerator.h

    r651 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)
  • 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
  • trunk/qmake/generators/unix/unixmake.cpp

    r651 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)
     
    6666    }
    6767
     68    if (project->isEmpty("QMAKE_PREFIX_SHLIB"))
     69        // Prevent crash when using the empty variable.
     70        project->values("QMAKE_PREFIX_SHLIB").append("");
     71
    6872    if(!project->isEmpty("QMAKE_FAILED_REQUIREMENTS")) /* no point */
    6973        return;
     
    100104        if(project->isEmpty("MAKEFILE"))
    101105            project->values("MAKEFILE").append("Makefile");
    102         if(project->isEmpty("QMAKE_QMAKE"))
    103             project->values("QMAKE_QMAKE").append("qmake");
    104106        if(project->values("QMAKE_INTERNAL_QMAKE_DEPS").indexOf("qmake_all") == -1)
    105107            project->values("QMAKE_INTERNAL_QMAKE_DEPS").append("qmake_all");
     
    452454                        libdirs.append(f);
    453455                } else if(opt.startsWith("-l")) {
    454                     if (project->isActiveConfig("rvct_linker")) {
     456                    if (!project->isEmpty("QMAKE_RVCT_LINKSTYLE")) {
     457                        (*it) = opt.mid(2);
     458                    } else if (project->isActiveConfig("rvct_linker")) {
    455459                        (*it) = "lib" + opt.mid(2) + ".so";
    456460                    } else {
     
    492496                if(!extn.isNull())
    493497                    extens << extn;
     498                else if (!project->isEmpty("QMAKE_SYMBIAN_SHLIB"))
     499                    // In Symbian you link to the stub .lib file, but run with the .dll file.
     500                    extens << "lib";
    494501                else
    495502                    extens << project->values("QMAKE_EXTENSION_SHLIB").first() << "a";
    496503                for(QStringList::Iterator extit = extens.begin(); extit != extens.end(); ++extit) {
    497504                    if(dir.isNull()) {
    498                         QString lib_stub;
    499505                        for(QList<QMakeLocalFileName>::Iterator dep_it = libdirs.begin(); dep_it != libdirs.end(); ++dep_it) {
    500                             if(exists((*dep_it).local() + Option::dir_sep + "lib" + stub +
    501                                       "." + (*extit))) {
    502                                 lib_stub = stub;
     506                            QString pathToLib = ((*dep_it).local() + Option::dir_sep
     507                                    + project->values("QMAKE_PREFIX_SHLIB").first()
     508                                    + stub + "." + (*extit));
     509                            if(exists(pathToLib)) {
     510                                if (!project->isEmpty("QMAKE_RVCT_LINKSTYLE"))
     511                                    (*it) = pathToLib;
     512                                else
     513                                    (*it) = "-l" + stub;
     514                                found = true;
    503515                                break;
    504516                            }
    505517                        }
    506                         if(!lib_stub.isNull()) {
    507                             (*it) = "-l" + lib_stub;
     518                    } else {
     519                        if(exists(project->values("QMAKE_PREFIX_SHLIB").first() + stub + "." + (*extit))) {
     520                            (*it) = project->values("QMAKE_PREFIX_SHLIB").first() + stub + "." + (*extit);
    508521                            found = true;
    509522                            break;
    510523                        }
    511                     } else {
    512                         if(exists("lib" + stub + "." + (*extit))) {
    513                             (*it) = "lib" + stub + "." + (*extit);
    514                             found = true;
    515                             break;
    516                         }
    517524                    }
    518525                }
    519526                if(!found && project->isActiveConfig("compile_libtool")) {
    520527                    for(int dep_i = 0; dep_i < libdirs.size(); ++dep_i) {
    521                         if(exists(libdirs[dep_i].local() + Option::dir_sep + "lib" + stub + Option::libtool_ext)) {
    522                             (*it) = libdirs[dep_i].real() + Option::dir_sep + "lib" + stub + Option::libtool_ext;
     528                        if(exists(libdirs[dep_i].local() + Option::dir_sep + project->values("QMAKE_PREFIX_SHLIB").first() + stub + Option::libtool_ext)) {
     529                            (*it) = libdirs[dep_i].real() + Option::dir_sep + project->values("QMAKE_PREFIX_SHLIB").first() + stub + Option::libtool_ext;
    523530                            found = true;
    524531                            break;
     
    545552    QList<QMakeLocalFileName> libdirs, frameworkdirs;
    546553    frameworkdirs.append(QMakeLocalFileName("/System/Library/Frameworks"));
    547     frameworkdirs.append(QMakeLocalFileName("/Library/Frameworks"));
    548554    const QString lflags[] = { "QMAKE_LIBDIR_FLAGS", "QMAKE_FRAMEWORKPATH_FLAGS", "QMAKE_LFLAGS", "QMAKE_LIBS", QString() };
    549555    for(int i = 0; !lflags[i].isNull(); i++) {
     
    561567                        const QMakeLocalFileName &lfn = libdirs[dep_i];
    562568                        if(!project->isActiveConfig("compile_libtool")) { //give them the .libs..
    563                             QString la = lfn.local() + Option::dir_sep + "lib" + lib + Option::libtool_ext;
     569                            QString la = lfn.local() + Option::dir_sep + project->values("QMAKE_PREFIX_SHLIB").first() + lib + Option::libtool_ext;
    564570                            if(exists(la) && QFile::exists(lfn.local() + Option::dir_sep + ".libs")) {
    565571                                QString dot_libs = lfn.real() + Option::dir_sep + ".libs";
     
    569575                        }
    570576
    571                         QString prl = lfn.local() + Option::dir_sep + "lib" + lib;
     577                        QString prl = lfn.local() + Option::dir_sep + project->values("QMAKE_PREFIX_SHLIB").first() + lib;
    572578                        if(!project->isEmpty("QMAKE_" + lib.toUpper() + "_SUFFIX"))
    573579                            prl += project->first("QMAKE_" + lib.toUpper() + "_SUFFIX");
     
    617623        //merge them into a logical order
    618624        if(!project->isActiveConfig("no_smart_library_merge") && !project->isActiveConfig("no_lflags_merge")) {
    619             QStringList lflags;
     625            QHash<QString, QStringList> lflags;
    620626            for(int lit = 0; lit < l.size(); ++lit) {
     627                QString arch("default");
    621628                QString opt = l.at(lit).trimmed();
    622629                if(opt.startsWith("-")) {
     630                    if (Option::target_mode == Option::TARG_MACX_MODE && opt.startsWith("-Xarch")) {
     631                        if (opt.length() > 7) {
     632                            arch = opt.mid(7);
     633                            opt = l.at(++lit);
     634                        }
     635                    }
     636
    623637                    if(opt.startsWith("-L") ||
    624638                       (Option::target_mode == Option::TARG_MACX_MODE && opt.startsWith("-F"))) {
    625                         if(lit == 0 || l.lastIndexOf(opt, lit-1) == -1)
    626                             lflags.append(opt);
    627                     } else if(opt.startsWith("-l")) {
    628                         if(lit == l.size()-1 || l.indexOf(opt, lit+1) == -1)
    629                             lflags.append(opt);
     639                        if(!lflags[arch].contains(opt))
     640                            lflags[arch].append(opt);
     641                    } else if(opt.startsWith("-l") || opt == "-pthread") {
     642                        // Make sure we keep the dependency-order of libraries
     643                        if (lflags[arch].contains(opt))
     644                            lflags[arch].removeAll(opt);
     645                        lflags[arch].append(opt);
    630646                    } else if(Option::target_mode == Option::TARG_MACX_MODE && opt.startsWith("-framework")) {
    631647                        if(opt.length() > 11)
    632648                            opt = opt.mid(11);
    633                         else
     649                        else {
    634650                            opt = l.at(++lit);
     651                            if (Option::target_mode == Option::TARG_MACX_MODE && opt.startsWith("-Xarch"))
     652                                opt = l.at(++lit); // The user has done the right thing and prefixed each part
     653                        }
    635654                        bool found = false;
    636                         for(int x = lit+1; x < l.size(); ++x) {
    637                             QString xf = l.at(x);
     655                        for(int x = 0; x < lflags[arch].size(); ++x) {
     656                            QString xf = lflags[arch].at(x);
    638657                            if(xf.startsWith("-framework")) {
    639658                                QString framework;
     
    641660                                    framework = xf.mid(11);
    642661                                else
    643                                     framework = l.at(++x);
     662                                    framework = lflags[arch].at(++x);
    644663                                if(framework == opt) {
    645664                                    found = true;
     
    649668                        }
    650669                        if(!found) {
    651                             lflags.append("-framework");
    652                             lflags.append(opt);
     670                            lflags[arch].append("-framework");
     671                            lflags[arch].append(opt);
    653672                        }
    654673                    } else {
    655                         lflags.append(opt);
     674                        lflags[arch].append(opt);
    656675                    }
    657676                } else if(!opt.isNull()) {
    658                     if(lit == 0 || l.lastIndexOf(opt, lit-1) == -1)
    659                         lflags.append(opt);
    660                 }
    661             }
    662             l = lflags;
     677                    if(!lflags[arch].contains(opt))
     678                        lflags[arch].append(opt);
     679                }
     680            }
     681
     682            l =  lflags.take("default");
     683
     684            // Process architecture specific options (Xarch)
     685            QHash<QString, QStringList>::const_iterator archIterator = lflags.constBegin();
     686            while (archIterator != lflags.constEnd()) {
     687                const QStringList archOptions = archIterator.value();
     688                for (int i = 0; i < archOptions.size(); ++i) {
     689                    l.append(QLatin1String("-Xarch_") + archIterator.key());
     690                    l.append(archOptions.at(i));
     691                }
     692                ++archIterator;
     693            }
    663694        }
    664695    }
     
    780811        if(!links.isEmpty()) {
    781812            for(int i = 0; i < links.size(); ++i) {
    782                 if(Option::target_mode == Option::TARG_WIN_MODE ||
    783                    Option::target_mode == Option::TARG_OS2_MODE ||
    784                    Option::target_mode == Option::TARG_MAC9_MODE) {
    785                 } else if(Option::target_mode == Option::TARG_UNIX_MODE ||
    786                           Option::target_mode == Option::TARG_MACX_MODE) {
     813                if(Option::target_mode == Option::TARG_UNIX_MODE ||
     814                   Option::target_mode == Option::TARG_MACX_MODE) {
    787815                    QString link = Option::fixPathToTargetOS(destdir + links[i], false);
    788816                    int lslash = link.lastIndexOf(Option::dir_sep);
  • trunk/qmake/generators/unix/unixmake.h

    r651 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    bool init_flag, include_deps;
    52     bool writeMakefile(QTextStream &);
    5352    QString libtoolFileName(bool fixify=true);
    5453    void writeLibtoolFile();     // for libtool
     
    7675
    7776    void writeMakeParts(QTextStream &);
     77    bool writeMakefile(QTextStream &);
    7878
    7979private:
  • trunk/qmake/generators/unix/unixmake2.cpp

    r651 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)
     
    8282    writeHeader(t);
    8383    if(!project->values("QMAKE_FAILED_REQUIREMENTS").isEmpty()) {
    84         t << "QMAKE    = "        << (project->isEmpty("QMAKE_QMAKE") ? QString("qmake") : var("QMAKE_QMAKE")) << endl;
     84        t << "QMAKE    = " << var("QMAKE_QMAKE") << endl;
    8585        QStringList &qut = project->values("QMAKE_EXTRA_TARGETS");
    8686        for(QStringList::ConstIterator it = qut.begin(); it != qut.end(); ++it)
     
    149149        t << "LINK          = " << var("QMAKE_LINK") << endl;
    150150        t << "LFLAGS        = " << var("QMAKE_LFLAGS") << endl;
    151         t << "LIBS          = " << "$(SUBLIBS) " << var("QMAKE_FRAMEWORKDIR_FLAGS") << " "
     151        t << "LIBS          = " << "$(SUBLIBS) " << var("QMAKE_FRAMEWORKPATH_FLAGS") << " "
    152152          << var("QMAKE_LIBDIR_FLAGS") << " " << var("QMAKE_LIBS") << " " << var("QMAKE_LIBS_PRIVATE") << endl;
    153153    }
     
    155155    t << "AR            = " << var("QMAKE_AR") << endl;
    156156    t << "RANLIB        = " << var("QMAKE_RANLIB") << endl;
    157     t << "QMAKE         = " << (project->isEmpty("QMAKE_QMAKE") ? QString("qmake") : var("QMAKE_QMAKE")) << endl;
     157    t << "QMAKE         = " << var("QMAKE_QMAKE") << endl;
    158158    t << "TAR           = " << var("QMAKE_TAR") << endl;
    159159    t << "COMPRESS      = " << var("QMAKE_GZIP") << endl;
     
    178178        t << "export MACOSX_DEPLOYMENT_TARGET = " //exported to children processes
    179179          << project->first("QMAKE_MACOSX_DEPLOYMENT_TARGET") << endl;
     180
     181    if (!project->isEmpty("QMAKE_SYMBIAN_SHLIB")) {
     182        t << "vpath %.dso " << project->values("QMAKE_LIBDIR").join(":") << endl;
     183        t << "vpath %.lib " << project->values("QMAKE_LIBDIR").join(":") << endl;
     184    }
     185
    180186    t << endl;
    181187
     
    234240            t << "TARGETD       = " << escapeFilePath(var("TARGET_x.y")) << endl;
    235241            t << "TARGET0       = " << escapeFilePath(var("TARGET_")) << endl;
     242        } else if(!project->isEmpty("QMAKE_SYMBIAN_SHLIB")) {
     243            t << "TARGETD       = " << escapeFilePath(var("TARGET")) << endl;
    236244        } else if(project->isEmpty("QMAKE_HPUX_SHLIB")) {
    237245            t << "TARGETD       = " << escapeFilePath(var("TARGET_x.y.z")) << endl;
     
    333341        QStringList &l = project->values("SUBLIBS");
    334342        for(QStringList::Iterator it = l.begin(); it != l.end(); ++it)
    335             t << libdir << "lib" << (*it) << ".a ";
     343            t << libdir << project->first("QMAKE_PREFIX_STATICLIB") << (*it) << "."
     344              << project->first("QMAKE_EXTENSION_STATICLIB") << " ";
    336345        t << endl << endl;
    337346    }
     
    543552              << varGlue("QMAKE_LN_SHLIB","-"," ", " " + project->first("QMAKE_FRAMEWORK_VERSION") +
    544553                         " " + destdir + "Versions/Current") << "\n\t";
     554            if(!project->isEmpty("QMAKE_POST_LINK"))
     555                t << "\n\t" << var("QMAKE_POST_LINK");
     556            t << endl << endl;
     557        } else if(!project->isEmpty("QMAKE_SYMBIAN_SHLIB")) {
     558            t << "\n\t"
     559              << "-$(DEL_FILE) $(TARGET)" << "\n\t"
     560              << var("QMAKE_LINK_SHLIB_CMD");
     561            if(!destdir.isEmpty())
     562                t << "\n\t"
     563                  << "-$(DEL_FILE) " << destdir << "$(TARGET)\n\t"
     564                  << "-$(MOVE) $(TARGET) " << destdir;
    545565            if(!project->isEmpty("QMAKE_POST_LINK"))
    546566                t << "\n\t" << var("QMAKE_POST_LINK");
     
    861881        QStringList &l = project->values("SUBLIBS");
    862882        for(it = l.begin(); it != l.end(); ++it)
    863             t << libdir << "lib" << (*it) << ".a" << ":\n\t"
     883            t << libdir << project->first("QMAKE_PREFIX_STATICLIB") << (*it) << "."
     884              << project->first("QMAKE_EXTENSION_STATICLIB") << ":\n\t"
    864885              << var(QString("MAKELIB") + (*it)) << endl << endl;
    865886    }
     
    876897    } else if(!project->isActiveConfig("staticlib") && project->values("QMAKE_APP_FLAG").isEmpty() &&
    877898       !project->isActiveConfig("plugin")) {
    878         t << "\t-$(DEL_FILE) " << destdir << "$(TARGET)" << " " << endl
    879           << "\t-$(DEL_FILE) " << destdir << "$(TARGET0) " << destdir << "$(TARGET1) "
    880           << destdir << "$(TARGET2) $(TARGETA)" << endl;
     899        t << "\t-$(DEL_FILE) " << destdir << "$(TARGET)" << " " << endl;
     900        if (project->values("QMAKE_SYMBIAN_SHLIB").isEmpty())
     901            t << "\t-$(DEL_FILE) " << destdir << "$(TARGET0) " << destdir << "$(TARGET1) "
     902              << destdir << "$(TARGET2) $(TARGETA)" << endl;
    881903    } else {
    882904        t << "\t-$(DEL_FILE) " << "$(TARGET)" << " " << endl;
     
    9931015            project->values("TARGET_EXT").append(".exe");
    9941016    } else if (project->isActiveConfig("staticlib")) {
    995         project->values("TARGET").first().prepend("lib");
    996         project->values("TARGET").first() += ".a";
     1017        project->values("TARGET").first().prepend(project->first("QMAKE_PREFIX_STATICLIB"));
     1018        project->values("TARGET").first() += "." + project->first("QMAKE_EXTENSION_STATICLIB");
    9971019        if(project->values("QMAKE_AR_CMD").isEmpty())
    9981020            project->values("QMAKE_AR_CMD").append("$(AR) $(TARGET) $(OBJECTS)");
    9991021    } else {
    1000         project->values("TARGETA").append(project->first("DESTDIR") + "lib" + project->first("TARGET") + ".a");
     1022        project->values("TARGETA").append(project->first("DESTDIR") + project->first("QMAKE_PREFIX_STATICLIB")
     1023                + project->first("TARGET") + "." + project->first("QMAKE_EXTENSION_STATICLIB"));
    10011024        if(project->isActiveConfig("compile_libtool"))
    10021025            project->values("TARGET_la") = QStringList(project->first("DESTDIR") + "lib" + project->first("TARGET") + Option::libtool_ext);
     
    10461069            project->values("TARGET") = project->values("TARGET_x");
    10471070        } else if (!project->isEmpty("QMAKE_AIX_SHLIB")) {
    1048             project->values("TARGET_").append("lib" + project->first("TARGET") + ".a");
     1071            project->values("TARGET_").append(project->first("QMAKE_PREFIX_STATICLIB") + project->first("TARGET")
     1072                    + "." + project->first("QMAKE_EXTENSION_STATICLIB"));
    10491073            if(project->isActiveConfig("lib_version_first")) {
    10501074                project->values("TARGET_x").append("lib" + project->first("TARGET") + "." +
     
    10751099            }
    10761100            project->values("TARGET") = project->values("TARGET_x.y.z");
     1101        } else if (!project->isEmpty("QMAKE_SYMBIAN_SHLIB")) {
     1102            project->values("TARGET_").append(project->first("TARGET") + "." +
     1103                                                   project->first("QMAKE_EXTENSION_SHLIB"));
     1104            project->values("TARGET") = project->values("TARGET_");
    10771105        } else {
    10781106            project->values("TARGET_").append("lib" + project->first("TARGET") + "." +
  • trunk/qmake/generators/win32/borland_bmake.cpp

    r651 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)
     
    116116        if(project->values("MAKEFILE").isEmpty())
    117117            project->values("MAKEFILE").append("Makefile");
    118         if(project->values("QMAKE_QMAKE").isEmpty())
    119             project->values("QMAKE_QMAKE").append("qmake");
    120118        return;
    121119    }
  • trunk/qmake/generators/win32/borland_bmake.h

    r651 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)
  • trunk/qmake/generators/win32/mingw_make.cpp

    r651 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)
     
    144144       project->first("TEMPLATE") == "lib") {
    145145        if(Option::mkfile::do_stub_makefile) {
    146             t << "QMAKE    = "        << (project->isEmpty("QMAKE_QMAKE") ? QString("qmake") : var("QMAKE_QMAKE")) << endl;
     146            t << "QMAKE    = " << var("QMAKE_QMAKE") << endl;
    147147            QStringList &qut = project->values("QMAKE_EXTRA_TARGETS");
    148148            for(QStringList::ConstIterator it = qut.begin(); it != qut.end(); ++it)
     
    192192        t << "CREATE " << target << endl;
    193193        for (QStringList::ConstIterator it = objList.constBegin(); it != objList.constEnd(); ++it) {
    194             if (QDir::isRelativePath(*it))
    195                 t << "ADDMOD " << *it << endl;
    196             else
    197                 t << *it << endl;
     194            t << "ADDMOD " << *it << endl;
    198195        }
    199196        t << "SAVE" << endl;
     
    249246        if(project->values("MAKEFILE").isEmpty())
    250247            project->values("MAKEFILE").append("Makefile");
    251         if(project->values("QMAKE_QMAKE").isEmpty())
    252             project->values("QMAKE_QMAKE").append("qmake");
    253248        return;
    254249    }
     
    374369        }
    375370        createArObjectScriptFile(ar_script_file, var("DEST_TARGET"), project->values("OBJECTS"));
    376         objectsLinkLine = "ar -M < " + ar_script_file;
     371        // QMAKE_LIB is used for win32, including mingw, whereas QMAKE_AR is used on Unix.
     372        // Strip off any options since the ar commands will be read from file.
     373        QString ar_cmd = var("QMAKE_LIB").section(" ", 0, 0);;
     374        if (ar_cmd.isEmpty())
     375            ar_cmd = "ar";
     376        objectsLinkLine = ar_cmd + " -M < " + ar_script_file;
    377377    } else {
    378378        QString ld_script_file = var("QMAKE_LINK_OBJECT_SCRIPT") + "." + var("TARGET");
     
    418418        t << escapeDependencyPath(var("RES_FILE")) << ": " << rc_file << "\n\t"
    419419          << var("QMAKE_RC") << " -i " << rc_file << " -o " << var("RES_FILE")
    420           << " --include-dir=" << incPathStr << endl << endl;
     420          << " --include-dir=" << incPathStr << " $(DEFINES)" << endl << endl;
    421421    }
    422422}
  • trunk/qmake/generators/win32/mingw_make.h

    r651 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)
  • trunk/qmake/generators/win32/msvc_nmake.cpp

    r651 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)
     
    157157        if(project->values("MAKEFILE").isEmpty())
    158158            project->values("MAKEFILE").append("Makefile");
    159         if(project->values("QMAKE_QMAKE").isEmpty())
    160             project->values("QMAKE_QMAKE").append("qmake");
    161159        if(project->isEmpty("QMAKE_COPY_FILE"))
    162160            project->values("QMAKE_COPY_FILE").append("$(COPY)");
     
    216214    }
    217215    if(project->isActiveConfig("debug")) {
    218         project->values("QMAKE_CLEAN").append(project->first("DESTDIR") + project->first("TARGET") + version + ".pdb");
     216        project->values("QMAKE_DISTCLEAN").append(project->first("DESTDIR") + project->first("TARGET") + version + ".pdb");
    219217        project->values("QMAKE_CLEAN").append(project->first("DESTDIR") + project->first("TARGET") + version + ".ilk");
    220218        project->values("QMAKE_CLEAN").append("vc*.pdb");
     
    313311    }
    314312    if(!project->isEmpty("QMAKE_POST_LINK")) {
    315         if (useSignature)
    316             t << " && " << var("QMAKE_POST_LINK");
    317         else
    318             t << "\n\t" << var("QMAKE_POST_LINK");
     313        t << "\n\t" << var("QMAKE_POST_LINK");
    319314    }
    320315    t << endl;
  • trunk/qmake/generators/win32/msvc_nmake.h

    r651 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)
  • trunk/qmake/generators/win32/msvc_objectmodel.cpp

    r651 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)
     
    4242#include "msvc_objectmodel.h"
    4343#include "msvc_vcproj.h"
     44#include "msvc_vcxproj.h"
    4445#include <qstringlist.h>
    4546#include <qfileinfo.h>
     
    280281}
    281282
     283// VCToolBase -------------------------------------------------
     284QStringList VCToolBase::fixCommandLine(const QString &input)
     285{
     286    // The splitting regexp is a bit bizarre for backwards compat reasons (why else ...).
     287    return input.split(QRegExp(QLatin1String("\n\t|\r\\\\h|\r\n")));
     288}
     289
     290static QString vcCommandSeparator()
     291{
     292    // MSVC transforms the build tree into a single batch file, simply pasting the contents
     293    // of the custom commands into it, and putting an "if errorlevel goto" statement behind it.
     294    // As we want every sub-command to be error-checked (as is done by makefile-based
     295    // backends), we insert the checks ourselves, using the undocumented jump target.
     296    static QString cmdSep =
     297            QLatin1String("&#x000D;&#x000A;if errorlevel 1 goto VCReportError&#x000D;&#x000A;");
     298    return cmdSep;
     299}
     300
    282301// VCCLCompilerTool -------------------------------------------------
    283302VCCLCompilerTool::VCCLCompilerTool()
     
    673692            if(third == 'd')
    674693                RuntimeLibrary = rtMultiThreadedDebug;
     694            break;
     695        } else if (second == 'P') {
     696            if (config->CompilerVersion >= NET2005)
     697                AdditionalOptions += option;
     698            else
     699                warn_msg(WarnLogic, "/MP option is not supported in Visual C++ < 2005, ignoring.");
    675700            break;
    676701        }
     
    14241449    case 0x0034160: // /MAP[:filename]
    14251450        GenerateMapFile = _True;
    1426         MapFileName = option+5;
     1451        if (option[4] == ':')
     1452            MapFileName = option+5;
    14271453        break;
    14281454    case 0x164e1ef: // /MAPINFO:{EXPORTS|LINES}
     
    19061932XmlOutput &operator<<(XmlOutput &xml, const VCCustomBuildTool &tool)
    19071933{
    1908     // The code below offers two ways to split custom build step commands.
    1909     // Normally the $$escape_expand(\n\t) is used in a project file, which is correctly translated
    1910     // in all generators. However, if you use $$escape_expand(\n\r) (or \n\h) instead, the VCPROJ
    1911     // generator will instead of binding the commands with " && " will insert a proper newline into
    1912     // the VCPROJ file. We sometimes use this method of splitting commands if the custom buildstep
    1913     // contains a command-line which is too big to run on certain OS.
    1914     QString cmds;
    1915     int end = tool.CommandLine.count();
    1916     for(int i = 0; i < end; ++i) {
    1917         QString cmdl = tool.CommandLine.at(i);
    1918         if (cmdl.contains("\r\t")) {
    1919             if (i == end - 1)
    1920                 cmdl = cmdl.trimmed();
    1921             cmdl.replace("\r\t", " && ");
    1922         } else if (cmdl.contains("\r\n")) {
    1923             ;
    1924         } else if (cmdl.contains("\r\\h")) {
    1925             // The above \r\n should work, but doesn't, so we have this hack
    1926             cmdl.replace("\r\\h", "\r\n");
    1927         } else {
    1928             if (i < end - 1)
    1929                 cmdl += " && ";
    1930         }
    1931         cmds += cmdl;
    1932     }
    19331934    return xml
    19341935        << tag(_Tool)
    19351936            << attrS(_Name, tool.ToolName)
    19361937            << attrX(_AdditionalDependencies, tool.AdditionalDependencies, ";")
    1937             << attrS(_CommandLine, cmds)
     1938            << attrS(_CommandLine, tool.CommandLine.join(vcCommandSeparator()))
    19381939            << attrS(_Description, tool.Description)
    19391940            << attrX(_Outputs, tool.Outputs, ";")
     
    19951996            << attrS(_Name, tool.ToolName)
    19961997            << attrS(_Path, tool.ToolPath)
    1997             << attrS(_CommandLine, tool.CommandLine)
     1998            << attrS(_CommandLine, tool.CommandLine.join(vcCommandSeparator()))
    19981999            << attrS(_Description, tool.Description)
    19992000            << attrT(_ExcludedFromBuild, tool.ExcludedFromBuild)
     
    22892290            CustomBuildTool.Description += " & ";
    22902291        CustomBuildTool.Description += cmd_name;
    2291         CustomBuildTool.CommandLine += cmd.trimmed().split("\n", QString::SkipEmptyParts);
     2292        CustomBuildTool.CommandLine += VCToolBase::fixCommandLine(cmd.trimmed());
    22922293        int space = cmd.indexOf(' ');
    22932294        QFileInfo finf(cmd.left(space));
  • trunk/qmake/generators/win32/msvc_objectmodel.h

    r651 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)
     
    5959    NET2003 = 0x71,
    6060    NET2005 = 0x80,
    61     NET2008 = 0x90
     61    NET2008 = 0x90,
     62    NET2010 = 0xa0
    6263};
    6364
     
    475476            parseOption((*it).toLatin1());
    476477    }
     478    static QStringList fixCommandLine(const QString &input);
    477479};
    478480
     
    746748public:
    747749    // Variables
    748     QString                 CommandLine;
     750    QStringList             CommandLine;
    749751    QString                 Description;
    750752    triState                ExcludedFromBuild;
     
    868870    customBuildCheck        CustomBuild;
    869871
    870     bool                    useCustomBuildTool;
     872    bool                    useCustomBuildTool;
    871873    VCCustomBuildTool       CustomBuildTool;
    872874
  • trunk/qmake/generators/win32/msvc_vcproj.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)
     
    6868#ifdef Q_OS_WIN32
    6969#include <qt_windows.h>
    70 #include <windows/registry.h>
     70#include <windows/registry_p.h>
    7171
    7272QT_BEGIN_NAMESPACE
     
    7878} dotNetCombo[] = {
    7979#ifdef Q_OS_WIN64
     80    {NET2010, "MSVC.NET 2010 (10.0)", "Software\\Wow6432Node\\Microsoft\\VisualStudio\\10.0\\Setup\\VC\\ProductDir"},
     81    {NET2010, "MSVC.NET 2010 Express Edition (10.0)", "Software\\Wow6432Node\\Microsoft\\VCExpress\\10.0\\Setup\\VC\\ProductDir"},
    8082    {NET2008, "MSVC.NET 2008 (9.0)", "Software\\Wow6432Node\\Microsoft\\VisualStudio\\9.0\\Setup\\VC\\ProductDir"},
    8183    {NET2008, "MSVC.NET 2008 Express Edition (9.0)", "Software\\Wow6432Node\\Microsoft\\VCExpress\\9.0\\Setup\\VC\\ProductDir"},
     
    8587    {NET2002, "MSVC.NET 2002 (7.0)", "Software\\Wow6432Node\\Microsoft\\VisualStudio\\7.0\\Setup\\VC\\ProductDir"},
    8688#else
     89    {NET2010, "MSVC.NET 2010 (10.0)", "Software\\Microsoft\\VisualStudio\\10.0\\Setup\\VC\\ProductDir"},
     90    {NET2010, "MSVC.NET 2010 Express Edition (10.0)", "Software\\Microsoft\\VCExpress\\10.0\\Setup\\VC\\ProductDir"},
    8791    {NET2008, "MSVC.NET 2008 (9.0)", "Software\\Microsoft\\VisualStudio\\9.0\\Setup\\VC\\ProductDir"},
    8892    {NET2008, "MSVC.NET 2008 Express Edition (9.0)", "Software\\Microsoft\\VCExpress\\9.0\\Setup\\VC\\ProductDir"},
     
    116120    int i = 0;
    117121    for(; dotNetCombo[i].version; ++i) {
    118         QString path = readRegistryKey(HKEY_LOCAL_MACHINE, dotNetCombo[i].regKey);
     122        QString path = qt_readRegistryKey(HKEY_LOCAL_MACHINE, dotNetCombo[i].regKey);
    119123        if(!path.isEmpty()) {
    120124            ++installed;
     
    133137    i = installed = 0;
    134138    for(; dotNetCombo[i].version; ++i) {
    135         QString productPath = readRegistryKey(HKEY_LOCAL_MACHINE, dotNetCombo[i].regKey).toLower();
     139        QString productPath = qt_readRegistryKey(HKEY_LOCAL_MACHINE, dotNetCombo[i].regKey).toLower();
    136140                if (productPath.isEmpty())
    137141                        continue;
     
    166170const char _slnHeader70[]       = "Microsoft Visual Studio Solution File, Format Version 7.00";
    167171const char _slnHeader71[]       = "Microsoft Visual Studio Solution File, Format Version 8.00";
    168 const char _slnHeader80[]       = "Microsoft Visual Studio Solution File, Format Version 9.00";
    169 const char _slnHeader90[]       = "Microsoft Visual Studio Solution File, Format Version 10.00";
     172const char _slnHeader80[]       = "Microsoft Visual Studio Solution File, Format Version 9.00"
     173                                  "\n# Visual Studio 2005";
     174const char _slnHeader90[]       = "Microsoft Visual Studio Solution File, Format Version 10.00"
     175                                  "\n# Visual Studio 2008";
     176const char _slnHeader100[]      = "Microsoft Visual Studio Solution File, Format Version 11.00"
     177                                  "\n# Visual Studio 2010";
    170178                                  // The following UUID _may_ change for later servicepacks...
    171179                                  // If so we need to search through the registry at
     
    355363
    356364    switch(which_dotnet_version()) {
     365    case NET2010:
     366        t << _slnHeader100;
     367        break;
    357368    case NET2008:
    358369        t << _slnHeader90;
     
    890901    conf.compiler.ProgramDataBaseFileName = ".\\" ;
    891902    conf.compiler.ObjectFile = placement ;
     903    conf.compiler.ExceptionHandling = ehNone;
    892904    // PCH
    893905    if (usePCH) {
     
    907919    if(project->isActiveConfig("debug")){
    908920        // Debug version
    909         conf.compiler.parseOptions(project->values("QMAKE_CXXFLAGS_DEBUG"));
    910921        if((projectTarget == Application) || (projectTarget == StaticLib))
    911922            conf.compiler.parseOptions(project->values("QMAKE_CXXFLAGS_MT_DBG"));
     
    914925    } else {
    915926        // Release version
    916         conf.compiler.parseOptions(project->values("QMAKE_CXXFLAGS_RELEASE"));
    917927        conf.compiler.PreprocessorDefinitions += "QT_NO_DEBUG";
    918928        conf.compiler.PreprocessorDefinitions += "NDEBUG";
     
    924934
    925935    // Common for both release and debug
    926     if(project->isActiveConfig("warn_off"))
    927         conf.compiler.parseOptions(project->values("QMAKE_CXXFLAGS_WARN_OFF"));
    928     else if(project->isActiveConfig("warn_on"))
    929         conf.compiler.parseOptions(project->values("QMAKE_CXXFLAGS_WARN_ON"));
    930936    if(project->isActiveConfig("windows"))
    931937        conf.compiler.PreprocessorDefinitions += project->values("MSVCPROJ_WINCONDEF");
     
    990996    conf.linker.OutputFile += project->first("MSVCPROJ_TARGET");
    991997
    992     if(project->isActiveConfig("debug")){
    993         conf.linker.parseOptions(project->values("QMAKE_LFLAGS_DEBUG"));
    994     } else {
    995         conf.linker.parseOptions(project->values("QMAKE_LFLAGS_RELEASE"));
    996     }
    997 
    998998    if(project->isActiveConfig("dll")){
    999999        conf.linker.parseOptions(project->values("QMAKE_LFLAGS_QT_DLL"));
    10001000    }
    1001 
    1002     if(project->isActiveConfig("console")){
    1003         conf.linker.parseOptions(project->values("QMAKE_LFLAGS_CONSOLE"));
    1004     } else {
    1005         conf.linker.parseOptions(project->values("QMAKE_LFLAGS_WINDOWS"));
    1006     }
    1007 
    10081001}
    10091002
     
    10351028}
    10361029
    1037 QString VcprojGenerator::fixCommandLine(DotNET version, const QString &input) const
    1038 {
    1039     QString result = input;
    1040 
    1041     if (version >= NET2005)
    1042         result = result.replace(QLatin1Char('\n'), QLatin1String("&#x000D;&#x000A;"));
    1043 
    1044     return result;
    1045 }
    1046 
    10471030void VcprojGenerator::initPostBuildEventTools()
    10481031{
    10491032    VCConfiguration &conf = vcProject.Configuration;
    10501033    if(!project->values("QMAKE_POST_LINK").isEmpty()) {
    1051         QString cmdline = fixCommandLine(conf.CompilerVersion, var("QMAKE_POST_LINK"));
     1034        QStringList cmdline = VCToolBase::fixCommandLine(var("QMAKE_POST_LINK"));
    10521035        conf.postBuild.CommandLine = cmdline;
    1053         if (conf.CompilerVersion < NET2005)
    1054             cmdline = cmdline.replace("\n", "&&");
    1055         conf.postBuild.Description = cmdline;
     1036        conf.postBuild.Description = cmdline.join(QLatin1String("\r\n"));
    10561037    }
    10571038
     
    10601041                        !project->isEmpty("CE_SDK") && !project->isEmpty("CE_ARCH");
    10611042    if(useSignature)
    1062         conf.postBuild.CommandLine.prepend(QLatin1String("signtool sign /F ") + signature + " \"$(TargetPath)\"\n" +
    1063             (!conf.postBuild.CommandLine.isEmpty() ? " && " : ""));
     1043        conf.postBuild.CommandLine.prepend(
     1044                QLatin1String("signtool sign /F ") + signature + QLatin1String(" \"$(TargetPath)\""));
    10641045
    10651046    if(!project->values("MSVCPROJ_COPY_DLL").isEmpty()) {
    1066         if(!conf.postBuild.CommandLine.isEmpty())
    1067             conf.postBuild.CommandLine += " && ";
    10681047        conf.postBuild.Description += var("MSVCPROJ_COPY_DLL_DESC");
    10691048        conf.postBuild.CommandLine += var("MSVCPROJ_COPY_DLL");
     
    11941173    VCConfiguration &conf = vcProject.Configuration;
    11951174    if(!project->values("QMAKE_PRE_LINK").isEmpty()) {
    1196         QString cmdline = fixCommandLine(conf.CompilerVersion, var("QMAKE_PRE_LINK"));
    1197         conf.preLink.Description = cmdline;
     1175        QStringList cmdline = VCToolBase::fixCommandLine(var("QMAKE_PRE_LINK"));
    11981176        conf.preLink.CommandLine = cmdline;
     1177        conf.preLink.Description = cmdline.join(QLatin1String("\r\n"));
    11991178    }
    12001179}
     
    16091588        ofile = ofile.replace('-', '_');
    16101589    } else {
    1611         int hypenfind = ofile.indexOf('-', slashfind);
    1612         while (hypenfind != -1 && slashfind < hypenfind) {
    1613             ofile = ofile.replace(hypenfind, 1, '_');
    1614             hypenfind = ofile.indexOf('-', hypenfind + 1);
     1590        int hyphenfind = ofile.indexOf('-', slashfind);
     1591        while (hyphenfind != -1 && slashfind < hyphenfind) {
     1592            ofile = ofile.replace(hyphenfind, 1, '_');
     1593            hyphenfind = ofile.indexOf('-', hyphenfind + 1);
    16151594        }
    16161595    }
     
    16271606       !exists((ret = QString(QLibraryInfo::location(QLibraryInfo::DataPath) + "/win32-msvc2003/" + file))) &&
    16281607       !exists((ret = QString(QLibraryInfo::location(QLibraryInfo::DataPath) + "/win32-msvc2005/" + file))) &&
    1629        !exists((ret = QString(QLibraryInfo::location(QLibraryInfo::DataPath) + "/win32-msvc2008/" + file))) &&
    1630        !exists((ret = (QString(qgetenv("HOME")) + "/.tmake/" + file))))
     1608       !exists((ret = QString(QLibraryInfo::location(QLibraryInfo::DataPath) + "/win32-msvc2008/" + file))))
    16311609        return "";
    16321610    debug_msg(1, "Generator: MSVC.NET: Found template \'%s\'", ret.toLatin1().constData());
  • trunk/qmake/generators/win32/msvc_vcproj.h

    r651 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)
     
    6262    bool writeMakefile(QTextStream &);
    6363    bool writeProjectMakefile();
    64     void writeSubDirs(QTextStream &t);
    6564
    6665    QString findTemplate(QString file);
     
    120119    void initExtraCompilerOutputs();
    121120
     121    void writeSubDirs(QTextStream &t); // Called from VCXProj backend
     122    QUuid getProjectUUID(const QString &filename=QString()); // Called from VCXProj backend
     123
    122124    Target projectTarget;
    123125
     
    129131
    130132private:
    131     QString fixCommandLine(DotNET version, const QString &input) const;
    132     QUuid getProjectUUID(const QString &filename=QString());
    133133    QUuid increaseUUID(const QUuid &id);
    134134    friend class VCFilter;
  • trunk/qmake/generators/win32/winmakefile.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)
     
    473473        project->values("RES_FILE").prepend(fileInfo(resFile).fileName());
    474474        if (!project->values("OBJECTS_DIR").isEmpty()) {
    475             if(project->isActiveConfig("staticlib"))
    476                 project->values("RES_FILE").first().prepend(fileInfo(project->values("DESTDIR").first()).absoluteFilePath() + Option::dir_sep);
     475            QString resDestDir;
     476            if (project->isActiveConfig("staticlib"))
     477                resDestDir = fileInfo(project->first("DESTDIR")).absoluteFilePath();
    477478            else
    478               project->values("RES_FILE").first().prepend(project->values("OBJECTS_DIR").first() + Option::dir_sep);
     479                resDestDir = project->first("OBJECTS_DIR");
     480            resDestDir.append(Option::dir_sep);
     481            project->values("RES_FILE").first().prepend(resDestDir);
    479482        }
    480483        project->values("RES_FILE").first() = Option::fixPathToTargetOS(project->values("RES_FILE").first(), false, false);
     
    605608    writeLibsPart(t);
    606609
    607     t << "QMAKE         = " << (project->isEmpty("QMAKE_QMAKE") ? QString("qmake") :
    608                               Option::fixPathToTargetOS(var("QMAKE_QMAKE"), false)) << endl;
     610    t << "QMAKE         = " << var("QMAKE_QMAKE") << endl;
    609611    t << "IDC           = " << (project->isEmpty("QMAKE_IDC") ? QString("idc") :
    610612                              Option::fixPathToTargetOS(var("QMAKE_IDC"), false)) << endl;
     
    658660    t << "DIST          = " << varList("DISTFILES") << endl;
    659661    t << "QMAKE_TARGET  = " << var("QMAKE_ORIG_TARGET") << endl;
    660     // The comment is important to maintain variable compatability with Unix
     662    // The comment is important to maintain variable compatibility with Unix
    661663    // Makefiles, while not interpreting a trailing-slash as a linebreak
    662664    t << "DESTDIR        = " << escapeFilePath(destDir) << " #avoid trailing-slash linebreak" << endl;
     
    789791        target = project->first("TARGET");
    790792    return QString(target + project->first("TARGET_VERSION_EXT") + ".lib");
     793}
     794
     795QString Win32MakefileGenerator::getPdbTarget()
     796{
     797    return QString(project->first("TARGET") + project->first("TARGET_VERSION_EXT") + ".pdb");
    791798}
    792799
     
    841848            uninst.append("-$(DEL_FILE) \"" + dst_targ + "\"" + del_suffix);
    842849        }
     850        if(project->isActiveConfig("shared") && project->isActiveConfig("debug")) {
     851            QString pdb_target = getPdbTarget();
     852            pdb_target.remove('"');
     853            QString src_targ = (project->isEmpty("DESTDIR") ? QString("$(DESTDIR)") : project->first("DESTDIR")) + pdb_target;
     854            QString dst_targ = filePrefixRoot(root, fileFixify(targetdir + pdb_target, FileFixifyAbsolute));
     855            if(!ret.isEmpty())
     856                ret += "\n\t";
     857            ret += QString("-$(INSTALL_FILE)") + " \"" + src_targ + "\" \"" + dst_targ + "\"";
     858            if(!uninst.isEmpty())
     859                uninst.append("\n\t");
     860            uninst.append("-$(DEL_FILE) \"" + dst_targ + "\"");
     861        }
    843862    }
    844863
  • trunk/qmake/generators/win32/winmakefile.h

    r651 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)
     
    8585    virtual void processFileTagsVar();
    8686    virtual QString getLibTarget();
     87    virtual QString getPdbTarget();
    8788};
    8889
  • trunk/qmake/generators/xmloutput.cpp

    r651 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)
     
    8080{
    8181    currentState = state;
     82}
     83
     84void XmlOutput::setFormat(XMLFormat newFormat)
     85{
     86    format = newFormat;
    8287}
    8388
     
    173178        newTagOpen(o.xo_text);
    174179        break;
     180    case tTagValue:
     181        addRaw(QString("\n%1<%2>").arg(currentIndent).arg(o.xo_text));
     182        addRaw(QString("%1").arg(o.xo_value));
     183        addRaw(QString("</%1>").arg(o.xo_text));
     184        break;
     185    case tValueTag:
     186        addRaw(QString("%1").arg(doConversion(o.xo_text)));
     187        setFormat(NoNewLine);
     188        closeTag();
     189        setFormat(NewLine);
     190        break;
     191    case tImport:
     192        addRaw(QString("\n%1<Import %2=\"%3\" />").arg(currentIndent).arg(o.xo_text).arg(o.xo_value));
     193        break;
    175194    case tCloseTag:
    176195        if (o.xo_value.count())
     
    183202    case tAttribute:
    184203        addAttribute(o.xo_text, o.xo_value);
     204        break;
     205    case tAttributeTag:
     206        addAttributeTag(o.xo_text, o.xo_value);
    185207        break;
    186208    case tData:
     
    267289            break;
    268290        case Attribute:
    269             xmlFile << "/>";
     291            xmlFile << " />";
    270292            tagStack.pop_back();
    271293            currentState = Tag;
     
    308330            return;
    309331    }
    310     QString outData = QString("<?xml version=\"%1\" encoding = \"%2\"?>")
     332    QString outData = QString("<?xml version=\"%1\" encoding=\"%2\"?>")
    311333                              .arg(doConversion(version))
    312334                              .arg(doConversion(encoding));
     
    338360}
    339361
     362void XmlOutput::addAttributeTag(const QString &attribute, const QString &value)
     363{
     364     switch(currentState) {
     365        case Bare:
     366        case Tag:
     367            //warn_msg(WarnLogic, "<%s>: Cannot add attribute since tags not open", tagStack.last().toLatin1().constData());
     368            qDebug("<%s>: Cannot add attribute (%s) since tag's not open",
     369                   (tagStack.count() ? tagStack.last().toLatin1().constData() : "Root"),
     370                   attribute.toLatin1().constData());
     371            return;
     372        case Attribute:
     373            break;
     374    }
     375    xmlFile << " " << doConversion(attribute) << "=\"" << doConversion(value) << "\"";
     376}
     377
    340378QT_END_NAMESPACE
  • trunk/qmake/generators/xmloutput.h

    r651 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)
     
    7070        tDeclaration,       // <?xml version="x.x" encoding="xxx"?>
    7171        tTag,               // <tagname attribute1="value"
     72        tTagValue,          // <tagname>value</tagname>
     73        tValueTag,          // value</tagname>
    7274        tCloseTag,          // Closes an open tag
    7375        tAttribute,         //  attribute2="value">
     76        tAttributeTag,      //  attribute on the same line as a tag
    7477        tData,              // Tag data (formating done)
     78        tImport,            // <import "type"="path" />
    7579        tComment,           // <!-- Comment -->
    7680        tCDATA              // <![CDATA[ ... ]]>
     
    8690    int indentLevel();
    8791    void setState(XMLState state);
     92    void setFormat(XMLFormat newFormat);
    8893    XMLState state();
    8994
     
    122127    void addRaw(const QString &rawText);
    123128    void addAttribute(const QString &attribute, const QString &value);
     129    void addAttributeTag(const QString &attribute, const QString &value);
    124130    void addData(const QString &data);
    125131
     
    164170}
    165171
     172
     173inline XmlOutput::xml_output valueTag(const QString &value)
     174{
     175    return XmlOutput::xml_output(XmlOutput::tValueTag, value, QString());
     176}
     177
     178inline XmlOutput::xml_output tagValue(const QString &tagName, const QString &value)
     179{
     180    return XmlOutput::xml_output(XmlOutput::tTagValue, tagName, value);
     181}
     182
     183inline XmlOutput::xml_output import(const QString &tagName, const QString &value)
     184{
     185    return XmlOutput::xml_output(XmlOutput::tImport, tagName, value);
     186}
     187
    166188inline XmlOutput::xml_output closetag()
    167189{
     
    185207}
    186208
     209inline XmlOutput::xml_output attributeTag(const QString &name,
     210                                       const QString &value)
     211{
     212    return XmlOutput::xml_output(XmlOutput::tAttributeTag, name, value);
     213}
     214
    187215inline XmlOutput::xml_output attr(const QString &name,
    188216                                  const QString &value)
     
    191219}
    192220
     221inline XmlOutput::xml_output attrTag(const QString &name,
     222                                  const QString &value)
     223{
     224    return attributeTag(name, value);
     225}
     226
    193227inline XmlOutput::xml_output data(const QString &text = QString())
    194228{
Note: See TracChangeset for help on using the changeset viewer.