
Clinton Mead
I'm currently trying to bring my company around to using a bit of Haskell. One issue is that a number of our clients are based in South East Asia and need software that runs on Windows XP.
Ooph, that is quite tricky. Indeed we dropped XP support for Windows 8.0, at which point XP had already been EoL'd for seven years.
Unfortunately it seems the last version of GHC that produces executables that run on Windows XP is GHC 7.10. Whilst this table https://gitlab.haskell.org/ghc/ghc/-/wikis/platforms/windows suggests the issue may only running GHC 8.0+ on Windows XP, I've confirmed that GHC 8.0 executables (even "Hello World") will not run on Windows XP, presumably because a non-XP WinAPI call in the runtime.
Indeed. The dropping of XP support was prompted by the need to use a newer Win32 interface (I can't recall which in particular).
My first thought would be to restrict myself to GHC 7.10 features (i.e. 2015). This would be a slight annoyance but GHC 7.10 still presents a reasonable language. But my concern would be that increasingly I'll run into issues with libraries that use extensions post GHC 7.10, particularly libraries with large dependency lists.
I would also be concerned about this. I wouldn't expect to be able to get very far with GHC 7.10 in 2021.
So there's a few options I've considered at this point:
1. Use GHCJS to compile to Javascript, and then dig out a version of NodeJS that runs on Windows XP. GHCJS seems to at least have a compiler based on GHC 8.6.
This is an option, although only you know whether this would fit your application given your memory and CPU constraints. I also have no idea how easy it would be to find a functional version of NodeJS.
But then I had a thought. If GHC Core isn't supposed to change much between versions is it? Which made me come up with these approaches:
3. Hack up a script to compile programs using GHC 9 to Core, then feed that Core output into GHC 7.10. OR
4. Produce a chimera style GHC by importing the GHC 9.0 API and the GHC 7.10 API, and making a version of GHC that does Haskell -> Core in GHC 9.0 and the rest of the code generation in GHC 7.10.
Sadly, I suspect this isn't going to work. While Core itself doesn't change (that much), the primops do. Even getting Core produced by GHC 9.0 to build under GHC 8.10 would require a considerable amount of work.
One issue with 4 will be that presumably that because I'm importing GHC 9.0 API and the 7.10 API separately, all their data types will technically be separate, so I'll need to basically deep copy the GHC 9.0 core datatype (and perhaps others) to GHC 7.10 datatypes. But presuming their largely similar this should be fairly mechanical.
I'm not sure how mechanical this would be, to be honest.
So are any of these approaches (well, particularly 2 and 4) reasonable? Or am I going to run into big problems with either of them? Is there another approach I haven't thought of?
My sense is that if you don't need the threaded runtime system it would probably be easiest to just try to make a modern GHC run on Windows XP. As Tamar suggested, it likely not easy, but also not impossible. WinIO is indeed problematic, but thankfully the old MIO IO manager is still around (and will be in 9.2). The possible reasons for Windows XP incompatibility that I can think of off the top of my head are: * Timers (we now use QueryPerformanceCounter) * Big-PE support, which is very much necessary for profiled builds * Long file path support (mostly a build-time consideration as Haskell build systems tend to produce very long paths) There may be others, but I would start looking there. I am happy to answer any questions that might arise. Cheers, - Ben