Skip to content

Conversation

@JohnsterID
Copy link

@JohnsterID JohnsterID commented Jan 6, 2026

Enables buidling g_generals and z_generals with MinGW-w64 (GCC) i686.

Related to previous work in #547, #670, #671, #672, #665.

Currently RC Resource Compilation disabled and also MFC Tools not supported.

TODO: Need to update dx8.cmake (6c3f32e) depending on the outcome of TheSuperHackers/min-dx8-sdk#4.

Debian/Ubuntu (Trixie or later):

# Install MinGW-w64 toolchain
sudo apt-get update
sudo apt-get install -y mingw-w64 cmake

# Install Wine and widl for COM interface generation
sudo dpkg --add-architecture i386
sudo mkdir -pm755 /etc/apt/keyrings
sudo wget -O /etc/apt/keyrings/winehq-archive.key https://dl.winehq.org/wine-builds/winehq.key
sudo wget -NP /etc/apt/sources.list.d/ https://dl.winehq.org/wine-builds/debian/dists/trixie/winehq-trixie.sources
sudo apt-get update
sudo apt-get install -y --install-recommends winehq-stable wine-stable-dev

Release build:

# Configure
cmake --preset mingw-w64-i686

# Build both games
cmake --build --preset mingw-w64-i686

# Or build specific targets
cmake --build build/mingw-w64-i686 --target g_generals    # Generals only
cmake --build build/mingw-w64-i686 --target z_generals    # Zero Hour only

Debug build:

cmake --preset mingw-w64-i686-debug
cmake --build --preset mingw-w64-i686-debug

Add cross-compilation support for building with MinGW-w64 (GCC) on Linux
targeting 32-bit Windows executables. This enables building Generals and
Zero Hour without requiring MSVC or Windows.

Core components:
- Toolchain file for i686-w64-mingw32 cross-compiler
- MinGW-specific compiler flags and library linking
- MSVC compatibility macros (__forceinline, __int64, _int64)
- Math constants (M_PI) required for C++ mode
- Windows library dependencies (ole32, d3d8, dinput8, etc.)
- d3dx8 library aliasing for MinGW compatibility

The toolchain forces 32-bit compilation, disables MFC-dependent tools,
and configures proper search paths for cross-compilation environment.

Build with: cmake -DCMAKE_TOOLCHAIN_FILE=cmake/toolchains/mingw-w64-i686.cmake

Files:
- cmake/toolchains/mingw-w64-i686.cmake: Cross-compilation toolchain
- cmake/mingw.cmake: MinGW-specific build configuration
- CMakeLists.txt: Include MinGW configuration when MINGW is detected
Add Wine IDL Compiler (widl) as a replacement for Microsoft's MIDL compiler
when building with MinGW-w64. This enables generation of COM interface code
from IDL files on Linux cross-compilation environments.

Features:
- Auto-detect widl executable (widl or widl-stable)
- Version detection and reporting
- Dynamic Wine include path detection via wineg++ preprocessor
- Configure Wine header paths for COM interface compilation
- Fallback to known Wine stable/development include paths
- IDL compilation function for generating headers and type libraries

The widl compiler generates compatible COM interface definitions required
for DirectX 8, Windows browser control, and other COM-based APIs used by
the game engine.

Files:
- cmake/widl.cmake: widl detection and configuration
- CMakeLists.txt: Include widl configuration for MinGW builds
Add ReactOS Active Template Library (ATL) support for MinGW-w64 builds,
enabling ATL/COM functionality without MSVC dependencies. This provides
the ATL headers needed for COM-based browser control integration.

Components:
- ReactOS ATL headers (v0.4.15) fetched from ReactOS project
- ReactOS PSEH (exception handling) in C++-compatible dummy mode
- ATL compatibility header with MinGW-specific macro definitions
- PSEH compatibility header ensuring proper exception handling

The implementation uses ReactOS PSEH in dummy mode (_USE_DUMMY_PSEH)
because MinGW-w64's native PSEH uses GNU C nested functions which are
incompatible with C++. This provides ATL functionality needed for:
- CComPtr and CComBSTR smart pointers
- ATL string conversion macros
- COM interface implementations

