Developer Blog - Inventic.eu
  • Skipper - The ORM Designer
  • VsBuilds - Parallel building
  • Pulpo - Free Skipper CLI

Category: Qt

QML Notes

Sources

F5 for instant reload

class UltraView : public QQuickView {
  protected: 
  void keyPressEvent(QKeyEvent*event) override { 
    if(event->key()==Qt::Key_F5){ 
      auto oldSource=source(); 
      setSource({}); 
      engine()->clearComponentCache(); 
      setSource(oldSource); 
    } 
  } 
};  

F10 and F11 for slowing down animations

else if(event->key()==Qt::Key_F10) {  
  QUnifiedTimer::instance()->setSlowModeEnabled(true);  
  QUnifiedTimer::instance()->setSlowdownFactor(10);  
} else if(event->key()==Qt::Key_F11) {  
  QUnifiedTimer::instance()->setSlowModeEnabled(false);  
  QUnifiedTimer::instance()->setSlowdownFactor(1);  
}  

QML Live editing

QML Lint

02 Jan 2016

Posted by: ludek.vodicka

Qt #Qt #debugging #qml #developing

Debugging QML application

Batches, clip, changes and overdraw

 

SET QSG_VISUALIZE=batches<br />
or<br />
SET QSG_VISUALIZE=clip<br />
or<br />
SET QSG_VISUALIZE=changes<br />
or<br />
SET QSG_VISUALIZE=overdraw</p>
<p>qmlviewer test.qml<br />

Links:

02 Jan 2016

Posted by: ludek.vodicka

Qt #Qt #debug #qml

Qml & QtQuick

Qt documentation

QML Canvas

QML States

QML MouseEvents

QML c++ integration

QtQuick painted items

QML charts

QML Diagrams

QML & QtQuick blogposts

QML Selection, multiselection, rectangle-selection

QML Tools

QML Applications

 

Other topics

27 Dec 2015

Posted by: ludek.vodicka

Qt #Qt #qtquick #qml

Qt 5.5.0 an Qt 5.5.1, QWebEngine, QtWebKit and ICU

Notes about compiling QtWebEngine (instead of QtWebkit) together with Qt 5.5.1

Qt 5.5.0 configure switches for ICU:

configure \<br />
    -icu \<br />
    -I Q:\SharedLibraries\icu4c-51_1\icu\include \<br />
    -L Q:\SharedLibraries\icu4c-51_1\icu\lib64<br />

Starting with 5.5.1 it shouldn't be necessary to compile and ship ICU libraries because ICU should be included in Qt package itself.

Compile QtWebkit

It's necessary to compile it as standalone module.

cd Qt/qtwebkit<br />
perl Tools\Scripts\build-webkit<br />

Simpler solution

Much easier solution seem to be to use http://www.awesomium.com/  ;-)

Notes:

  • When changing configure settings, it's sometimes necessary to perform complete clean rebuild. The  best way how to do that is download completely new source package.
  • nmake clean or nmake distclean unfortunately didn't work for 100%
  • It's necessary to have installed Ruby, Python and Perl

Source links:

Other info:

06 Dec 2015

Posted by: ludek.vodicka

Qt #Qt #webengine #webkit #icu

Qt - This application failed to start because it could not find or load the Qt platform plugin "windows"

This application failed to start because it could not find or load the Qt platform plugin "windows".

As temporary fix, set following environment variable in VS (Debugging->Environment):


QT_PLUGIN_PATH=q:\SharedLibraries\Qt32\bin\plugins

23 Sep 2015

Posted by: ludek.vodicka

Qt Windows #Qt #plugins

Crash in QTreeWidget / QTreeView index mapping on Mac OSX 10.10 part III

So, one more attempt. Previous articles (part1, part2) mentioned possible solutions to fix crash insinde the QTreeWidget and QAccessibleTableCell.

Unfortunately, deselecting current item still doesn't fix all issues. The problem with deselection is that it's not handled correctly via QAccessibleTableCell:

If current index isn't valid, QAccessible doesn't correctly update currect QAccessibleTableCell object which caused all this evil crashes.

So there are two ways how to fix it. One is to manually set QAccessibleTableCell but I didn't find a way how to do that. The second way is to disable QAccessible for Property editor. Unfortunately it's not an easy task. In QAccessible exists method setActive:

QAccessible::setActive(false)

But this method works only with AccessibleObserver class but not with QPlatformAcessibility which handles real QAcessible::isActive result. Because of this it's necessary to update setActive method in file qacessible.cpp inside the Qt.

Original method:

</p>
<p>void QAccessible::setActive(bool active)<br />
{<br />
  for (int i = 0; i &lt; qAccessibleActivationObservers()-&gt;count() ;++i)<br />
    qAccessibleActivationObservers()-&gt;at(i)-&gt;accessibilityActiveChanged(active);<br />
}</p>
<p>

and updated version:

void QAccessible::setActive(bool active)<br />
{<br />
  #ifndef QT_NO_ACCESSIBILITY<br />
    if ( QPlatformAccessibility *pfAccessibility = platformAccessibility() )<br />
      pfAccessibility-&gt;setActive(active);<br />
  #endif</p>
<p>  for (int i = 0; i &lt; qAccessibleActivationObservers()-&gt;count() ;++i)<br />
    qAccessibleActivationObservers()-&gt;at(i)-&gt;accessibilityActiveChanged(active);<br />
}</p>
<p>

In case you will find better way how to turn off accessibility, please let me know.

But there is still one more problem. Occasionally OS X decides to switch accessible back on:

And this is probably the reason why everything works ok on older OS X but not on 10.10. Because OS X 10.10 randomly turns accessible on which causes this crash. Accessible is usually turned on when opening some modal dialog.

This explains why opening an empty dialog increased the probability to crash the application. The only solution I have found is to disable QAccessible every time the PropertyEditor is cleared up.

21 May 2015

Posted by: ludek.vodicka

Programming Qt Mac OS #Qt #crash #tree #property-editor

Crash in QTreeWidget / QTreeView index mapping on Mac OSX 10.10 part II

As mentioned in the first part of this article, the workaround with focus unfortunately didn't work. In some cases application is still crashing. So after next hours of debugging and unsuccessful consulting the problem on stack overflow I probably found a the core reason of this bug and the solution too.

2015-05-18_0850

 

The core of this problem doesn't lie in the QTreeModel, but in Qt implementation of Cocoa Accessible. The problem is that although the PropertyTree is correctly cleared, there is object QAccessibleTableCell which isn't correctly updated after

clear()

.

This means that although the PropertyTree and TreeWidget is empty, the QAccessibleTableCell object still holds m_index variable to invalid element. And when

 NSAcessibleEntryPointrAttributeNames 

is executed, m_index is translated to QTreeWidget element pointer and accessed. And this means that application completely crashes.

The solution is pretty simple. Together with property editor clear set also current index and selected index to NULL.

	propertyBrowser-&gt;clear();<br />
	propertyManagers-&gt;clear();<br />
	propertyManagers-&gt;treeWidget()-&gt;setCurrentItem(NULL);<br />
	propertyManagers-&gt;treeWidget()-&gt;setItemSelected(NULL, false);<br />

And that is it. Thanks for this your application will not crash any more (on this bug ;-) ).

 

21 May 2015

Posted by: ludek.vodicka

Qt Mac OS #qt treewidget model crash

QDialog::reject can be invoked multiple times

When user use ESC to close the dialog and press it very quickly two or more times in a row, QDialog::reject can be invoked also multiple times.

This is very dangerous and unpredictable because in case your reject will contain some one-time-execute routine the application will start crashing.

The only solution I found is to add these routines to QDialog destructor instead of to reject/accept.

24 Feb 2015

Posted by: ludek.vodicka

Programming Qt #Qt #qtgui

Qt Creator debugger doesn't work after last MacOS 10.9.4 update

Problem is caused by  lldbbridge.py file, where it's necessary to update few lines. After that, debugger will work like charm.

24 Sep 2014

Posted by: ludek.vodicka

Qt Mac OS #Qt #MacOs #debugger #freeze #hangup

Qt5 application hangs-up when QNetworkAccessManager and QEventLoop is used on Mac OS

To be more specific, problem occurs only in very specific circumstances. It's in situation, when application is compiled as console-app and it's compiled on Mac OS X version older than 10.9:

CONFIG -= gui<br />
CONFIG -= console<br />

and when you're using QEventLoop::exec in mode processing all events except user events (QEventLoop::ExcludeUserInputEvents):

</p>
<p>//it's only demonstration, not full code...<br />
QNetworkAccessManager manager; ...<br />
QNetworkRequest request; ...<br />
QNetworkReply *reply = manager-&gt;post(request,arData);<br />
...</p>
<p>eventLoop.exec(QEventLoop::ExcludeUserInputEvents);<br />

In this situation, application hangs-up. When the application is compiled with GUI mode or when application is compiled on Linux/Windows (no matter if gui or console), everything works find. To fix this problem, it's necessary to implement hack similar to this (simplified version):

   bool bAllowUserInputEvents = false;</p>
<p>#if defined(PLATFORM_MACOS) &amp;&amp; defined(AX_APP_CONSOLE)<br />
   bAllowUserInputEvents = true;<br />
#endif</p>
<p>  if ( bAllowUserInputEvents == false )<br />
    eventLoop.exec(QEventLoop::ExcludeUserInputEvents);<br />
  else<br />
    eventLoop.exec(QEventLoop::AllEvents);<br />

17 Sep 2014

Qt5 application crashed with error 0xc0000005

This is very interesting crash and I think it should be considered as Qt bug. This problem arise only under very special circumstances. But one after another.

You will identify this problem when your application stopped/exited immediately after the start without any visible error message. It looks like the application isn't executed at all. When you check application log (Computer -> manage -> Event viewer -> Windows logs -> Application), you will see Error logs:

Windows applications logs

The most interesting part of this log is crash location: ntdll.dll

Faulting application name: Skipper.exe, version: 3.0.1.1120, time stamp: 0x53e9c8d7<br />
Faulting module name: ntdll.dll, version: 6.1.7601.18247, time stamp: 0x521ea8e7<br />
Exception code: 0xc0000005<br />
Fault offset: 0x0002e3be<br />
Faulting process id: 0x1c88<br />
Faulting application start time: 0x01cfb606553e594b<br />
Faulting application path: T:\S2\Skipper.exe<br />
Faulting module path: C:\Windows\SysWOW64\ntdll.dll<br />
Report Id: 98cc8228-21f9-11e4-ab5d-005056c00008<br />

At first sight it seems like some problem inside the windows. But the opposite is true, the problem (as almost always) is inside your app ;-).

As the next step, you can try to debug this executable via Visual Studio to see what happens inside. Simply open executable as project together with .pdb files and execute it. Now you can see that application is correctly executed but crashes as soon as it touches Qt library. The location of crash is inside ntdll.dll in RtlHeapFree() function.

Debuging crash in VisualStudio 2013

So the problem is inside the Qt, right? Almost true, but not for the 100%. When I tried to run this application on computers of my colleagues, everything works ok. So why the application doesn't work on my computer too?

Resolution

The problem is in new Qt5 plugin system. Besides the common Qt5*.dll files which are loaded immediately after the application start, Qt5 is also loading plugins/platform-plugins dynamically when the application is executed. To locate this plugins, Qt5 uses following method to identify directories where to search for plugins:

QStringList QCoreApplication::libraryPaths()<br />

For some strange reason this library returns as first directory path where Qt5 libraries were compiled and after that location based on the executable. So if your Qt5 path is C:\Qt5, this will be the first path where all plugins are searched for, no matter if the correct version of plugin is located in APP\plugins or APP\platforms. **I think this is serious bug in Qt5**.

Where is the problem?

And here we're getting to the core of the whole problem.

**If application is compiled on computer with one compiler and used on second  computer which contains the same path to which original computer has installed Qt, the application will load all plugins from your folder instead of itself folder.**

In case your computer will contain different version of Qt, different compiler or different platform, application loads incorrect libraries and crashes. Completely, silently and without easy way to determine what's wrong.

Solution?

The solution is simple, but it isn't achievable from outside of the Qt library. It would be necessary to Qt as first tried to load libraries from application directory. And only if no plugins were found in application directory, the application would try to search for plugins in Qt directory.

Qt change solution

The simplest way how to fix this issue inside the Qt library would be to rename/update appendApplicationPathToLibraryPaths  function to prependApplicationPathToLibraryPaths and change

void QCoreApplicationPrivate::prependApplicationPathToLibraryPaths()<br />
{<br />
#ifndef QT_NO_LIBRARY<br />
    QStringList *app_libpaths = coreappdata()-&gt;app_libpaths;<br />
    if (!app_libpaths)<br />
        coreappdata()-&gt;app_libpaths = app_libpaths = new QStringList;<br />
    QString app_location = QCoreApplication::applicationFilePath();<br />
    app_location.truncate(app_location.lastIndexOf(QLatin1Char('/')));<br />
#ifdef Q_OS_WINRT<br />
    if (app_location.isEmpty())<br />
        app_location.append(QLatin1Char('/'));<br />
#endif<br />
    app_location = QDir(app_location).canonicalPath();<br />
    if (QFile::exists(app_location) &amp;&amp; !app_libpaths-&gt;contains(app_location))<br />
        //CHANGE THIS ROW: app_libpaths-&gt;append(app_location);<br />
        //TO FOLLOWING<br />
        app_libpaths-&gt;prepend(app_location);<br />
#endif<br />
}<br />

InApp solution

Unfortunately it isn't possible to simply change this behavior from your app. All of these operations happen directly in QCoreApplication constructor so if you try to change it after, it's too late.

The temporary solution before this problem will be resolved is to reinitialize library paths before QCoreApplication is initialized. It's necessary to clean libray paths, compute new paths and re-initialize QCoreApplication::libraryPaths before QCoreApplication object is initialized. This can be done in main.cpp of your application before you will create QApplication/QCoreApplication object.

  QString executable = argv[0];<br />
  QString executablePath = executable.mid(0,executable.lastIndexOf(&quot;\\&quot;));<br />
  QString installPathPlugins = QLibraryInfo::location(QLibraryInfo::PluginsPath);<br />
  QCoreApplication::removeLibraryPath(installPathPlugins);<br />
  QCoreApplication::addLibraryPath(installPathPlugins);<br />
  QCoreApplication::addLibraryPath(executablePath);<br />

