Blog 
Cross-platform Compiling on a Windows System
Tuesday 29th April 2025
My journey from misconception to mild insanity...
Background
About 10+ years ago, I was sitting in a CompSci lecture piss farting around in Visual Studios when I found a re-implementation of the Borland Graphics Interface (BGI) called OpenBGI library, I think I then spent the remainder of that session hacking (but never intending to finish) a Pong clone.
I think I left whatever it was that I was working on in a public repository on GitHub, and moved on with life, Fast forward to just a few weeks back and a colleague asks about getting into game development, I gave the usual rant about game engines not mattering and the more important aspect of making something fun and unique but most of all stick-to-itiveness, that led to the question where to start? Like always, start with the basics, make a copy of hangman, noughts and crosses or pong, it will give you an idea of game loop, just start somewhere.
Sometime later, I was sent a link to my old pong repository, apparently it was on some GitList marked as "simply game projects", so at least my buddy didn't start with chat-gypo-tee, and it's not the first time something that I made many years ago has come up in conversation...(to clarify, something that I have simply just forgotten about)
I had some interesting misconceptions about the possibility of cross compilation on Windows operating system targeting Linux; to start, I was always under the impression that MSVC's cross platform compiler was able to natively target Linux elf binaries because of the company's azure cloud offerings (or whatever their variant of Linux is).
It all started the other day when I was using an updated version of the Open Watcom C compiler for a project that I hadn't touched in over 10 years, a port of the classic computer game pong for the Borland Graphics Interface that I had re-factored to use Windows GDI.
"Hey, wouldn't it be cool if we built a Linux version instead as well, and the Watcom C compiler supports Linux as a target, so I'll add that in!"
Straight up we can build an elf binary Hello World in C, but anything far more complicated than that and you begin to require library support which from my experience isn't available, I tried to find a version of the X11 library that was compatible with the Watcom C compiler and ended up trying to recompile it from source, stole some of the libraries out of MinGW (obviously the libraries for Watcom C and MinGW are in different formats, but it was worth a try), and that led me to the thought of, "Why don't I just build it in MinGW?".
After some time messing about with that, I got the application to build, but it produced a PE format executable For Windows,
For Fuck's sake, OK frustratingly after some research I discovered that the Watcom compiler leans on libraries provided by GCC and it's not 100% compatible.
So, what other options are there?
I tried with Cygwin, but it became pretty obvious pretty quickly that it was more of a runtime environment rather than an actual Linux emulator, but I still see value in making a Cygwin version for testing.
I bit the bullet and decided to set up a docker environment although I intended to use rancher, after being told to install WSL (Windows Subsystem for Linux) I gave up and just started using WSL, since it's basically a virtual machine it felt like a bit of a cop out.
Eventually I got Borland BGI for dos, TCC for Windows and GCC via WSL building an x11 hello world app, among the other platform specific versions, so I could finally write some game code.
For classic Mac OS (68k) I settled on a very early version of Code Warrior 5 for Windows, that is, among a few things one of the only development suites\IDES that has a cross compiler for the 68K Macintosh platform on Windows.
I was a bit taken back by the idea that the Watcom C compiler is the only one that can compile for Linux on a Windows system (that I know of), and its support is very limited.
It also has support for 16-bit Windows and some of the more obscured platforms like the OS/2, so the plan is with my silly Pong project, to ported to as many platforms as possible using C, (I am currently reading through the C programming book but it remains to be seen that I'll complete it, still this project was a great compliment to reading that book).
For the project itself, Pong isn't hard to remake, easy in fact, but I think I must have spent about a day procrastinating and pondering over the pseudo code for it, trying to think back to those first-year university lecturers that had pong re-implemented in scratch that started this whole endeavour in the first place.
The thing is, I didn't want to google it because I'd end up referencing someone else's code, and that also rules out using AI, because "you can just google it", and I have my own thoughts about AI without it hijacking the conversation, I don't use it to avoid the learned helplessness, that I currently find myself in with the problem at hand being relatively simple to solve.
It's pong for fucks sake, I have a tella-TV-something sitting in a box next to my desk, I could always pull that out to study it, but alas, I pushed through it and started knocking out the pseudo code for it.
There's a game loop, an enum for game state, an object to represent the player or paddles, that object needs at least an x and y coordinate, even though each player only moves positions on the x axis.
Each paddle can receive input to increment or de-increment its x axis. (Allowing the object to traverse up and down)
A ball object, and something to keep track of score.
The ball object moves in a random direction when the game starts, the game state is now "ball in play", if the ball hits a player paddle or "on collision", the ball bounces in a random direction (usually a value between 0 to 360 or within a full circle or a complete rotation), if the ball position exceeds A threshold set by the game board or canvas or background rectangle image, depending on whether the coordinates are positive or negative determine which player scores, at which point the game is now in "reset" and the score counter is incremented, the score counter that is comprised of a strut, where each node keeps track of player score, If one of the nodes exceeds more than three then game over. (or, best 2 out of 3) and the ball Returns to its original origin being the centre of the game board, the game state is now "ball in play" and a new round starts.
I started writing a pseudo code doc in the project's repo, I am close to release, but I think I'm going to have to make a follow up Part 2 to this post because it's gotten a bit too complicated, in the meantime, the new repo can be found here.
I hate the idea of making a Part 2 because I wanted this article to be a full solution, but it seems the issue is a lot more complex than I first initially thought it would be.
I want to add in that while the game code is relatively simple, the complexity of cross platform compilation from a single host system is what fascinates me to document my journey, for example Windows NT (4.0 specifically), supports a multitude of different CPU architecture types, (PPC, and MIPS to name a few, then there's Itanium) I have never compiled code for any of these platforms, So the journey is only just begun to write a multi-platform codebase in C, it's also a much more higher level, elegant and especially versatile programming language compared to my usual assembler, and a good break from it.
I am also planning to read Show Stopper!: The Breakneck Race to Create Windows NT and the Next Generation at Microsoft by G. Pascal Zachary, as part of my research for this project.
Then there's MacOS; I have some 68k dev notes that I'm yet to publish, but that has become a journey onto itself...
Home | Blog Index | RSS