Files:
- cmake/reactos-atl.cmake: ReactOS ATL integration
- Dependencies/Utility/Utility/atl_compat.h: ATL compatibility layer
- Dependencies/Utility/Utility/pseh_compat.h: PSEH compatibility layer
- CMakeLists.txt: Include ReactOS ATL configuration
Add header-only implementation of COM support string conversion utilities
for MinGW-w64. These utilities are provided by comsuppw.lib in MSVC but
are not available in MinGW-w64's standard library.

Provides:
- _com_util::ConvertStringToBSTR(): Convert char* to BSTR
- _com_util::ConvertBSTRToString(): Convert BSTR to char*

These functions are essential for COM string handling in the browser
control integration and other COM-based APIs. The header-only approach
eliminates the need for linking against an external library and provides
a lightweight, portable solution compatible with both MSVC and MinGW-w64.

Implementation uses standard Windows APIs (SysAllocString, WideCharToMultiByte,
MultiByteToWideChar) to perform the conversions.

Files:
- Dependencies/Utility/Utility/comsupp_compat.h: COM string utilities
@JohnsterID JohnsterID force-pushed the mingw-w64-build branch 2 times, most recently from 34e4e3f to 7977965 Compare January 12, 2026 08:35
Update DirectX 8, Miles Sound System, and Bink Video SDK to versions with MinGW-w64 compatibility fixes.
Add MinGW-w64 detection and configure compiler flags to optimize build
output for cross-compilation:

- Detect MinGW-w64 compiler and set IS_MINGW_BUILD flag
- Skip debug symbols (-g) in MinGW Release builds to reduce executable size
  (MSVC Release builds already exclude debug info by default)
- Maintain debug symbols for MinGW Debug builds

This reduces the size of MinGW Release builds significantly while keeping
compatibility with MSVC build configurations. Debug builds still include
full debugging information for development.

Files:
- cmake/compilers.cmake: Add MinGW detection and conditional debug flags
Add configure, build, and workflow presets for MinGW-w64 32-bit (i686)
cross-compilation. Enables easy building with standardized configurations.

Presets:
- mingw-w64-i686: Release build (optimized, no debug symbols)
- mingw-w64-i686-debug: Debug build (with debugging symbols)
- mingw-w64-i686-profile: Profile build (optimized with profiling)

All presets:
- Use Unix Makefiles generator (as required for MinGW)
- Reference the mingw-w64-i686.cmake toolchain file
- Generate compile_commands.json for IDE integration
- Build to build/mingw-w64-i686 directory
- Include corresponding build and workflow presets

Usage:
  cmake --preset mingw-w64-i686
  cmake --build --preset mingw-w64-i686

Or use workflow preset:
  cmake --workflow --preset mingw-w64-i686

Files:
- CMakePresets.json: Add MinGW i686 configure/build/workflow presets
Include ATL compatibility layer in precompiled headers for both Generals
and Zero Hour to enable MinGW-w64 builds with ReactOS ATL support.

Changes:
- Include atl_compat.h before atlbase.h for GCC/MinGW builds
- Add pragma pop at end of header to restore warnings
- Conditional compilation ensures MSVC builds remain unchanged

The ATL compatibility header must be included before ATL headers to:
- Define _USE_DUMMY_PSEH for C++-compatible exception handling
- Configure ReactOS ATL include paths
- Disable problematic GCC warnings for ATL code
- Define ATL-specific macros for MinGW compatibility

This change enables CComPtr, CComBSTR, and other ATL functionality
in MinGW-w64 builds while maintaining full MSVC compatibility.

Files:
- Generals/Code/GameEngine/Include/Precompiled/PreRTS.h
- GeneralsMD/Code/GameEngine/Include/Precompiled/PreRTS.h
Update CMakeLists.txt files to fix library dependencies and ensure proper
linking for MinGW-w64 builds:

Core libraries:
- WW3D2: Add core_wwdebug, core_wwlib, core_wwmath dependencies
  Make comsuppw library MSVC-only (MinGW uses header-only comsupp_compat.h)
  Link WW3D2 libraries for core_wwdebug target
- WWMath: Add core_wwsaveload dependency
- GameEngine: Add widl support for browser control IDL compilation
- EABrowserDispatch/Engine: Include widl-generated headers

