Author Topic: How to compile Code::Blocks 20.03 in 32-bit mode with TDM-GCC  (Read 990 times)

Offline SiZiOUS

  • Single posting newcomer
  • *
  • Posts: 3
    • SiZiOUS :: Serial Koder
How to compile Code::Blocks 20.03 in 32-bit mode with TDM-GCC
« on: October 08, 2020, 10:02:22 pm »
Hello to all,

This is my first post here so let me introduce myself in summary,
I'm SiZiOUS, french hobbyist developer. I'm the author of the DreamSDK package, a project which provides a full environment for developing on Sega Dreamcast (an old video-game console released back in 1998) under Windows. This package supports Code::Blocks as the default IDE so that's why I'm here... ;)

I did a special version of the 17.12 release (which can be found here) in order to add some features to Code::Blocks, including, but not limited to:
  • New compiler/options file (dc-gcc) which specify the GNU GCC Compiler for Sega Dreamcast compiler.
  • The compiler and debugger plugins have been patched to run a loader before running the target.
  • The Sega Dreamcast Project (dc) wizard template has been added (Note: a new sdk (codeblocks.dll) module is needed to expose the required CallHooks function in the Squirrel script, that's why almost all compiled binaries are provided in the generated patch).

I want to port my changes from the 17.12 to the 20.03 release but the difficulty here is the 20.03 release is available in both 32-bit and 64-bit targets. I've successfully compiled the 64-bit release using TDM-GCC-64 (based on MinGW-w64 project) but for the 32-bit release is much more difficult.

Indeed, building the 32-bit release is made with TDM-GCC-64 too (with the -m32 switch) because the TDM-GCC-32 is too old (based on the original MinGW.org project) and doesn't support some features needed by C::B. I finally successfully compiled C::B 20.03 in 32-bit after digging on the whole process; the issue is when I start the compiled C::B 32-bit binary, it crashes immediately with the following Windows message:

Code: [Select]
0xC000007B STATUS INVALID IMAGE FORMAT
This kind of error is typically happening when a 32-bit process try to load a 64-bit dependency. The thing is, I don't know where the issue is located...

So my question is simple, what is the process for building a working C::B 20.03 release for 32-bit under Windows?

Thank you very much!

PS: I think that I will commit my changes to the official trunk if you think these useful.

Offline sodev

  • Regular
  • ***
  • Posts: 407
Re: How to compile Code::Blocks 20.03 in 32-bit mode with TDM-GCC
« Reply #1 on: October 08, 2020, 10:29:04 pm »
Is there any specific reason why you are using the TDM-GCC toolchain? I am using the plain MinGW-w64 builds from the official site and both architectures build without problem. Just don't forget to add the required DLL's to the output directory and you are good to go.

About your issue, how did you set the -m32 switch? At the global compiler settings level? Or on project level?

Offline stahta01

  • Lives here!
  • ****
  • Posts: 7018
    • My Best Post
Re: How to compile Code::Blocks 20.03 in 32-bit mode with TDM-GCC
« Reply #2 on: October 08, 2020, 11:33:27 pm »
Quote
what is the process for building a working C::B 20.03 release for 32-bit under Windows?

Use an 32 bit compiler is the first step!!

The option "-m32" does not work for any of the MinGW GCC 64 bit toolchains I know about!
Edit: The MinGW GCC 64 bit toolchains I know about are all missing the 32 bit libraries needed to build Code::Blocks.

Tim S.
« Last Edit: October 09, 2020, 01:25:34 am by stahta01 »
C Programmer working to learn more about C++ and Git.
On Windows 7 64 bit and Windows 10 32 bit.
On Debian Stretch, compiling CB Trunk against wxWidgets 3.0.
--
When in doubt, read the CB WiKi FAQ. http://wiki.codeblocks.org

Offline SiZiOUS

  • Single posting newcomer
  • *
  • Posts: 3
    • SiZiOUS :: Serial Koder
Re: How to compile Code::Blocks 20.03 in 32-bit mode with TDM-GCC
« Reply #3 on: October 11, 2020, 08:20:21 pm »
First of all, thanks for the answers :)