It's not a nice solution, but it works. I tried  to report this issue also to bugreports.QtProject, so maybe in later version this will be fixed.

12 Aug 2014

How to create .pdb files also for Release version of Qt library

For debugging purposes it's a good idea to keep .pdb files also for release version of your libraries. Unfortunately in default configuration Qt library doesn't generate .pdb files. It's a not big deal, create .pdb files for release version it's pretty simple.

1) Add compilation flags to .pro file

The easiest way how to create pdb files is pass /Zi switch to compiler and /Debug to linker.

QMAKE_CXXFLAGS+=/Zi<br />
QMAKE_LFLAGS+= /INCREMENTAL:NO /Debug<br />

2) Solution via mkspec

As pointed out in this QtProject article, another way is to edit mkspec so any future compilations will have this option turned on. It's necessary to modify correct mkspec file, for example

Qt&lt;/span&gt;\mkspecs\win32-msvc2005\qmake.conf<br />

and add following lines (it should be sufficient to add only /Zi and /Debug switch):

QMAKE_CFLAGS_RELEASE += /Zi<br />
QMAKE_LFLAGS_RELEASE += /INCREMENTAL:NO /DEBUG<br />
12 Aug 2014

Posted by: ludek.vodicka

Qt Windows #Qt #Windows #debugging #pdb

Qt app crash on mac when executed with parameters

Our reporting tool occasional crashed on MacOs when was executed with several command line params. Command looked like this:

/app-path/OrmDesigner2 -crash-report -dump-directory /var/folders/4z/k1r35jnn4v77mzl7hzf8wvvw0000gn/T/OrmDesigner2/CrashReports<br />

When inspecting exception report, we found following stack trace:

Thread 0 Crashed:  Dispatch queue: com.apple.main-thread<br />
0   QtCore                         0x0000000100d671da QString::fromLocal8Bit(char const*, int) + 42<br />
1   QtCore                         0x0000000100e72dac QCoreApplication::arguments() + 124<br />
2   QtGui                          0x00000001000de8ef -[QCocoaApplicationDelegate application:openFiles:] + 223<br />
3   com.apple.AppKit               0x00007fff805f3b52 -[NSApplication(NSAppleEventHandling) _handleAEOpenDocumentsForURLs:] + 505<br />
4   com.apple.AppKit               0x00007fff804c0065 -[NSApplication(NSAppleEventHandling) _handleCoreEvent:withReplyEvent:] + 217<br />
5   com.apple.Foundation           0x00007fff800f90d6 -[NSAppleEventManager dispatchRawAppleEvent:withRawReply:handlerRefCon:] + 360<br />
6   com.apple.Foundation           0x00007fff800f8f06 _NSAppleEventManagerGenericHandler + 114<br />
7   com.apple.AE                   0x00007fff82b1c32b aeDispatchAppleEvent(AEDesc const*, AEDesc*, unsigned int, unsigned char*) + 162<br />
8   com.apple.AE                   0x00007fff82b1c224 dispatchEventAndSendReply(AEDesc const*, AEDesc*) + 32<br />
9   com.apple.AE                   0x00007fff82b1c12b aeProcessAppleEvent + 210<br />
10  com.apple.HIToolbox            0x00007fff875ed619 AEProcessAppleEvent + 48<br />
11  com.apple.AppKit               0x00007fff803c5095 _DPSNextEvent + 1191<br />
12  com.apple.AppKit               0x00007fff803c4801 -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 155<br />
13  com.apple.AppKit               0x00007fff8038a68f -[NSApplication run] + 395<br />
14  QtGui                          0x00000001000e7c04 QEventDispatcherMac::processEvents(QFlags) + 1588<br />
15  QtCore                         0x0000000100e70774 QEventLoop::processEvents(QFlags) + 68<br />
16  QtCore                         0x0000000100e70a94 QEventLoop::exec(QFlags) + 180<br />
17  QtCore                         0x0000000100e720bc QCoreApplication::exec() + 188<br />
18  com.inventic.ormdesigner       0x0000000100003447 main + 46 (main.cpp:31)<br />
19  com.inventic.ormdesigner       0x00000001000032e0 start + 52<br />

After some google-searching I found out that the problem is in core of our application. When subclassing Qt QApplication, it's necessary to pass argc with reference, not by value. So after adding one little &, everything works like charm!

//construct application object<br />
CApplication(int&amp; argc, char **argv);<br />

External links

01 Mar 2014

VS2010 always rebuilding moc files on Qt

My VS2010 on every build always recreate all .moc files and associated .cpp files. Problem was in incredibuild clausule during compilation of my Qt libraries.

 

      &lt;AdditionalInputs Condition=&quot;'$(Configuration)|$(Platform)'=='Debug|Win32'&quot;&gt;Rem;axApplication\axAppException\dialogUnhandledException.ui;%(AdditionalInputs)&lt;/AdditionalInputs&gt;<br />
      &lt;Command Condition=&quot;'$(Configuration)|$(Platform)'=='Debug|Win32'&quot;&gt;Rem IncrediBuild_AllowRemote &amp;#x000D;&amp;#x000A;if errorlevel 1 goto VCEnd&amp;#x000D;&amp;#x000A; Rem IncrediBuild_OutputFile ..\GeneratedFiles\ui_dialogUnhandledException.h &amp;#x000D;&amp;#x000A;if errorlevel 1 goto VCEnd&amp;#x000D;&amp;#x000A; Q:\ExternalLibraries\qt-git-32bit\bin\uic.exe axApplication\axAppException\dialogUnhandledException.ui -o ..\GeneratedFiles\ui_dialogUnhandledException.h&lt;/Command&gt;<br />
      &lt;Message Condition=&quot;'$(Configuration)|$(Platform)'=='Debug|Win32'&quot;&gt;UIC axApplication\axAppException\dialogUnhandledException.ui&lt;/Message&gt;<br />
      &lt;Outputs Condition=&quot;'$(Configuration)|$(Platform)'=='Debug|Win32'&quot;&gt;..\GeneratedFiles\ui_dialogUnhandledException.h;%(Outputs)&lt;/Outputs&gt;<br />

instead of

      &lt;AdditionalInputs Condition=&quot;'$(Configuration)|$(Platform)'=='Debug|Win32'&quot;&gt;Q:\ExternalLibraries\qt-4.8.2-32bit\bin\uic.exe;axApplication\axAppException\dialogUnhandledException.ui;%(AdditionalInputs)&lt;/AdditionalInputs&gt;<br />
      &lt;Command Condition=&quot;'$(Configuration)|$(Platform)'=='Debug|Win32'&quot;&gt;Q:\ExternalLibraries\qt-4.8.2-32bit\bin\uic.exe axApplication\axAppException\dialogUnhandledException.ui -o ..\GeneratedFiles\ui_dialogUnhandledException.h&lt;/Command&gt;<br />
      &lt;Message Condition=&quot;'$(Configuration)|$(Platform)'=='Debug|Win32'&quot;&gt;UIC axApplication\axAppException\dialogUnhandledException.ui&lt;/Message&gt;<br />
      &lt;Outputs Condition=&quot;'$(Configuration)|$(Platform)'=='Debug|Win32'&quot;&gt;..\GeneratedFiles\ui_dialogUnhandledException.h;%(Outputs)&lt;/Outputs&gt;<br />

Although qmake added all these incredibuild defines to my VS project, Incredibuild still doesn't compile it in parallel so it was totally useless. The most simply way is edit incredibuild_xge.prf and turn-off it.

mkspecs\features\incredibuild_xge.prf </p>
<p>contains(TEMPLATE, &quot;XXXvc.*&quot;) {<br />

How to enable VS2010 logging

06 Jan 2014

Posted by: ludek.vodicka

Programming Qt #Qt #incredibuild #qmake #vs2010

GetTickCount64 problem on WindowsXP

[caption id="" align="aligncenter" width="637"]
The procedure entry point GetTickCount64 could not be located in the dynamic link library KERNEL32.dll
The procedure entry point GetTickCount64 could not be located in the dynamic link library KERNEL32.dll[/caption]

Today we received report from one of our customers about problem with our ORM Designer on WindowsXP - 32bit. Our latest version returns following error:

The procedure entry point GetTickCount64 could not be located in the dynamic link library KERNEL32.dll

**The problem is that GetTickCount64 doesn't exists in XP system**.

**Solution:**

It's necessary to compile your application (and any library which uses GetTickCount64) with correct **WINVER** and **_WIN32_WINNT **defines value. List of WINVER values for all Windows version can be found here.

You can define these values in your resource.h file:

#define WINVER 0x0501
#define _WIN32_WINNT 0x0501

or add it to a project property -> C/C++ -> Preprocessor -> Preprocessor Definitions:

2013-08-29_15-45-10

**Qt Solution:**

If you want to define these values automatically in Qt project, add following lines to your .pro file:

#Windows XP compatability
DEFINES += "WINVER=0x0501"
DEFINES += "_WIN32_WINNT=0x0501"

External links:

29 Aug 2013

How to sign your Qt Mac OS X App for Gatekeeper

Starting from Mac os 10.8 apple applications requires certificate. Without that certificate (or without additional system tweaks described here on our product support page: http://support.orm-designer.com/5/macos-mountain-lion-10-8-unidentified-developer ) user will se following message:

&quot;OrmDesigner2&quot; can't be opened because it is from an unidentified developer.<br />

[caption id="" align="aligncenter" width="435"] MacOS unidentified developer in ORM Designer[/caption]

Solution

To solve this error message it's necessary to do following steps:

  1. Register in Apple developer program and pay $99 per year
  2. Download and install developer certificate
  3. Sign whole application
  4. Test it!

1) Register on Developer.apple.com

You need to create registration here: https://developer.apple.com/. It's necessary to fill info about contact person and company. After that, your registration will be reviewed by apple team and if everything will be OK, your registration will be approved.

**2) Use Apple site to generate certificates**

Open https://developer.apple.com/account/overview.action ,choose **Certificates, ** Click Add. Than select certificate parameters suitable for your need. In my case it was **Mac Development** and ** Developer ID.**

Now you need to install this certificate to your developer machine. Simply double-click on certificate and let system to import it. You can check that certificate is imported in **Go->Utilities->Keychain Access->login. **Now search for "Developer ID Application: XXXX"

MacOS certificate

**Note: **In my case when I transfer certificate to several developer machines I need to migrate also other Apple certificates. Without that my certificate wasn't a valid.

**3) Sign your application**

Now you need to sign your application including all plugins and frameworks inside app bundle. **After you sing your app, you can't do any changes in the bundle.** So as first run your deploy as usual and as **last step **do app singing.

For ORM Designer sign script looks like this:

#go to deploy directory<br />
cd $StarkDeploy.directory$/deploy</p>
<p>#sign app<br />
codesign --force --verify --verbose --sign &quot;Developer ID Application: Inventic s.r.o.&quot; ./OrmDesigner2.app</p>
<p>#sign all *.dylib files<br />
find OrmDesigner2.app -name *.dylib | xargs -I $ codesign --force --verify --verbose --sign &quot;Developer ID Application: Inventic s.r.o.&quot; $</p>
<p>#sign all Qt* frameworks<br />
find OrmDesigner2.app -name Qt* -type f | xargs -I $ codesign --force --verify --verbose --sign &quot;Developer ID Application: Inventic s.r.o.&quot; $<br />

4) Test it!

As last step it's necessary to test that sign process was successful. As first you can try following command line to validate  it:

codesign -vvv -d OrmDesigner2.app</p>
<p>#RESULT:<br />
Executable=/OrmDesigner2/DeployFiles/macos64/deploy/OrmDesigner2.app/Contents/MacOS/OrmDesigner2<br />
Identifier=com.orm-designer.OrmDesigner2<br />
Format=bundle with Mach-O thin (x86_64)<br />
CodeDirectory v=20100 size=174478 flags=0x0(none) hashes=8717+3 location=embedded<br />
Hash type=sha1 size=20<br />
CDHash=5a491e16f7dcca15b44af4XXXX1a2d2dcc786518<br />
Signature size=4237<br />
Authority=Developer ID Application: Inventic s.r.o. (6BYV46LH6T)<br />
Authority=Developer ID Certification Authority<br />
Authority=Apple Root CA<br />
Signed Time=6 Jun 2013 23:16:08<br />
Info.plist entries=10<br />
Sealed Resources rules=4 files=27<br />
Internal requirements count=1 size=212<br />

Now when you checked that App is correctly signed, it's time to try it on clean computer where no security policy changes was made. Upload your app and execute it.

If you don't see annoying screen "Can't execute application from unidentified developer", **you win** ;-).

External links

**How to transfer certificate: **

**How to import:**

**Apple links**

07 Jun 2013

Posted by: ludek.vodicka

Qt Mac OS #MacOs #certificate #developer

Qt stylesheet guidance

Style sheets

Layout Management

How to tips

How to recompute Qt style-sheet based on Q_PROPERTY:

void QControl::RedrawWidgetStylesheet()<br />
{<br />
	style()-&gt;unpolish(this);<br />
	style()-&gt;polish(this);<br />
	update();<br />
}<br />
02 May 2013

Posted by: ludek.vodicka

Qt #Qt #stylesheet

Problem with Qt application on MacOS Retina display

Standard Qt application on retina display looks ugly. Fuzzy fonts and images. This is how ORM Designer originaly looks on Retina:

[caption id="" align="aligncenter" width="2880"] ORM Designer on Retina before optimizations[/caption]

Improve font autoscaling

First step how to improve Qt application on retina is by adding following definise to Info.plist

NSPrincipalClass<br />
NSApplication<br />

[caption id="" align="alignnone" width="405"] How to update Info.plist[/caption]

If you're updating existing application, it's necessary to copy application to different location after Info.plist update. MacOS cache all .plist files and without that update will not be apply.

After applying this fix, this is how application looks:

[caption id="" align="aligncenter" width="2880"] How ORM Designer looks after fix[/caption]

