Cross Compilation
I can say with confidence that I had this working a couple of years ago. When I created the Alpha/Beta version, I did not care about cross-compilation, or making it build for Linux at all. The reason was that I had only one computer, and that had Windows. Using Visual Studio made things easy and I could just build what needed to be built and publish it to the web. I then had a small urge to try out Linux, so I set up Ubuntu in a VM and tried to make PixelMap work on that, which took some effort, and eventually I at least got the CLI version going, ignoring the GUI as it was heavily influenced by Windows infrastructure.
Later on, when I started to experiment with v2(also called Gold), I wanted it to be able to be run on any platform. I therefore chose to use Qt instead. It started off pretty well, I got it to run and work in Windows fine, but when it came to compile it in Linux, I found a couple of issues, one of them being that Qt, while being told to be cross-platform, was not that cross-platform at all, mostly as their code in itself was cross-compliant, but the underlying system an libraries was not. After tackling with it for a while, released a couple of versions, I chose to go back to my roots of programming-only GUI, and found Dear ImGui. As I had split up the project into multiple repositories (library, cli, qt), I created a fourth repository (im) and started experimenting, which took faster than I expected. This time I developed only in Linux, just because it was less cumbersome. Due to this, I had to back-port it to Windows. I previously set up a CI to make it easier to publish the program, so now I just had to change the dependencies, and eventually I got to a satisfying result.
Due to circumstances regarding a previous addition, I found myself rewriting the dependency system. I have been using CMake right after I started with v2, and while I struggled a lot to follow the standard and debug whatever I did wrong most of the time, in the end the system works. As it is the most used build system today, I will most probably keep using it in the future. Although, I often try to use older technology, which was the reason I barely upgraded to newer C++ versions, only using C++17 just recently, I avoided newer CMake versions and features. But this time, I found myself at a wall where it was difficult to maintain my own code, and it still did not work as intended. I therefore threw out the ordinary find_library
1 and custom download code and embraced FetchContent
2, something that both reduced the code footprint, but also made it more consistent and secure.
I fought back and forth with variables and libraries until I finally made it possible to compile in both Linux and Windows. The general idea was that I had left PNG_BUILD_ZLIB
on, and spdlog
3 as INTERFACE
4. The former was probably due to PNG having their own build system which did not work with my system, and the latter I can only assume was that it behaved differently between platforms regarding building and inlining the library, but at least it now works. I also had to use zlib-cmake boilerplate to make zlib act nice. It is just a bit frustrating that I fought for days, if not weeks, to get this to work, even though it was mostly a simple flip of a switch(es).
The only faulty type variant I found odd was the LP64 vs LLP64 standards 5. It differentiates only in long
, where on Windows it is 32 bits (LLP64) and on on all other platforms it is 64 bits (LP64). The bug was found in the tests, where I had used long
in one test, leading it to discard the higher bytes. Changing that to long long
solved the issue, and would also follow the above mentioned standards. Other than 32/64-bit compatibility, one need to test different libraries and make sure that you only use as little libraries as possible, so you can pack less for the user. An another issue I found was that I never tested Windows code, meaning I actually had bug where the program crashed on load. After locating it, I fixed it fairly quickly, so now everything works as expected.