Is there any specific reason why you are using the TDM-GCC toolchain?
Because it was the recommanded toolchain at least for 17.12 release. Plus, the TDM-GCC-64 toolchain can compile both 32-bit and 64-bit binaries.

I am using the plain MinGW-w64 builds from the official site and both architectures build without problem. Just don't forget to add the required DLL's to the output directory and you are good to go.
Thank you for your tip! I've just installed MinGW-w64 and successfully built the 32-bit release of Code::Blocks, but there is some remaining issues:
  • I needed to build wxWidgets 3.1.3 with TDM-GCC-64 in both 32-bit and 64-bit flavour as I can't build that library under MinGW-w64... The windres utility included in the MinGW-w64 package can't find the main wx include dir. Which is wierd as it works with TDM-GCC-64...
  • When I build the C::B executable I need to copy some of the MinGW-w64 DLL in the same directory of the target C::B, but I think I need to put somewhere the -static switch... I guess...

About your issue, how did you set the -m32 switch? At the global compiler settings level? Or on project level?
In the C::B GCC Compiler definition, I've just checked the -m32 checkbox, then I added some additional parameters for windres (i.e. "-F pe-i386").

For information I'm using Boost 1.64 for 32-bit C::B (as I don't want to remove Windows XP support) and Boost 1.74 for 64-bit C::B. I've compiled these with TDM-GCC-64 too.

I found this forum thread but I'm not sure if it would help me... :(

Quote
what is the process for building a working C::B 20.03 release for 32-bit under Windows?

