How to Qt - Qml debugging and/or profiling? - c++

What software Qt/QML pieces are needed to compile in an app to be able to debug/profile QML?
My current app is build using cmake and runs on a embedded device. Furthermore, I'm starting to use Qt 4.8.3 (until now 4.7.0).
I would like to use these fancy/cool features (for an embedded developer):
http://doc.qt.digia.com/qtcreator/creator-qml-performance-monitor.html
I've searched trough qt-project looking for help, but I haven't got clear what are the steps needed when you want to debug/profile a remote app, with a customize build environment.
So, I would like to know if it is needed any of the following steps, and in positive case, what is in fact the needed code.
Qt libraries ./configure specific options.
QtCreator specific options to attach/launch to remote app.
Cmake includes and libraries needed in the final app executable .
Any help, link, etc is welcomed.

With Qt 4.8 this got pretty easy. All required libraries are now part of Qt itself and you don't have to build the debug library for your Qt version yourself.
I'm developing a Qt/QML desktop application also built with CMake. I had to complete the following steps to enable QML debugging:
Include the debugging enabler into my application's start-up code
#include <QtDeclarative/qdeclarativedebug.h>
/* [...] */
QDeclarativeDebuggingEnabler enabler;
Add QML_DISABLE_OPTIMIZER=1 to execution environment of my application
This can be done within Qt Creator in the execution tab of the projects page.
Tick the checkbox for QML debugging also found in the execution tab
This adds the required command line parameters for the communication between Qt Creator and the QML debugger component embedded in the application
If everything went fine the application greets you with the following output if started in debug mode:
Qml debugging is enabled. Only use this in a safe environment!
QDeclarativeDebugServer: Waiting for connection on port 3768...
QDeclarativeDebugServer: Connection established
After that I was able to set breakpoints and inspect variables. Also the profiler accessible via the analyze page just worked.
Your case is obviously a little bit more complicated as your developing an embedded application.
Qt creator has no support for deploying and executing CMake-based projects on embedded platforms. You will have to do that yourself. Don't forget to pass the required arguments to your application to configure the QML debugging:
$ your-app -qmljsdebugger=port:3768,block
To attach Qt Creator to a remotely running application for a profiling session use the corresponding "External" entries in the "Analyze" menu in the Qt Creator main menu. Where is a likewise option for debugging with "Connect to Debug-Server" under "Debug" > "Debug".

I'm using Qt 5, and it got even easier. Just this one step was required on my side to do QML profiling:
#include <QQmlDebuggingEnabler>
...
QQmlDebuggingEnabler enabler;

Checking the docs all given answers seem to be unnecessary. Further it hardcodes debug code in releases. I have no clue why QQmlDebuggingEnabler would be necessary, but if you check the code here and here, you will recognize, that the instatiation of QQmlDebuggingEnabler is not necessary. Just include QQmlDebuggingEnabler and set the QT_QML_DEBUG flag e.g. like this (CMake)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DQT_QML_DEBUG ")
However according to the docs QQmlDebuggingEnabler is not necessary.
Furtermore: profiling unoptimized code makes no sense.
For me setting QT_QML_DEBUG as flag and checking the checkbox for QML debugging is sufficient.

Here is a "cleaner" alternative to #sebasgo's answer, item 1.
If you are using Qt5 with QtQuick2, you only need to define QT_QML_DEBUG before including QtQuick in some file (it does not matter what file, as long as it is a part of the executable). For example, it is sufficient to start your main.cpp with lines:
#define QT_QML_DEBUG
#include <QtQuick>
It won't hurt if you instead use compiler's -DQT_QML_DEBUG flag (e.g. via qmake DEFINES or cmake add_definitions directives), possibly only in debug builds.
If you are stuck with legacy QtQuick1 (in either Qt5 or Qt4) use QT_DECLARATIVE_DEBUG macro instead, e.g.
#define QT_DECLARATIVE_DEBUG
#include <QtDeclarative>
For the curious, here is a relevant Qt source, short and self-explanatory:
QtQuick2
QtQuick1 in Qt5
QtQuick1 in Qt4.8

With Qt 5.1 the new function qInstallMessageHandler was added.
It will let you catch, and log, errors and warnings so you can deal with them as you like.

Related

What does Qt Creator `Separate debug info` means?

