Monday, July 20, 2009

Gdb Typedef Bug - Update

Looks like the gdb typedef debugging helper issue isn't going to be easy to fix:

The type reported by gdb is 'List'. I could resolve this to 'QList' 'manually', However, doing so would generally impact the debugging helper performance as this would need an additional roundtrip for each item in the Locals&Watchers view (and an roundtrip takes several dozen milliseconds even on fast machines, so we are talking about slowing down each 'step' by a second or so.)

You can get a 'nice' display of list2 'manually' by creating a 'Watcher' with expression *('QList'*)&list2 .

I understand this is neither obvious nor convenient, but I am also a bit afraid of the general slowdown.

So for now I am tempted to leave it as it is.
The manual watcher tip is one to remember.

The Qt Bible

If you're new to Qt development then you must buy this book - I really cannot recommend it highly enough.

Sunday, July 19, 2009

Context-Sensitive Help

The Qt help is superb and makes the MSDN help in Visual Studio look like the dog we all know it is (every C++ developer knows that the MSDN has sucked since the MSVC 6 days). However, the context-sensitive help in Qt Creator doesn't always do what you'd expect. For example, if you have a #include selected, F1 will not display the relevant help page, which is a shame.

#include <QString>

Put your cursor between the braces and hit F1. I would expect the QString help page to appear, but instead I get No documentation available. Hardly the end of the world, but little touches like this would add even more shine to an already shiny IDE.

Delete All Breakpoints?

There is no way to delete (or disable) all breakpoints in Qt Creator - they have to be disabled individually. Ack. I would find such a feature very useful.

Debugging Helpers typedef Bug

Debugging helpers are great. They show you the contents of common Qt types such as maps, lists and strings and are invaluble when debugging code. However, a bug exists that means if you typedef a QMap, QList, etc. then the debugging helper won't work. Take the following example:

#include <QtCore/QCoreApplication>
#include <QMap>

#include <QString>

#include <QListv


int main(int argc, char *argv[])

{

QCoreApplication a(argc, argv);

QMap<QString, QString> map1;

map1["Hello"] = "World!";


typedef QMap<QString, QString> Map;

Map map2;

map2["Hello"] = "World!";


QList<int> list1;

list1.append(1234);


typedef <int> List;

List list2;

list2.append(1234);

return a.exec();

}


If you stick a breakpoint on the last line the debugger happily displays the contents of map1 and list1, but not map2 and list2 as they have been declared using the typedef. Now, I use the typedef keyword a lot, so this is a PITA, but it's been reported so I'm sure a fix is in the works.


Debugging With gdb Using A Dell Laptop

When I started out with Qt Creator I had a big show-stopping problem debugging apps on my Dell work laptop. I thought I'd post my original messages to the mailing list in case anyone else suffers from the same problem.

**********

I have Qt Creator 1.1.1 running on Windows XP and I cannot debug GUI apps. As soon as I start the debugger, it stops with 'signal-received' somewhere in C:\WINDOWS\system32\wxvault.dll. Further up the call stack is 'QGraphicsWidget::paintWindowFrame'. Here is what I am getting:

0 wxvault!??0Cwxvault@@QAE at XZ C:\\WINDOWS\\system32\\wxvault.dll 0
1 ?? 0
2 ?? 0
3 ?? 0
4 ?? 0
5 ?? 0
6 ?? 0
7 QGraphicsWidget::paintWindowFrame qgraphicswidget.cpp 2184
8 wxvault!??0Cwxvault@@QAE at XZ C:\\WINDOWS\\system32\\wxvault.dll 0
9 ?? 0
10 wxvault!??0Cwxvault@@QAE at XZ C:\\WINDOWS\\system32\\wxvault.dll 0
11 ?? 0

This is my first day with Qt Creator and not being able to debug is a show stopper.

My version of gdb is the one that ships with QT Creator, v6.8. I can run my app fine with Ctrl+R.

**********

OK, I found the problem - a package called 'Embassy Security Center' by 'Wave Systems'. This comes pre-installed on most Dell's. Instead of uninstalling it (which I'm told will cause me a lot of grief) I stopped the wxvault.dll being loaded with other DLLs by editing
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Windows\AppInit_DLLs

(the DLL was in this list). Removing it makes gdb play nicely.

Unit Test Results In The Application Output Pane

I would find it really useful if when displaying the results of a QTestLib app in the Application Output pane I could double-click on a FAIL! to jump directly to the test that failed. Once you have a lot of tests, this feature would prove to be a real time-saver. FWIW I have used the Boost.Test framework with MSVC in the past and you can do something similar.

For example, consider the following output from a test run (this is copied directly from the Application Output pane in Qt Creator):

********* Start testing of LogFileTests *********
Config: Using QTest library 4.5.1, Qt 4.5.1
PASS : LogFileTests::initTestCase()
FAIL! : LogFileTests::LoadFile() 'entries.last() == LogEntry("Test")'
returned FALSE. ()
LogFileTests.cpp(30) : failure location
PASS : LogFileTests::cleanupTestCase()
Totals: 2 passed, 1 failed, 0 skipped
********* Finished testing of LogFileTests *********