External sources

20 Feb 2013

Posted by: ludek.vodicka

Qt #Qt #MacOs #Retina

Qt QtDBus compilation

To add DBUS to Qt compilation, add following switch

./configure -opensource -dbus ....<br />

If you get following error:

The QtDBus module cannot be enabled because libdbus-1 version 0.93 was not found.<br />
Turn on verbose messaging (-v) to ./configure to see the final report.<br />
If you believe this message is in error you may use the continue<br />
switch (-continue) to ./configure to continue.<br />

It's necessary to install libsbus:

sudo apt-get install libdbus-1-3<br />
Reading package lists... Done<br />
Building dependency tree<br />
Reading state information... Done<br />
libdbus-1-3 is already the newest version.<br />

and also developer package:

sudo apt-get install libdbus-1-dev<br />

Now everything should work correctly.

24 Jan 2013

Posted by: ludek.vodicka

Qt Linux #Qt #Linux #system

Qt and Google breakpad Windows/Linux/MacOS

Integration of Google breakpad on any platform is really challenge. I didn't figure out how to do it by using recommended ways. So I did it my way ;-)

Create your own Qt project

As first thing I did when integrating Qt and Breakpad is creation of my own .pri file. I manually add all required files from Breakpad one-by-one, starting with src/platform/exception_handler continuing with all files included in previous ones. The complete .pri file you will find at end of this post.

After that I created simple CCrashHandler (inspired by qt-breakpad project) class which register exception handler. It's necessary to implement this handler for each platform separately because each platform have different parameters in google_breakpad::ExceptionHandler() constructor. CrashHandler source code you can find also at end of this post.

Using Breakpad on Linux:

Article about Linux integration.

Notes Linux

  • GCC 4.6.3
  • Ubuntu 12.04.1 32/64bit

Get and Compile Breakpad

#get breakpad latest version<br />
svn checkout http://google-breakpad.googlecode.com/svn/trunk/ google-breakpad-read-only</p>
<p>#compile all breakpad tools for extracting symbol files<br />
./configure<br />
make<br />
sudo make install</p>
<p>#when compilation is ready, you should have installed file dump_syms from original directory /src/tools/linux/dump_syms in your /usr/bin<br />
dump_syms<br />

Generate symbol file and test debug info

Now how to generate and use symbol file:

#generate .sym file<br />
dump_syms ./Application &gt; Application.sym</p>
<p>#store sym file in the correct location<br />
#this step is necessary. Without that minidump_stackwalk tool doesn't work</p>
<p>head -n1 Application.sym<br />
#Result: MODULE Linux x86_64 6EDC6ACDB282125843FD59DA9C81BD830 Application</p>
<p>mkdir -p ./symbols/Application/6EDC6ACDB282125843FD59DA9C81BD830<br />
mv Application.sym ./symbols/Application/6EDC6ACDB282125843FD59DA9C81BD830</p>
<p>#show stack with using minidump_stackwalk tool<br />
minidump_stackwalk ./crash.dmp ./symbols<br />

Result of minidump_stackwalk tool can look like this:

Use additional tools

There is script written by Mozzila corp which simplifies extracting and storing .sym file:
http://mxr.mozilla.org/mozilla-central/source/toolkit/crashreporter/tools/symbolstore.py?raw=1

Now with this script, you can do only one step instead of all described above.

python /path/to/script/symbolstore.py /usr/local/bin/dump_syms ./symbol-storage ./Application<br />

This command correctly creates folder Application/uuid in path symbol-storage and copy generated .sym file inside.

Using Breakpad on MacOS:

To integrate Breakpad and Qt on MacOS I used the same article as for Linux because I'm using gcc and linux-like development toolchain. For native XCode integration you have to probably use this article.

Notes MacOS

  • GCC 4.6.3
  • Qt creator toolchain
  • Mac OS 10.7.3 64bit
  • Don't using any of XCode tool chaing

Do almost all steps like on Linux integration. There is one exception, because you can't compile Breakpad tools using linux-like configure&make. You have to build these tools with XCode.

Compile google_breakpad/src/tools/mac/dump_syms/dump_syms.xcodeproj with XCode

Before I managed to successfully compile dump_syms in XCode, I have to update Architectures Debug/Release to 64-bit Intel and BaseSDK to "Latest Mac OS X". I also fix all issues displayed in the left part of XCode window.

Next step is change compilation type from Debug to Release. After a short searching I found a way in "Schema->Edit schema->Build configuration".

To be honest, I was not sure what I did, but it worked ;-). Maybe there is some easier way how to compile dump_syms in xcode, but I don't know how. This was my first contact with XCode ;-).

The application is compiled to path "/Users/User/Library/Developer/Xcode/DerivedData/dump_syms-bjvr/Build/Products/Release/dump_syms". Now copy dump_syms to safe location from where you will use it.

The rest steps are same like in the Linux.

Using Breakpad on Windows

Notes Windows

Article about Windows integration.

  • Compile with Visual Studio 2010
  • Post-mortem debugging is done also via VS2010
  • Google breakpad under windows generates common .dmp files which can by simply load directly to VS

Generate symbol files and test debug info

You have to choices for Windows. First option is use standard .PDB and .DMP files mechanism in VS. Second is use the same way how you can did it for Linux and Mac.

**First way**: Let compiler generate .PDB file. Store this files and use them later in VS together with your crash dump.

**Second way**: Use dump_sys.exe. This file is located in the google breakpad directory tree: google-breakpad\src\tools\windows\binaries\dump_syms.exe .

dump_syms.exe AtomixDevelopment.exe &gt;AtomixDevelopment.sym<br />

And also like under Linux, you can use Python script symbolstore.py to extract symbols to correct directory:

python.exe symbolstore.py binaries\dump_syms.exe .\Symbols AtomixDevelopment.exe<br />

Minidump stackwalk for windows:
http://code.google.com/p/pcxfirefox/source/browse/trunk/betterpgo/talos/talos/breakpad/win32/minidump_stackwalk.exe?r=19

The best thing at end

The most amazing thing I found about dump_syms is their platform independence. If you correctly extract symbol file on each platform and store it in one location, you can analyze any crashdump on one location. No matter what is source platform, you will analyze .dmp file by using **minidump_stackwalk ./crash.dmp ./symbols**.

How to include CrashHandler directly to your project

This is what I get when I follow all includes from **.h** and **.cpp** files starting with exception_handler.h for all platforms. With small modification you can include it to your project and your application will be fully breakpad-able ;-).

# ---------- HEADER -----------------------------------------------------------<br />
OTHERS   += $$PWD/axCrashHandler.pri<br />
HEADERS += $$PWD/CrashHandler.h<br />
SOURCES += $$PWD/CrashHandler.cpp</p>
<p>BREAKPAD_PATH=$$EXTERNAL_LIBRARIES_PATH/breakpad-qt<br />
INCLUDEPATH += $$BREAKPAD_PATH/src</p>
<p>OSMAC {<br />
  HEADERS += $$BREAKPAD_PATH/src/client/mac/handler/exception_handler.h<br />
  HEADERS += $$BREAKPAD_PATH/src/client/mac/crash_generation/crash_generation_client.h<br />
  HEADERS += $$BREAKPAD_PATH/src/client/mac/crash_generation/crash_generation_server.h<br />
  HEADERS += $$BREAKPAD_PATH/src/client/mac/crash_generation/client_info.h<br />
  HEADERS += $$BREAKPAD_PATH/src/client/mac/handler/minidump_generator.h<br />
  HEADERS += $$BREAKPAD_PATH/src/client/mac/handler/dynamic_images.h<br />
  HEADERS += $$BREAKPAD_PATH/src/client/mac/handler/breakpad_nlist_64.h<br />
  HEADERS += $$BREAKPAD_PATH/src/client/mac/handler/mach_vm_compat.h<br />
  HEADERS += $$BREAKPAD_PATH/src/client/minidump_file_writer.h<br />
  HEADERS += $$BREAKPAD_PATH/src/client/minidump_file_writer-inl.h<br />
  HEADERS += $$BREAKPAD_PATH/src/common/mac/macho_utilities.h<br />
  HEADERS += $$BREAKPAD_PATH/src/common/mac/byteswap.h<br />
  HEADERS += $$BREAKPAD_PATH/src/common/mac/MachIPC.h<br />
  HEADERS += $$BREAKPAD_PATH/src/common/mac/scoped_task_suspend-inl.h<br />
  HEADERS += $$BREAKPAD_PATH/src/common/mac/file_id.h<br />
  HEADERS += $$BREAKPAD_PATH/src/common/mac/macho_id.h<br />
  HEADERS += $$BREAKPAD_PATH/src/common/mac/macho_walker.h<br />
  HEADERS += $$BREAKPAD_PATH/src/common/mac/macho_utilities.h<br />
  HEADERS += $$BREAKPAD_PATH/src/common/mac/bootstrap_compat.h<br />
  HEADERS += $$BREAKPAD_PATH/src/common/mac/string_utilities.h<br />
  HEADERS += $$BREAKPAD_PATH/src/common/linux/linux_libc_support.h<br />
  HEADERS += $$BREAKPAD_PATH/src/common/string_conversion.h<br />
  HEADERS += $$BREAKPAD_PATH/src/common/md5.h<br />
  HEADERS += $$BREAKPAD_PATH/src/common/memory.h<br />
  HEADERS += $$BREAKPAD_PATH/src/common/using_std_string.h<br />
  HEADERS += $$BREAKPAD_PATH/src/common/convert_UTF.h<br />
  HEADERS += $$BREAKPAD_PATH/src/processor/scoped_ptr.h<br />
  HEADERS += $$BREAKPAD_PATH/src/google_breakpad/common/minidump_exception_mac.h<br />
  HEADERS += $$BREAKPAD_PATH/src/google_breakpad/common/breakpad_types.h<br />
  HEADERS += $$BREAKPAD_PATH/src/google_breakpad/common/minidump_format.h<br />
  HEADERS += $$BREAKPAD_PATH/src/google_breakpad/common/minidump_size.h<br />
  HEADERS += $$BREAKPAD_PATH/src/third_party/lss/linux_syscall_support.h</p>
<p>  SOURCES += $$BREAKPAD_PATH/src/client/mac/handler/exception_handler.cc<br />
  SOURCES += $$BREAKPAD_PATH/src/client/mac/crash_generation/crash_generation_client.cc<br />
  SOURCES += $$BREAKPAD_PATH/src/client/mac/crash_generation/crash_generation_server.cc<br />
  SOURCES += $$BREAKPAD_PATH/src/client/mac/handler/minidump_generator.cc<br />
  SOURCES += $$BREAKPAD_PATH/src/client/mac/handler/dynamic_images.cc<br />
  SOURCES += $$BREAKPAD_PATH/src/client/mac/handler/breakpad_nlist_64.cc<br />
  SOURCES += $$BREAKPAD_PATH/src/client/minidump_file_writer.cc<br />
  SOURCES += $$BREAKPAD_PATH/src/common/mac/macho_id.cc<br />
  SOURCES += $$BREAKPAD_PATH/src/common/mac/macho_walker.cc<br />
  SOURCES += $$BREAKPAD_PATH/src/common/mac/macho_utilities.cc<br />
  SOURCES += $$BREAKPAD_PATH/src/common/mac/string_utilities.cc<br />
  SOURCES += $$BREAKPAD_PATH/src/common/mac/file_id.cc<br />
  SOURCES += $$BREAKPAD_PATH/src/common/mac/MachIPC.mm<br />
  SOURCES += $$BREAKPAD_PATH/src/common/mac/bootstrap_compat.cc<br />
  SOURCES += $$BREAKPAD_PATH/src/common/md5.cc<br />
  SOURCES += $$BREAKPAD_PATH/src/common/string_conversion.cc<br />
  SOURCES += $$BREAKPAD_PATH/src/common/linux/linux_libc_support.cc<br />
  SOURCES += $$BREAKPAD_PATH/src/common/convert_UTF.c<br />
  LIBS += /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation<br />
  LIBS += /System/Library/Frameworks/CoreServices.framework/Versions/A/CoreServices<br />
  #breakpad app need debug info inside binaries<br />
  QMAKE_CXXFLAGS+=-g<br />
}</p>
<p>OSLIN {<br />
  HEADERS += $$BREAKPAD_PATH/src/client/linux/handler/exception_handler.h<br />
  HEADERS += $$BREAKPAD_PATH/src/client/linux/crash_generation/crash_generation_client.h<br />
  HEADERS += $$BREAKPAD_PATH/src/client/linux/handler/minidump_descriptor.h<br />
  HEADERS += $$BREAKPAD_PATH/src/client/linux/minidump_writer/minidump_writer.h<br />
  HEADERS += $$BREAKPAD_PATH/src/client/linux/minidump_writer/line_reader.h<br />
  HEADERS += $$BREAKPAD_PATH/src/client/linux/minidump_writer/linux_dumper.h<br />
  HEADERS += $$BREAKPAD_PATH/src/client/linux/minidump_writer/linux_ptrace_dumper.h<br />
  HEADERS += $$BREAKPAD_PATH/src/client/linux/minidump_writer/directory_reader.h<br />
  HEADERS += $$BREAKPAD_PATH/src/client/linux/log/log.h<br />
  HEADERS += $$BREAKPAD_PATH/src/client/minidump_file_writer-inl.h<br />
  HEADERS += $$BREAKPAD_PATH/src/client/minidump_file_writer.h<br />
  HEADERS += $$BREAKPAD_PATH/src/common/linux/linux_libc_support.h<br />
  HEADERS += $$BREAKPAD_PATH/src/common/linux/eintr_wrapper.h<br />
  HEADERS += $$BREAKPAD_PATH/src/common/linux/ignore_ret.h<br />
  HEADERS += $$BREAKPAD_PATH/src/common/linux/file_id.h<br />
  HEADERS += $$BREAKPAD_PATH/src/common/linux/memory_mapped_file.h<br />
  HEADERS += $$BREAKPAD_PATH/src/common/linux/safe_readlink.h<br />
  HEADERS += $$BREAKPAD_PATH/src/common/linux/guid_creator.h<br />
  HEADERS += $$BREAKPAD_PATH/src/common/linux/elfutils.h<br />
  HEADERS += $$BREAKPAD_PATH/src/common/linux/elfutils-inl.h<br />
  HEADERS += $$BREAKPAD_PATH/src/common/using_std_string.h<br />
  HEADERS += $$BREAKPAD_PATH/src/common/memory.h<br />
  HEADERS += $$BREAKPAD_PATH/src/common/basictypes.h<br />
  HEADERS += $$BREAKPAD_PATH/src/common/memory_range.h<br />
  HEADERS += $$BREAKPAD_PATH/src/common/string_conversion.h<br />
  HEADERS += $$BREAKPAD_PATH/src/common/convert_UTF.h<br />
  HEADERS += $$BREAKPAD_PATH/src/google_breakpad/common/minidump_format.h<br />
  HEADERS += $$BREAKPAD_PATH/src/google_breakpad/common/minidump_size.h<br />
  HEADERS += $$BREAKPAD_PATH/src/google_breakpad/common/breakpad_types.h<br />
  HEADERS += $$BREAKPAD_PATH/src/processor/scoped_ptr.h<br />
  HEADERS += $$BREAKPAD_PATH/src/third_party/lss/linux_syscall_support.h<br />
  SOURCES += $$BREAKPAD_PATH/src/client/linux/crash_generation/crash_generation_client.cc<br />
  SOURCES += $$BREAKPAD_PATH/src/client/linux/handler/exception_handler.cc<br />
  SOURCES += $$BREAKPAD_PATH/src/client/linux/handler/minidump_descriptor.cc<br />
  SOURCES += $$BREAKPAD_PATH/src/client/linux/minidump_writer/minidump_writer.cc<br />
  SOURCES += $$BREAKPAD_PATH/src/client/linux/minidump_writer/linux_dumper.cc<br />
  SOURCES += $$BREAKPAD_PATH/src/client/linux/minidump_writer/linux_ptrace_dumper.cc<br />
  SOURCES += $$BREAKPAD_PATH/src/client/linux/log/log.cc<br />
  SOURCES += $$BREAKPAD_PATH/src/client/minidump_file_writer.cc<br />
  SOURCES += $$BREAKPAD_PATH/src/common/linux/linux_libc_support.cc<br />
  SOURCES += $$BREAKPAD_PATH/src/common/linux/file_id.cc<br />
  SOURCES += $$BREAKPAD_PATH/src/common/linux/memory_mapped_file.cc<br />
  SOURCES += $$BREAKPAD_PATH/src/common/linux/safe_readlink.cc<br />
  SOURCES += $$BREAKPAD_PATH/src/common/linux/guid_creator.cc<br />
  SOURCES += $$BREAKPAD_PATH/src/common/linux/elfutils.cc<br />
  SOURCES += $$BREAKPAD_PATH/src/common/string_conversion.cc<br />
  SOURCES += $$BREAKPAD_PATH/src/common/convert_UTF.c<br />
  #breakpad app need debug info inside binaries<br />
  QMAKE_CXXFLAGS+=-g<br />
}</p>
<p>OSWIN {<br />
  BREAKPAD_PATH=q:/Applications/breakpad-qt/third-party/latest-breakpad<br />
  INCLUDEPATH += $$BREAKPAD_PATH/src<br />
  HEADERS += $$BREAKPAD_PATH/src/common/windows/string_utils-inl.h<br />
  HEADERS += $$BREAKPAD_PATH/src/common/windows/guid_string.h<br />
  HEADERS += $$BREAKPAD_PATH/src/client/windows/handler/exception_handler.h<br />
  HEADERS += $$BREAKPAD_PATH/src/client/windows/common/ipc_protocol.h<br />
  HEADERS += $$BREAKPAD_PATH/src/google_breakpad/common/minidump_format.h<br />
  HEADERS += $$BREAKPAD_PATH/src/google_breakpad/common/breakpad_types.h<br />
  HEADERS += $$BREAKPAD_PATH/src/client/windows/crash_generation/crash_generation_client.h<br />
  HEADERS += $$BREAKPAD_PATH/src/processor/scoped_ptr.h </p>
<p>  SOURCES += $$BREAKPAD_PATH/src/client/windows/handler/exception_handler.cc<br />
  SOURCES += $$BREAKPAD_PATH/src/common/windows/string_utils.cc<br />
  SOURCES += $$BREAKPAD_PATH/src/common/windows/guid_string.cc<br />
  SOURCES += $$BREAKPAD_PATH/src/client/windows/crash_generation/crash_generation_client.cc<br />
}<br />

