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

Offline SiZiOUS

  • Single posting newcomer
  • *
  • Posts: 6
    • 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
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: 427
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?

Online stahta01

  • Lives here!
  • ****
  • Posts: 7108
    • 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: 6
    • 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 »

Online stahta01

  • Lives here!
  • ****
  • Posts: 7108
    • 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: 6
    • 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
///////////////////////////////////////////////////////////////////////////////
// Specify the processor architecture (wxWidgets seems not to do this correctly)
#if defined(_M_AMD64)
  #if  defined(WX_CPU_X86)
    #undef WX_CPU_X86
  #endif
  #if !defined(WX_CPU_AMD64)
    #define WX_CPU_AMD64
  #endif
#elif defined(_M_IA64)
  #if  defined(WX_CPU_X86)
    #undef WX_CPU_X86
  #endif
  #if !defined(WX_CPU_IA64)
    #define WX_CPU_IA64
  #endif
#elif defined(_M_IX86) || defined(_X86_)
  #if !defined(WX_CPU_X86)
    #define WX_CPU_X86
  #endif
#endif

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.

Online stahta01

  • Lives here!
  • ****
  • Posts: 7108
    • 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

Offline SiZiOUS

  • Single posting newcomer
  • *
  • Posts: 6
    • SiZiOUS :: Serial Koder
Re: How to compile Code::Blocks 20.03 in 32-bit mode with TDM-GCC
« Reply #7 on: December 28, 2020, 06:46:16 pm »
Hello,

So I did have some troubles by using the TDM-GCC compiler for building Code::Blocks 64-bit (everything is fine with 32-bit).
Indeed, when compiling in 64-bit flavour with TDM-GCC-64 (as it should be), all the wx produced programs just crashes at the exit directly in the wx runtime library.
I did post a subject on the wxWidgets library forum and now it works.

In summary, what I did for recompiling the Code::Blocks 20.03 source code for Windows, on both 32-bit and 64-bit flavours:
  • I fixed the C::B source code like I described in this thread (important).
  • I did some bug fixes in the wx 3.1.3 library (back-porting some changes from 3.1.4 to 3.1.3).
  • Then I compile the project:
    • For 32-bit: I use TDM-GCC-64 with the -m32 switch like described here (Why? TDM-GCC-32 uses MinGW.org toolchain as base and this project is outdated, it doesn't includes some recent headers like the one for enabling Direct2D; when TDM-GCC-64 is based on MinGW-w64 and it includes everything needed)
    • For 64-bit: I use the Nuwen 16.1 toolchain. Don't try to use a more recent Nuwen toolchain, OR if you do so, you have to migrate the wx library from 3.1.3 to 3.1.4.
If you are curious, this is my repository which contains everything for building a working copy of C::B 20.03 on Windows, on both 32-bit and 64-bit releases. This repo includes some addition I made as my C::B release is improved for supporting the Sega Dreamcast platform.

Online oBFusCATed

  • Developer
  • Lives here!
  • *****
  • Posts: 13232
    • Travis build status
Re: How to compile Code::Blocks 20.03 in 32-bit mode with TDM-GCC
« Reply #8 on: December 28, 2020, 07:50:51 pm »
@SiZiOUS: I'm not sure what is the goal of your post, but if you want to contribute changes to codeblocks it is best to post patches in https://sourceforge.net/p/codeblocks/tickets/ (starting pull requests on my repo in github is also acceptable). I've skimmed the wxwidgets topic and I didn't see anything looking like a patch.
(most of the time I ignore long posts)
[strangers don't send me private messages, I'll ignore them; post a topic in the forum, but first read the rules!]