If I could double-click on either the FAIL! line or the line below (LogFileTests.cpp(30) : failure location) and jump straight to the test, I would be very happy.

Compiling a Single .cpp File

Qt Creator won't allow you to compile a single .cpp file - you have to build the the entire project - which is slightly annoying. When working on a complicated source file I sometime like to let the compiler rip to make sure it compiles.

However, a fix may be in the pipeline:

Latest Qt Creator Snapshots

If you want to grab the latest version of Qt Creator before it is released to the general public you can grab a copy using FTP from here:


You can also download the Qt Creator source and build it yourself - you can even build a copy of Qt Creator using Qt Creator!


MinGW/gcc 4.4

The current version of Qt Creator (1.2.1) ships with a free compiler based on gcc 3.4.5 which is now 5 years old. This compiler is free, so I can't complain too much, but it generates EXE/DLL files which are much larger than their MSVC equivalents (usually 15%-20% larger, sometimes up to 50%) and, by all accounts, slower code. Qt Creator itself is built using MSVC, and I have also built Qt from source using MSVC in both shared and static forms (details on how to do this next week.) I tend to use the MinGW Qt toolset for debug builds (as the debugging helpers for gdb are better) and the static MSVC version of Qt for release builds.

However, there is a new version of the MinGW toolset which includes a shiny new version of gcc (v4.4). By all accounts this is a much faster compiler that generates better code. This toolset will hopefully ship with Qt 4.6.

Although MSVC is a superb compiler, I don't want to have to depend on it, so I look forward to gcc 4.4. Having versions of Qt built with different compilers is an interesting exercise for the user but is ultimately a pain in the arse to manage.

Note that disabling support for exception handling can mean smaller executables when building with gcc, but I haven't tried this and am not sure how I can specify the relevant compiler options from Qt Creator itself.

Saturday, July 18, 2009

Qt Designer Action Naming

This is a minor niggle... Qt uses camelCase throughout, but when adding menu items using the designer, ampersands are replaced with an underscore - I always end up renaming these.

For example, if you add a menu item called E&xit the designer will create a QAction called actionE_xit. Bah. Just ignore ampersands and call it actionExit.

Support For Workspaces?

I'm not convinced about the Qt Creator support for 'sessions'. Currently, if I open a project and it depends on other projects, they won't be opened automatically, and the official advice is to use sessions to manage multiple projects. The problem is that these sessions are not stored in the root project folder and hence can't be added to your version control system. This is a pain. If I am working on a project that contains a number of different .pro files, another member of my team would need to create their own duplicate session in Qt Creator if they wanted to work on the same code.

I think either a simple 'workspace' or 'solution' concept is required that will group projects together, or a way of creating a session file that can be stored in the root folder and added to version control.

Note that that may be a way to do this by hand-editing your .pro files, but I haven't investigated this yet. I think the IDE should perform this task though...

Project Not Linked When Dependent Library Changes

I recently found a bug that was driving me nuts. If you have a project that depends on a separate .lib project, and you change the .lib but NOT the main project, when the main project builds it will correctly rebuild the .lib but will NOT re-link! This means your library changes are not included and you end up confusing both yourself and the debugger.

I use unit tests in a big way (a good thing) and tend to have core code in a .lib which is used by both the main application and the unit test project. One day last week a test failed so I fixed the code in the core lib and ran the tests EXE again ... which built the .lib but as it didn't link with it, the tests failed again. Cue much head scratching.

I posted this to the Qt Creator mailing list.


And at least one other user on the list was having a similar issue.


One suggested workaround was to add a PRE_TARGETDEPS line to the .pro file which I will try when I am back in the office.

Debugging a Project

One feature I would find really useful in Qt Creator would be the ability to right-click on a project and select a Debug option. Currently to debug a project you need to first right-click on the project and select Set Run Configuration before launching the debugger with F5 or via the Debug menu. When you have multiple projects loaded this is a bit of a pain (I always have a main project and a unit test project loaded for example.)

Linking With Release/Debug Libraries

If you have a project that depends on a library project then you'll want the debug version to link with the debug library and the release version to link with the release library. To do this you'll need to edit your main project's .pro file and do something like this:

debug {
LIBS += -L./libfolder -lmydebuglib.lib
}

release {
LIBS += -L./libfolder -lmyreleaselib.lib
}

Note that the first brace must appear on the same line as the configuration name - the following will cause qmake to error:

debug
{
LIBS += ...
}

I posted a question about this on Stack Overflow as well as asking on the Qt Creator mailing list.

Additional Include Folders

If you want to add additional include folders to your projects, then you need to edit the .pro file by hand and add an entry like the following:

INCLUDEPATH += [path]

This is especially useful if like me, you add core code to a separate .lib project but you don;t want to use relative paths in your #include statements.

You can add as many of these INCLUDEPATH statements as you like.

Eventually I'd like to see support for this in the IDE. In fact, I'd go as far as saying the editor should expose lots more additional .pro functionality without the user having to edit these files themselves.

Welcome

Welcome to my Qt Creator blog where I will document my experiences of this superb C++ IDE and framework. I have recently started using Qt Creator and am so impressed that I have decided to blog about it.