And this is the minimal implementation of your new CrashHandler. My ownd crash handler is much more sophisticate to perform reporting, sending crash dump etc. But for purposes of this article this is what you need (And also I don't want to share my whole know-how here ;-)))

CrashHandler.h

#pragma once<br />
#include &lt;QtCore/QString&gt;</p>
<p>namespace Atomix<br />
{<br />
	class CrashHandlerPrivate;<br />
	class CrashHandler<br />
	{<br />
	public:<br />
		static CrashHandler* instance();<br />
    void Init(const QString&amp;  reportPath);</p>
<p>		void setReportCrashesToSystem(bool report);<br />
		bool writeMinidump();</p>
<p>	private:<br />
		CrashHandler();<br />
		~CrashHandler();<br />
		Q_DISABLE_COPY(CrashHandler)<br />
		CrashHandlerPrivate* d;<br />
	};<br />
}<br />

CrashHandler.cpp

#include &quot;CrashHandler.h&quot;<br />
#include &lt;QtCore/QDir&gt;<br />
#include &lt;QtCore/QProcess&gt;<br />
#include &lt;QtCore/QCoreApplication&gt;<br />
#include &lt;QString&gt;</p>
<p>#if defined(Q_OS_MAC)<br />
#include &quot;client/mac/handler/exception_handler.h&quot;<br />
#elif defined(Q_OS_LINUX)<br />
#include &quot;client/linux/handler/exception_handler.h&quot;<br />
#elif defined(Q_OS_WIN32)<br />
#include &quot;client/windows/handler/exception_handler.h&quot;<br />
#endif</p>
<p>namespace Atomix<br />
{<br />
	/************************************************************************/<br />
	/* CrashHandlerPrivate                                                  */<br />
	/************************************************************************/<br />
	class CrashHandlerPrivate<br />
	{<br />
	public:<br />
		CrashHandlerPrivate()<br />
		{<br />
			pHandler = NULL;<br />
		}</p>
<p>		~CrashHandlerPrivate()<br />
		{<br />
			delete pHandler;<br />
		}</p>
<p>		void InitCrashHandler(const QString&amp; dumpPath);<br />
		static google_breakpad::ExceptionHandler* pHandler;<br />
		static bool bReportCrashesToSystem;<br />
	};</p>
<p>	google_breakpad::ExceptionHandler* CrashHandlerPrivate::pHandler = NULL;<br />
	bool CrashHandlerPrivate::bReportCrashesToSystem = false;</p>
<p>	/************************************************************************/<br />
	/* DumpCallback                                                         */<br />
	/************************************************************************/<br />
#if defined(Q_OS_WIN32)<br />
	bool DumpCallback(const wchar_t* _dump_dir,const wchar_t* _minidump_id,void* context,EXCEPTION_POINTERS* exinfo,MDRawAssertionInfo* assertion,bool success)<br />
#elif defined(Q_OS_LINUX)<br />
	bool DumpCallback(const google_breakpad::MinidumpDescriptor &amp;md,void *context, bool success)<br />
#elif defined(Q_OS_MAC)<br />
	bool DumpCallback(const char* _dump_dir,const char* _minidump_id,void *context, bool success)<br />
#endif<br />
	{<br />
		Q_UNUSED(context);<br />
#if defined(Q_OS_WIN32)<br />
		Q_UNUSED(_dump_dir);<br />
		Q_UNUSED(_minidump_id);<br />
		Q_UNUSED(assertion);<br />
		Q_UNUSED(exinfo);<br />
#endif<br />
		qDebug(&quot;BreakpadQt crash&quot;);</p>
<p>		/*<br />
		NO STACK USE, NO HEAP USE THERE !!!<br />
		Creating QString's, using qDebug, etc. - everything is crash-unfriendly.<br />
		*/<br />
		return CrashHandlerPrivate::bReportCrashesToSystem ? success : true;<br />
	}</p>
<p>	void CrashHandlerPrivate::InitCrashHandler(const QString&amp; dumpPath)<br />
	{<br />
		if ( pHandler != NULL )<br />
			return;</p>
<p>#if defined(Q_OS_WIN32)<br />
		std::wstring pathAsStr = (const wchar_t*)dumpPath.utf16();<br />
		pHandler = new google_breakpad::ExceptionHandler(<br />
			pathAsStr,<br />
			/*FilterCallback*/ 0,<br />
			DumpCallback,<br />
			/*context*/<br />
			0,<br />
			true<br />
			);<br />
#elif defined(Q_OS_LINUX)<br />
		std::string pathAsStr = dumpPath.toStdString();<br />
		google_breakpad::MinidumpDescriptor md(pathAsStr);<br />
		pHandler = new google_breakpad::ExceptionHandler(<br />
			md,<br />
			/*FilterCallback*/ 0,<br />
			DumpCallback,<br />
			/*context*/ 0,<br />
			true,<br />
			-1<br />
			);<br />
#elif defined(Q_OS_MAC)<br />
		std::string pathAsStr = dumpPath.toStdString();<br />
		pHandler = new google_breakpad::ExceptionHandler(<br />
			pathAsStr,<br />
			/*FilterCallback*/ 0,<br />
			DumpCallback,<br />
			/*context*/<br />
			0,<br />
			true,<br />
			NULL<br />
			);<br />
#endif<br />
	}</p>
<p>	/************************************************************************/<br />
	/* CrashHandler                                                         */<br />
	/************************************************************************/<br />
	CrashHandler* CrashHandler::instance()<br />
	{<br />
		static CrashHandler globalHandler;<br />
		return &amp;globalHandler;<br />
	}</p>
<p>	CrashHandler::CrashHandler()<br />
	{<br />
		d = new CrashHandlerPrivate();<br />
	}</p>
<p>	CrashHandler::~CrashHandler()<br />
	{<br />
		delete d;<br />
	}</p>
<p>	void CrashHandler::setReportCrashesToSystem(bool report)<br />
	{<br />
		d-&gt;bReportCrashesToSystem = report;<br />
	}</p>
<p>	bool CrashHandler::writeMinidump()<br />
	{<br />
		bool res = d-&gt;pHandler-&gt;WriteMinidump();<br />
		if (res) {<br />
			qDebug(&quot;BreakpadQt: writeMinidump() successed.&quot;);<br />
		} else {<br />
			qWarning(&quot;BreakpadQt: writeMinidump() failed.&quot;);<br />
		}<br />
		return res;<br />
	}</p>
<p>	void CrashHandler::Init( const QString&amp; reportPath )<br />
	{<br />
		d-&gt;InitCrashHandler(reportPath);<br />
	}<br />
}<br />

Main.cpp

And here is how to use it:

#include &quot;axCore/axCrashHandler/CrashHandler.h&quot;<br />
#include &lt;QDebug&gt;<br />
#include &lt;QCoreApplication&gt;<br />
#include &lt;iostream&gt;</p>
<p>int buggyFunc()<br />
{<br />
	delete reinterpret_cast&lt;QString*&gt;(0xFEE1DEAD);<br />
	return 0;<br />
}</p>
<p>int main(int argc, char * argv[])<br />
{<br />
	qDebug() &lt;&lt; &quot;App start&quot;;<br />
	QCoreApplication app(argc, argv);</p>
<p>#if defined(Q_OS_WIN32)<br />
	Atomix::CrashHandler::instance()-&gt;Init(&quot;c:\\dump&quot;);<br />
#elif defined(Q_OS_LINUX)<br />
	Atomix::CrashHandler::instance()-&gt;Init(&quot;/Users/dev/dump&quot;);<br />
#elif defined(Q_OS_MAC)<br />
	Atomix::CrashHandler::instance()-&gt;Init(&quot;/Users/User/dump&quot;);<br />
#endif</p>
<p>	qDebug() &lt;&lt; &quot;CrashHandlerSet&quot;;<br />
	buggyFunc();<br />
	return 0;<br />
}<br />

QWidget: Must construct a QApplication before a QPaintDevice

Today I encounter this error after applying **macdeployqt** to my application. There is a lot of questions about this topic on google but not very answers.

The most important thing is setup following variable.

export DYLD_PRINT_LIBRARIES=1<br />

Using this you will se which libraries are loaded during execution of your application. The interesting thing is, that I see loading a libraries from their original directories instead of Application.app. But when I temporary moved these libraries from their location, libraries begin to load from then bundle location.

The reason for my "QWidget: Must construct a QApplication before a QPaintDevice" was executing an older version of QTitanRibbon from shared libraries path instead of the newest one compiled directly to /usr/lib.
The second reason for this issue was caused by another path in "export DYLD_LIBRARY_PATH". It seems that application search for libraries first in DYLD_LIBRARY_PATH and after in paths from their inner records.

To turn off this debug output, use:

unset DYLD_PRINT_LIBRARIES<br />

29 Aug 2012

Posted by: ludek.vodicka

Programming Qt Mac OS #Qt #MacOs #deploy

Error compiling Qt 4.8.2 under older versions of Ubuntu

If you encounter to this error

error package gstreamer-app-0.10 not found<br />

simply install/reinstall gstreamer packages

sudo apt-get install libgstreamer0.10-dev libgstreamer-plugins-base0.10-dev<br />
21 Aug 2012

Posted by: ludek.vodicka

Qt Linux #Qt #Linux

How to create nice MacOS DMG installer

In this article I will show how to create DMG installer in reusable way. The most of things and ideas presented here are ideas from several articles mentioned on the end of this article.

1) As first step we need to create our DMG template with link to Applications.
2) Next we have to modify the visual representation of DMG file.
3) Next we store created DMG as template
4) Now mount copied template as directory, fill DMG with real files
5) Detach mounted DMG, pack DMG
6) Distribute app ;-)

More detailed info about all these steps you will find in articles mentioned below. Here is a short script I wrote for three-phase deploying (1) create template, 2) pack template, 3)fill template with real data and compress it)

#! /bin/bash</p>
<p>TEMPLATE_DMG=atomix-development-template.dmg<br />
VOLUME_NAME=&quot;Atomix Development&quot;<br />
APPLICATION_FILE_NAME=&quot;AtomixDevelopment.app&quot;</p>
<p>if [ &quot;$1&quot; = &quot;create-template&quot; ]<br />
then<br />
  echo Create DMG template<br />
  mkdir template<br />
  cd template<br />
  mkdir $APPLICATION_FILE_NAME<br />
  touch $APPLICATION_FILE_NAME/fake<br />
  ln -s /Applications/ Applications<br />
  cd ..<br />
  rm $TEMPLATE_DMG<br />
  rm $TEMPLATE_DMG.bz2<br />
  hdiutil create -fs HFSX -layout SPUD -size 100m &quot;$TEMPLATE_DMG&quot; -srcfolder template -format UDRW -volname &quot;$VOLUME_NAME&quot; -quiet<br />
  rm -rf template<br />
elif [ &quot;$1&quot; = &quot;zip-template&quot; ]<br />
then<br />
  echo Zipping DMG template<br />
  bzip2 &quot;$TEMPLATE_DMG&quot;<br />
elif [ &quot;$1&quot; = &quot;create-dmg&quot; ]<br />
then<br />
  echo Creating DMG file from template and data</p>
<p>  #unzip template<br />
  rm $TEMPLATE_DMG<br />
  bunzip2 -k $TEMPLATE_DMG.bz2</p>
<p>  #create pack path and attach DMG<br />
  PACK_PATH=`pwd`/dmg-pack<br />
  mkdir $PACK_PATH<br />
  hdiutil attach &quot;$TEMPLATE_DMG&quot; -noautoopen -quiet -mountpoint &quot;$PACK_PATH&quot;</p>
<p>  #copy new content to DMG<br />
  cp -r &quot;$2&quot; &quot;$PACK_PATH&quot;<br />
  rm $PACK_PATH/$APPLICATION_FILE_NAME/fake</p>
<p>  #detach DMG, remove mount path<br />
  hdiutil detach &quot;$PACK_PATH&quot; -force -quiet<br />
  rm -rf $PACK_PATH</p>
<p>  #compress DMG<br />
  hdiutil convert -format UDZO -o tmp-packer-output.dmg &quot;$TEMPLATE_DMG&quot; -imagekey zlib-level=9<br />
  rm ./$TEMPLATE_DMG<br />
  mv ./tmp-packer-output.dmg $TEMPLATE_DMG</p>
<p>  #rm $TEMPLATE_DMG<br />
else<br />
  echo Missing parameter<br />
  echo &quot;create-dmg [create|zip-template|create-dmg Path/Application.app]&quot;<br />
fi<br />

So, it looks like that DMG file for ORM Designer2 is ready ;-)

Another tools to create DMG package

External links

http://codevarium.gameka.com.br/how-to-create-your-own-beautiful-dmg-files/
http://el-tramo.be/guides/fancy-dmg/
http://stackoverflow.com/questions/96882/how-do-i-create-a-nice-looking-dmg-for-mac-os-x-using-command-line-tools
http://stackoverflow.com/questions/8680132/creating-nice-dmg-installer-for-mac-os-x
http://stackoverflow.com/questions/2104364/how-to-install-a-qt-application-on-a-customers-system

16 Aug 2012

Posted by: ludek.vodicka

Qt Mac OS #MacOs #deploy

How to deploy Qt application on MacOS - part II

In first part of this article I introduced a manual way how to deploy MacOS application. Because doing all these stuff manually was a lot of hand work, Qt introduced small tool called **macdeployqt**.

This utility looks very good, but also have some drawbacks. As first I will show you how utility works:

macdeployqt Application.app<br />

That's all ;-). This command should do all the hard work for you. But in some cases it didn't.

ERROR: no file at &quot;/usr/lib/libboost_iostreams.dylib&quot;<br />
ERROR: no file at &quot;/usr/lib/libboost_filesystem.dylib&quot;<br />
ERROR: no file at &quot;/usr/lib/libboost_system.dylib&quot;<br />
ERROR: no file at &quot;/usr/lib/libboost_thread.dylib&quot;<br />
ERROR: no file at &quot;/usr/lib/libboost_date_time.dylib&quot;<br />
ERROR: no file at &quot;/usr/lib/libboost_regex.dylib&quot;<br />
ERROR: no file at &quot;/usr/lib/libboost_chrono.dylib&quot;<br />
ERROR: no file at &quot;/usr/lib/libyaml-cpp.0.2.dylib&quot;<br />

The problem is that libraries mentioned in the previous list doesn't has included absolute path. If you inspecit this library, you will se this:

otool -L libboost_regex.dylib<br />
libboost_regex.dylib:<br />
	libboost_regex.dylib (compatibility version 0.0.0, current version 0.0.0)<br />
	/usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 52.0.0)<br />
	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 159.1.0)<br />

And this is the problem. Inner path in library is only filename without full path, so when we link library with our executable, our executable also has only relative path. And when macdeployqt try to find this library, automatically try to search in /usr/lib.

One possible solution is copy libraries to /usr/lib. Second solution is update paths in libraries to absolute paths. The third way is fix library linker to include full paths in libraries.

I found out that the simplies way how to fix it is call install_name_tool after library compilation and fix the path (don't forget to update library paths inside other library paths!)

  install_name_tool -id &quot;$SHL_PATH/boost/lib/libboost_chrono.dylib&quot; $SHL_PATH/boost/lib/libboost_chrono.dylib<br />
  install_name_tool -id &quot;$SHL_PATH/boost/lib/libboost_date_time.dylib&quot; $SHL_PATH/boost/lib/libboost_date_time.dylib<br />
  ...<br />
  install_name_tool -change &quot;libboost_system.dylib&quot; &quot;$SHL_PATH/boost/lib/libboost_system.dylib&quot; $SHL_PATH/boost/lib/libboost_chrono.dylib<br />
  install_name_tool -change &quot;libboost_system.dylib&quot; &quot;$SHL_PATH/boost/lib/libboost_system.dylib&quot; $SHL_PATH/boost/lib/libboost_filesystem.dylib<br />

So, now when we have updated all libraries, we can try to create application bundle again

macdeployqt AtomixDevelopment.app/<br />

And if we did everything correctly, now we should have a working app ;-).

Troubleshooting

In some cases you can get error "Permission defined", "Bad file descriptor" or other similar errors when using macdeployqt.

ERROR: &quot;install_name_tool: can't open input file: OrmDesigner2.app/Contents/Frameworks//libssl.1.0.0.dylib for writing (Permission denied)<br />
install_name_tool: can't lseek to offset: 0 in file: OrmDesigner2.app/Contents/Frameworks//libssl.1.0.0.dylib for writing (Bad file descriptor)<br />
install_name_tool: can't write new headers in file: OrmDesigner2.app/Contents/Frameworks//libssl.1.0.0.dylib (Bad file descriptor)<br />
install_name_tool: can't close written on input file: OrmDesigner2.app/Contents/Frameworks//libssl.1.0.0.dylib (Bad file descriptor)<br />

The reason is insufficient permissions for modifying copied libraries. Simple execute

sudo macdeployqt<br />

and everything should work ok. Another workaround for this issue is using newer version of Qt. I figured out that on MacOS I wrongly use Qt 4.7.4. When I correct this to version Qt 4.8.2 this issue was solved.

DMG file

If you want to create simply DMG file, simply call macdeployqt with param --dmg. But this dmg doesn't look so good:

This will need more investigation how to make DMG files nicer ;-).

Notes

  • Everytime you run macdeployqt run it on clean folder. The best way is to call rm -rf Application, compile app and than run macdeployqt

Notes to bug in macdeployqt

The problem is caused by invalid permissions. Copied libraries have the same permissions like in the source location. There are three different solutions:

  1. Use sudo and execute macdeployqt with root permissions
  2. Update external libraries permissions to rw, so also copies will have a correct permissions
  3. Update macdeployqt script. In file shared.cpp on line 91 is method copyFilePrintStatus. Here is a necessary to update copied files permissions to correct rw

In my case the problem was in file liblzma.5.dylib

Frameworks/liblzma.5.dylib is not writable (Permission denied)<br />

Orinal library is located in path:

/usr/local/Cellar/xz/5.0.4/lib<br />
16 Aug 2012

Posted by: ludek.vodicka

Qt Mac OS #Qt #MacOs #deploy

How to deploy Qt application on MacOS - part I

As I wrote yesterday, I found the way how to proceed deployment on the Linux system. Today I have to manage it the same on the MacOS systems.

Note: the simplest way is introduced in the second part of this article.

The first usefull command for tracking dependencies between your application and other shared libraries is otool:

#path to executable, not .App directory!<br />
otool -L Application.app/Contents/MacOS/AppExecutable<br />

Now we can see paths to our libraries. The bad news is that MacOS doesn't have any -RPATH and $ORIGIN. The good news is utility install_name_tool and variable @executable_path which works similar like $ORIGIN.
Note: For newer versions of MacOS there are more variables like @executable_path. On version 10.4 was introduced @loader_path and on version 10.5 apple introduce @rpath variable.

The step-by-step solution

As first step it's necessary to upload all dependent libraries directly to the Application.app/Contents/MacOS/. For list all required files use otool:

cd Application.app/Contents/MacOS<br />
otool -L AppExecutable<br />

When we have copied all libraries, we need to change paths **for** and **in** all libraries.

Here is example how to set libxml2 library. As first step we will check how is library referred.

$user otool -L AtomixDevelopment</p>
<p>AtomixDevelopment:<br />
	libboost_iostreams.dylib (compatibility version 0.0.0, current version 0.0.0)<br />
	libboost_filesystem.dylib (compatibility version 0.0.0, current version 0.0.0)<br />
	/Users/User/dev/SharedLibraries/libxml/lib/libxml2.2.dylib (compatibility version 10.0.0, current version 10.8.0)<br />
	/Users/User/dev/SharedLibraries/libxslt/lib/libxslt.1.dylib (compatibility version 3.0.0, current version 3.26.0)<br />
	/Users/User/dev/SharedLibraries/libxslt/lib/libexslt.0.dylib (compatibility version 9.0.0, current version 9.15.0)<br />

And Library:

User$ otool -L libxml2.2.dylib<br />
libxml2.2.dylib:<br />
	/Users/User/dev/SharedLibraries/libxml/lib/libxml2.2.dylib (compatibility version 10.0.0, current version 10.8.0)<br />
	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 159.1.0)<br />
	/usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.5)<br />
	/usr/lib/libiconv.2.dylib (compatibility version 7.0.0, current version 7.0.0)<br />

When we checked libxml2.2.dylib library with otool, we can see that library has hardocoded our development path. This isn't good ;-). So we now change this value to path relative to the executable and again verify this inner path.

install_name_tool -id &quot;@loader_path/libxml2.2.dylib&quot; libxml2.2.dylib<br />
otool -L libxml2.2.dylib<br />
libxml2.2.dylib:<br />
	@loader_path/libxml2.2.dylib (compatibility version 10.0.0, current version 10.8.0)<br />
	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 159.1.0)<br />
	/usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.5)<br />
	/usr/lib/libiconv.2.dylib (compatibility version 7.0.0, current version 7.0.0)<br />

As you can see, now is path (first line) set up to reffer @loader_path/libxml2.2.dylib. It's correct now. As second step we have to update path in our executable, because also there is path hardcoded to our library repository.

install_name_tool -change &quot;/Users/User/dev/ExternalLibraries/../SharedLibraries/libxml/lib/libxml2.2.dylib&quot; &quot;@loader_path/libxml2.2.dylib&quot; AtomixDevelopment</p>
<p>otool -L AtomixDevelopment<br />
AtomixDevelopment:<br />
	libboost_iostreams.dylib (compatibility version 0.0.0, current version 0.0.0)<br />
	libboost_filesystem.dylib (compatibility version 0.0.0, current version 0.0.0)<br />
	@loader_path/libxml2.2.dylib (compatibility version 10.0.0, current version 10.8.0)<br />
        ...<br />

So, now we have changed also path in our executable. And now we need to do all these steps for all libraries..... ;-).

 

Notes

To follow the MacOS application convention it's better to place libraries to folder Application.app/Contents/Frameworks. Here is a directory schema for Qt example application plugAndPaint.

External links

16 Aug 2012

Posted by: ludek.vodicka

Qt Mac OS #Qt #MacOs #deploy

Why is compiled Linux executable so large?

Today I encountered another issue when compiling my Qt application http://www.orm-designer.com/ under Linux. The size of final executable was about 400MB.
The first thought was that there is some static libraries compiled to application. But the problem was elsewhere.

Unlike to Windows compilation where linker creates .exe and .pdb file, linux linker creates only one final file. So this file includes also lot of additional symbols useful for debugging and post-mortem bugs finding. But it is not so usefull for distribution your application. To strip all these symbols, use following command

strip --strip-unneeded /path/to/application<br />

Strip command have a lot of switches, but after a short testing it seems that the results are the same. Maybe I'm doing something wrong or simply my executable doesn't contain any additional infos for stripping.

15 Aug 2012

Posted by: ludek.vodicka

Qt Linux #Linux #deploy

The most easiest way how to deploy Qt linux Application