In Qt Creator, Tools, Options, Build & Run, Default Build Properties I can see
Separate debug info (Use Project Default/Enable/Disable)
What that means?
I was guessing it will put debug/release build on separate folders but that seems to happen anyway.
Separate debug info in Qt is typically used when you compile in Profile mode.
Profile mode in Qt is used mainly for analyzing your application and profiling it. This mode creates an optimized binary file (as in Release Mode) with debug symbols in a different file (Debug mode, however, puts the symbols in the same file). This allows you to analyze the optimized application. So, this option in Qt tells the compiler to generate debug symbols in a separate file.
Don't worry. Sometimes Qt Documentation is a little dense and does not explain things in detail. You'll get used to it. Here are some useful links for understanding this:
How it works in gdb: https://guix.gnu.org/manual/en/html_node/Separate-Debug-Info.html
Specifying debug settings in Qt: https://doc.qt.io/qtcreator/creator-build-settings.html
Using performance analyzer in Qt: https://doc.qt.io/qtcreator/creator-cpu-usage-analyzer.html#using-the-performance-analyzer

Does Qt Creator support incremental build?

My current work is transplanting one project in Netbeans to Qt Creator, and
NetBeans IDE supports automatic checking of file dependencies and does its best to make incremental rebuild work correctly
at https://netbeans.org/kb/docs/cnd/depchecking.html. My question is weather Qt Creator have these abilities or need some plugins.
The 'includes' dependency checking is the default behavior of every compiler tool chain. It is done by mingw, or visual, ....
So it is the default behavior on QtCretor. It is not an option.
If you want to rebuild all, you have to ask it explicitly.

How do I configure QT5 without Xlib

