Add official support for MinGW (32 and 64 bit targets)

Issue #1111 resolved
Yaron Cohen-Tal
created an issue

MinGW comes in many flavors, some on Windows, some not. Ideally we would support all those flavors. Shouldn't be too much work as we already support Windows and GCC, and MinGW is more or less a combination of them.

Comments (22)

  1. Lukas Meindl

    Typically only the people who have problems are very vocal ;D So it might seem bigger than it is.

    We don't have any figures how large the percentage of MingW users actually is , but probably way lower than VS users, nevertheless it is a good idea to support it one way or the other. Any fixes are appreciated. I still would like to know at which point you think we can consider this ticket "resolved". What steps need to be undertaken for it to be resolved?

  2. Yaron Cohen-Tal reporter

    This is quite similar to issue #1110. Assuming u use e.g. TDM-GCC (one of the builds of MinGW), from a terminal (not IDE), here is what has to be done:

    1) Don't make any change to CEGUI files.

    2) Open a terminal, and make sure the MinGW compiler u wish to use is first in your environment variable "PATH".

    3) Configure CEGUI for MinGW makefiles, by doing one of the following:

    • To use the command line CMake, run: cmake -G "MinGW Makefiles" <other-options> <src-dir>
    • To use the GUI CMake, run "cmake-gui", press "configure", and under "Specify the generator for this project, choose "MinGW Makefiles"

    Either way, the "MinGW Makefiles" is called the CMake generator that u use. So it's not part of the CMake files, but part of how u run CMake.

    4) Build, by running "mingw32-make". Fix any build errors.

    5) Run. Fix any bugs.

    Only steps 4 and 5 actually change anything in CEGUI files. Theoretically, it's possible that building and running will just work out of the box, in which case there'll b no need to change anything in CEGUI files!

    Now, the steps may be a bit different if u build on Unix, Cygwin or MSYS2, or if u use an IDE, but the general recipe is the same.

    MinGW has many different builds, including TDM-gcc, MinGW-builds, Cygwin (cross compiler), MSYS2 (cross compiler), Debian (cross compiler) and nuwen MinGW. Ideally, we'd test all of them, but in practice they're all quite equivalent, so I think it's enough to officially support one of them.

    MinGW can target either 32 or 64 bit. Choosing one of them can be a bit different depending of which build of MinGW u use, but for example if u use TDM-GCC (as in the steps above), u need to make sure the right compiler (i.e. the one targetting 32 or 64 bit) is first in the "PATH" in step 2 above.

    Once CEGUI works with one of the builds of MinGW, targetting both 32 and 64 bit, I consider the issue resolved. Then, as an extra, would be nice if it were included in the automated builds, and if some1 actually checked that it works from time to time.

  3. timotei

    Btw, we do have some support for MinGW (the "normal", native for Windows one), as I've worked on it for a while (and even tested and ran CEGUI samples), but maybe new stuff has surfaced in the meantime.

    Anyway, the builds seem? to work on our build page (I won't put it here so it's not stolen by bots, but you can ask it on the channel), both for deps and CEGUI itself. I have a half-abandoned job also here: https://ci.appveyor.com/project/timootei/cegui-dependencies-521 , I haven't found yet a quick way to setup MINGW, so I need to refresh my memory on Appveyor's infrastructure, as I remember they offer some preinstalled MinGW nodes.

  4. Yaron Cohen-Tal reporter

    @timotei: I'm now in the process of building CEGUI and its deps on Debian 8.2 with MinGW targeting 64-bit. I haven't finished yet but indeed there are rather few problems.

    I didn't understand, do we have some automatic build of MinGW? What exactly do u not want to put here?

  5. Christopher Beck

    For what it's worth, I have been building v0-8-4 using mingw from Ubuntu trusty repository for several months now, using this lib collection, and testing it regularly in my project:

    https://github.com/cbeck88/mingw_lib_kit

    At least the v0-8 branch seems to work great and I haven't noticed any problems at all.

    Edit: I guess in my project itself I also have libxml2, SILLY, pcre in tree, because emscripten cannot provide those deps itself so it needs to be in tree more or less. But none of that has been problematic either.

  6. Christopher Beck

    Oh, if you guys are planning to officially support mingw now (and mingw-w64?), I should mention that I fixed a few warnings in the code, and one which was fairly problematic was related to this code:

    https://bitbucket.org/cegui/cegui/src/4118c453c5dc71ba341fb42f07769b285f69af01/cegui/include/CEGUI/PropertyHelper.h?at=v0-8&fileviewer=file-view-default#PropertyHelper.h-332

    This would fail to compile when using -Wall -Werror, saying that %lld is unrecognized, when using this distribution of mingw-w64 targetting win32: http://packages.ubuntu.com/trusty/devel/g++-mingw-w64-i686

    I guess that this earlier line in CEGUI is supposed to enable the use of posix format strings?

    https://bitbucket.org/cegui/cegui/src/4118c453c5dc71ba341fb42f07769b285f69af01/cegui/include/CEGUI/PropertyHelper.h?at=v0-8&fileviewer=file-view-default#PropertyHelper.h-57

    But for whatever reason it stopped working -- possibly because, I'm not sure what type the CEGUI type int64 actually refers to when compiling for Win32?

    There is a fair amount of docu and conflicting advice from mingw-w64 project on how to get this to work, I guess that they did it one way for a long time and then changed their minds. Part of it is because, do they want to make their printf run through the windows crt implementation, or roll their own.

    Suggestions I've read:
    - Use _mingw_printf instead of printf.
    - Use %l64d instead of %lld on mingw.
    - Use a macro PRIuMAX instead of either of these format specifiers, this macro should select the correct format specifier...

    References:
    http://sourceforge.net/p/mingw-w64/wiki2/gnu%20printf/
    http://stackoverflow.com/questions/13590735/printf-long-long-int-in-c-with-gcc
    http://sourceforge.net/p/mingw-w64/mailman/message/29128283/
    ^ This email comment is from the lead developer of mingw-w64
    https://lists.gnu.org/archive/html/bug-gnulib/2014-09/msg00056.html

    None of the above worked for me, and at some point I overdosed on all of this and changed the CEGUI header in my project to use std::stringstream for int64 conversions instead of scanf / snprintf, even if its the dumb slow way. I think possibly, attempting to use C format specifiers for conversion with 64 bit types is just asking for painful portability problems, but that's just my 2 cents.

  7. Yaron Cohen-Tal reporter

    @Christopher Beck: Thanx for the thorough investigation! As a matter of fact I've encountered this warning just yesterday and fought hard with it. And lost.. So eventually I just disabled the warning when compiling the lua script-module. From tests I've made "%llu" does work, the bug seems to be in the warning being triggered (which in most cases doesn't happen either!)

    Actually I'm currently working only on MinGW-w64 support (targetting either 32-bit or 64-bit). If I have time I'll support also the original MinGW.

  8. Christopher Beck

    So the thing is, for me its not enough to just disable the warning in the lua script-module, it shows up in any file in my project that includes the property helper header from CEGUI, and disabling C format warnings is not something I want to do permanently in my project since those warnings can indicate UB.

    My take is that there's not usually a reason to use scanf in C++ projects -- Joel de Guzman claims that boost spirit's numeric parser primitives are multiple times faster than atoi, strtol and the other C integer and floating-point parsing functions, because of significant overhead built into those functions.

    http://boost-spirit.com/home/2014/09/03/fastest-numeric-parsers-in-the-world/

    Actually I didn't even know until reading the comments, that the behavior of atoi depends on the C locale.

    I don't know what the right answer is for the cegui library since cegui doesn't use boost, but at least in my other projects my take is that, if you need speed, then use one of the spirit parsers, and if not then use a stringstream, but you shouldn't use atoi or scanf in general. Maybe only in this niche where you can't tolerate any external dependency and yet need something faster than stringstream.

  9. Yaron Cohen-Tal reporter

    @Christopher Beck: And btw "uint64" is "unsigned long long". The reason we don't use "std::uint64_t" is coz that's C++11 and branch "v0-8" is based on C++03. For the same reason we can't use macros like "PRIu64". We'll use them in branch "default" that is based on C++11.

  10. Christopher Beck

    I'm using Linux Mint 17.2

    $ cat /etc/issue
    Linux Mint 17.2 Rafaela \n \l
    

    I install mingw like this:

    $ sudo apt-get install g++-mingw-w64-i686
    $ i686-w64-mingw32-g++ -v
    Using built-in specs.
    COLLECT_GCC=i686-w64-mingw32-g++
    COLLECT_LTO_WRAPPER=/usr/lib/gcc/i686-w64-mingw32/4.8/lto-wrapper
    Target: i686-w64-mingw32
    Configured with: ../../src/configure --build=x86_64-linux-gnu --prefix=/usr --includedir='/usr/include' --mandir='/usr/share/man' --infodir='/usr/share/info' --sysconfdir=/etc --localstatedir=/var --libexecdir='/usr/lib/gcc-mingw-w64' --disable-maintainer-mode --disable-dependency-tracking --prefix=/usr --enable-shared --enable-static --disable-multilib --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --libdir=/usr/lib --enable-libstdcxx-time=yes --with-tune=generic --enable-version-specific-runtime-libs --enable-threads=posix --enable-fully-dynamic-string --enable-sjlj-exceptions --enable-libgomp --enable-languages=c,c++,fortran,objc,obj-c++ --enable-lto --with-plugin-ld --target=i686-w64-mingw32 --with-gxx-include-dir=/usr/include/c++/4.8 --with-as=/usr/bin/i686-w64-mingw32-as --with-ld=/usr/bin/i686-w64-mingw32-ld
    Thread model: posix
    gcc version 4.8.2 (GCC) 
    

    I believe it is this package (ubuntu trusty).

    My CEGUI version is 0.8.4, and I have modified it in various ways, for instances I'm using my OpenGLES2 renderer instead of yours, although eventually I plan to remove it and switch to yours when CEGUI 0.8.5 is released. Also I had to modify stuff so that it includes opengl differently for emscripten. I have some project to make a compatibility header for emscripten / Epoxy that emscripten could compile programs which include epoxy headers without them needing to be changed, so that CEGUI sources would not need to changed to use it with emscripten... but I did not finish that project yet. In the meantime I do like

    #ifdef __EMSCRIPTEN
    #include "GL/gles2.h"
    #else
    #include "epoxy/gl.h"
    #endif
    

    in all the cegui renderer code basically. Anyway that's off topic, the point is, I don't think I made any changes that should be related to this issue.

  11. Yaron Cohen-Tal reporter

    @Christopher Beck: I eventually solved it like this:

        static return_type fromString(const String& str)
        {
            uint64 val = 0;
    #ifdef __MINGW32__
            static const std::string format(" %llu");
            sscanf(str.c_str(), format.c_str(), &val);
    #else
            sscanf(str.c_str(), " %llu", &val);
    #endif
    
            return val;
        }
    

    This suppresses the warning..

    I'll soon submit my MinGW support project.

    Thanx for the info for building mesa, it might help me to test Windows builds!

  12. Log in to comment