Published:

Afterthoughts after creating a QT Desktop application

bookmark 3 min read

The application I made was a fairly simple time tracker application, whid, that uses a traditional user interface with a tree o the left and details on the right. Coding the essentials took 1 week. After that, I started using the application, and spent another week adding features and making it usable for others. So all in all, about two weeks development. This was my first desktop application using QT. So I had to do a lot of reading to understand how to implement everything correct. Without all the learning, it would probably have taken me just one week to write the application.

Platform specific issues

I developed the application in QT Creator under Debian GNU Linux. I used the latest version of QT and Qt Creator, and not the one bundled with Debian. When I was done with the basics, everything worked fine under Debian. When I tried the application under Windows, it crashed and would not start at all in release build. When I fixed that (stopped writing to std::cout), button states were not correct. So the events sent from the widgets when something was selected etc. was not the same under Windows and Linux. That was also easily fixed, by handling more signals, and updating the button states more aggressively.

On macOS, I had an issue where the sqlite database query seems to return different data then it does under Linux. (I have not yet had time to look deeper into that one). There was also a few other issues that was only seen under macOS.

Jenkins

I used Jenkins to build the project for all platforms. Jenkins is powerful and gets the job done, but it is poorly documented and it was a long process to figure out how to make it work. It took about 1 week. The only way to see if you get it right with Jenkins is to start a build and see where it fails. That means that each step or each error you make take a lot of time. When it also lacks documentation and examples, that means that the only way to move forward often is to just try and fail. By the time I had a build for 3 Linux distributions, macOS and Windows, I probably started around 150 Jenkins builds. That is a lot of time spent waiting for the console output.

One thing to be aware of is that under Windows, if you use a batch command to build the project, you have to check that the build succeeded in the script, and return a non-zero value if it failed. If not, Jenkins will happily mark the build as OK.

I also failed to find a way in Jenkins to verify that the expected deliverables (.exe or .msi) actually existed, and fail the build if not. I spend half a day on this before I gave up and checked it in a shell script in stead. I also spent half a day trying to make Jenkins rename the deliverables, so that each .deb package had a name corresponding to the distribution it is for. Here, I also had to delegate the responsibility to the build script. I don't think the build script is the correct layer to deal with this. It should not know anything about distributions, or the overall work-flow. It should only know how to create a deliverable.

Docker

Docker is awesome, and makes it very simple to build for a specific Linux version. While there is much confusion regarding how to make sane Dockerfile's (hint: Keep it simple, stupid!) Docker itself is a joy to use. It just works.

Msi and WiX

Windows Installer is an over-engineered piece of shit, and the WiX toolkit reflects that. It's a mess. It is actually very hard to make an installer for Windows and get it right.

The fact that the WiX toolkit's homepage don't even manage to do https right is a red flag about how serious Microsoft is about software installation on Windows. WiX homepage don't even get https right

And don't get me going regarding code signing under Windows. In short, it provides no security what so ever, but if you don't waste money on an expensive signing certificate, and use it, Windows installer will try to prevent users from installing your application by hiding the install button. Idiots!

It took me 3 days to get the .msi install package right. I actually ended up making a github project, mksmi, to build the .msi package.

macOS and dmg

It is surprisingly simple to make a QT application package for macOS. You must however sign it, and initially I was a bit confused when I tried to install it on my Mac Mini. After downloading the dmg package, you have to drag it into the Application Folder in order to install it. It's simple when you know how to do it.

Conclusion

I spent just as much time setting up a build process and getting all the tiny details right, as I spent making the application. That's a lot. To me this indicate that there is plenty of room for innovation in this space, especially in simplifying Windows installers, but also in the build / "continuous integration" domain.