I am trying to configure (and build) QT5 static. I want it to draw to the framebuffer and use webkit. I searched the docs but I didn't find anything on how I can do this without X. Does anyone know a way of doing this ?
Building Qt statically is totally orthogonal to the platform selection. Depending on your target device, you can choose between using Wayland, EGLFS, LinuxFB/DirectFB, etc.
Just be sure when you run configure that the actual plugin you're interested in gets compiled. In other words, check configure's final output (or read the config.summary file generated). If the platform is not there, run configure -v and try to see what's missing (headers, libs, ...).
You can then make any application use a given plugin by simply starting the application and passing the argument -platform eglfs|wayland|... (or by setting the QT_QPA_PLATFORM environment variable; or you can make it the default by mangling with the device mkspecs). More info here.
When it actually comes to static linking: this multi-platform support is implemented via plugins. A statically linked application won't have plugin loading available, so you must actually link the platform plugin into the application itself by adding something like
QTPLUGIN.platforms = eglfs
into your .pro file. More info here.
The best way is to use the "minimal" plugin and blit it into the framebuffer (something similar to the discussion at http://lists.qt-project.org/pipermail/development/2015-April/021160.html). However, ask your Platform vendor - check if "eglfs with fb" is a supported option.
However be aware that things like Cursor, overlays, rotation, vsync handling, GPU acceleration, may not be fully supported in these non-mainstream options on Linux.

QML - Imperative code not supported

Can someone comment on the fact that for QML, any imperative JavaScript code is not executed unless it is part of an extra component. I am facing such kind of problem when I include the following code to my QML:
function qmlSlot(text){
page.data=text
if(page.data==="received")
page.color="black";
}
As the Qt Designer get frozen and shows the following warning:
Imperative code is not supported in the Qt Quick Designer
I read that building qmlpuppet installs an executable for rendering components in the /bin directory of the Qt building it. Qt Quick Designer checks for the Qt of the current project if a qmlpuppet is in the /bin directory. If yes it takes the qmlpuppet provided by the Qt version instead of the one provided by Qt Creator itself. In my case I haven't used the Qt static binary install, but instead built Qt from the source, thus qmlpuppet executable was generated and is already located at:
/usr/local/Qt-5.2.1/qtcreator/bin
-rwxr-xr-x 1 qml2puppet
-rwxr-xr-x 1 qmlpuppet
So, the executable qmlpuppet is placed where is expected to be found and still this annoying message continues.
The workaround I took at moment is to comment out any so called "Imperative code" for when I want to edit the front-end QML using Qt Designer. Then after take out those comments to have the "Imperative code" activated again. But this is very annoying, although the code compile and works as I expected it to behave.
So, should I get worried about this warning? Anyway, there is some mean to get rid of this problem, as it froze the Qt Designer?
This is currently a reported QtCreator Bug :
https://bugreports.qt-project.org/browse/QTCREATORBUG-10940?page=com.atlassian.streams.streams-jira-plugin:activity-stream-issue-tab
https://bugreports.qt.io/browse/QTCREATORBUG-10940
So don't be worried about the warning, it will be fix

How to import and use QObject in a BB10 Cocos2D based app

I am currently working on building a Cocos2d-x game for the BB10 platform using the BBTemplateProject sample provided with Cocos2dx. I am new to C++ programming, and the current game is a port of a java project Iv been working on for a while. In order to save game data (scores, some settings etc), I intend to use the QtSQl Library which BB10 provides.
I have successfully run some sample Qtsql code in a sample Cascades application and it works fine.
However, integrating the same code into my Cocos2dx BB10 project just doesnt work .
I use the momentics IDE and have added the qt4, QtCore, QtDeclarative, paths/symbols to the project but still recieve the following errors
undefined reference to `QObject::QObject(QObject*)'
undefined reference to `vtable
undefined reference to `QSqlDatabase::defaultConnection'
.. and a bunch of other Q- related object errors.
After reading up on Qobject here http://developer.blackberry.com/cascades/reference/moc.html
I suspect that the MOC compiler is not appropriating referenced or a similar issue. Also, given the same code works well when integrated in an auto generated cascades project in the Momentics IDE, I am led to believe it is some sort of moc compiler issue. Given that I am quite new to C++ development, I still havent been able to figure out how to add the appropriate qmake file rules to the Momentics IDE in order to recognise Qobjects . Help is needed in this area.
Will definitely appreciate any pointers on how to go about this from experienced c++ devs or better ways to store data within cocos2dx blackberry 10 projects.
Thanks in advance.
Edit :
Here's , my progress thus far in trying to use QtSql for database interaction. QtSQl requires QtCore which contains QObject above. Thus far I have been unable to successfully integrate QtCore library.
I have done the following.
Added the /usr/include/qt4 and /usr/include/QtCore and /usr/include/QtSql to my include list using the following procedure
Right click over your project in Project Explorer and choose Properties
Expand the tree to C/C++ General / Paths and Symbols
Change the Configuration in the Paths and Symbols frame to [All configurations]
Click the Includes tag and select GNU C in the Languages list (or do this for every language).
Click Add... and type ${QNX_TARGET}/usr/include/qt4 and press OK
Click Add... and type ${QNX_TARGET}/usr/include/qt4/QtCore and press OK
Used the Momentics IDE add library function to add both QtCore and QtSql to the project. RightClick->configure->add Library and Standard BlackBerry Platform Library. The library gets added successfully.
I basically followed the steps detailed in this related post Adding QtCore Library in blackberry 10 sdk . But now get this error.
\win32\x86\usr\bin\ntoarm-ld: cannot find -lQtCore
The OP in that post mentions solving "some linker problems" but fails to mention how. I have also tried modifying the bar-descriptor.xml file adding the following lines
<env var="LD_LIBRARY_PATH" value="app/native/lib:/usr/lib/qt4/lib"/>
<asset path="${QNX_TARGET}\${CPUVARDIR}usr\lib\qt4\lib\libQtCore.so" type="Qnx/Elf">lib/libQtCore.so.4</asset>
Error still remains.
How do I solve this "linker" or library-no-found error ? Many Thanks.
First, if you plan to use the same application on both BlackBerry 10 and, I guess, Android as you are coming from Java, I'd try to use something smaller than Qt, like SQLite library, to keep it as simple as possible to port between the two platforms. But you can obviously use QtSQL on BB10 and something else in Android, you'll just have more code to write.
Second, regarding your issue: the undefined reference to QObject::QObject(QObject*) means that you are using this symbol (the QObject constructor, which you are probably calling because one of you class inherits from QObject), but nothing is providing it. You have probably added QtCore to your include path as the compiler found it, but not the linker: you need to specify that you want your application to be linked with QtCore.so (or maybe QtCore4.so, I don't have the SDK right now to check the exact name). You'll find everything you need on how to do this here.
About moc: moc stands for Meta Object Compiler. It basically parses your headers, looking for metadata on your classes: mainly properties, signals and slots. More specifically, everything that requires the Q_OBJECT macro. If you don't use theses functionalities, you don't need to run moc.
If you have to run it (because you use some meta object functionalities): you have two options. Option one: use QMake to compile your project. You'll have to recreate your project from scratch as a Qt project (maybe not differentiated of Cascades projects on Momentics, however it's just a matter of removing libraries you're linking to, not a big deal) to do this. Option two: add custom rules to run moc on headers needing it. It will generates some moc_yourclass.cpp files that you'll need to include in your project. I don't know how to do add a custom step on Momentics, but I think it should be doableā€¦