Skip to content

feat(build): Add Docker-based Linux build using Wine and MSVC 2022#389

Merged
x64-dev merged 1 commit intoGeneralsOnlineDevelopmentTeam:mainfrom
bill-rich:go_linux_builder
Mar 20, 2026
Merged

feat(build): Add Docker-based Linux build using Wine and MSVC 2022#389
x64-dev merged 1 commit intoGeneralsOnlineDevelopmentTeam:mainfrom
bill-rich:go_linux_builder

Conversation

@bill-rich
Copy link

Summary

Add a Docker build system that compiles the game on Linux using Wine and
MSVC Build Tools, producing Windows executables equivalent to native
VS2022 builds.

Currently builds Zero Hour only (z_generals / GeneralsMD). The
original Generals (g_generals) was skipped because shared Core/
headers which include Zero Hour-specific files.

Files

  • scripts/docker-build-msvc.sh — Host-side build script with
    --target, --clean, --cmake, and --interactive options
  • resources/dockerbuild-msvc/Dockerfile — Container image with Wine,
    MSVC 2022 (via msvc-wine), Windows CMake, Ninja, and Git
  • resources/dockerbuild-msvc/entrypoint.sh — Build orchestration
    inside the container
  • CMakePresets.json — New msvc-wine preset for the Wine build
  • GeneralsMD/Code/Main/RTS.RC — Replace afxres.h with winresrc.h

Why some of this looks hacky

sed path fixups on build.ninja (entrypoint.sh lines 89-103):
CMake runs as a Windows executable under Wine and generates Unix-style
paths (/build/cnc/...) for MSVC flags like /FI, /Yc, /Fp, and
source file arguments. MSVC executables running under Wine need Z:
drive-prefixed paths to resolve correctly. CMake has no built-in
mechanism to add drive letter prefixes in a cross-Wine scenario, so
post-processing build.ninja with sed is the most reliable approach.
An alternative would be a compiler wrapper script that translates paths
at invocation time, but that adds per-compilation overhead and is harder
to debug. The CMake regeneration rule is also removed so Ninja doesn't
overwrite the fixed paths on incremental builds.

WindowsKits symlink (entrypoint.sh lines 38-44):
The Windows SDK installs to a directory named Windows Kits (with a
space). When CMake under Wine resolves this path, the Windows API
returns 8.3 short filenames (e.g. WIND~2DP) because of the space.
Wine's Z: drive maps directly to the Linux filesystem, which has no
8.3 short name support, so these paths fail to resolve at build time.
A symlink (WindowsKitsWindows Kits) eliminates the space so 8.3
conversion never occurs. Renaming the directory was considered but could
break msvc-wine's own tooling that expects the canonical path.

RC compiler flags (entrypoint.sh lines 47-48, cmake line 82):
CMake doesn't automatically pass Windows SDK include paths to rc.exe
in this cross-compilation scenario. CMAKE_RC_FLAGS adds the necessary
-I flags so the resource compiler can find system headers.

afxres.hwinresrc.h (RTS.RC):
The original afxres.h is an MFC header that requires the MFC
component of Visual Studio. The game itself does not use MFC — only
standalone editor tools (ParticleEditor, W3DView) do. The afxres.h
include was a default from Microsoft Developer Studio's auto-generated
RC template. winresrc.h is part of the standard Windows SDK and
provides the same resource compiler defines needed here.

Hardcoded MSVC/SDK versions (entrypoint.sh lines 14-15):
The MSVC toolset version (14.50.35717) and SDK version
(10.0.26100.0) are hardcoded to match what msvc-wine/vsdownload.py
currently installs. A future improvement would be to auto-detect these
from the installed directory structure.

@x64-dev x64-dev merged commit a84d7b0 into GeneralsOnlineDevelopmentTeam:main Mar 20, 2026
5 checks passed
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.

2 participants