Qt on custom Windows CE devices

Since the initial release of Qt for Windows CE we have received a lot of requests regarding custom devices and how one could get Qt running on it. Most of the times this is related to the device missing symbols in one or more libraries.

This article is supposed to give you some insights, on what happens on a regular basis on Windows CE and why it is so hard for us to provide “out-of-the-box” support of Qt for Windows CE, cursing included.

First of all, let me give you a summary on what the typical scenarios for custom Windows CE devices are:

  • The device vendor ships a Windows CE SDK together with their device. In this perfect scenario one would think that a successful build of Qt will naturally lead to Qt running on this device. Unfortunately we have had scenarios, where this does not apply at all. While the SDK has been made for the device once, the OS itself has been updated in the meantime. And during that update the vendor decided to modify the libraries in a way that applications linked to the previous version do not start anymore.

  • The device vendor is not willing to provide an SDK made by themselves. Instead he suggests to use the Standard SDK provided by Microsoft for Windows CE 5.0. To summarize shortly, the Standard SDK was supposed to define a standard subset of what a Windows CE device should contain feature and symbol-wise. Unfortunately there are hardly devices out there, which actually apply to the Standard SDK.

  • Similar to the second scenario a third party developer got his or her hands on a Windows CE device and wants (or needs) to develop for it. As there is no SDK available, the Standard SDK sounds suitable and he directly falls into the same trap as described above.

The problem is the extremely meaningful error output on Windows CE devices. Windows CE shows the following:

Qt not starting

It is very hard for developers who are new to that platform to identify the reason for this message. Well, it was for us as well, when we first hit that problem (at that point we had our second pre-release).

As it happens you build Qt for Windows CE on the desktop against one version of the libraries successfully. But when you deploy everything on the device the application recognizes missing symbols at startup time as there is a separate version of the lib available.

Finding a solution basically consists of two steps:

  1. Identify the symbol missing

  2. Figure out, which part of Qt for Windows CE uses this function and disable it by using QtConfig

What we usually suggested is to build Qt, deploy it and then run something like the following code snippet in the debugger:


HINSTANCE instance = LoadLibraryW(L"QtGui.dll");
if (instance != NULL) {
OutputDebugStringW(L" : Successfully instantiatedn");
FreeLibrary(instance);
} else {
OutputDebugStringW(L" : Could not be loadedn");
}

If you are lucky, the debugger will print out the missing symbol and then you are ready to go to the next step. But usually, things are getting a little bit more complicated. Due to our experiences, in 80% of the cases, symbols from the coredll.dll were missing and this leads us to even more problems. All exports in coredll are actually ordinals. You might remember my last entry about ordinals. Step 1 needs to be splitted into

a) Identify the symbol/ordinal

b) Figure the correct function according to the ordinal

The standard Microsoft tools are usually of help here. link.exe has the /DUMP /EXPORTS option, which returns a mapping between ordinals and functions. All you need to do is search through the list for the ordinal, and you will know the function.

Beside all these troubles, I have mentioned a requirement earlier, which I want to emphasize on. You do need the Visual Studio debugger to follow above procedure. In the code snippet you do not see any output done manually about the missing function. It is happening inside the core libraries of the system, sending the output to the debugger. Even if you use a console (like PocketCMD or such), there is no way to retrieve this output. Consequently, the device also needs CoreConnectivity and/or ActiveSync installed to properly connect to the debugger.

This all sounds like a huge hassle, which needs to be simplified. Using the dump options of link, I've created a small wizard you can download here. Basically what it does is asking you for your Qt build directory, the SDK you used for compilation and then generates some code for you. It reads the import data of each Qt library and dumps it into an array of library- and function names. So all functions that Qt relies on to exist at startup time will be checked for availability on the device. All you need to do is run the generated code snippet on the device and copy the output file back to your desktop machine. The verification wizard then will show you results like this:

 

Verify Result Table

If the missing function is known to be a problem, it gives you a hint, which options you need to set to get Qt for Windows CE running successfully, otherwise it asks you to search the sources for usage. Afterwards you will need to disable that component using QFeatures.

In case you are one of the victims of incompatible libraries between desktop and device, feel free to test this snippet and give us feedback in the comment section. This way we can extend the hint information.

The sources will be available here on labs soon. We are currently collecting some tools/snippets we have made during all the time, which helped us developing for Windows CE during the last two years and will make them available here on labs soon.

 


Blog Topics:

Comments