From e7d505e35666393ea965e41c59742f609344e858 Mon Sep 17 00:00:00 2001 From: axis Date: Mon, 1 Nov 2010 17:05:18 +0100 Subject: Fixed event starvation with pointer events on Symbian. The CEikonEnv active object is used by Symbian to indicate that new window server events are available, in this case pointer events. Since this object was being controlled by Symbian, it was not subject to Qt's round robin queue. In a case where the event handler for the pointer event would take very long, it was possible for the active object to be completed again before the previous handler was finished, causing it to be called in a loop. This was fixed by making a new Qt-owned class as a subclass of CEikonEnv, and in its RunL, make sure that the object follows the round-robin queue. Because the round robin code is located in a subclass of CEikonEnv that we own, the fix will have no effect if Qt is loaded after the Eikon framework (such as a Qt plugin in a non-Qt app). Task: QT-4077 RevBy: mread AutoTest: N/A, system events --- src/corelib/kernel/qeventdispatcher_symbian.cpp | 9 ++-- src/corelib/kernel/qeventdispatcher_symbian_p.h | 4 +- src/gui/kernel/qapplication_s60.cpp | 2 +- src/gui/kernel/qeventdispatcher_s60.cpp | 66 +++++++++++++++++++++++++ src/gui/kernel/qeventdispatcher_s60_p.h | 24 +++++++++ 5 files changed, 100 insertions(+), 5 deletions(-) diff --git a/src/corelib/kernel/qeventdispatcher_symbian.cpp b/src/corelib/kernel/qeventdispatcher_symbian.cpp index d8cc344..bb9bd01 100644 --- a/src/corelib/kernel/qeventdispatcher_symbian.cpp +++ b/src/corelib/kernel/qeventdispatcher_symbian.cpp @@ -975,9 +975,7 @@ bool QEventDispatcherSymbian::sendPostedEvents() inline void QEventDispatcherSymbian::addDeferredActiveObject(QActiveObject *object) { - if (m_deferredActiveObjects.isEmpty()) { - m_completeDeferredAOs->complete(); - } + queueDeferredActiveObjectsCompletion(); m_deferredActiveObjects.append(object); } @@ -986,6 +984,11 @@ inline void QEventDispatcherSymbian::removeDeferredActiveObject(QActiveObject *o m_deferredActiveObjects.removeAll(object); } +void QEventDispatcherSymbian::queueDeferredActiveObjectsCompletion() +{ + m_completeDeferredAOs->complete(); +} + void QEventDispatcherSymbian::reactivateDeferredActiveObjects() { while (!m_deferredActiveObjects.isEmpty()) { diff --git a/src/corelib/kernel/qeventdispatcher_symbian_p.h b/src/corelib/kernel/qeventdispatcher_symbian_p.h index 1486db5..3615996 100644 --- a/src/corelib/kernel/qeventdispatcher_symbian_p.h +++ b/src/corelib/kernel/qeventdispatcher_symbian_p.h @@ -247,7 +247,9 @@ public: void addDeferredActiveObject(QActiveObject *object); void removeDeferredActiveObject(QActiveObject *object); - void reactivateDeferredActiveObjects(); + void queueDeferredActiveObjectsCompletion(); + // Can be overridden to activate local active objects too, but do call baseclass! + virtual void reactivateDeferredActiveObjects(); inline int iterationCount() const { return m_iterationCount; } diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp index 5ff2fd4..7c2ab29 100644 --- a/src/gui/kernel/qapplication_s60.cpp +++ b/src/gui/kernel/qapplication_s60.cpp @@ -1425,7 +1425,7 @@ void qt_init(QApplicationPrivate * /* priv */, int) TInt err = CApaCommandLine::GetCommandLineFromProcessEnvironment(commandLine); // After this construction, CEikonEnv will be available from CEikonEnv::Static(). // (much like our qApp). - CEikonEnv* coe = new CEikonEnv; + QtEikonEnv* coe = new QtEikonEnv; //not using QT_TRAP_THROWING, because coe owns the cleanupstack so it can't be pushed there. if(err == KErrNone) TRAP(err, coe->ConstructAppFromCommandLineL(factory,*commandLine)); diff --git a/src/gui/kernel/qeventdispatcher_s60.cpp b/src/gui/kernel/qeventdispatcher_s60.cpp index bc787b8..77ebd0d 100644 --- a/src/gui/kernel/qeventdispatcher_s60.cpp +++ b/src/gui/kernel/qeventdispatcher_s60.cpp @@ -45,6 +45,62 @@ QT_BEGIN_NAMESPACE +QtEikonEnv::QtEikonEnv() + : m_lastIterationCount(0) + , m_savedStatusCode(KRequestPending) + , m_hasAlreadyRun(false) +{ +} + +QtEikonEnv::~QtEikonEnv() +{ +} + +void QtEikonEnv::RunL() +{ + QEventDispatcherS60 *dispatcher = qobject_cast(QAbstractEventDispatcher::instance()); + if (!dispatcher) { + CEikonEnv::RunL(); + return; + } + + if (m_lastIterationCount != dispatcher->iterationCount()) { + m_hasAlreadyRun = false; + m_lastIterationCount = dispatcher->iterationCount(); + } + + if (m_hasAlreadyRun) { + // Fool the active scheduler into believing we are still waiting for events. + // The window server thinks we are not, however. + m_savedStatusCode = iStatus.Int(); + iStatus = KRequestPending; + SetActive(); + dispatcher->queueDeferredActiveObjectsCompletion(); + } else { + m_hasAlreadyRun = true; + CEikonEnv::RunL(); + } +} + +void QtEikonEnv::DoCancel() +{ + complete(); + + CEikonEnv::DoCancel(); +} + +void QtEikonEnv::complete() +{ + if (m_hasAlreadyRun) { + if (m_savedStatusCode != KRequestPending) { + TRequestStatus *status = &iStatus; + QEventDispatcherSymbian::RequestComplete(status, m_savedStatusCode); + m_savedStatusCode = KRequestPending; + } + m_hasAlreadyRun = false; + } +} + QEventDispatcherS60::QEventDispatcherS60(QObject *parent) : QEventDispatcherSymbian(parent), m_noInputEvents(false) @@ -127,4 +183,14 @@ void QEventDispatcherS60::removeInputEventsForWidget(QObject *object) } } +// reimpl +void QEventDispatcherS60::reactivateDeferredActiveObjects() +{ + if (S60->qtOwnsS60Environment) { + static_cast(CCoeEnv::Static())->complete(); + } + + QEventDispatcherSymbian::reactivateDeferredActiveObjects(); +} + QT_END_NAMESPACE diff --git a/src/gui/kernel/qeventdispatcher_s60_p.h b/src/gui/kernel/qeventdispatcher_s60_p.h index d2f327c..c14fef0 100644 --- a/src/gui/kernel/qeventdispatcher_s60_p.h +++ b/src/gui/kernel/qeventdispatcher_s60_p.h @@ -56,8 +56,30 @@ #include #include "qt_s60_p.h" +#include + QT_BEGIN_NAMESPACE +class QEventDispatcherS60; + +class QtEikonEnv : public CEikonEnv +{ +public: + QtEikonEnv(); + ~QtEikonEnv(); + + // from CActive. + void RunL(); + void DoCancel(); + + void complete(); + +private: + int m_lastIterationCount; + TInt m_savedStatusCode; + bool m_hasAlreadyRun; +}; + class Q_GUI_EXPORT QEventDispatcherS60 : public QEventDispatcherSymbian { Q_OBJECT @@ -73,6 +95,8 @@ public: void saveInputEvent(QSymbianControl *control, QWidget *widget, QInputEvent *event); + void reactivateDeferredActiveObjects(); + private: bool sendDeferredInputEvents(); -- cgit v0.12 From e6ad4d01e1ff483f5ed81168ffa4500deaf69954 Mon Sep 17 00:00:00 2001 From: axis Date: Mon, 1 Nov 2010 19:38:20 +0100 Subject: Fixed test after the fix to QT-4077. Since the events are balanced now, we need to give them time to get through. RevBy: Trust me --- tests/auto/qinputcontext/tst_qinputcontext.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/auto/qinputcontext/tst_qinputcontext.cpp b/tests/auto/qinputcontext/tst_qinputcontext.cpp index 7811a53..5a258a9 100644 --- a/tests/auto/qinputcontext/tst_qinputcontext.cpp +++ b/tests/auto/qinputcontext/tst_qinputcontext.cpp @@ -158,8 +158,8 @@ public: } // For some reason, the test fails if using processEvents instead of an event loop - // with a zero timer to quit it, so use the timer. -#define KEY_WAIT 0 + // with a timer to quit it, so use the timer. +#define KEY_WAIT 10 void replay(QWidget *w) { -- cgit v0.12 From 5fffdfb33379210ef37a68ae4257e693f7181c48 Mon Sep 17 00:00:00 2001 From: axis Date: Fri, 5 Nov 2010 16:23:34 +0100 Subject: Revert "Use qtmain.lib to provide entry point for all Symbian applications" This reverts commit 564058a1bbfb1c67bc3d68b7c7a2ebfe83481334. It breaks massively on the symbian/linux-armcc mkspec. Will find a different solution. --- mkspecs/common/symbian/symbian.conf | 3 +-- mkspecs/features/symbian/default_post.prf | 3 +++ mkspecs/features/symbian/symbian_building.prf | 20 +++++++++++++++----- 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/mkspecs/common/symbian/symbian.conf b/mkspecs/common/symbian/symbian.conf index 6d1f708..decec14 100644 --- a/mkspecs/common/symbian/symbian.conf +++ b/mkspecs/common/symbian/symbian.conf @@ -79,6 +79,7 @@ QMAKE_LIBS_OPENGL_ES2_QT = -llibglesv2 -lcone -lws32 QMAKE_LIBS_OPENVG = -llibOpenVG -lfbscli -lbitgdi -lgdi QMAKE_LIBS_THREAD = -llibpthread QMAKE_LIBS_COMPAT = +QMAKE_LIBS_QT_ENTRY = -llibcrt0.lib QMAKE_LIBS_S60 = -lavkon -leikcoctl exists($${EPOCROOT}epoc32/include/platform/sgresource/sgimage.h) { @@ -126,8 +127,6 @@ QT_ARCH = symbian load(qt_config) -QMAKE_LIBS_QT_ENTRY = -lqtmain$${QT_LIBINFIX}.lib - # These directories must match what configure uses for QT_INSTALL_PLUGINS and QT_INSTALL_IMPORTS QT_PLUGINS_BASE_DIR = /resource/qt$${QT_LIBINFIX}/plugins QT_IMPORTS_BASE_DIR = /resource/qt/imports diff --git a/mkspecs/features/symbian/default_post.prf b/mkspecs/features/symbian/default_post.prf index 348c366..0564e9b 100644 --- a/mkspecs/features/symbian/default_post.prf +++ b/mkspecs/features/symbian/default_post.prf @@ -3,6 +3,9 @@ load(default_post) contains(TEMPLATE, ".*app") { contains(CONFIG, stdbinary) { QMAKE_LIBS += + } else:contains(QT, gui):contains(CONFIG,qt) { + S60MAIN_LIBS = -leuser + QMAKE_LIBS += -lqtmain$${QT_LIBINFIX}.lib $$S60MAIN_LIBS } else { QMAKE_LIBS += $$QMAKE_LIBS_QT_ENTRY } diff --git a/mkspecs/features/symbian/symbian_building.prf b/mkspecs/features/symbian/symbian_building.prf index 20bc3a3..1a51cb2 100644 --- a/mkspecs/features/symbian/symbian_building.prf +++ b/mkspecs/features/symbian/symbian_building.prf @@ -187,16 +187,26 @@ contains(TEMPLATE, app):!contains(QMAKE_LINK, "^@:.*") { linux-armcc: { QMAKE_LIBS += usrt2_2.lib dfpaeabi.dso dfprvct2_2.dso drtaeabi.dso scppnwdl.dso drtrvct2_2.dso h_t__uf.l\\(switch8.o\\) QMAKE_LIBS += -leexe.lib\\(uc_exe_.o\\) - QMAKE_LIBS -= $$QMAKE_LIBS_QT_ENTRY - QMAKE_LIBS += $$QMAKE_LIBS_QT_ENTRY + contains(CONFIG, "qt"):contains(QT, "gui") { #if linking with QtCore + QMAKE_LIBS -= -lqtmain$${QT_LIBINFIX}.lib + QMAKE_LIBS += -lqtmain$${QT_LIBINFIX}.lib + } else { + QMAKE_LIBS -= -llibcrt0.lib + QMAKE_LIBS += -llibcrt0.lib + } } else :linux-gcce { # notice that we can't merge these as ordering of arguments is important. QMAKE_LIBS += \ -l:eexe.lib \ -l:usrt2_2.lib - modified_entry = $$replace(QMAKE_LIBS_QT_ENTRY, "^-l", "-l:") - QMAKE_LIBS -= $$modified_entry - QMAKE_LIBS += $$modified_entry + contains(CONFIG, "qt"):contains(QT, "gui") { #if linking with QtCore + QMAKE_LIBS -= -l:qtmain$${QT_LIBINFIX}.lib + QMAKE_LIBS += -l:qtmain$${QT_LIBINFIX}.lib + } else { + QMAKE_LIBS -= -l:libcrt0.lib + QMAKE_LIBS -= -l:libcrt0_gcce.lib + QMAKE_LIBS += -l:libcrt0_gcce.lib + } QMAKE_LIBS += \ -l:dfpaeabi.dso \ -l:drtaeabi.dso \ -- cgit v0.12 From d3f8374c9e980b9e74cde2ee6cba8dd8312e5ac4 Mon Sep 17 00:00:00 2001 From: axis Date: Mon, 8 Nov 2010 10:49:37 +0100 Subject: Added missing def file symbol. --- src/s60installs/eabi/QtCoreu.def | 1 + 1 file changed, 1 insertion(+) diff --git a/src/s60installs/eabi/QtCoreu.def b/src/s60installs/eabi/QtCoreu.def index eb53dca..aefbe1f 100644 --- a/src/s60installs/eabi/QtCoreu.def +++ b/src/s60installs/eabi/QtCoreu.def @@ -3713,4 +3713,5 @@ EXPORTS _ZrsR11QDataStreamR12QEasingCurve @ 3712 NONAME _Z26qt_symbian_SetupThreadHeapiR24SStdEpocThreadCreateInfo @ 3713 NONAME _ZN24QAbstractDeclarativeData17objectNameChangedE @ 3714 NONAME DATA 4 + _ZN23QEventDispatcherSymbian36queueDeferredActiveObjectsCompletionEv @ 3715 NONAME -- cgit v0.12 From e8b10f2239a15e8d0ad1b676b7f03d03543efc67 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Fri, 5 Nov 2010 16:20:00 +0200 Subject: Allow pkg_prerules and pkg_postrules to be targeted to separate files Pkg_prerules and pkg_postrules can now be targeted to apply only to main template pkg, installer pkg, or stub pkg file using .main, .installer, or .stub suffix on the variable. Also clarified documentation of these variables. Cherry picked to 4.7 branch from master branch as part of QTBUG-15068, original commit: a537137fffd72d153a35828228c00567a563e787 Task-number: QTBUG-15068 Task-number: QTBUG-13159 Reviewed-by: axis Conflicts: doc/src/development/qmake-manual.qdoc doc/src/snippets/code/doc_src_qmake-manual.qdoc --- doc/src/development/qmake-manual.qdoc | 31 +++- doc/src/snippets/code/doc_src_qmake-manual.qdoc | 5 + qmake/generators/symbian/symbiancommon.cpp | 235 ++++++++++++++++-------- qmake/generators/symbian/symbiancommon.h | 11 ++ 4 files changed, 197 insertions(+), 85 deletions(-) diff --git a/doc/src/development/qmake-manual.qdoc b/doc/src/development/qmake-manual.qdoc index d65967d..a520838 100644 --- a/doc/src/development/qmake-manual.qdoc +++ b/doc/src/development/qmake-manual.qdoc @@ -1394,12 +1394,16 @@ On the Symbian platform, generic PKG file content can also be specified with this variable. You can use either \c pkg_prerules or \c pkg_postrules to pass raw data to PKG file. The strings in \c pkg_prerules are added before - package-body and \c pkg_postrules after. The strings defined in - \c pkg_postrules or \c pkg_prerules are not parsed by qmake, so they - should be in a format understood by Symbian package generation tools. + package-body and \c pkg_postrules after. \c pkg_prerules is used for + defining vendor information, dependencies, custom package headers, and the + like, while \c pkg_postrules is used for custom file deployment and + embedded sis directives. + The strings defined in \c pkg_postrules or \c pkg_prerules are not parsed + by qmake, so they should be in a format understood by Symbian package + generation tools. Please consult the Symbian platform documentation for correct syntax. - For example, to deploy DLL and add a new dependency: + For example, to deploy DLL and add a new dependency: \snippet doc/src/snippets/code/doc_src_qmake-manual.qdoc 140 @@ -1415,13 +1419,28 @@ \o localized and unique vendor, for example \BR %{"Vendor-EN", ..., "Vendor-FR"} :"Unique vendor name" - \endlist + \endlist - If you decide to override any of these statements, you need to pay + If you decide to override any of these statements, you need to pay attention that also other statements stay valid. For example if you override languages statement, you must override also package-header statement and all other statements which are language specific. + On the Symbian platform, three separate PKG files are generated: + + \list + \o _template.pkg - For application SIS file. Rules suffix: \c{.main} + \o _installer.pkg - For smart installer SIS file. Rules suffix: \c{.installer} + \o _stub.pkg - For ROM stubs. Rules suffix: \c{.stub} + \endlist + + \c pkg_prerules and \c pkg_postrules given without rules suffix will + intelligently apply to each of these files, but rules can also be + targeted to only one of above files by appending listed rules suffix + to the variable name: + + \snippet doc/src/snippets/code/doc_src_qmake-manual.qdoc 153 + On the Symbian platform, the \c default_deployment item specifies default platform and package dependencies. Those dependencies can be selectively disabled if alternative dependencies need to be defined diff --git a/doc/src/snippets/code/doc_src_qmake-manual.qdoc b/doc/src/snippets/code/doc_src_qmake-manual.qdoc index 8c35c3f..379d081 100644 --- a/doc/src/snippets/code/doc_src_qmake-manual.qdoc +++ b/doc/src/snippets/code/doc_src_qmake-manual.qdoc @@ -1009,3 +1009,8 @@ my_exports = \ "bar.h /epoc32/include/mylib/bar.h" BLD_INF_RULES.prj_exports += my_exports //! [152] + +//! [153] +my_note.pkg_postrules.installer = "\"myinstallnote.txt\" - \"\", FILETEXT, TEXTCONTINUE" +DEPLOYMENT += my_note +//! [153] diff --git a/qmake/generators/symbian/symbiancommon.cpp b/qmake/generators/symbian/symbiancommon.cpp index 6fea8fd..3183e27 100644 --- a/qmake/generators/symbian/symbiancommon.cpp +++ b/qmake/generators/symbian/symbiancommon.cpp @@ -204,44 +204,71 @@ void SymbianCommonGenerator::generatePkgFile(const QString &iconFile, bool epocB tw << headerComment.arg(wrapperPkgFilename).arg(dateStr); ts << headerComment.arg(stubPkgFileName).arg(dateStr); - // Construct QStringList from pkg_prerules since we need search it before printed to file - // Note: Though there can't be more than one language or header line, use stringlists + QStringList commonRawPreRules; + QStringList mainRawPreRules; + QStringList instRawPreRules; + QStringList stubRawPreRules; + + // Though there can't be more than one language or header line, use stringlists // in case user wants comments to go with the rules. - QStringList rawPkgPreRules; + // Note that it makes no sense to have file specific language or header rules, + // except what is provided for installer header via "DEPLOYMENT.installer_header" variable, + // because stub and main headers should always match. Vendor rules are similarly limited to + // make code cleaner as it is unlikely anyone will want different vendor in different files. QStringList languageRules; QStringList headerRules; - foreach(QString deploymentItem, project->values("DEPLOYMENT")) { - foreach(QString pkgrulesItem, project->values(deploymentItem + ".pkg_prerules")) { - QStringList pkgrulesValue = project->values(pkgrulesItem); - // If there is no stringlist defined for a rule, use rule name directly - // This is convenience for defining single line mmp statements - if (pkgrulesValue.isEmpty()) { - if (pkgrulesItem.startsWith("&")) - languageRules << pkgrulesItem; - else if (pkgrulesItem.startsWith("#")) - headerRules << pkgrulesItem; - else - rawPkgPreRules << pkgrulesItem; - } else { - if (containsStartWithItem('&', pkgrulesValue)) { - foreach(QString pkgrule, pkgrulesValue) { - languageRules << pkgrule; - } - } else if (containsStartWithItem('#', pkgrulesValue)) { - foreach(QString pkgrule, pkgrulesValue) { - headerRules << pkgrule; - } - } else { - foreach(QString pkgrule, pkgrulesValue) { - rawPkgPreRules << pkgrule; - } - } - } + QStringList vendorRules; + + QStringList commonRawPostRules; + QStringList mainRawPostRules; + QStringList instRawPostRules; + QStringList stubRawPostRules; + + QStringList failList; // Used for detecting incorrect usage + + QString emptySuffix; + QString mainSuffix(".main"); + QString instSuffix(".installer"); + QString stubSuffix(".stub"); + + foreach(QString item, project->values("DEPLOYMENT")) { + parsePreRules(item, emptySuffix, &commonRawPreRules, &languageRules, &headerRules, &vendorRules); + parsePreRules(item, mainSuffix, &mainRawPreRules, &failList, &failList, &failList); + parsePreRules(item, instSuffix, &instRawPreRules, &failList, &failList, &failList); + parsePreRules(item, stubSuffix, &stubRawPreRules, &failList, &failList, &failList); + + parsePostRules(item, emptySuffix, &commonRawPostRules); + parsePostRules(item, mainSuffix, &mainRawPostRules); + parsePostRules(item, instSuffix, &instRawPostRules); + parsePostRules(item, stubSuffix, &stubRawPostRules); + } + + if (!failList.isEmpty()) { + fprintf(stderr, "Warning: Custom language, header, or vendor definitions are not " + "supported by file specific pkg_prerules.* variables.\n" + "Use plain pkg_prerules and/or DEPLOYMENT.installer_header for customizing " + "these items.\n"); + } + + foreach(QString item, commonRawPreRules) { + if (item.startsWith("(")) { + // Only regular pkg file should have package dependencies + mainRawPreRules << item; + } else if (item.startsWith("[")) { + // stub pkg file should not have platform dependencies + mainRawPreRules << item; + instRawPreRules << item; + } else { + mainRawPreRules << item; + instRawPreRules << item; + stubRawPreRules << item; } } - // Apply some defaults if specific data does not exist in PKG pre-rules + // Currently common postrules only go to main + mainRawPostRules << commonRawPostRules; + // Apply some defaults if specific data does not exist in PKG pre-rules if (languageRules.isEmpty()) { // language, (*** hardcoded to english atm, should be parsed from TRANSLATIONS) languageRules << "; Language\n&EN\n\n"; @@ -313,49 +340,38 @@ void SymbianCommonGenerator::generatePkgFile(const QString &iconFile, bool epocB ts << headerRules.join("\n") << endl; } - // Localized vendor name - QString vendorName; - if (!containsStartWithItem('%', rawPkgPreRules)) { - vendorName += "; Localised Vendor name\n%{\"Vendor\"}\n\n"; + // Vendor name + if (!containsStartWithItem('%', vendorRules)) { + vendorRules << "; Default localized vendor name\n%{\"Vendor\"}\n\n"; } - - // Unique vendor name - if (!containsStartWithItem(':', rawPkgPreRules)) { - vendorName += "; Unique Vendor name\n:\"Vendor\"\n\n"; + if (!containsStartWithItem(':', vendorRules)) { + vendorRules << "; Default unique vendor name\n:\"Vendor\"\n\n"; } - t << vendorName; - tw << vendorName; - ts << vendorName; + t << vendorRules.join("\n") << endl; + tw << vendorRules.join("\n") << endl; + ts << vendorRules.join("\n") << endl; // PKG pre-rules - these are added before actual file installations i.e. SIS package body - if (rawPkgPreRules.size()) { - QString comment = "\n; Manual PKG pre-rules from PRO files\n"; + QString comment = "\n; Manual PKG pre-rules from PRO files\n"; + + if (mainRawPreRules.size()) { t << comment; + t << mainRawPreRules.join("\n") << endl; + } + if (instRawPreRules.size()) { tw << comment; + tw << instRawPreRules.join("\n") << endl; + } + if (stubRawPreRules.size()) { ts << comment; - - foreach(QString item, rawPkgPreRules) { - // Only regular pkg file should have package dependencies - if (item.startsWith("(")) { - t << item << endl; - } - // stub pkg file should not have platform dependencies - else if (item.startsWith("[")) { - t << item << endl; - tw << item << endl; - } - else { - t << item << endl; - ts << item << endl; - tw << item << endl; - } - } - t << endl; - ts << endl; - tw << endl; + ts << stubRawPreRules.join("\n") << endl; } + t << endl; + tw << endl; + ts << endl; + // Begin Manufacturer block if (!project->values("DEPLOYMENT.manufacturers").isEmpty()) { QString manufacturerStr("IF "); @@ -481,21 +497,19 @@ void SymbianCommonGenerator::generatePkgFile(const QString &iconFile, bool epocB ts << endl; // PKG post-rules - these are added after actual file installations i.e. SIS package body - t << "; Manual PKG post-rules from PRO files" << endl; - foreach(QString deploymentItem, project->values("DEPLOYMENT")) { - foreach(QString pkgrulesItem, project->values(deploymentItem + ".pkg_postrules")) { - QStringList pkgrulesValue = project->values(pkgrulesItem); - // If there is no stringlist defined for a rule, use rule name directly - // This is convenience for defining single line statements - if (pkgrulesValue.isEmpty()) { - t << pkgrulesItem << endl; - } else { - foreach(QString pkgrule, pkgrulesValue) { - t << pkgrule << endl; - } - } - t << endl; - } + comment = "; Manual PKG post-rules from PRO files\n"; + + if (mainRawPostRules.size()) { + t << comment; + t << mainRawPostRules.join("\n") << endl; + } + if (instRawPostRules.size()) { + tw << comment; + tw << instRawPostRules.join("\n") << endl; + } + if (stubRawPostRules.size()) { + ts << comment; + ts << stubRawPostRules.join("\n") << endl; } // Close Manufacturer block @@ -1037,3 +1051,66 @@ void SymbianCommonGenerator::fillQt2S60LangMapTable() qt2S60LangMapTable.insert("ny", "SC"); //Chewa // } +void SymbianCommonGenerator::parsePreRules(const QString &deploymentVariable, + const QString &variableSuffix, + QStringList *rawRuleList, + QStringList *languageRuleList, + QStringList *headerRuleList, + QStringList *vendorRuleList) +{ + QMakeProject *project = generator->project; + foreach(QString pkgrulesItem, project->values(deploymentVariable + ".pkg_prerules" + variableSuffix)) { + QStringList pkgrulesValue = project->values(pkgrulesItem); + // If there is no stringlist defined for a rule, use rule name directly + // This is convenience for defining single line statements + if (pkgrulesValue.isEmpty()) { + if (pkgrulesItem.startsWith("&")) + *languageRuleList << pkgrulesItem; + else if (pkgrulesItem.startsWith("#")) + *headerRuleList << pkgrulesItem; + else if (pkgrulesItem.startsWith("%") || pkgrulesItem.startsWith(":")) + *vendorRuleList << pkgrulesItem; + else + *rawRuleList << pkgrulesItem; + } else { + if (containsStartWithItem('&', pkgrulesValue)) { + foreach(QString pkgrule, pkgrulesValue) { + *languageRuleList << pkgrule; + } + } else if (containsStartWithItem('#', pkgrulesValue)) { + foreach(QString pkgrule, pkgrulesValue) { + *headerRuleList << pkgrule; + } + } else if (containsStartWithItem('%', pkgrulesValue) + || containsStartWithItem(':', pkgrulesValue)) { + foreach(QString pkgrule, pkgrulesValue) { + *vendorRuleList << pkgrule; + } + } else { + foreach(QString pkgrule, pkgrulesValue) { + *rawRuleList << pkgrule; + } + } + } + } +} + +void SymbianCommonGenerator::parsePostRules(const QString &deploymentVariable, + const QString &variableSuffix, + QStringList *rawRuleList) +{ + QMakeProject *project = generator->project; + foreach(QString pkgrulesItem, project->values(deploymentVariable + ".pkg_postrules" + variableSuffix)) { + QStringList pkgrulesValue = project->values(pkgrulesItem); + // If there is no stringlist defined for a rule, use rule name directly + // This is convenience for defining single line statements + if (pkgrulesValue.isEmpty()) { + *rawRuleList << pkgrulesItem; + } else { + foreach(QString pkgrule, pkgrulesValue) { + *rawRuleList << pkgrule; + } + } + } +} + diff --git a/qmake/generators/symbian/symbiancommon.h b/qmake/generators/symbian/symbiancommon.h index dae1e4a..80f2079 100644 --- a/qmake/generators/symbian/symbiancommon.h +++ b/qmake/generators/symbian/symbiancommon.h @@ -86,6 +86,17 @@ protected: QStringList symbianLangCodesFromTsFiles(); void fillQt2S60LangMapTable(); + void parsePreRules(const QString &deploymentVariable, + const QString &variableSuffix, + QStringList *rawRuleList, + QStringList *languageRuleList, + QStringList *headerRuleList, + QStringList *vendorRuleList); + void parsePostRules(const QString &deploymentVariable, + const QString &variableSuffix, + QStringList *rawRuleList); + + protected: MakefileGenerator *generator; -- cgit v0.12 From 70770a2e4fc7581f56a39f7b8b89dd5782cd29c0 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Fri, 5 Nov 2010 16:45:39 +0200 Subject: Make default application deployment removable Default application deployment was hard coded in qmake, so it was impossible to replace with custom deployment. Now the default deployment is generated via .prf files and is removable. Cherry picked to 4.7 branch from master branch as part of QTBUG-15068, original commit: 494ce0dac35c7ade0ce78589878597a7ca912864 Task-number: QTBUG-15068 Task-number: QTBUG-13367 Reviewed-by: axis Conflicts: qmake/generators/symbian/symbiancommon.cpp --- doc/src/development/qmake-manual.qdoc | 16 +++++ doc/src/snippets/code/doc_src_qmake-manual.qdoc | 4 ++ mkspecs/common/symbian/symbian.conf | 2 +- mkspecs/features/symbian/application_icon.prf | 49 ++++++++++----- mkspecs/features/symbian/default_post.prf | 9 +-- qmake/generators/symbian/symbiancommon.cpp | 82 +------------------------ 6 files changed, 61 insertions(+), 101 deletions(-) diff --git a/doc/src/development/qmake-manual.qdoc b/doc/src/development/qmake-manual.qdoc index a520838..278822e 100644 --- a/doc/src/development/qmake-manual.qdoc +++ b/doc/src/development/qmake-manual.qdoc @@ -1458,6 +1458,22 @@ \snippet doc/src/snippets/code/doc_src_qmake-manual.qdoc 141 + On the Symbian platform, a default deployment is generated for all + application projects. You can modify the autogenerated default + deployment via following \c DEPLOYMENT variable values: + + \list + \o default_bin_deployment - Application executable + \o default_resource_deployment - Application resources, including icon + \o default_reg_deployment - Application registration file + \endlist + + For example: + + \snippet doc/src/snippets/code/doc_src_qmake-manual.qdoc 154 + + This will entirely remove the default application deployment. + On the Symbian platform, you can use \c{DEPLOYMENT.installer_header} variable to generate smart installer wrapper for your application. If you specify just UID of the installer package as the value, then diff --git a/doc/src/snippets/code/doc_src_qmake-manual.qdoc b/doc/src/snippets/code/doc_src_qmake-manual.qdoc index 379d081..20d8d45 100644 --- a/doc/src/snippets/code/doc_src_qmake-manual.qdoc +++ b/doc/src/snippets/code/doc_src_qmake-manual.qdoc @@ -1014,3 +1014,7 @@ BLD_INF_RULES.prj_exports += my_exports my_note.pkg_postrules.installer = "\"myinstallnote.txt\" - \"\", FILETEXT, TEXTCONTINUE" DEPLOYMENT += my_note //! [153] + +//! [154] +DEPLOYMENT -= default_bin_deployment default_resource_deployment default_reg_deployment +//! [154] diff --git a/mkspecs/common/symbian/symbian.conf b/mkspecs/common/symbian/symbian.conf index decec14..2fb799d 100644 --- a/mkspecs/common/symbian/symbian.conf +++ b/mkspecs/common/symbian/symbian.conf @@ -202,7 +202,7 @@ pkg_platform_dependencies = \ "[0x20032DE7],0,0,0,{\"S60ProductID\"}" \ " " -DEPLOYMENT += default_deployment +DEPLOYMENT += default_deployment default_bin_deployment default_resource_deployment default_reg_deployment defineReplace(symbianRemoveSpecialCharacters) { # Produce identical string to what SymbianCommonGenerator::removeSpecialCharacters and diff --git a/mkspecs/features/symbian/application_icon.prf b/mkspecs/features/symbian/application_icon.prf index 9a9395a..39f10fb 100644 --- a/mkspecs/features/symbian/application_icon.prf +++ b/mkspecs/features/symbian/application_icon.prf @@ -1,21 +1,39 @@ load(data_caging_paths) -# If no_icon keyword exist, the S60 UI app is just made hidden. This because S60 app FW -# requires the registration resource file to exist always -contains( CONFIG, no_icon ) { - symbian:RSS_RULES += "hidden = KAppIsHidden;" - CONFIG -= no_icon -} else { -# There is no point in compiling the MIF icon if no_icon CONFIGS is set - !isEmpty(ICON) { +contains(CONFIG, no_icon) { + # If no_icon keyword exist, the S60 UI app is just made hidden. This because S60 app FW + # requires the registration resource file to exist always + contains(QT, gui):contains(CONFIG, qt) { + symbian:RSS_RULES += "hidden = KAppIsHidden;" + CONFIG -= no_icon + } +} + +!contains(CONFIG, no_icon) { + baseTarget = $$symbianRemoveSpecialCharacters($$basename(TARGET)) + symbian-abld|symbian-sbsv2 { + resourceZDir = $$EPOCROOT$$HW_ZDIR$$APP_RESOURCE_DIR + regZDir = $$EPOCROOT$$HW_ZDIR$$REG_RESOURCE_IMPORT_DIR + } else { + isEmpty(DESTDIR) { + resourceZDir = . + } else { + resourceZDir = $$DESTDIR + } + regZDir = $$resourceZDir + } + default_resource_deployment.sources += $$resourceZDir/$${baseTarget}.rsc + default_resource_deployment.path = $$APP_RESOURCE_DIR + default_reg_deployment.sources += $$regZDir/$${baseTarget}_reg.rsc + default_reg_deployment.path = $$REG_RESOURCE_IMPORT_DIR + + !isEmpty(ICON) { !count(ICON, 1) { ICON = $$first(ICON) warning("Only first icon specified in ICON variable is used: $$ICON") } - baseTarget = $$symbianRemoveSpecialCharacters($$basename(TARGET)) - # Note: symbian-sbsv2 builds can't utilize extra compiler for mifconv, so ICON handling is done in code !symbian-sbsv2 { # Absolute path required for shadow builds. @@ -27,13 +45,10 @@ contains( CONFIG, no_icon ) { ICON_backslashed = $$ICON symbian-abld { + # ${ZDIR} is defined in Makefile mifIconZDir = ${ZDIR}$$APP_RESOURCE_DIR } else { - isEmpty(DESTDIR) { - mifIconZDir = . - } else { - mifIconZDir = $$DESTDIR - } + mifIconZDir = $$resourceZDir } # Extra compiler rules for mifconv @@ -54,5 +69,9 @@ contains( CONFIG, no_icon ) { # Rules to use generated MIF file from symbian resources RSS_RULES.number_of_icons = $$size(ICON_backslashed) RSS_RULES.icon_file = $$APP_RESOURCE_DIR/$${baseTarget}.mif + + default_resource_deployment.sources += $$resourceZDir/$${baseTarget}.mif } } + + diff --git a/mkspecs/features/symbian/default_post.prf b/mkspecs/features/symbian/default_post.prf index 0564e9b..362bd6c 100644 --- a/mkspecs/features/symbian/default_post.prf +++ b/mkspecs/features/symbian/default_post.prf @@ -9,6 +9,11 @@ contains(TEMPLATE, ".*app") { } else { QMAKE_LIBS += $$QMAKE_LIBS_QT_ENTRY } + + default_bin_deployment.sources += $$symbianRemoveSpecialCharacters($$basename(TARGET)).exe + default_bin_deployment.path += /sys/bin + + load(application_icon.prf) } contains(TEMPLATE, lib): { contains(CONFIG, staticlib)|contains(CONFIG, static): { @@ -26,10 +31,6 @@ contains(TEMPLATE, lib): { MMP_RULES -= EXPORTUNFROZEN } -contains(TEMPLATE, ".*app"):contains(QT, gui):contains(CONFIG,qt) { - load(application_icon.prf) -} - isEmpty(TARGET.UID3):TARGET.UID3 = $$generate_uid("$${OUT_PWD}/$${TARGET}") isEmpty(TARGET.UID2) { contains(CONFIG, stdbinary) { diff --git a/qmake/generators/symbian/symbiancommon.cpp b/qmake/generators/symbian/symbiancommon.cpp index 3183e27..c0a6626 100644 --- a/qmake/generators/symbian/symbiancommon.cpp +++ b/qmake/generators/symbian/symbiancommon.cpp @@ -383,87 +383,7 @@ void SymbianCommonGenerator::generatePkgFile(const QString &iconFile, bool epocB t << manufacturerStr << endl; } - // Install paths on the phone *** should be dynamic at some point - QString installPathBin = "!:\\sys\\bin"; - QString installPathResource = "!:\\resource\\apps"; - QString installPathRegResource = "!:\\private\\10003a3f\\import\\apps"; - - // Find location of builds - QString destDirBin; - QString destDirResource; - QString destDirRegResource; - if (epocBuild) { - destDirBin = QString("%1epoc32/release/$(PLATFORM)/$(TARGET)").arg(epocRoot()); - destDirResource = QString("%1epoc32/data/z/resource/apps").arg(epocRoot()); - destDirRegResource = QString("%1epoc32/data/z/private/10003a3f/import/apps").arg(epocRoot()); - } else { - destDirBin = project->first("DESTDIR"); - if (destDirBin.isEmpty()) - destDirBin = "."; - else if (destDirBin.endsWith('/') || destDirBin.endsWith('\\')) - destDirBin.chop(1); - destDirResource = destDirBin; - destDirRegResource = destDirBin; - } - - if (targetType == TypeExe) { - // deploy .exe file - t << "; Executable and default resource files" << endl; - QString exeFile = fixedTarget + ".exe"; - t << QString("\"%1/%2\" - \"%3\\%4\"") - .arg(destDirBin) - .arg(exeFile) - .arg(installPathBin) - .arg(exeFile) << endl; - ts << QString("\"\" - \"%1\\%2\"") - .arg(romPath(installPathBin)) - .arg(exeFile) << endl; - - // deploy rsc & reg_rsc file - if (!project->isActiveConfig("no_icon")) { - t << QString("\"%1/%2\" - \"%3\\%4\"") - .arg(destDirResource) - .arg(fixedTarget + ".rsc") - .arg(installPathResource) - .arg(fixedTarget + ".rsc") << endl; - ts << QString("\"\" - \"%1\\%2\"") - .arg(romPath(installPathResource)) - .arg(fixedTarget + ".rsc") << endl; - - t << QString("\"%1/%2\" - \"%3\\%4\"") - .arg(destDirRegResource) - .arg(fixedTarget + "_reg.rsc") - .arg(installPathRegResource) - .arg(fixedTarget + "_reg.rsc") << endl; - ts << QString("\"\" - \"%1\\%2\"") - .arg(romPath(installPathRegResource)) - .arg(fixedTarget + "_reg.rsc") << endl; - - if (!iconFile.isEmpty()) { - if (epocBuild) { - t << QString("\"%1epoc32/data/z%2\" - \"!:%3\"") - .arg(epocRoot()) - .arg(iconFile) - .arg(QString(iconFile).replace('/', '\\')) << endl << endl; - ts << QString("\"\" - \"%1\"") - .arg(romPath(QString(iconFile).replace('/', '\\'))) << endl << endl; - } else { - QDir mifIconDir(project->first("DESTDIR")); - QFileInfo mifIcon(mifIconDir.relativeFilePath(project->first("TARGET"))); - QString mifIconFileName = mifIcon.fileName(); - mifIconFileName.append(".mif"); - t << QString("\"%1/%2\" - \"!:%3\"") - .arg(mifIcon.path()) - .arg(mifIconFileName) - .arg(QString(iconFile).replace('/', '\\')) << endl << endl; - ts << QString("\"\" - \"%1\"") - .arg(romPath(QString(iconFile).replace('/', '\\'))) << endl << endl; - } - } - } - } - - // deploy any additional DEPLOYMENT files + // deploy files specified by DEPLOYMENT variable QString remoteTestPath; QString zDir; remoteTestPath = QString("!:\\private\\%1").arg(privateDirUid); -- cgit v0.12 From f6d645b54dd11ac8d12da12751a88e831e3f3415 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Tue, 5 Oct 2010 17:20:29 +0300 Subject: Added .flags modifier support for DEPLOYMENT items in Symbian The .flags modifier can be used to specify pkg flags for files. For example, to make default application run after install: default_bin_deployment.flags += FR RI For example, to show a note at installation time: notedep.sources = install_note.txt notedep.flags = FT TC DEPLOYMENT += notedep See Symbian package file format documentation for exact supported flag values. Cherry picked to 4.7 branch from master branch as part of QTBUG-15068, original commit: 50b2477e6ffd64a0730cc5c0f0a6190b1a6b5861 Task-number: QTBUG-15068 Task-number: QTBUG-13367 Reviewed-by: Janne Anttila --- doc/src/development/qmake-manual.qdoc | 17 +++++++++++++++++ doc/src/snippets/code/doc_src_qmake-manual.qdoc | 7 +++++++ .../generators/symbian/initprojectdeploy_symbian.cpp | 20 ++++++++++++++------ qmake/generators/symbian/initprojectdeploy_symbian.h | 6 +++++- qmake/generators/symbian/symbiancommon.cpp | 20 ++++++++++++++++++-- 5 files changed, 61 insertions(+), 9 deletions(-) diff --git a/doc/src/development/qmake-manual.qdoc b/doc/src/development/qmake-manual.qdoc index 278822e..883c9d8 100644 --- a/doc/src/development/qmake-manual.qdoc +++ b/doc/src/development/qmake-manual.qdoc @@ -1474,6 +1474,23 @@ This will entirely remove the default application deployment. + On the Symbian platform, you can specify file specific install options + with \c{.flags} modifier. Please consult the Symbian platform documentation + for supported options. + + For example: + + \snippet doc/src/snippets/code/doc_src_qmake-manual.qdoc 155 + + This will show a message box that gives user an option to cancel the + installation and then automatically runs the application after + installation is complete. + + \note Automatically running the applications after install may require signing + the package with better than self-signed certificate, depending on the phone model. + Additionally, some tools such as Runonphone may not work properly with sis + packages that automatically run the application upon install. + On the Symbian platform, you can use \c{DEPLOYMENT.installer_header} variable to generate smart installer wrapper for your application. If you specify just UID of the installer package as the value, then diff --git a/doc/src/snippets/code/doc_src_qmake-manual.qdoc b/doc/src/snippets/code/doc_src_qmake-manual.qdoc index 20d8d45..a5bc1f3 100644 --- a/doc/src/snippets/code/doc_src_qmake-manual.qdoc +++ b/doc/src/snippets/code/doc_src_qmake-manual.qdoc @@ -1018,3 +1018,10 @@ DEPLOYMENT += my_note //! [154] DEPLOYMENT -= default_bin_deployment default_resource_deployment default_reg_deployment //! [154] + +//! [155] +default_bin_deployment.flags += FILERUN RUNINSTALL +dep_note.sources = install_note.txt +dep_note.flags = FILETEXT TEXTEXIT +DEPLOYMENT += dep_note +//! [155] diff --git a/qmake/generators/symbian/initprojectdeploy_symbian.cpp b/qmake/generators/symbian/initprojectdeploy_symbian.cpp index 5963773..22a4a82 100644 --- a/qmake/generators/symbian/initprojectdeploy_symbian.cpp +++ b/qmake/generators/symbian/initprojectdeploy_symbian.cpp @@ -253,6 +253,8 @@ void initProjectDeploySymbian(QMakeProject* project, continue; } + QStringList flags = project->values(item + ".flags"); + foreach(QString source, project->values(item + ".sources")) { source = Option::fixPathToLocalOS(source); QString nameFilter; @@ -284,13 +286,15 @@ void initProjectDeploySymbian(QMakeProject* project, Option::fixPathToLocalOS(targetPath.absolutePath() + "/" + info.fileName(), false, true), fixPathToEpocOS(devicePath.left(2) + QLatin1String(SYSBIN_DIR "/") - + info.fileName()))); + + info.fileName()), + flags)); } else { deploymentList.append(CopyItem( Option::fixPathToLocalOS(targetPath.absolutePath() + "/" + info.fileName(), false, true), fixPathToEpocOS(deploymentDrive + QLatin1String("/" SYSBIN_DIR "/") - + info.fileName()))); + + info.fileName()), + flags)); } } if (isPlugin(info, devicePath)) { @@ -301,7 +305,8 @@ void initProjectDeploySymbian(QMakeProject* project, // Generate deployment even if file doesn't exist, as this may be the case // when generating .pkg files. deploymentList.append(CopyItem(Option::fixPathToLocalOS(info.absoluteFilePath()), - fixPathToEpocOS(devicePath + "/" + info.fileName()))); + fixPathToEpocOS(devicePath + "/" + info.fileName()), + flags)); continue; } } @@ -328,12 +333,14 @@ void initProjectDeploySymbian(QMakeProject* project, deploymentList.append(CopyItem( Option::fixPathToLocalOS(absoluteItemPath + "/" + iterator.fileName()), fixPathToEpocOS(devicePath.left(2) + QLatin1String(SYSBIN_DIR "/") - + iterator.fileName()))); + + iterator.fileName()), + flags)); } else { deploymentList.append(CopyItem( Option::fixPathToLocalOS(absoluteItemPath + "/" + iterator.fileName()), fixPathToEpocOS(deploymentDrive + QLatin1String("/" SYSBIN_DIR "/") - + iterator.fileName()))); + + iterator.fileName()), + flags)); } } createPluginStub(info, devicePath + "/" + absoluteItemPath.right(diffSize), @@ -343,7 +350,8 @@ void initProjectDeploySymbian(QMakeProject* project, deploymentList.append(CopyItem( Option::fixPathToLocalOS(absoluteItemPath + "/" + iterator.fileName()), fixPathToEpocOS(devicePath + "/" + absoluteItemPath.right(diffSize) - + "/" + iterator.fileName()))); + + "/" + iterator.fileName()), + flags)); } } } diff --git a/qmake/generators/symbian/initprojectdeploy_symbian.h b/qmake/generators/symbian/initprojectdeploy_symbian.h index 2653d2a..bc17b04 100644 --- a/qmake/generators/symbian/initprojectdeploy_symbian.h +++ b/qmake/generators/symbian/initprojectdeploy_symbian.h @@ -56,9 +56,13 @@ struct CopyItem { - CopyItem(const QString& f, const QString& t) : from(f) , to(t) { } + CopyItem(const QString& f, const QString& t) + : from(f) , to(t) { } + CopyItem(const QString& f, const QString& t, const QStringList& l) + : from(f) , to(t), flags(l) { } QString from; QString to; + QStringList flags; }; typedef QList DeploymentList; diff --git a/qmake/generators/symbian/symbiancommon.cpp b/qmake/generators/symbian/symbiancommon.cpp index c0a6626..5e8bc4a 100644 --- a/qmake/generators/symbian/symbiancommon.cpp +++ b/qmake/generators/symbian/symbiancommon.cpp @@ -397,6 +397,15 @@ void SymbianCommonGenerator::generatePkgFile(const QString &iconFile, bool epocB for (int i = 0; i < depList.size(); ++i) { QString from = depList.at(i).from; QString to = depList.at(i).to; + QString flags; + bool showOnlyFile = false; + foreach(QString flag, depList.at(i).flags) { + if (flag == QLatin1String("FT") + || flag == QLatin1String("FILETEXT")) { + showOnlyFile = true; + } + flags.append(QLatin1Char(',')).append(flag); + } if (epocBuild) { // Deploy anything not already deployed from under epoc32 instead from under @@ -410,8 +419,15 @@ void SymbianCommonGenerator::generatePkgFile(const QString &iconFile, bool epocB } } - t << QString("\"%1\" - \"%2\"").arg(from.replace('\\','/')).arg(to) << endl; - ts << QString("\"\" - \"%1\"").arg(romPath(to)) << endl; + // Files with "FILETEXT"/"FT" flag are meant for showing only at installation time + // and therefore do not belong to the stub package and will not install the file into phone. + if (showOnlyFile) + to.clear(); + else + ts << QString("\"\" - \"%1\"").arg(romPath(to)) << endl; + + t << QString("\"%1\" - \"%2\"%3").arg(from.replace('\\','/')).arg(to).arg(flags) << endl; + } t << endl; ts << endl; -- cgit v0.12 From e00354a40db497fe35fde7055521c2246e7a3e7c Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Thu, 7 Oct 2010 15:36:45 +0300 Subject: Implement support for DEPLOYMENT.display_name in Symbian The default package name and the default name that appears in the application menu is derived from the TARGET variable. Often the default is not optimal for displaying to end user. To set a better display name for these purposes DEPLOYMENT.display_name variable can now be used. Cherry picked to 4.7 branch from master branch as part of QTBUG-15068, original commit: 9cb24d1c4b7359ec84708ba770050de720b50cdf Task-number: QTBUG-15068 Task-number: QTBUG-14280 Reviewed-by: Janne Anttila --- doc/src/development/qmake-manual.qdoc | 7 +++++++ doc/src/snippets/code/doc_src_qmake-manual.qdoc | 4 ++++ qmake/generators/symbian/symbiancommon.cpp | 21 ++++++++++++++------- 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/doc/src/development/qmake-manual.qdoc b/doc/src/development/qmake-manual.qdoc index 883c9d8..6531d25 100644 --- a/doc/src/development/qmake-manual.qdoc +++ b/doc/src/development/qmake-manual.qdoc @@ -1491,6 +1491,13 @@ Additionally, some tools such as Runonphone may not work properly with sis packages that automatically run the application upon install. + On the Symbian platform, the default package name and the default name that + appears in application menu is derived from the \c TARGET variable. + Often the default is not optimal for displaying to end user. To set a better + display name for these purposes, use \c{DEPLOYMENT.display_name} variable: + + \snippet doc/src/snippets/code/doc_src_qmake-manual.qdoc 156 + On the Symbian platform, you can use \c{DEPLOYMENT.installer_header} variable to generate smart installer wrapper for your application. If you specify just UID of the installer package as the value, then diff --git a/doc/src/snippets/code/doc_src_qmake-manual.qdoc b/doc/src/snippets/code/doc_src_qmake-manual.qdoc index a5bc1f3..4f74e9c 100644 --- a/doc/src/snippets/code/doc_src_qmake-manual.qdoc +++ b/doc/src/snippets/code/doc_src_qmake-manual.qdoc @@ -1025,3 +1025,7 @@ dep_note.sources = install_note.txt dep_note.flags = FILETEXT TEXTEXIT DEPLOYMENT += dep_note //! [155] + +//! [156] +DEPLOYMENT.display_name = My Qt App +//! [156] diff --git a/qmake/generators/symbian/symbiancommon.cpp b/qmake/generators/symbian/symbiancommon.cpp index 5e8bc4a..0938b58 100644 --- a/qmake/generators/symbian/symbiancommon.cpp +++ b/qmake/generators/symbian/symbiancommon.cpp @@ -320,7 +320,9 @@ void SymbianCommonGenerator::generatePkgFile(const QString &iconFile, bool epocB // Package header QString sisHeader = "; SIS header: name, uid, version\n#{\"%1\"},(%2),%3\n\n"; - QString visualTarget = generator->escapeFilePath(project->first("TARGET")); + QString visualTarget = project->values("DEPLOYMENT.display_name").join(" "); + if (visualTarget.isEmpty()) + visualTarget = generator->escapeFilePath(project->first("TARGET")); visualTarget = removePathSeparators(visualTarget); QString wrapperTarget = visualTarget + " installer"; @@ -641,6 +643,11 @@ void SymbianCommonGenerator::writeLocFile(QStringList &symbianLangCodes) if (ft.open(QIODevice::WriteOnly)) { generatedFiles << ft.fileName(); QTextStream t(&ft); + + QString displayName = generator->project->values("DEPLOYMENT.display_name").join(" "); + if (displayName.isEmpty()) + displayName = generator->escapeFilePath(generator->project->first("TARGET")); + t << "// ============================================================================" << endl; t << "// * Generated by qmake (" << qmake_version() << ") (Qt " QT_VERSION_STR ") on: "; t << QDateTime::currentDateTime().toString(Qt::ISODate) << endl; @@ -649,16 +656,16 @@ void SymbianCommonGenerator::writeLocFile(QStringList &symbianLangCodes) t << "// ============================================================================" << endl; t << endl; t << "#ifdef LANGUAGE_SC" << endl; - t << "#define STRING_r_short_caption \"" << fixedTarget << "\"" << endl; - t << "#define STRING_r_caption \"" << fixedTarget << "\"" << endl; + t << "#define STRING_r_short_caption \"" << displayName << "\"" << endl; + t << "#define STRING_r_caption \"" << displayName << "\"" << endl; foreach(QString lang, symbianLangCodes) { t << "#elif defined LANGUAGE_" << lang << endl; - t << "#define STRING_r_short_caption \"" << fixedTarget << "\"" << endl; - t << "#define STRING_r_caption \"" << fixedTarget << "\"" << endl; + t << "#define STRING_r_short_caption \"" << displayName << "\"" << endl; + t << "#define STRING_r_caption \"" << displayName << "\"" << endl; } t << "#else" << endl; - t << "#define STRING_r_short_caption \"" << fixedTarget << "\"" << endl; - t << "#define STRING_r_caption \"" << fixedTarget << "\"" << endl; + t << "#define STRING_r_short_caption \"" << displayName << "\"" << endl; + t << "#define STRING_r_caption \"" << displayName << "\"" << endl; t << "#endif" << endl; } else { PRINT_FILE_CREATE_ERROR(filename); -- cgit v0.12 From e5345aa59d6573abb39b50285b63aafcddd9f13b Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Thu, 4 Nov 2010 09:47:08 +0200 Subject: Make qmake to pass all UTF-8 characters unchanged through parser. QMakeProject::parse() calls QString::simplified(), which assumes any byte 0xA0 in multibyte UTF-8 characters is a space character (0x00A0 is unicode character NBSP [non-breaking space]) and replaces those bytes with regular space, corrupting the UTF-8 string. Fixed by temporarily changing all 0xA0 bytes in parser input to another non-space character 0x01A0. This is safe replacement as qmake doesn't accept unicode .pro files, so there should never be actual NBSP or the replacement 0x01A0 characters in a valid .pro file. Note that there are a couple of more uses of QString::simplified() in qmake, but those do not deal with strings that need to be UTF-8 compatible as far as I can tell, so no need to touch them. Cherry picked to 4.7 branch from master branch as part of QTBUG-15068, original commit: 15a7626480b64d85992bed819fe6052e0c5c8fa9 Task-number: QTBUG-15068 Task-number: QTBUG-14357 Reviewed-by: Oswald Buddenhagen --- qmake/project.cpp | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/qmake/project.cpp b/qmake/project.cpp index 427bea3..fe08b7b 100644 --- a/qmake/project.cpp +++ b/qmake/project.cpp @@ -677,7 +677,23 @@ QMakeProject::reset() bool QMakeProject::parse(const QString &t, QMap &place, int numLines) { - QString s = t.simplified(); + // To preserve the integrity of any UTF-8 characters in .pro file, temporarily replace the + // non-breaking space (0xA0) characters with another non-space character, so that + // QString::simplified() call will not replace it with space. + // Note: There won't be any two byte characters in .pro files, so 0x10A0 should be a safe + // replacement character. + static QChar nbsp(0xA0); + static QChar nbspFix(0x01A0); + QString s; + if (t.indexOf(nbsp) != -1) { + s = t; + s.replace(nbsp, nbspFix); + s = s.simplified(); + s.replace(nbspFix, nbsp); + } else { + s = t.simplified(); + } + int hash_mark = s.indexOf("#"); if(hash_mark != -1) //good bye comments s = s.left(hash_mark); -- cgit v0.12 From 5657b8f13bd6ef456a1da7ae08a2924e256b8ea3 Mon Sep 17 00:00:00 2001 From: axis Date: Mon, 8 Nov 2010 15:18:11 +0100 Subject: Started using qtmain.lib for all Qt applications, also corelib ones. This commit also fixes the issue that 564058a1bb didn't, namely that config tests broke on Symbian. It does this by continuing to use the Open C libcrt0.lib library for non-Qt applications. This is also more correct, since you should not have to compile the Qt libs to compile a non-Qt app. Task: QTBUG-14735 RevBy: Miikka Heikkinen --- config.tests/symbian/audio/audio.pro | 1 + config.tests/symbian/simple/simple.pro | 1 + mkspecs/common/symbian/symbian.conf | 5 ++++- mkspecs/features/symbian/default_post.prf | 7 +++---- mkspecs/features/symbian/symbian_building.prf | 25 ++++++++++++++----------- 5 files changed, 23 insertions(+), 16 deletions(-) diff --git a/config.tests/symbian/audio/audio.pro b/config.tests/symbian/audio/audio.pro index b2a1986..b496341 100644 --- a/config.tests/symbian/audio/audio.pro +++ b/config.tests/symbian/audio/audio.pro @@ -6,4 +6,5 @@ INCLUDEPATH += $${EPOCROOT}epoc32/include/mmf/common INCLUDEPATH += $${EPOCROOT}epoc32/include/platform LIBS += -lmmfdevsound +CONFIG -= qt QT = diff --git a/config.tests/symbian/simple/simple.pro b/config.tests/symbian/simple/simple.pro index fa086c9..9c60d62 100644 --- a/config.tests/symbian/simple/simple.pro +++ b/config.tests/symbian/simple/simple.pro @@ -1,4 +1,5 @@ TEMPLATE = app +CONFIG -= qt QT = SOURCES += main.cpp diff --git a/mkspecs/common/symbian/symbian.conf b/mkspecs/common/symbian/symbian.conf index 2fb799d..69188a8 100644 --- a/mkspecs/common/symbian/symbian.conf +++ b/mkspecs/common/symbian/symbian.conf @@ -79,7 +79,6 @@ QMAKE_LIBS_OPENGL_ES2_QT = -llibglesv2 -lcone -lws32 QMAKE_LIBS_OPENVG = -llibOpenVG -lfbscli -lbitgdi -lgdi QMAKE_LIBS_THREAD = -llibpthread QMAKE_LIBS_COMPAT = -QMAKE_LIBS_QT_ENTRY = -llibcrt0.lib QMAKE_LIBS_S60 = -lavkon -leikcoctl exists($${EPOCROOT}epoc32/include/platform/sgresource/sgimage.h) { @@ -127,6 +126,10 @@ QT_ARCH = symbian load(qt_config) +QMAKE_LIBS_QT_ENTRY = -lqtmain$${QT_LIBINFIX}.lib +QMAKE_LIBS_NO_QT_ENTRY = -llibcrt0.lib +QMAKE_LIBS_NO_QT_ENTRY_GCCE = -llibcrt0_gcce.lib + # These directories must match what configure uses for QT_INSTALL_PLUGINS and QT_INSTALL_IMPORTS QT_PLUGINS_BASE_DIR = /resource/qt$${QT_LIBINFIX}/plugins QT_IMPORTS_BASE_DIR = /resource/qt/imports diff --git a/mkspecs/features/symbian/default_post.prf b/mkspecs/features/symbian/default_post.prf index 362bd6c..b62bf98 100644 --- a/mkspecs/features/symbian/default_post.prf +++ b/mkspecs/features/symbian/default_post.prf @@ -3,11 +3,10 @@ load(default_post) contains(TEMPLATE, ".*app") { contains(CONFIG, stdbinary) { QMAKE_LIBS += - } else:contains(QT, gui):contains(CONFIG,qt) { - S60MAIN_LIBS = -leuser - QMAKE_LIBS += -lqtmain$${QT_LIBINFIX}.lib $$S60MAIN_LIBS - } else { + } else:contains(CONFIG,qt) { QMAKE_LIBS += $$QMAKE_LIBS_QT_ENTRY + } else { + QMAKE_LIBS += $$QMAKE_LIBS_NO_QT_ENTRY } default_bin_deployment.sources += $$symbianRemoveSpecialCharacters($$basename(TARGET)).exe diff --git a/mkspecs/features/symbian/symbian_building.prf b/mkspecs/features/symbian/symbian_building.prf index 1a51cb2..0cedaa0 100644 --- a/mkspecs/features/symbian/symbian_building.prf +++ b/mkspecs/features/symbian/symbian_building.prf @@ -187,25 +187,28 @@ contains(TEMPLATE, app):!contains(QMAKE_LINK, "^@:.*") { linux-armcc: { QMAKE_LIBS += usrt2_2.lib dfpaeabi.dso dfprvct2_2.dso drtaeabi.dso scppnwdl.dso drtrvct2_2.dso h_t__uf.l\\(switch8.o\\) QMAKE_LIBS += -leexe.lib\\(uc_exe_.o\\) - contains(CONFIG, "qt"):contains(QT, "gui") { #if linking with QtCore - QMAKE_LIBS -= -lqtmain$${QT_LIBINFIX}.lib - QMAKE_LIBS += -lqtmain$${QT_LIBINFIX}.lib + contains(CONFIG, "qt") { + QMAKE_LIBS -= $$QMAKE_LIBS_QT_ENTRY + QMAKE_LIBS += $$QMAKE_LIBS_QT_ENTRY } else { - QMAKE_LIBS -= -llibcrt0.lib - QMAKE_LIBS += -llibcrt0.lib + QMAKE_LIBS -= $$QMAKE_LIBS_NO_QT_ENTRY + QMAKE_LIBS += $$QMAKE_LIBS_NO_QT_ENTRY } } else :linux-gcce { # notice that we can't merge these as ordering of arguments is important. QMAKE_LIBS += \ -l:eexe.lib \ -l:usrt2_2.lib - contains(CONFIG, "qt"):contains(QT, "gui") { #if linking with QtCore - QMAKE_LIBS -= -l:qtmain$${QT_LIBINFIX}.lib - QMAKE_LIBS += -l:qtmain$${QT_LIBINFIX}.lib + contains(CONFIG, "qt") { + modified_entry = $$replace(QMAKE_LIBS_QT_ENTRY, "^-l", "-l:") + QMAKE_LIBS -= $$modified_entry + QMAKE_LIBS += $$modified_entry } else { - QMAKE_LIBS -= -l:libcrt0.lib - QMAKE_LIBS -= -l:libcrt0_gcce.lib - QMAKE_LIBS += -l:libcrt0_gcce.lib + modified_entry = $$replace(QMAKE_LIBS_NO_QT_ENTRY, "^-l", "-l:") + QMAKE_LIBS -= $$modified_entry + modified_entry = $$replace(QMAKE_LIBS_NO_QT_ENTRY_GCCE, "^-l", "-l:") + QMAKE_LIBS -= $$modified_entry + QMAKE_LIBS += $$modified_entry } QMAKE_LIBS += \ -l:dfpaeabi.dso \ -- cgit v0.12 From 1dab1be81c2f295736f196a9d56ce4facb59fe64 Mon Sep 17 00:00:00 2001 From: axis Date: Mon, 8 Nov 2010 16:13:54 +0100 Subject: Fixed deployment for symbian/linux-armcc when using shadow builds. RevBy: Miikka Heikkinen --- mkspecs/features/symbian/application_icon.prf | 8 +++++--- mkspecs/features/symbian/default_post.prf | 8 +++++++- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/mkspecs/features/symbian/application_icon.prf b/mkspecs/features/symbian/application_icon.prf index 39f10fb..6e1aa8e 100644 --- a/mkspecs/features/symbian/application_icon.prf +++ b/mkspecs/features/symbian/application_icon.prf @@ -15,10 +15,12 @@ contains(CONFIG, no_icon) { resourceZDir = $$EPOCROOT$$HW_ZDIR$$APP_RESOURCE_DIR regZDir = $$EPOCROOT$$HW_ZDIR$$REG_RESOURCE_IMPORT_DIR } else { - isEmpty(DESTDIR) { - resourceZDir = . - } else { + contains(DESTDIR, "/.*") { resourceZDir = $$DESTDIR + } else:isEmpty(DESTDIR) { + resourceZDir = $$OUT_PWD + } else { + resourceZDir = $$OUT_PWD/$$DESTDIR } regZDir = $$resourceZDir } diff --git a/mkspecs/features/symbian/default_post.prf b/mkspecs/features/symbian/default_post.prf index b62bf98..d9ff03d 100644 --- a/mkspecs/features/symbian/default_post.prf +++ b/mkspecs/features/symbian/default_post.prf @@ -9,7 +9,13 @@ contains(TEMPLATE, ".*app") { QMAKE_LIBS += $$QMAKE_LIBS_NO_QT_ENTRY } - default_bin_deployment.sources += $$symbianRemoveSpecialCharacters($$basename(TARGET)).exe + contains(DESTDIR, "/.*") { + default_bin_deployment.sources += $$DESTDIR/$$symbianRemoveSpecialCharacters($$basename(TARGET)).exe + } else:isEmpty(DESTDIR) { + default_bin_deployment.sources += $$OUT_PWD/$$symbianRemoveSpecialCharacters($$basename(TARGET)).exe + } else { + default_bin_deployment.sources += $$OUT_PWD/$$DESTDIR/$$symbianRemoveSpecialCharacters($$basename(TARGET)).exe + } default_bin_deployment.path += /sys/bin load(application_icon.prf) -- cgit v0.12