Game executables:
- Generals/GeneralsMD Main: Make NODEFAULTLIB and RC files MSVC-only
  (MinGW doesn't support /NODEFAULTLIB or .rc resource compilation via these paths)

These changes ensure:
- Proper link order and dependency resolution
- MSVC-specific features don't break MinGW builds
- COM interface code generation works with widl
- All required libraries are linked

Files:
- Core/GameEngine/CMakeLists.txt
- Core/Libraries/Source/EABrowserDispatch/CMakeLists.txt
- Core/Libraries/Source/EABrowserEngine/CMakeLists.txt
- Core/Libraries/Source/WWVegas/WW3D2/CMakeLists.txt
- Core/Libraries/Source/WWVegas/WWMath/CMakeLists.txt
- Generals/Code/Libraries/Source/WWVegas/WW3D2/CMakeLists.txt
- Generals/Code/Main/CMakeLists.txt
- GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/CMakeLists.txt
- GeneralsMD/Code/Main/CMakeLists.txt
Add comprehensive MinGW-w64 compatibility fixes to Core engine and library code:

Type definitions and compatibility (always.h, BaseTypeCore.h):
- Add __int64 and _int64 type definitions for MinGW
- Add NOMINMAX and min/max template handling
- Add __forceinline macro mapping

Calling conventions (wwstring, widestring, GameText, profile):
- Standardize Format() functions to __cdecl for cross-compiler compatibility
- Fix variadic macro handling for GCC
- Add explicit calling convention specifications where needed

Headers and forward declarations:
- Add missing forward declarations (WorldHeightMap.h, texture.h, textureloader.h)
- Fix include path case sensitivity (endian_compat.h, winsock.h)
- Include comsupp_compat.h before comutil.h for COM support

Compiler guards and compatibility:
- Guard MSVC SEH (MiniDumper.cpp) with _MSC_VER checks
- Guard inline assembly with compiler checks (debug_stack.cpp, debug_except.cpp)
- Add GCC inline assembly alternatives where needed
- Disable MSVC SEH for MinGW (thread.cpp, Except.cpp)

Linkage fixes:
- Remove inappropriate static qualifiers (W3DWaterTracks.cpp)
- Fix extern/static mismatches (missingtexture.cpp)
- Add explicit void* casts for function pointers

Includes and dependencies:
- Add stddef.h for size_t (wwmemlog.h)
- Add missing headers for MinGW compilation
- Fix COM browser header inclusion order

Audio and misc:
- Fix __stdcall in AudioEvents.h function pointer typedefs
- Fix volatile atomic operations (NoxCompress.cpp)
- Use portable sint64 types (wwprofile.cpp)

All changes are guarded with compiler checks to maintain MSVC compatibility.

Files: 31 Core library source and header files
Add forward declarations for PathfindCell and Anim2DCollection classes
to resolve MinGW-w64 compilation errors due to incomplete types.

MinGW-w64 is stricter about forward declarations than MSVC, requiring
explicit forward declarations for classes used in header files before
their first usage.

Files modified:
- Generals/Code/GameEngine/Include/GameLogic/AIPathfind.h
- Generals/Code/GameEngine/Include/GameClient/Anim2D.h
- GeneralsMD/Code/GameEngine/Include/GameLogic/AIPathfind.h
- GeneralsMD/Code/GameEngine/Include/GameClient/Anim2D.h
Adjust function and variable linkage to resolve MinGW-w64 linker errors:
- Remove 'static' from TheEvaMessageNames and TheShellHookNames arrays
  to allow external linkage when referenced from other translation units
- Remove 'static' from hLine* functions in PartitionManager that are
  passed as function pointers to external modules
- Add 'static' to messageBoxYes forward declaration in PopupPlayerInfo
  to match definition scope

MinGW-w64 is stricter about ODR (One Definition Rule) violations and
requires consistent linkage specifications across translation units.

Files modified:
- Eva.cpp: TheEvaMessageNames array
- Scripts.cpp: TheShellHookNames array
- PartitionManager.cpp: hLine* helper functions
- PopupPlayerInfo.cpp: messageBoxYes forward declaration
… macros

Fix calling convention compatibility issues for cross-compiler support:

1. Variadic Macro Handling:
   - Use ##__VA_ARGS__ extension in FETCH_OR_SUBSTITUTE_FORMAT macros
   - Allows format strings without arguments by removing preceding comma
     when __VA_ARGS__ is empty
   - Supported by both GCC/MinGW and modern MSVC (2015+)

2. Calling Convention Consistency:
   - Change compareLUT function from _cdecl to __cdecl
   - Ensures consistent calling convention syntax across compilers

These changes resolve MinGW-w64 compilation warnings and errors related
to variadic macro expansion and calling convention specifications.

Files modified:
- GameText.h: FETCH_OR_SUBSTITUTE_FORMAT macros
- GameText.cpp: compareLUT calling convention
…tackDump

Add cross-compiler support for register capture in stack trace functionality:

1. MSVC Support (existing):
   - Keep original __asm blocks for MSVC x86-32 builds

2. GCC/Clang Support (new):
   - Add GCC/Clang inline assembly using AT&T syntax
   - Capture EIP, ESP, EBP registers for stack unwinding
   - Only enabled for x86-32 architectures (__i386__ or _M_IX86)

3. Compiler Guards:
   - Use #if defined(_MSC_VER) for MSVC-specific code
   - Use #elif for GCC/Clang alternatives
   - Add #error directive for unsupported compilers/architectures

This enables MinGW-w64 to compile StackDump.cpp by providing GCC-compatible
inline assembly alternatives to MSVC's __asm syntax. The functionality
remains identical across compilers.

Files modified:
- Generals/Code/GameEngine/Source/Common/System/StackDump.cpp
- GeneralsMD/Code/GameEngine/Source/Common/System/StackDump.cpp
Replace lowercase min/max function calls with uppercase MIN/MAX macros
in RealRange::combine() method.

MinGW-w64 headers define min/max as macros in <windows.h>, which can
conflict with std::min/std::max and cause compilation issues. Using
the uppercase MIN/MAX macros (defined in BaseTypeCore.h) ensures
consistent behavior across compilers and avoids macro/function
name conflicts.

This change maintains compatibility with existing MSVC builds while
enabling successful MinGW-w64 compilation.

Files modified:
- Generals/Code/Libraries/Include/Lib/BaseType.h
- GeneralsMD/Code/Libraries/Include/Lib/BaseType.h
Add explicit void* casts to function pointers in function tables and
callback registrations to resolve MinGW-w64 type-punning warnings.

Changes:
1. FunctionLexicon.cpp:
   - Cast all GameWindow callback functions to (void*) in:
     * gameWinDrawTable
     * gameWinSystemTable
     * gameWinInputTable
     * gameWinHelpBoxTable
     * gameWinTooltipTable

2. W3DFunctionLexicon.cpp:
   - Cast all W3D callback functions to (void*) in lexicon tables

3. SkirmishGameOptionsMenu.cpp:
   - Cast aiPlayerControlCallback to (void*) in window registrations

MinGW-w64 requires explicit casts when storing function pointers with
different signatures in void* fields, as the compiler is stricter about
type safety than MSVC in this context. These casts are safe because the
functions are later cast back to their correct types before invocation.

Files modified:
- FunctionLexicon.cpp (both games)
- W3DFunctionLexicon.cpp (both games)
- SkirmishGameOptionsMenu.cpp (both games)
Remove static qualifiers from callback functions that are referenced
from other translation units to resolve MinGW-w64 linker errors.

Changes:
1. WOLBuddyOverlay.cpp:
   - Remove 'static' from insertChat() function

2. WOLLobbyMenu.cpp:
   - Remove 'static' from helper functions used across modules

3. W3DMainMenu.cpp:
   - Remove 'static' from menu callback functions

4. GameWindowTransitionsStyles.cpp:
   - Remove 'static' from transition style functions

MinGW-w64 enforces stricter linkage rules and requires functions
referenced externally to have external linkage.

Files modified:
- WOLBuddyOverlay.cpp (both games)
- WOLLobbyMenu.cpp (both games)
- W3DMainMenu.cpp (both games)
- GameWindowTransitionsStyles.cpp (both games)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant