Skip to main content

Command Palette

Search for a command to run...

The "Warf" Way: Seamless Windows Testing on Linux using MinGW & Wine

Published
3 min read
The "Warf" Way: Seamless Windows Testing on Linux using MinGW & Wine
F
Software developer with experience in security, graphics, and compilers.

In the world of language development, even a "toy" language needs a solid foundation. My project, warfLang, isn't trying to replace C++ or Rust. It’s an LL(1) parser written in C++ that generates an Abstract Syntax Tree (AST)—essentially a glorified calculator that supports variable definitions.

warflang logo

But even a calculator needs to count correctly on every platform. To ensure warfLang remains truly cross-platform, I needed a CI/CD pipeline that could verify its logic on Windows without the overhead of actually owning a Windows machine.

The Problem: Cross-Platform Logic is Tricky

Even for a high-level parser, moving from Linux to Windows introduces subtle behavioral risks and differences especially when you are compiling acros different compilers like CL, Clang, and GCC or different libC implementations.

Inspired by Gianni Milanesi’s post, I realized I didn't need a native Windows environment to find out. I just needed a containerized "Build Appliance."

Note this post will not be the promised part 5 of the Cross-Compiling series since we are using mingw-w64 and not clang.

The "Warf" Solution: Dockerizing the Toolchain

Instead of manually managing cross-compilers, I use a custom Dockerfile Dockerfile.mingw-cross. This encapsulates the entire MinGW-w64 suite, ensuring that the environment where I build warfLang today is the exact same one I'll use six months from now.

Why Docker makes it easy:

  1. Zero Setup: A new contributor doesn't need to install binutils-mingw-w64. They just run the container.

  2. Consistency: It's a container, it always the works the same thats the point.

  3. The "Magic" Compiler: We get instant access to x86_64-w64-mingw32-gcc, which treats our C++ code as a native Windows project.

FROM ubuntu:latest
  
# Install MinGW for building and Wine for testing
RUN apt-get update && apt-get install -y \
 mingw-w64 \
 cmake \
 wine \
 && rm -rf /var/lib/apt/lists/\*

...

RUN cmake -S . -B build \
 -GNinja -DCMAKE\_BUILD\_TYPE=Release \
 -DCMAKE\_C\_COMPILER=x86\_64-w64-mingw32-gcc-posix \
 -DCMAKE\_CXX\_COMPILER=x86\_64-w64-mingw32-g++-posix \
 -DBuildTest=TRUE \
 -DCMAKE\_SYSTEM\_NAME=Windows -DCMAKE\_CROSS\_COMPILING=TRUE

Bundling Wine: Testing the Calculator

The real value of the "Warf" way is the inclusion of Wine. For a project like warfLang , testing is straightforward: I feed the parser an expression (like x = 5; x * 2;), and I expect a specific AST output. By bundling Wine in the Docker image, I can run the Windows version immediately after compiling it without having to context switch to a new device. This works the same on my local dev machines as well as in the CI.

Why this is vital for a "Toy" Language:

  • It isn't: but it is fun 😂!
  • Headless Validation: The real reason I did this no context switching for testing cross plat. Using wine ./warf_tests.exe in a headless Docker container gives me instant feedback if something works on windows without having to have a dedicated windows device.

Leveraging GitHub Actions

By using this crossPlat builder approach, my GitHub Actions workflow is faster and cheaper (see runner pricing). I pull a single Linux-based image, build the Windows .exe file, and run the test suite through Wine.

Runner prices

When I see the "Green Checkmark" now it proves that the "calculator" works on Windows, even though it was born and raised on Linux.

Conclusion

Whether you're building a massive compiler or a glorified calculator like warfLang , the "Warf" way combining Docker, MinGW, and Wine provides a professional, reproducible, and verifiable way to ship to Windows users without ever leaving the comfort of Linux.

Check out the implementation and play with the parser in the WarfLang WASM demo.

First published 4/19/26 on blog.farzon.org

The "Warf Way": Headless Cross-Platform C++ Development

Part 2 of 2

This series explores how to build a seamless, fully containerized CI/CD pipeline for C++ projects without ever leaving Linux. By wrapping toolchains and translation layers like MinGW, Wine, osx-cross, and Darling inside Docker, "The Warf Way" demonstrates how to compile and execute Windows and macOS binaries from a single environment. Learn how to eliminate context switching, drop expensive dedicated CI hardware, and guarantee reproducible builds across your entire development lifecycle.

Start from the beginning

The "Warf" Way Part II: Tackling the macOS Frontier with osx-cross and Darling

In my last post, The Warf Way: Seamless Windows Testing we looked at how to streamline Windows testing by leveraging Docker and Wine. It provided a seamless way to validate Windows-specific logic with

More from this blog