**I found solution also for the problem with executing application form in-app directory!!, Look to text bellow.**
Warning: This solution has one big disadvantage ;-(. It's necessary to execute application only from app-dir. In other cases system doesn't find required libraries.
The solution could be run patchelf on the client computer with final installation path

Today I start working on deploying my http://www.orm-designer.com/ Qt application on linux platform.

I read a lot of articles about deploying applications but all of the suggested methods was impractical, too complex or unusable. Here is a list of them:

  • Using qt.conf in Qt resource or application dir. Usefull for Qt libraries, but not third party libraries
  • Installing Qt and third-party libraries in one of the system library path. This method need root permission for app users
  • Using startup script for setting correct LD_LIBRARY_PATH. Really? It's too complicated for maintenance and users
  • Using -rpath to specify predetermined path. This method requires the users have this directory and have the full access to this directory

Another solution, the simplest one

I'm not sure why this solution isn't mentioned in Qt forums or anywhere else. Maybe this solution isn't so clean and perfect for Linux gurus, but it's perfect for me.

The solution is in simply changing the search path in already compiled application to "." (current directory) **current application location by using $ORIGIN variable**, so application will search all libraries in application directory first. It's simple, it's clean. All libraries distributed with application will be isolated in application directory and app-loader will not load any other library by mistake.

**Updated**: The keyword $ORIGIN do the trick, that you can run application from anywhere on your computer. $ORIGIN is absolute path to your executable.

And how to do this change? As first, you need to download small utility called PatchELF. With this application you can change -rpath in app to anything you need.

patchelf --set-rpath '$ORIGIN' ./ApplicationExecutable<br />

And it is. Now you can copy all required libraries to directory with your application and everything will works correctly.

Installation

Download Ubuntu 32/64bit package from site http://hydra.nixos.org/release/patchelf/patchelf-0.6

Note

Maybe there is a way how to set rpath directly in the linking proces by using -rpath linker param. But I didn't manage it to work.

If you want to display list of shared libraries used by your application, use this command:

ldd ./ApplicationExecutable<br />

External links

15 Aug 2012

Posted by: ludek.vodicka

Qt Linux #Linux #Programming #deploy application

Problem with Qt 4.8.2 QWebkit compilation under Ubuntu

The error message is following:

In file included from /usr/include/glib-2.0/glib/gasyncqueue.h:34:0,<br />
                 from /usr/include/glib-2.0/glib.h:34,<br />
                 from /usr/include/glib-2.0/gobject/gbinding.h:30,<br />
                 from /usr/include/glib-2.0/glib-object.h:25,<br />
                 from /usr/include/glib-2.0/gio/gioenums.h:30,<br />
                 from /usr/include/glib-2.0/gio/giotypes.h:30,<br />
                 from /usr/include/glib-2.0/gio/gio.h:28,<br />
                 from wtf/gobject/GOwnPtr.cpp:24:<br />
/usr/include/glib-2.0/glib/gthread.h:51:16: error: ‘union’ tag used in naming ‘struct _GMutex’ [-fpermissive]<br />
/usr/include/glib-2.0/glib/gthread.h:58:7: error: ‘union’ tag used in naming ‘struct _GMutex’ [-fpermissive]<br />
make[2]: *** [.obj/release-static/GOwnPtr.o] Error 1<br />
make[2]: Leaving directory `/home/honza/qt-everywhere-opensource-src-4.8.2/src/3rdparty/webkit/Source/JavaScriptCore'<br />
make[1]: *** [sub-JavaScriptCore-JavaScriptCore-pro-make_default-ordered] Error 2<br />
make[1]: Leaving directory `/home/honza/qt-everywhere-opensource-src-4.8.2/src/3rdparty/webkit/Source'<br />
make: *** [sub-webkit-make_default-ordered] Error 2<br />

the reason is because of incompatibility between Qt 4.8.2 and glib-2.0.

The solution is described in this (not commited) bug fix:

https://codereview.qt-project.org/#patch,sidebyside,25069,1,src/3rdparty/webkit/Source/JavaScriptCore/wtf/gobject/GTypedefs.h

Simply edit following file

Qt/src/3rdparty/webkit/Source/JavaScriptCore/wtf/gobject/GTypedefs.h<br />

and modify following line

55: typedef struct _GMutex GMutex;<br />

to

55: typedef union _GMutex GMutex;<br />

that's it.

14 Aug 2012

Posted by: ludek.vodicka

Qt

Qmake 4.8.2 unresolved external symbol QSystemLocale

So, after updating my Qt version to 4.8.2 I encounter another compilation problems (as usual ;-) ).

As first, this is my linker output:

qlocale.obj : error LNK2001: unresolved external symbol &quot;public: virtual class QVariant __thiscall QSystemLocale::query(enum QSystemLocale::QueryType,class QVariant)const &quot; ([email protected]@@UBE?AVQVariant@@[email protected]@V2@@Z)<br />
1&gt;qlocale.obj : error LNK2001: unresolved external symbol &quot;public: virtual class QLocale __thiscall QSystemLocale::fallbackLocale(void)const &quot; ([email protected]@@UBE?AVQLocale@@XZ)<br />
1&gt;qlocale.obj : error LNK2019: unresolved external symbol &quot;class QString &amp; __cdecl decimalForm(class QChar,class QChar,class QChar,class QString &amp;,int,unsigned int,enum PrecisionMode,bool,bool)&quot; (?decimalForm@@YAAAVQString@@VQChar@@[email protected]@@[email protected]) referenced in function &quot;public: static class QString __cdecl QLocalePrivate::doubleToString(class QChar,class QChar,class QChar,class QChar,class QChar,class QChar,double,int,enum QLocalePrivate::DoubleForm,int,unsigned int)&quot; ([email protected]@@SA?AVQString@@VQChar@@[email protected]@[email protected])<br />
1&gt;qlocale.obj : error LNK2019: unresolved external symbol &quot;class QString &amp; __cdecl exponentForm(class QChar,class QChar,class QChar,class QChar,class QChar,class QChar,class QString &amp;,int,unsigned int,enum PrecisionMode,bool)&quot; (?exponentForm@@YAAAVQString@@VQChar@@[email protected]@@[email protected]) referenced in function &quot;public: static class QString __cdecl QLocalePrivate::doubleToString(class QChar,class QChar,class QChar,class QChar,class QChar,class QChar,double,int,enum QLocalePrivate::DoubleForm,int,unsigned int)&quot; ([email protected]@@SA?AVQString@@VQChar@@[email protected]@[email protected])<br />
1&gt;qlocale.obj : error LNK2019: unresolved external symbol &quot;char * __cdecl qdtoa(double,int,int,int *,int *,char * *,char * *)&quot; (?qdtoa@@[email protected]) referenced in function &quot;public: static class QString __cdecl QLocalePrivate::doubleToString(class QChar,class QChar,class QChar,class QChar,class QChar,class QChar,double,int,enum QLocalePrivate::DoubleForm,int,unsigned int)&quot; ([email protected]@@SA?AVQString@@VQChar@@[email protected]@[email protected])<br />
1&gt;qlocale.obj : error LNK2019: unresolved external symbol &quot;class QString __cdecl qulltoa(unsigned __int64,int,class QChar)&quot; (?qulltoa@@YA?AVQString@@_KHVQChar@@@Z) referenced in function &quot;public: static class QString __cdecl QLocalePrivate::longLongToString(class QChar,class QChar,class QChar,class QChar,__int64,int,int,int,unsigned int)&quot; ([email protected]@@SA?AVQString@@VQChar@@[email protected])<br />
1&gt;qlocale.obj : error LNK2019: unresolved external symbol &quot;class QString __cdecl qlltoa(__int64,int,class QChar)&quot; (?qlltoa@@YA?AVQString@@_JHVQChar@@@Z) referenced in function &quot;public: static class QString __cdecl QLocalePrivate::longLongToString(class QChar,class QChar,class QChar,class QChar,__int64,int,int,int,unsigned int)&quot; ([email protected]@@SA?AVQString@@VQChar@@[email protected])<br />
1&gt;qlocale.obj : error LNK2019: unresolved external symbol &quot;bool __cdecl removeGroupSeparators(class QVarLengthArray&lt;char,256&gt; *)&quot; (?removeGroupSeparators@@YA_NPAV?$QVarLengthArray@D$0BAA@@@@Z) referenced in function &quot;public: bool __thiscall QLocalePrivate::numberToCLocale(class QString const &amp;,enum QLocalePrivate::GroupSeparatorMode,class QVarLengthArray&lt;char,256&gt; *)const &quot; ([email protected]@@QBE_NABVQString@@[email protected]@PAV?$QVarLengthArray@D$0BAA@@@@Z)<br />
1&gt;qlocale.obj : error LNK2019: unresolved external symbol &quot;double __cdecl qstrtod(char const *,char const * *,bool *)&quot; (?qstrtod@@[email protected]) referenced in function &quot;public: static double __cdecl QLocalePrivate::bytearrayToDouble(char const *,bool *,bool *)&quot; ([email protected]@@[email protected])<br />
1&gt;qlocale.obj : error LNK2019: unresolved external symbol &quot;__int64 __cdecl qstrtoll(char const *,char const * *,int,bool *)&quot; (?qstrtoll@@[email protected]) referenced in function &quot;public: static __int64 __cdecl QLocalePrivate::bytearrayToLongLong(char const *,int,bool *,bool *)&quot; ([email protected]@@[email protected])<br />
1&gt;qlocale.obj : error LNK2019: unresolved external symbol &quot;unsigned __int64 __cdecl qstrtoull(char const *,char const * *,int,bool *)&quot; (?qstrtoull@@[email protected]) referenced in function &quot;public: static unsigned __int64 __cdecl QLocalePrivate::bytearrayToUnsLongLong(char const *,int,bool *)&quot; ([email protected]@@[email protected])<br />
1&gt;..\bin\\qmake.exe : fatal error LNK1120: 11 unresolved externals<br />

The reason for this is missing two definitions in qmake.pri.

First is system-dependent **qlocale_win.cpp / qlocale_unix.cpp**. For fixing it you have to update these to files to unix{} and win32{}

 unix {<br />
        SOURCES += qfilesystemengine_unix.cpp qfilesystemiterator_unix.cpp qfsfileengine_unix.cpp qlocale_unix.cpp #&lt;&lt;---- HERE<br />
        mac {<br />
          SOURCES += qfilesystemengine_mac.cpp<br />
          SOURCES += qcore_mac.cpp qsettings_mac.cpp<br />
          QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.4 #enables weak linking for 10.4 (exported)<br />
          LIBS += -framework ApplicationServices<br />
        }<br />
    } else:win32 {<br />
        SOURCES += qfilesystemengine_win.cpp qfsfileengine_win.cpp qfilesystemiterator_win.cpp qsettings_win.cpp \<br />
            qsystemlibrary.cpp qlocale_win.cpp #&lt;&lt;--------- AND HERE<br />
        win32-msvc*:LIBS += ole32.lib advapi32.lib<br />
        win32-g++*:LIBS += -lole32 -luuid -ladvapi32 -lkernel32<br />
    }<br />

If you update .pri like this, you will gain another cute unresolved external:

qlocale.obj : error LNK2019: unresolved external symbol &quot;class QString &amp; __cdecl decimalForm(class QChar,class QChar,class QChar,class QString &amp;,int,unsigned int,enum PrecisionMode,bool,bool)&quot; (?decimalForm@@YAAAVQString@@VQChar@@[email protected]@@[email protected]) referenced in function &quot;public: static class QString __cdecl QLocalePrivate::doubleToString(class QChar,class QChar,class QChar,class QChar,class QChar,class QChar,double,int,enum QLocalePrivate::DoubleForm,int,unsigned int)&quot; ([email protected]@@SA?AVQString@@VQChar@@[email protected]@[email protected])<br />
1&gt;qlocale.obj : error LNK2019: unresolved external symbol &quot;class QString &amp; __cdecl exponentForm(class QChar,class QChar,class QChar,class QChar,class QChar,class QChar,class QString &amp;,int,unsigned int,enum PrecisionMode,bool)&quot; (?exponentForm@@YAAAVQString@@VQChar@@[email protected]@@[email protected]) referenced in function &quot;public: static class QString __cdecl QLocalePrivate::doubleToString(class QChar,class QChar,class QChar,class QChar,class QChar,class QChar,double,int,enum QLocalePrivate::DoubleForm,int,unsigned int)&quot; ([email protected]@@SA?AVQString@@VQChar@@[email protected]@[email protected])<br />
1&gt;qlocale.obj : error LNK2019: unresolved external symbol &quot;char * __cdecl qdtoa(double,int,int,int *,int *,char * *,char * *)&quot; (?qdtoa@@[email protected]) referenced in function &quot;public: static class QString __cdecl QLocalePrivate::doubleToString(class QChar,class QChar,class QChar,class QChar,class QChar,class QChar,double,int,enum QLocalePrivate::DoubleForm,int,unsigned int)&quot; ([email protected]@@SA?AVQString@@VQChar@@[email protected]@[email protected])<br />
1&gt;qlocale.obj : error LNK2019: unresolved external symbol &quot;class QString __cdecl qulltoa(unsigned __int64,int,class QChar)&quot; (?qulltoa@@YA?AVQString@@_KHVQChar@@@Z) referenced in function &quot;public: static class QString __cdecl QLocalePrivate::longLongToString(class QChar,class QChar,class QChar,class QChar,__int64,int,int,int,unsigned int)&quot; ([email protected]@@SA?AVQString@@VQChar@@[email protected])<br />
1&gt;qlocale.obj : error LNK2019: unresolved external symbol &quot;class QString __cdecl qlltoa(__int64,int,class QChar)&quot; (?qlltoa@@YA?AVQString@@_JHVQChar@@@Z) referenced in function &quot;public: static class QString __cdecl QLocalePrivate::longLongToString(class QChar,class QChar,class QChar,class QChar,__int64,int,int,int,unsigned int)&quot; ([email protected]@@SA?AVQString@@VQChar@@[email protected])<br />
1&gt;qlocale.obj : error LNK2019: unresolved external symbol &quot;bool __cdecl removeGroupSeparators(class QVarLengthArray&lt;char,256&gt; *)&quot; (?removeGroupSeparators@@YA_NPAV?$QVarLengthArray@D$0BAA@@@@Z) referenced in function &quot;public: bool __thiscall QLocalePrivate::numberToCLocale(class QString const &amp;,enum QLocalePrivate::GroupSeparatorMode,class QVarLengthArray&lt;char,256&gt; *)const &quot; ([email protected]@@QBE_NABVQString@@[email protected]@PAV?$QVarLengthArray@D$0BAA@@@@Z)<br />
1&gt;qlocale.obj : error LNK2019: unresolved external symbol &quot;double __cdecl qstrtod(char const *,char const * *,bool *)&quot; (?qstrtod@@[email protected]) referenced in function &quot;public: static double __cdecl QLocalePrivate::bytearrayToDouble(char const *,bool *,bool *)&quot; ([email protected]@@[email protected])<br />
1&gt;qlocale.obj : error LNK2019: unresolved external symbol &quot;__int64 __cdecl qstrtoll(char const *,char const * *,int,bool *)&quot; (?qstrtoll@@[email protected]) referenced in function &quot;public: static __int64 __cdecl QLocalePrivate::bytearrayToLongLong(char const *,int,bool *,bool *)&quot; ([email protected]@@[email protected])<br />
1&gt;qlocale_win.obj : error LNK2001: unresolved external symbol &quot;__int64 __cdecl qstrtoll(char const *,char const * *,int,bool *)&quot; (?qstrtoll@@[email protected])<br />
1&gt;qlocale.obj : error LNK2019: unresolved external symbol &quot;unsigned __int64 __cdecl qstrtoull(char const *,char const * *,int,bool *)&quot; (?qstrtoull@@[email protected]) referenced in function &quot;public: static unsigned __int64 __cdecl QLocalePrivate::bytearrayToUnsLongLong(char const *,int,bool *)&quot; ([email protected]@@[email protected])<br />
1&gt;qlocale_win.obj : error LNK2001: unresolved external symbol &quot;unsigned __int64 __cdecl qstrtoull(char const *,char const * *,int,bool *)&quot; (?qstrtoull@@[email protected])<br />
1&gt;..\bin\\qmake.exe : fatal error LNK1120: 9 unresolved externals<br />