Use an 32 bit compiler is the first step!!
MinGW-w64 and TDM-GCC-64 are both 32-bit/64-bit toolchains... but maybe you're right, it isn't the best process to follow. :(

Edit: Now, with MinGW-w64, I have an issue with the 64-bit release of C::B :o The same error message as above. Of course, I changed the definition in the GCC Compiler to point to the mingw64 directory of my MinGW-w64 toolchain...  ???
« Last Edit: October 11, 2020, 08:26:41 pm by SiZiOUS »

Offline stahta01

  • Lives here!
  • ****
  • Posts: 7018
    • My Best Post
Re: How to compile Code::Blocks 20.03 in 32-bit mode with TDM-GCC
« Reply #4 on: October 12, 2020, 02:52:16 am »
Does the MinGW GCC toolchain have an i686-w64-mingw32 folder to match the x86_64-w64-mingw32 folder?

If not, then you are [likely] missing the 32 bit libraries needed to build any program that is very complex.

Edit: You are likely wanting an MinGW GCC built with "--enable-multilib".

Tim S.
« Last Edit: October 12, 2020, 10:30:46 am by stahta01 »
C Programmer working to learn more about C++ and Git.
On Windows 7 64 bit and Windows 10 32 bit.
On Debian Stretch, compiling CB Trunk against wxWidgets 3.0.
--
When in doubt, read the CB WiKi FAQ. http://wiki.codeblocks.org

Offline SiZiOUS

  • Single posting newcomer
  • *
  • Posts: 3
    • SiZiOUS :: Serial Koder
Re: How to compile Code::Blocks 20.03 in 32-bit mode with TDM-GCC
« Reply #5 on: October 15, 2020, 11:03:08 pm »
Hello there,

Finally, I successfully compiled C::B 20.03, in 32-bit and 64-bit mode using TDM-GCC-64. It was not straightforward at all. I got several issues for doing that.

First of all I'm still using TDM-GCC-64 but this applies on MinGW-w64 as well. Of course as you might know, TDM-GCC-64 is based on MinGW-w64 which can target both x86 and x64 binaries. I can't use TDM-GCC-32 because this one is based on the old MinGW project which is outdated (e.g. it doesn't include some required files like for enabling Direct2D) so using this project isn't an option. Despite of their names, MinGW and MinGW-w64 are completely separated projects.

So my initial issue was, when I was compiling C::B 20:03 in 32-bit mode from my Windows 7 x64 VM, all the produced x86 binaries were showing the following error: STATUS_INVALID_IMAGE_FORMAT (0xc000007b). As I stated from the beginning, this issue was caused when 32-bit binaries try to load 64-bit libraries. But I didn't understand why this happened... until now.

I noticed after that some compiled 32-bit binaries ... were actually working. These binaries were the one with no embedded resources (i.e. compiled with windres). So when I explored in deep the resources of these executables, I saw the issue: the manifest embedded in the executables were forcing the compiled 32-bit binaries to load 64-bit libraries...

So after investigating a lot, I saw that the generated rcdefs.h file when compiling wxWidgets was wrong. The WX_CPU_AMD64 directive was incorrectly added in the file... because my OS is actually a x64 OS. That's the reason why the x64 manifest was added to x86 binaries.

The fun fact is, I was using the wx 3.1.3, and this bug has been fixed in 3.1.4... as you may see here. So I fixed my working copy of wx 3.1.3 with the provided patch in that ticket and now, I got the WX_CPU_X86 define in the rcdefs.h so it's OK.

So, it was working for all the produced 32-bit binaries except... C::B itself. Pretty confusing... because for all produced binaries it was working but C::B still embed the x64 manifest!

So I've checked the codeblocks/src/src/resources/resources.rc file and then I saw this:

Code: Javascript
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // Specify the processor architecture (wxWidgets seems not to do this correctly)
  3. #if defined(_M_AMD64)
  4.   #if  defined(WX_CPU_X86)
  5.     #undef WX_CPU_X86
  6.   #endif
  7.   #if !defined(WX_CPU_AMD64)
  8.     #define WX_CPU_AMD64
  9.   #endif
  10. #elif defined(_M_IA64)
  11.   #if  defined(WX_CPU_X86)
  12.     #undef WX_CPU_X86
  13.   #endif
  14.   #if !defined(WX_CPU_IA64)
  15.     #define WX_CPU_IA64
  16.   #endif
  17. #elif defined(_M_IX86) || defined(_X86_)
  18.   #if !defined(WX_CPU_X86)
  19.     #define WX_CPU_X86
  20.   #endif
  21. #endif
  22.  

Like the first comment say here, it's perfectly true. When using windres, the WX_CPU_AMD64 value was still used, even if the WX_CPU_X86 define was put in rcdefs.h! But even worse, the C::B team integrated the code above which create that double issue (I mean: the original, failback rcdefs.h was computing the WX_CPU_AMD64 define incorrectly since my OS is x64, and the C::B team added a copy of this detection on this resource.rc file).

Then after come the second fix: the include order was actually wrong defined in the projects. In fact, the rcdefs.h file is generated when compiling wx but there is a failback rcdefs.h file in the "include" directory. Because of this, the wrong rcdefs.h file was used which defined WX_CPU_AMD64 for my x86 wx binary, instead of WX_CPU_X86.

So I needed to change on all C::B projects the include order to fix that.

As you might see here, the highlighted row should be set before the standard wx include dir in order to take into account the generated rcdefs.h file. So just use the top arrow button on the right to switch the order of includes.

After that, I setup a new GCC Compiler with my x86 switches (i.e. the famous -m32 switch). And now, I'm able to compile both x86 and x64 C::B 20.03 release from my Windows x64 computer.

If you are interested I can write a how-to telling all the steps for compiling C::B in both x86 and x64 flavours using TDM-GCC-64.

Offline stahta01

  • Lives here!
  • ****
  • Posts: 7018
    • My Best Post
Re: How to compile Code::Blocks 20.03 in 32-bit mode with TDM-GCC
« Reply #6 on: October 16, 2020, 07:48:03 am »
So, you succeeded, that is good. I wonder whether in a year or two you will considered it a useful use of your time.
Me, I would likely have taken the easy route of using an MinGW64 GCC 32 bit build.

Tim S.
 
C Programmer working to learn more about C++ and Git.
On Windows 7 64 bit and Windows 10 32 bit.
On Debian Stretch, compiling CB Trunk against wxWidgets 3.0.
--
When in doubt, read the CB WiKi FAQ. http://wiki.codeblocks.org