Sunday, 22 June 2014

Windows Qt binaries for the Haskell Platform (HsQML)

Since upgrading to Qt 5, the installation procedure for HsQML, my Qt Quick binding for Haskell, has been been less than ideal on Windows. This is because the official Qt SDK for Windows now uses a much newer version of MinGW than ships with GHC or the Haskell Platform and the two are no longer binary compatible. Binaries compiled by GHC using these Qt libraries simply crash on start-up.

It has always been possible to work around this problem by modifying GHC's configuration files to use the C compiler from Qt's MinGW rather than its own. However, this is a rather awkward thing to have to do and, regrettably, the instructions on my web-site for doing it weren't terribly clear.

I have now produced a special build of Qt 5.3.0 using GHC's MinGW which should work out of the box. The download and updated instructions are available from the Windows section on the HsQML web-site. Hopefully this will make getting HsQML running on Windows much simpler.

Longer term, GHC ticket #9218 tracks updating the version of MinGW which ships with GHC to something more recent.

Technical Details

I began by making a straightforward build of ICU 53.1, which is a Qt dependency, and then configured the Qt source tree to make a release build using the desktop OpenGL graphics stack as follows:

configure -opensource -release -opengl desktop -no-angle -skip qtwinextras -prefix C:\qt530-hp

The one oversight here was not using the -no-sseX flags to limit the use of instructions set extensions. I presume therefore that build targeted the host machine and may not work on processors which don't support SSE 4.1 or later. The QtWinExtras module relied to too heavily on functionality missing from the older MinGW headers and so I had to disable it.

Once the build was under way I ran into a few minor tool-chain issues which I resolved as follows:-
  • Remove some flags which are unsupported by the older compiler. Namely -fno-keep-inline-dllexport in qtbase/mkspecs/win32-g++/qmake.conf and -Wno-error=unused-but-set-variable in qtwebkit/Source/ThirdParty/leveldb/Target.pri.
  • Redirect required symbols missing from MinGW to suitable alternatives. Namely YieldProcessor to _mm_pause, MemoryBarrier to _mm_mfence, strcasecmp to _stricmp, strncasecmp to _strnicmp, strdup to _strdup, _exit to _Exit, and _MAX_PATH to MAX_PATH.
  • Change the name of the GUID member of the VMRGUID structure in MinGW's strmif.h so that it doesn't have the same name as its type.
  • Add the missing header file delayimp.h by copying it from a newer version of MinGW.
When I repeat this process for the next release of Qt 5, I will prepare a proper diff against the MinGW headers to make this set up more easily reproducible.

Finally, when testing the resulting binaries, I found a MinGW-specific bug which had been introduced in the Qt 5.3 release and causes it to intermittently crash. This has been filed as QTBUG-39793 and the patch attached to that bug was applied to this build.

No comments:

Post a Comment