cfyzium / bearlibterminal

Interface library for applications with text-based console-like output
Other
119 stars 18 forks source link

Compilation fix for MinGW. #6

Closed Gravecat closed 3 years ago

Gravecat commented 3 years ago

This fix allows BLT to compile cleanly under MinGW/MSYS on Windows.

cfyzium commented 3 years ago

Uh oh. This innocently looking thing uncovers a huge issue.

The library just does not build under MSYS2, at all. And I am afraid the fix offered won't cut it out =).

Here I am assuming that MSYS is the MSYS2 from www.msys2.org, as far as I can see the only active and alive MSYS by now -- and one of the only two active MinGW branches. I personally use the other one, the simple and straightforward mingw-w64 build that is also used by Qt and which only includes GCC and nothing else. That one compiles the library just fine because it is essentially WIN32.

If it is neither of those, I think your toolchain might be a little out of date (for some time MinGW was a complete and utter mess, that might explain why a single preprocessor directive seems to be enough to fix the build). Or maybe I have missed some other MinGW-based toolchain out there.

Personally, I've never seriously used MSYS2. The last time I've checked it years ago, it was in early barely usable stages of development and also I didn't really like the approach. Checking it now, I can at least see its benefits but the most controversial aspect in my opinion has only solidified. The whole thing is a complete environment into itself, kind of like Cygwin but from a different angle. It just does not interact with outside system and installed tools (MSVC, installed CMake, etc.) well, if at all.

And here comes the problem as I see it. For the project being developed, the current MSYS2 is essentially another target system that requires a separate cross-platform support, just like Linux.

A naive attempt to simply build BearLibTerminal under MSYS2 immediately stumbles upon CMake warning that MSYS is not the WIN32 and appropriate measures might have to be taken. After acknowledging the issue, the build immediately fails saying that MSYS platform is not supported, because CMAKE_SYSTEM_NAME is now MSYS and neither Windows, Linux or macOS. After turning the check off, the build fails to find OpenGL library because although CMake is aware that MSYS is not WIN32 anymore, its FindOpenGL search module is not. It is probably solved by installing the appropriate mesa package mimicking Linux, but then another issue arises: it will link to the mesa libraries and not system-wide Windows libraries as it was intended.

And even after that there is about a dozen places in the code where being "not WIN32" assumes being either Linux or macOS and not another variation of Windows environment. I am doubtful everything will just work without checking every case.

So, I am afraid that a single change won't be enough to actually fix build under MSYS2 MinGW =___=.

However, I acknowledge that MSYS2 is a valid build environment and will try to support it as well.

Gravecat commented 3 years ago

Hey, thanks for the reply! :)

This is an odd one, though! I've been using MinGW/MSYS exclusively for personal projects for a fair while now, and had no trouble compiling BearLibTerminal myself on MSYS -- it just required that one little tweak to make the build work, as localtime_r didn't exist in that build environment, but localtime_s did. Though, also worth mentioning that I've only had success with CMake and MinGW/MSYS (for anything, not just BLT) when specifying -G"MSYS Makefiles" for CMake's initial build folder setup.

My build environment's a bit of a weird convoluted mess by this point, though, so it's hard to say anything for sure. Since I've already had success making a working build of BLT with this tweak, I'll see about setting up a clean virtual machine environment tomorrow to see if I can replicate it. I'll report back here if I can figure out anything useful. :)

Gravecat commented 3 years ago

Hokay, reporting back with some extra information after testing. :)

I set up a virtual machine with MSYS2 from www.msys2.org and CMake from www.cmake.org, and the GCC packages in MSYS2, and after a great deal of tinkering, managed to get BLT to build happily using the modified version of Log.cpp in my pull request. There's a few caveats that I'll get into below.

Without the modified Log.cpp, the build fails as localtime_r is not declared:

C:/Users/grave/Desktop/temp/bearlibterminal-master/Terminal/Source/Log.cpp: In function 'std::string BearLibTerminal::FormatTime()': C:/Users/grave/Desktop/temp/bearlibterminal-master/Terminal/Source/Log.cpp:43:3: error: 'localtime_r' was not declared in this scope; did you mean 'localtime_s'?

With the modified Log.cpp, it will compile happily, under the following conditions:

I also did a test with the other mingw-w64 build you linked above... which worked pretty flawlessly on both the modified and unmodified versions (using the MinGW Makefiles generator). I'll leave this pull request here to do with as you wish, as it seems to allow MinGW/MSYS2 builds (with the steps taken above) without adversely affecting the non-MSYS MinGW builds. :)

cfyzium commented 3 years ago

Well, I couldn't sit idle either and tried to figure out the exact source of the problem. And it seems some things do not change easily, this is still quite a mess =).

Must install CMake separately in Windows (downloaded from the website above), not the MSYS2 CMake package.

This one is crucial. You have to get the CMake version right. The one installed from MSYS2 cannot build BLT because it presents itself as a separate MSYS environment: CMAKE_SYSTEM_NAME is set to "MSYS", variable MSYS is set to TRUE and variable WIN32 is not set at all.

The official CMake for Windows on the other hand at least sets CMAKE_SYSTEM_NAME to "Windows" which allows BLT's CMakeLists.txt to work. However, next there is a catch =).

Using "MSYS Makefiles" generator, it also sets quite a few identification variables, in particular WIN32, MSYS and CYGWIN simultaneously (this also means that checking MSYS only won't be enough). And just until very recently (commit from August 6, 2020), the FindOpenGL.cmake module has been checking for CYGWIN first and WIN32 after.

As the result, in any version except the most recent one i. e. anything below 3.19.0 -- released literally 10 days ago! -- looking for OpenGL when using "MSYS Makefiles" will fail because execution will go down the Cygwin code path expecting the library to be installed into a Unix prefix.

Funny enough, the MSYS2 CMake 3.18.4 has been patched to remove CYGWIN case (the patch is called 3.17.3-opengl.patch but it is actually applied to 3.18.4 wtf =___=), but as far as I can see it does not help one bit because the CYGWIN variable is not even set during generation.

The whole thing is, putting it mildly, somewhat messy and fragile =). I think I'll stick to the standalone mingw-w64 build for the time being =).

I think I will merge the fix anyway because as you've said it does fix at least one case without any negative effects. But the situation is far from being resolved and I'll have to add another big TODO to the already very long list >___<.

Gravecat commented 3 years ago

Holy crap, that's quite the rabbit-hole I've sent you down over what I thought was a very quick and simple fix. :) I had no idea the whole of MSYS2 was such a convoluted mess.

(Though with that said, I've actually now switched entirely away from MSYS2 and to the stand-alone MinGW you linked above; I think I was only using MSYS2 because it was the best option available at the time, that being several years ago, and I wasn't aware that better options now existed. :3)