Porting Linux to Windows: the case of Splash

EMMANUEL DURAND

2024-01-30

The Linux-to-Windows port of Splash videomapping software, using the MSYS2 platform.

A little opportunism

The possibility of running Splash on Windows has been a recurring topic of discussion, since the very beginning of its development in late 2013. This is one of the reasons why cross platform libraries have been favored to facilitate this eventual transition, such as GLFW, FFmpeg and ZMQ.

Splash on Windows 11

A recently opened ticket by a (potential) user revived this topic, and all the more so when a second user/contributor, Pip Eicp, shared his own experiments trying to compile the software under Windows. All this piqued my interest and I embarked on a few tests, estimating the work needed to accomplish this task in weeks.

Getting off to a good start

The route explored by Pip Eicp was to attempt compilation using the MinGW-w64 development environment. Having already used this environment, and having found myself stuck when porting other software over the years, I wasn’t very enthusiastic about the idea of finding myself in the same situation. So I naively tried my hand at it, taking advantage of the fact that CMake, the software builder used in Splash, can generate projects for the tools usually found on Linux, but also for XCode (on macOS) and Visual Studio (on Windows).

This proved to be a failure. To begin with, projects can be used in Visual Studio, but a priori not in Visual Studio Code, requiring the use of a proprietary tool with a limited license. Beyond that, the compilation errors proved difficult to decipher. So I put that aside, considering that my lack of recent experience with Visual Studio was going to get in the way.

To find a better way, I looked at what’s used with other software, starting with some tools I use regularly and which are available for Windows as well as Linux. One thing led to another and I came across the documentation for packaging Darktable on Windows, which mentions MSYS2, a software compilation and distribution platform for Windows. The fact that it’s based on Cygwin, as well as the many already compiled libraries available and the use of a well-known package manager, pacman, intrigued me quite quickly. The possibility of generating a package while working in an environment close to my own was no mean feat. The icing on the cake is that the actual package generation is done using NSIS automatically through CMake, potentially making the task much easier.

Installing the development environment

Now that we’ve set the scene, let’s get down to business. To begin with, I don’t happen to have a Windows computer at hand. So I naturally turned to installing a virtual machine, taking advantage of qemu and kvm. Without going into detail since others have already done so, I used a Windows 11 installation image freely available from Microsoft. Important subtlety: it is recommended to disable the virtual machine’s network during installation, to bypass the requirement to create a Microsoft account. I’m also leaving out sharing a PCIe graphics card with this virtual machine, without which Splash won’t launch. There are very good guides on this subject.

Once Windows has been installed and launched, it’s time to install the development environment. In what follows, I’m going to consider the specific case of Splash, so all the packages mentioned are obviously not mandatory for all software ports.

Installing MSYS2 is very simple, just download the installation program from their website and run it. Once installed, you’ll notice several “flavors” of their development environment. The specifics are explained in their documentation, so I’ll skip over them. In our case, I chose to use the UCRT64 environment, which has the advantage of being more modern, and natively supported since Windows 10. An important point to know is that packages installed with one flavor of the environment are not necessarily accessible with another, so it’s important to always work with the same flavor.

MSYS2 in its many flavors ...

Once the development environment (i.e., less prosaically, a terminal) has been launched, we can install the dependencies. As far as possible, I’ve decided to use already-packaged libraries rather than compiling those supplied in sub-modules, to limit compilation problems.

From there, it’s a matter of sorting out Splash-specific compilation problems, as much as disabling or replacing Linux-specific features. As for compiling Splash under Windows, the procedure is detailed in the Splash documentation, so I’ll spare you any redundancy here.

Redoing is still doing something

The Splash commit history is the best place to see the changes made between version 0.10.2 and 0.10.6 to enable compilation under Windows and to fix specific problems. The main issues were related to libraries specific to the Linux and/or Unix world on the one hand, graphics rendering with OpenGL on the other, and finally packaging and the file system.

In terms of specific libraries, we had to replace the uuid library available on Linux with a library offering equivalent functionality, namely stduuid. The conversion was relatively straightforward.

We also had to review the implementation of the ZMQ library. As it happens, the pre-existing implementation used the IPC (inter-process communication) transport protocol, which simply doesn’t exist under Windows. It was therefore necessary to add in-process message support for this platform. Although this is a priori a simple path change in the code, it turns out that this mode of transport is less permissive as far as implementation is concerned and we had to clean up all the code using ZMQ. On the whole, it’s quite positive.

On the OpenGL side, there were no major surprises, apart from a problem converting from the linear RGB color space to sRGB. This isn’t the first time this has happened, the previous one appeared when OpenGL ES support was added. Hence my astonishment, since I thought everything was now pretty square on that front. From my understanding, in this specific context (i.e. under Windows 11, in a virtual machine, using OpenGL as the rendering API), the blit from a framebuffer object to the backbuffer of a window doesn’t apply this color space conversion, whereas this is the case in all my tests under Linux (and a priori this is what the specifications say). So I moved the color space conversion to the framebuffer object at rendering time, which solved the problem.

Back slashes

There remains the question of the file system, which is managed quite differently under Windows than … anywhere else. As it happens, MSYS2 already does a great deal of the work, and makes much of the file management transparent. In other words, Windows paths are automatically converted to POSIX format, and vice versa. The part that required the most work from this point of view was packaging, and in particular the definition of the various installation paths.

Splash installation, after GPL acceptance

The current solution is to reproduce a folder infrastructure similar to that found on Linux, but limited to the Splash installation directory. The few Windows-specific features can be found in the CMake configuration file. As for the rest, once again CPack in conjunction with NSIS has greatly facilitated the generation of an accounting package from Windows 10.

That’s it?

In the end, the whole port took about three days, including the correction of minor problems. Although Splash hasn’t been tested on a real Windows installation, it’s largely usable. As I said in my introduction, I expected the work to be much longer and more painful.

The availability of a development environment that solves many common problems right from the start (availability of certain libraries and file systems, among others) was a great help, as was the fact of being able to rely on a familiar development environment. And of course, the initial decision to use cross platform libraries was a great help.

All that remains now is to use Splash in real-life conditions. And for that, apart from the few synthetic tests I can do, I can only rely on users to find out what’s broken and let me know. Starting with test installation!