Compilation with Code::Blocks and MinGW

Current state

  1. VCMI engine - works
  2. AI libs - works
  3. ERM - compiled
  4. 3rd party libs
    4.1) Boost - 1_55_0 - compiled static lib
    4.2) SDL, SDL_xxx - precompiled VCMI distribution
    4.2*) SDL2, SDL2_xxx - official binary builds
    4.3) zlib - precompiled VCMI distribution


  1. SetThreadName not supported on MinGW
  2. compilation is too slow
  3. dbghelp is not supported in MinGW (crash dump disabled)


  1. VCMI_lib must be compiled with at least O1 or Og (or some assembler files are too big for GNU assembler - error “too many sections”)
  2. bootstrap boost under Mingw is not trivial
    run ./ --with-toolset=mingw
    run sed -e s/gcc/mingw/ project-config.jam > project-config.jam
    *) see
    **) but for building boost toolset must be “gcc”
  3. C::B does not track changes in compiler settings and does not recompile entire project it that cases (file changes are tracked perfectly though).
  4. -std=gnu++0x (not -std=c++0x) is required to use boost with MinGW
  5. -DBOOST_THREAD_USE_LIB . Also seems to be required.
  6. “libgcc_s_dw2-1.dll” “libstdc+±6.dll” from mingw required for vcmi_client to run.
  7. boost::filesystem v3 has issues with current code, workaround used.

What is the error message?

AFAIR MinGW won’t work with __try/__catch. You can #ifdef the whole function out for MinGW (use ifdef _MSC_VER instead of _WIN32), it’s only purpose is making thread list readable in debugger.

Last build log:

mingw32-g++.exe -LE:\src\boost\boost_1_51_0\stage\lib -Lbin\Debug -LD:\MinGW\lib -LE:\src\boost\boost_1_51_0\stage\lib -o bin\Debug\VCMI_server.exe obj\Debug\server\StdInc.o obj\Debug\server\NetPacksServer.o obj\Debug\server\CVCMIServer.o obj\Debug\server\CGameHandler.o -lboost_program_options-mgw47-mt-d-1_51 -lboost_filesystem-mgw47-mt-d-1_51 -lboost_system-mgw47-mt-d-1_51 -lboost_thread-mgw47-mt-d-1_51 -lboost_iostreams-mgw47-mt-d-1_51 -lboost_chrono-mgw47-mt-d-1_51 -lVCMI_lib -lws2_32 -lole32
obj\Debug\server\CVCMIServer.o: In function `_ZN5boost12interprocess6winapi23get_wmi_class_attributeERSbIwSt11char_traitsIwESaIwEEPKwS8_':
E:/src/boost/boost_1_51_0/boost/interprocess/detail/win32_api.hpp:1768: undefined reference to `[email protected]'
obj\Debug\server\CVCMIServer.o: In function `_ZN5boost4asio6detail10socket_ops20complete_iocp_acceptEjPvmP8sockaddrPjjRNS_6system10error_codeE':
E:/src/boost/boost_1_51_0/boost/asio/detail/impl/socket_ops.ipp:179: undefined reference to `[email protected]'
obj\Debug\server\CVCMIServer.o: In function `_ZN5boost4asio6detail28win_iocp_socket_service_base15start_accept_opERNS2_24base_implementation_typeEbRNS1_13socket_holderEiiiPvmPNS1_18win_iocp_operationE':
E:/src/boost/boost_1_51_0/boost/asio/detail/impl/win_iocp_socket_service_base.ipp:494: undefined reference to `[email protected]'
obj\Debug\server\CVCMIServer.o: In function `_ZN5boost4asio6detail28win_iocp_socket_service_base17restart_accept_opEjRNS1_13socket_holderEiiiPvmPNS1_18win_iocp_operationE':
E:/src/boost/boost_1_51_0/boost/asio/detail/impl/win_iocp_socket_service_base.ipp:519: undefined reference to `[email protected]'
obj\Debug\server\CGameHandler.o: In function `_ZN13NewStructuresC1Ev':
D:/projects/vcmi/engine/server/../lib/NetPacks.h:630: undefined reference to `vtable for NewStructures'
obj\Debug\server\CGameHandler.o: In function `_ZN13NewStructuresD1Ev':
D:/projects/vcmi/engine/server/../lib/NetPacks.h:628: undefined reference to `vtable for NewStructures'
collect2.exe: ошибка: выполнение ld завершилось с кодом возврата 1
Process terminated with status 1 (1 minutes, 52 seconds)
6 errors, 0 warnings

Yes I`ve done this to make it compiled.

There were some more issues (f.e. DLL_LINKAGE in functions defined in includes)

Thanks for info.

Hmm… try linking also against oleaut32.lib ( -loleaut32 )?

Remove “virtual” keyword from line 636 in lib/NetPacks.h

Likely. Since all Win devs (so far) used Visual Studio there may be a number of places where it’s assumed that Win==MSVC.
If you send us a patch correcting this, I’ll be happy to commit it. :slight_smile:

Of course patch will be sent :slight_smile: Should I send partial patch? (Before compilation fully succeeded.)

As you like. I guess depends on how much work remains to be done. :slight_smile:

It is required for MSVC, the only purpose of this file is generating a compilation unit that’ll be used as a PCH. For MinGW it is probably not needed.

Current TODO:

  1. Build SDL_xxx libs
  2. link client with them
  3. setup remaining release configurations
  4. cleanup configuration (may be use some macros)
  5. test how it works :slight_smile:

You don’t have to. SDL_xxx are C libraries and they are portable across the compilers.
Just extract the libs/includes from the MSVC libraries pack, they should work just fine:
[Besides, building SDL_mixer is pain, since SMPEG MP3 support has (had?) subtle bugs on Win32 and we use MAD library.]

Are you based on makefile or cmake system or does C::B has its own project build system?

OK, i`ll try this package.

cmake will be suitable for release engineering, now I use C::B itself - it is an IDE so it has build system (by the way, it can use not only MinGW but other toolchains too).

  1. Debug build succeeded ! (game works, tested by loading XXL random map)
  2. release (O2+) compilation still require some tweaks.
  3. there are some more warnings. (report them later)
  4. [todo] #pragma once in SdtInc.h should be removed at least for GCC
  5. ERM: casting template magic consume to much memory, such huge compilation units require about 2GiB RAM per core for multi-thread build.

Well done!

Is this a problem?
Though… I guess pragma once is not really needed since PCH is included exactly once in each compile unit.

Yeah, metaprogramming parser generator was not that good idea after all. :stuck_out_tongue:
ERM module is entirely optional (and not functional ATM), so if its compilation requirements are too much, it can be safely excluded from build.

GCC emits warning about it. But PCH itself works though. (I`ve added global option -Winvalid-pch to check this.) (?) duplicate such options in project files or add notes to upcoming manual about c::b configuration.

p/s. patch uploaded.

Thank you for the patch! :slight_smile:
I have following remarks:

CBattleAnimations.cpp — MSVC requires that first include in each compilation unit is exactly the “StdInc.h” (and not “…/StdInc.h”). If the relative path is absolutely needed for MinGW, I guess it should be #ifdefed (or just add project directory to includes path? how does it work on Linux?).

#define BOOST_THREAD_VERSION 3 => that may cause problems, it’s likely that we rely on the old ~thread behaviour (detach, not terminate).

CConsoleHandler.cpp => why crashdump creation doesn’t work on MinGW? It should, it’s just winapi.

CVideoHandler.cpp — I’m curious what’s about reducing scope of waveout? (btw, it can be reduced even more by moving declaration/initialization into if( … ).

I recently uploaded a new project — BattleAI. Could you also add C::B project for it?

If you’d be willing mantain C::B projects on a constant basis (ie. add/remove files from them, as VCMI develops), then I can you SVN access. Without that I’m afraid the projects will soon become out-of-date and eventually will be removed (long time ago we had C::B projects and that’s what happened :frowning: ).[/quote]

  1. BOOST_FILESYSTEM v3 really has new semantics, but there is advanced option to control it. I`m just now working on it. (coding is only one “define” :slight_smile: but recompilation after after changing global.h got about 30 min …) I think we should refactor to speedup compilation (f/e/ use external templates and explicit template instantiation. This is another theme to discuss though)

  2. crashdump depends on dbghelp library. This is not a part of mingw. I prefere not use external dependencies on MSSDK in addition to MinGW.

3)CVideoHandler.cpp old scope crosses switch labels (as I remember).

  1. BattleAI. I’ll maintain this project too (simply now there are more important tasks)

  2. I will maintain C::B workspace with MinGW port, but not Cmake with MnGW.

  3. relative path to StdInc was a mistake. I`ve changed include path, but not reverted this

Nice job! I expected more troubles from mingw than that.

In CMake project directory is explicitly included. Autotools does this by default I guess.

30 mins? Something is wrong here unless you have 10-years old CPU. For me full rebuild with gcc takes 7 minutes or just 4 minutes with clang.

What’s the problem with that? Linux-specifc section can be separated quite easily. In this way you won’t need updating CB files that often.

  1. In c::b add project directory to search path is configurable option. I desided to add “.” explicitly in search paths.

  2. I use quite old laptop. (Core duo 1.6GGz with 2 GB RAM)

  3. I never used cmake at all, I should look at it first before I can succeed cmake build. OTOH I prefer using IDEs, so will maintain project files anyway.

  1. My system isn’t new either (Dual-Core, overclocked to 3 GHz) but more than 4 times slower compilation? That’s weird.

Some IDE’s can import (or even use as it) CMake files, for some IDE’s CMake can generate project files. IDE and CMake are not mutually exclusive.

CMake is easy to use - two lines in command line or 3-4 clicks on GUI and compilation is done.

  • Note that I have to switch to compilation in one thread (see above about memory requirements). Now I removed ERM from workspace, and will use both cores again. (2x faster)
  • gcc under Mingw is slow, ld is slow for PE/COFF.

building itself is easy yes, but configuration is not so easy for me yet.

Round 2 :slight_smile: Now for 64 bit.

  1. Global.h is a monster. 300 MB pre-compiled header crashes gcc even on 64 bit host. (the PCH itself is compiled successfully, but using it cause crash)

  2. Are there updated libs (aka msvs-pack) for win64?

  3. some needed workarounds (not related to 64 bit)

-Wno-unused-local-typedefs - fix warning spam with new versions of boost
-fext-numeric-literals - fix compilation new versions of boost

-liconv fixes liniking “undefiner reference to getACP()” (some bug in mingw64 ?). workaround found on Stackoverflow, but no information what is exact source of a problem.

  1. VCMI_client debug build w|o any optimizations fail to assemble - too many sections.

to be continued …

Global.h is a monster. 300 MB pre-compiled header crashes gcc even on 64 bit host. (the PCH itself is compiled successfully, but using it cause crash) 

Our CMake build files don’t use PCH and on my PC I archieve a full rebuild (core, launcher, unit test) of VCMI in 2:30min using Clang as a compiler. I don’t know if it would be faster with PCH. Global.h includes a lot of header files, perhaps we could also include only the essential ones. Anyway I don’t know if using PCH is really that good.