Also this linker error is caused by missing file in SOURCE definition. In this case add qlocale_tools.cpp to SOURCE in bootstrap { #Qt code

</p>
<p>bootstrap { #Qt code<br />
   DEFINES+=QT_NODLL QT_NO_THREAD<br />
   SOURCES+= \<br />
        qbitarray.cpp \<br />
        qbuffer.cpp \<br />
        qbytearray.cpp \<br />
        qbytearraymatcher.cpp \<br />
        qcryptographichash.cpp \<br />
        qdatetime.cpp \<br />
        qdir.cpp \<br />
        qdiriterator.cpp \<br />
        qfile.cpp \<br />
        qabstractfileengine.cpp \<br />
        qfileinfo.cpp \<br />
        qfilesystementry.cpp \<br />
        qfilesystemengine.cpp \<br />
        qfsfileengine.cpp \<br />
        qfsfileengine_iterator.cpp \<br />
        qglobal.cpp \<br />
        qnumeric.cpp \<br />
        qhash.cpp \<br />
        qiodevice.cpp \<br />
        qlist.cpp \<br />
        qlinkedlist.cpp \<br />
        qlocale.cpp \<br />
        qlocale_tools.cpp \  #&lt;&lt; ----- HERE<br />

Now re-call qmake and recompile it. Everything should works ok. The question is, why no-one in Qt didn't find this error.

12 Aug 2012

Posted by: ludek.vodicka

Qt

Qt on Ubuntu and Missing menu icons

This isn't bug, but feature ;-). It's described here: https://bugs.launchpad.net/ubuntu/+source/qt4-x11/+bug/501468

These commands fixed the issue:

gconftool-2 --type boolean --set /desktop/gnome/interface/buttons_have_icons true<br />
gconftool-2 --type boolean --set /desktop/gnome/interface/menus_have_icons true<br />

14 Feb 2012

Posted by: ludek.vodicka

Qt Linux

Qt application crash when compiled for 64-bit VS2010

Callstack

&gt;	QtGui4.dll!00000000652f071f()<br />
 	[Frames below may be incorrect and/or missing, no symbols loaded for QtGui4.dll]<br />
 	QtGui4.dll!00000000652f07ae()<br />
 	QtGui4.dll!0000000065326821()<br />
 	QtGui4.dll!0000000065327f30()<br />
 	QtGui4.dll!00000000653284ba()<br />
 	QtGui4.dll!000000006532a5f5()<br />
 	QtGui4.dll!00000000652f4792()<br />
 	QtGui4.dll!000000006532f701()<br />
 	QtGui4.dll!000000006535be71()<br />
 	QtCore4.dll!0000000059a0ab9f()<br />
 	QtGui4.dll!0000000065306eb9()<br />
 	QtCore4.dll!00000000599f7903()<br />
 	QtGui4.dll!0000000064eaffa2()<br />
 	QtGui4.dll!0000000064eb2e56()<br />
 	QtCore4.dll!00000000599f7792()<br />
 	QtGui4.dll!0000000064eec2a3()<br />
 	QtGui4.dll!0000000064eee85e()<br />
 	QtGui4.dll!0000000064eec265()<br />
 	QtGui4.dll!0000000064eee85e()<br />
 	QtGui4.dll!0000000064eec265()<br />
 	QtGui4.dll!0000000064eee85e()<br />
 	QtGui4.dll!0000000064efa870()<br />
 	QtGui4.dll!0000000065208727()<br />
 	QtGui4.dll!000000006527a082()<br />
 	QtGui4.dll!0000000064eaffb6()<br />
 	QtGui4.dll!0000000064eb2e56()<br />
 	QtCore4.dll!00000000599f7792()<br />
 	QtGui4.dll!0000000064ef264c()<br />
 	QtGui4.dll!0000000064ef26c7()<br />
 	QtGui4.dll!0000000064ef26c7()<br />
 	QtGui4.dll!0000000064ef26c7()<br />
 	QtGui4.dll!0000000064efe30c()<br />
 	OrmDesigner2.exe!000000013f95a2cf()<br />
 	OrmDesigner2.exe!000000013f95dce2()<br />
 	kernel32.dll!000000007794652d()<br />
 	ntdll.dll!0000000077c8c521()<br />

The bug is probably caused by wrong alignment or incorrect VS2010 compiler optimalization.

Found resources:
https://bugreports.qt.nokia.com//browse/QTBUG-11445
https://connect.microsoft.com/VisualStudio/feedback/details/573262/incorrect-alignment-with-x64-optimizer-and-movaps
http://support.microsoft.com/kb/2280741
https://connect.microsoft.com/VisualStudio/Downloads/DownloadDetails.aspx?DownloadID=31433

Workarounds:

First way - Update VS2010 mkspec for Qt

go to $QTDIR/mkspecs/win32-msvc2010/qmake.conf and replace -02 with -01 (ie. reducing the optimzation level).Also /Ob0 could be used.

Microsoft hotfix for VS

http://archive.msdn.microsoft.com/KB2280741
File patch name VS10-KB2268081-x86.exe

Install Visual Studio 2010 SP1

Service pack could also contains required fix.
http://www.microsoft.com/download/en/details.aspx?id=23691

22 Nov 2011

Create DLL/LIB project in Qt

10 May 2011

Posted by: ludek.vodicka

Qt

Problem with Qt compilation under Windows 64-bit

This short post will show you how to resolve following error during Qt compilation on 64-bit windows:

Creating library ..\..\..\..\lib\QtWebKitd4.lib and object ..\..\..\..\lib\Qt<br />
WebKitd4.exp<br />
PluginViewWin.obj : error LNK2019: unresolved external symbol _HBeginPaint refer<br />
enced in function &quot;private: static struct HDC__ * __cdecl WebCore::PluginView::h<br />
ookedBeginPaint(struct HWND__ *,struct tagPAINTSTRUCT *)&quot; ([email protected]<br />
[email protected]@@CAPEAUHDC__@@PEAUHWND__@@PEAUtagP AINTSTRUCT@@@Z)<br />
PluginViewWin.obj : error LNK2019: unresolved external symbol _HEndPaint referen<br />
ced in function &quot;private: static int __cdecl WebCore::PluginView::hookedEndPaint<br />
(struct HWND__ *,struct tagPAINTSTRUCT const *)&quot; ([email protected]@Web<br />
Core@@CAHPEAUHWND__@@PEBUtagPAINTSTRUCT@@@Z)<br />
..\..\..\..\lib\QtWebKitd4.dll : fatal error LNK1120: 2 unresolved externals<br />
NMAKE : fatal error U1077: '&quot;C:\Program Files (x86)\Microsoft Visual Studio 9.0\<br />
VC\BIN\x86_amd64\link.EXE&quot;' : return code '0x460'<br />
Stop.<br />
NMAKE : fatal error U1077: '&quot;C:\Program Files (x86)\Microsoft Visual Studio 9.0\<br />
VC\BIN\nmake.exe&quot;' : return code '0x2'<br />

This error is caused by bug in **QMAKE_HOST** variable used in WebCore.pro file. This variable is tested to determine destination platform (x86 or x64).
This variable contains x86 value also on 64-bit builds instead of x86_64 value. This value is tested on the following line in a WebCore.pro file:

win32:!win32-g++*:contains(QMAKE_HOST.arch, x86_64):{<br />

If you want to fix this error, simply replace **QMAKE_HOST** by **QMAKE_TARGET** variable. Updated line should look like this:

win32:!win32-g++*:contains(QMAKE_TARGET.arch, x86_64):{<br />

After this update all required asm defines are correctly included and build of WebKit will be successful.

Update for this error

In newer versions of Qt there is already applied fix the error with QMAKE_HOST / QMAKE_TARGET, but also there is a new problem ;-(.

The Problem is in the following "if" definition:

   if(win32-msvc2005|win32-msvc2008):equals(TEMPLATE_PREFIX, &quot;vc&quot;) {<br />
        SOURCES += \<br />
            plugins/win/PaintHooks.asm<br />
    }<br />

When you compile your project for MSVC 2010, .asm file isn't included. It's necessary to add win32-msvc2010 to this definition. So updated WebCore.pro for Qt 4.8 will look like this:

 if(win32-msvc2005|win32-msvc2008|win32-msvc2010):equals(TEMPLATE_PREFIX, &quot;vc&quot;) {<br />
        SOURCES += \<br />
            plugins/win/PaintHooks.asm<br />
    }<br />

Next problem solution

Next problem which I found during compilation is wrongly set QMAKE_TARGET.arg. For unspecified reason, when I compile 64bit library in 64bit system in 64bit VS command line, this variable has value x86 instead of x86_64.
The problem is in the qmake project.cpp file. QMAKE trying to determine 64/32 bit version based on the %PATH% configuration. Qmake search for VS-PATH\bin\amd64 of \bin\x86_amd64 string. Unfortunately there is a bug in concating searched string. This is how looks original project.cpp file at line 3177:

QString vcBin64 = qgetenv(&quot;VCINSTALLDIR&quot;).append(&quot;\\bin\\amd64&quot;);<br />
QString vcBinX86_64 = qgetenv(&quot;VCINSTALLDIR&quot;).append(&quot;\\bin\\x86_amd64&quot;);<br />

The problem is, that VCINSTALLDIR contains \ at the end of the string, and then we append \ again. So, result is:

QString vcBin64 = qgetenv(&quot;VCINSTALLDIR&quot;);<br />
if ( vcBin64.at( vcBin64.size()-1 ) != '\\' )<br />
  vcBin64.append(&quot;\\&quot;);<br />
vcBin64.append(&quot;bin\\amd64&quot;);</p>
<p>QString vcBinX86_64 = qgetenv(&quot;VCINSTALLDIR&quot;);<br />
if ( vcBinX86_64.at( vcBinX86_64.size()-1 ) != '\\' )<br />
  vcBinX86_64.append(&quot;\\&quot;);<br />
vcBinX86_64.append(&quot;bin\\x86_amd64&quot;);<br />

Now, QMake correctly determine 32/64 bit compilation and then correctly include PaintHooks.asm and your Qt WebCore will be sucesfully compiled.

28 Jan 2011

Qt programming tips

How to configure mkspec for paralel builds on Windows

Edit qmake.conf file in Qt\mkspecs\win32-msvcXXXX. Add **-MP2** / **-MP4** to the following defines:

QMAKE_CFLAGS_RELEASE    = -O2 -MD -MP4<br />
QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += -O2 -MD -Zi -MP4<br />
QMAKE_CFLAGS_DEBUG      = -Zi -MDd -MP4<br />
03 Jan 2011

Posted by: ludek.vodicka

Programming Qt

How to exclude demos and examples from Qt build

Because building Qt demos and examples is time consuming and sometime can't be correctly done because of missing sub-parts of Qt, it's good to remove it from main Qt build. To do this, pass following parameters to the ./configure script:

-nomake demos -nomake examples<br />
15 Dec 2010

Posted by: ludek.vodicka

Qt

How to deploy Qt application on MacOs

Missing dylib libraries

If your application using some externals dynamic libraries (called .dylib in MacOs system), you have to provide all these libraries. The simplest way is to provide these libraries into the Application.app directory.

Find out which libraries are used

Qt provide really useful tool called **"otool"** which serves to lots of purpose. One of them is to detect which shared libraries are required by our application. For this purpose otool has parameter -L. The usage is following:

otool -L ./Test1.app/Contents/MacOS/Test1<br />

Output could looks like this:

./Test1:<br />
        libboost_iostreams.dylib (compatibility version 0.0.0, current version 0.0.0)<br />
        libboost_filesystem.dylib (compatibility version 0.0.0, current version 0.0.0)<br />
        libboost_system.dylib (compatibility version 0.0.0, current version 0.0.0)<br />
        libboost_thread.dylib (compatibility version 0.0.0, current version 0.0.0)<br />
        libboost_date_time.dylib (compatibility version 0.0.0, current version 0.0.0)<br />
        libboost_regex.dylib (compatibility version 0.0.0, current version 0.0.0)<br />
        /Users/dev/dev/SharedLibraries/libiconv/lib/libiconv.2.dylib (compatibility version 8.0.0, current version 8.0.0)<br />
        /Users/dev/dev/ExternalLibraries/../SharedLibraries/libxml/lib/libxml2.2.dylib (compatibility version 10.0.0, current version 10.8.0)<br />
        /Users/dev/dev/ExternalLibraries/../SharedLibraries/libxslt/lib/libxslt.1.dylib (compatibility version 3.0.0, current version 3.26.0)<br />
        /Users/dev/dev/ExternalLibraries/../SharedLibraries/libxslt/lib/libexslt.0.dylib (compatibility version 9.0.0, current version 9.15.0)<br />
        /Users/dev/dev/ExternalLibraries/yaml-cpp-0.2.5/build/libyaml-cpp.0.2.dylib (compatibility version 0.2.0, current version 0.2.5)<br />
        QtGui.framework/Versions/4/QtGui (compatibility version 4.7.0, current version 4.7.0)<br />
        QtCore.framework/Versions/4/QtCore (compatibility version 4.7.0, current version 4.7.0)<br />
        /usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 7.9.0)<br />
        /usr/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 625.0.0)<br />
        /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.2.0)<br />

Output from "otool" is simmilar to linux tool "ldd".

The Mac Deployment Tool

Because manual copying and configuring all shared libraries to our application could be difficult, Qt have deployment tool which do all work for us. Tool is called "macdeployqt" and can be found in /Developer/Tools/Qt/macdeployqt.

 /Developer/Tools/Qt/macdeployqt ./GeneratedFilesMacOs/Debug/Test1.app<br />

**Note:** Every time when you call macdeployqt tool, project have to be build from scratch. But is sufficient when whole result directory is removed and linked again:

rm -rf ./GeneratedFilesMacOs/Debug/Test1.app/<br />
make<br />
13 Dec 2010

Posted by: ludek.vodicka

Programming Qt Linux #Qt #MacOs #Linux #C++ #Programming

How to configure Linux for Qt programming.

How to configure script for automatic run after login

Create .bash_profile file in your home directory.

nano ~/.bash_profile

And enter following content to the new created file:

 # ~/.bash_profile
# include .bashrc if it exists
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi

How to configure new search path

If you want to have bin folder in your home directory, enter following code snippet to your .bash_profile file:

PATH=$PATH;/Users/thomas/bin

Conclusion & Note

It's possible that all of these task can be done in simpler way, or can't be done at all. All comments and tips are based on my current experience with my first Linux configuration in my life ;-)

04 Nov 2010

Posted by: ludek.vodicka

Qt #Qt #Linux

How to configure MacOs for Qt programming.

How to configure script for automatic run after login

Create startup-script(or any other)file in your home directory. Then enter following command

nano startup-script
chmod 777 ./startup-script
sudo defaults write com.apple.loginwindow LoginHook /Users/thomas/.startup-script

Another solution is to create .bash_profile file, which is launched automatically by system.

or create

How to configure new search path

If you want to have bin folder in your home directory, enter following code snippet to your .profile file located in your home directory:

export PATH=$PATH:/Users/user_name/bin

Open file using:

nano ./.profile

**Note:**Path is separated by char ":".

How to instal apt-get alternative for MacOS

Mac OS have apt-get alternative called "**port**".

Additional notes

Realtek RTL81xx macOs version:

How to mount Windows drive from MacOs

As first, create some directory where you want to mount your shared drive

mkdir mnt
cd mnt
mkdir computer_d
mount -t smbfs //user_name:[email protected]/d computer_d

</div>

Conclusion & Note

It's possible that all of these task can be done in simpler way, or can't be done at all. All comments and tips are based on my current experience with my first MacOS configuration in my life ;-)

04 Nov 2010

Posted by: ludek.vodicka

Qt Linux #Qt #MacOs

Qt correct setup for QMAKESPEC, QTDIR and PATH

When you want to use different configurations for different platforms in your .pro file, it's necessary to correctly setup three variables: QMAKESPEC, QTDIR and PATH.

Here is how to configure for different platforms:

Microsoft Windows:

In SystemPropertes -> Enviroment variables add/update following values:

QTDIR = P:\QT\4.7.0<br />
PATH = %QTDIR%\bin<br />
QMAKESPEC=%QTDIR%\mkspecs\win32-msvc2005<br />
LANG = en_US<br />

Unix Bourne shell: (not tested)

QMAKESPEC=/usr/local/qt/mkspecs/linux-g++<br />
PATH=$PATH:/local/qmake/bin<br />
export QMAKESPEC PATH&lt;/pre&gt;<br />

Unix C shell: (not tested)

setenv QMAKESPEC /usr/local/qt/mkspecs/linux-g++<br />
setenv PATH $PATH:/local/qmake/bin&lt;/pre&gt;<br />

Note

You can optionally use LANG variable to setup QtCreator language.

Old qt 3.0 guide: http://doc.trolltech.com/3.0/qmake-guide.html
How to configure enviroment: http://doc.qt.nokia.com/4.0/qmake-environment-reference.html

04 Nov 2010

Posted by: ludek.vodicka

Qt #Qt #MacOs #Linux #Windows

Qt qmake enhancement - how to generate structure VS project

The problem

One of big disadvantage when creating Visual studio project from .pro files using qmake is missing support for hierachical folders. All files are stored in in four folders (filters) named "Source Files", "Header Files", "Generated Files" and "Form Files". When you have large project, this arrangement is really hard to use.

Simple Solution

qmake has undocumented setting parameter "flat". Using this switch, you can tell qmake to create filters in Visual studio dependent to directory structures of files. Only drawback of this solution is continuing sorting to "Source files","Header files",...

So result of this solution will look like this:

To achieve this behaviour, only thing what have to be done is add following line to your .pro file:

CONFIG -= flat

Final solution

But what to do when you want to have all files stored together in structure dependent on directory structure? Only solution which I found is update qmake project for myself. This update is simply and here is what is need to be done:

Add new method initHeaderAndSourceFiles to file msvc_vcproj.cpp and .h with following content

void VcprojGenerator::initHeaderAndSourceFiles()
{
	vcProject.SourceFiles.Name = &quot;Source And Header Files&quot;;
	vcProject.SourceFiles.Filter = &quot;cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx;h;hpp;hxx;hm;inl;inc;xsd&quot;;
	vcProject.SourceFiles.Guid = _GUIDSourceFiles;
	vcProject.SourceFiles.addFiles(project-&gt;values(&quot;HEADERS&quot;));
	vcProject.SourceFiles.addFiles(project-&gt;values(&quot;SOURCES&quot;));
	if (usePCH) // Generated PCH cpp file
		vcProject.HeaderFiles.addFile(precompH);
	vcProject.SourceFiles.Project = this;
	vcProject.SourceFiles.Config = &amp;(vcProject.Configuration);
	vcProject.SourceFiles.CustomBuild = none;
}

and update method VcprojGenerator::initProject() in msvc_vcproj.cpp file. Replace following two lines (currently located on line 762)

initSourceFiles();
initHeaderFiles();

with following code:

if ( project-&gt;isActiveConfig(&quot;grouped&quot;) == false ) {
	initSourceFiles();
	initHeaderFiles();
}
else {
	initHeaderAndSourceFiles();
}

Now you can add new flag "grouped" to your .pro file. After that, source and header files will be merged in the visual studio project tree.

CONFIG -= flat
CONFIG += grouped

And here is result screenshot:

01 Nov 2010

Posted by: ludek.vodicka

Qt #Qt #extending qt

First Qt attempts – qmake troubles

External links

qmake documentation: qmake tutorial.html
qmake variables: qmake variable reference

Generate vcproj from .pro file

Command line for generating Visual studio project file from Qt .pro file.

qmake -tp vc test.pro

Missing moc_*.cpp file

When some of moc file isn't properly generated and getting following error:

c1xx : fatal error C1083: Cannot open source file: '.\debug\moc_xxx.cpp': No such file or directory

try following:
Select corresponding .h file (for moc_xxx.cpp select xxx.h) in a project tree and select **Compile** from context menu. If the file is marked as "up-to-date", try to change something in this file and repeat a compilation. If in the output window will be "up-to-date" again, you found a problem.

Use context menu on the corresponding .h file, select properties and edit "Configuration properties |Custom build steps|General|Outputs" to any value (add some char to the end of value), confirm change by Ok button and then return value back to original (remove added char). After that, compilation on correspond file will be successfully performed.

Linux relevant tips

01 Nov 2010

Posted by: ludek.vodicka

Programming Qt #Qt #Windows

List of known issues and tips

This is list of all known issues and problems which we had to solve during our first Qt installation on Linux, Windows and Mac.

Known errors

Error: undefined interface

What to do when compilation of QT crash with message “Error: undefined interface”.
http://www.qtforum.org/article/31561/error-when-building-libraries.html
http://www.qtcentre.org/threads/26245-Qt-4.6-api/qscriptextensionplugin.h(43)-Error-Undefined-interface

make: g++: Command not found

it’s necessary to instal g++ support (sudo apt-get install g+)

Basic XLib functionality test failed!

it’s necessary to instal xlib(xorg??) support (sudo apt-get install xorg-dev)

*** [sub-corelib-make_default-ordered] Error 2

Probably mishmash on 32bit / 64bit  system and QT versions.

undefined reference to `QEventDispatcherGlib::versionSupported()’

Probably missing libglib2.0-dev on your system. (sudo apt-get install libglib2.0-dev).

Undefined reference to QSslSocket::*

Missing OpenSSL library on your system. (sudo apt-get install libssl-dev)

gtk/gtk.h: No such file or directory

Missing gtk package. (sudo apt-get install libgtk2.0-dev ). After that its necessary to update db (sudo updatedb).

if system can’t find file gtk/gtk.h because gtk is stored in gtk-2.0 directory, add -I (capitalised i) param to configure with gtk path:

 ./configure -opensource -I /usr/include/gtk-2.0 

cups/cups.h: No such file or directory

install libcups2. (sudo apt-get install libcups2-dev)

gst/gst.h: No such file or directory

install gstreamer 0.10. (sudo apt-get install libgstreamer0.10-dev)

Missing Include/glibconfig.h

it’s because this file isn’t in /usr/include/glib-2.0, but in /usr/lib/glib-2.0. So you have to include also this /usr/lib path or copy file to include/glib-2.0

Hints and tips

create symbolic link using **ln -nsf /usr/include/gtk-2.0/gtk /usr/include/gtk **

Minimal required libraries

List of libraries required by Qt:

  • libfontconfig1-dev
  • libfreetype6-dev
  • libx11-dev
  • libxcursor-dev
  • libxext-dev
  • libxfixes-dev
  • libxft-dev
  • libxi-dev
  • libxrandr-dev
  • libxrender-dev

And other which are required by some modules of Qt:

To install all required on Linux, use following commands

 sudo apt-get install libfontconfig1-dev libfreetype6-dev libx11-dev libxcursor-dev libxext-dev libxfixes-dev libxcups/cups.h: No such file or directory ft-dev libxi-dev libxrandr-dev libxrender-dev

sudo apt-get install bison flex libqt4-dev libqt4-opengl-dev libphonon-dev libicu-dev libsqlite3-dev libxext-dev libxrender-dev gperf libfontconfig1-dev libphonon-dev  

If error doesn’t disappear after installing correct library

Sometimes it’s necessary to reconfigure Qt using make confclean

How to find where is missing header file located on disk

Use find /path -iname xxx.h command

How to find package which contains missing header file

use apt-file application with following syntax:

 apt-file search gdk/gdk.h 

List of links about installation:
Building Qt on Linux

Qt configuration for succesfull build

This is currently my latest configure command to compile Qt on my Ubuntu 10.10.

Compilation fixes

This is necessary when search path for following libraries isn’t entered to configure.

 sudo ln -nsf /usr/include/gstreamer-0.10/gst /usr/include/gst 

Todo

Figure out how works pkg-config (pkg-config –cflags gstreamer-0.10)



27 Oct 2010

Qt installation and configuration

This is our company step-by-step guide to install and configure Qt on our developer machines.

How to install Qt

Link to Qt download site: http://qt.nokia.com/downloads

Windows (VS2005)

Download VS 2008 distribution from download site. When 2008 distribution is downloaded, it’s necessary to reconfigure and rebuild it for VS 2005 using next steps.

Linux

Download linux/x11 distro from Qt page. Download 32/64bit distro package. Setup downloaded files as executables:

 chmod +x qt-sdk-linux-x86-opensource-2009.01.bin chmod +x qt-creator-linux-x86-opensource-1.0.0.bin 

Install Qt sdk to default directory and begin with configuration.

MacOS

Download latest Qt SDK distribution and latest XCode developer pack from apple site. Then install both.

How to configure Qt

Qt configuration is done via Configure script/executable on all platforms.

Windows

Run “Start menu->Visual studio->Tools-> Visual studio command prompt”
Then go to “c:\Qt\Qt_Version\Qt” and run “configure” with additional params.

Our current configuration:

 configure -debug-and-release -opensource -shared -platform win32-msvc2005 -incredibuild-xge -openssl  

Clean configurations

run nmake confclean and nmake distclean to remove all previous version of QT compilations.

SSL support

For SSL Support add -openssl switch to configure.

Note!

: configure param HAVE TO be executed from Visual studio command prompt!

Linux

Enter Qt directory and enter following configure param:

 ./configure -opensource -I /usr/include/gtk-2.0 -L /usr/lib/gt-2.0 -I /usr/include/gstreamer-0.10 -L /usr/lib/gstreamer-0.10 -I /usr/include/glib-2.0 -L /usr/lib/glib-2.0 -I /usr/include/libxml2 -fast  

Clean configurations

run make confclean and then configure.

MacOS

How to compile Qt

Windows

Compile Qt using command prompt:

  • Run Visual studio command prompt.
  • And run nmake to build a whole library

Second option is open projects.sln located in p:/Qt/4.7.1/ using Visual Studio IDE  and compile it.

Linux

  • As first thing, use configure to setup Qt settings.
  • As next, run make to build a whole library
  • After a while when everything is compiled, use make install. This will install library to /usr/local/Trolltech/Qt-4.7.0

MacOS

Currently not tested, using default compilation.

How to compile application

When we have prepared Qt library, it’s time to compile our application.

MacOS

When using  qmake without additional params, qmake generate xcode project from .pro instad makefile for g++. To generate makefile, use following params:

 qmake -spec macx-g++  
make  

Deploying application

Windows

Not testes.

External link: http://doc.trolltech.com/4.5/deployment-windows.html

Linux

Not testes.

MacOS

Not testes.

27 Oct 2010