How to compile for Windows on Linux with gcc/g++?

Learn how to compile for windows on linux with gcc/g++? with practical examples, diagrams, and best practices. Covers c++, opengl, gcc development techniques with visual explanations.

Cross-Compiling for Windows on Linux with GCC/G++

Hero image for How to compile for Windows on Linux with gcc/g++?

Learn how to set up a MinGW-w64 cross-compilation environment on Linux to build Windows executables using GCC/G++, including OpenGL and GLUT/FreeGLUT applications.

Developing applications for Windows while working on a Linux system can be a common requirement, especially for cross-platform projects or when targeting specific Windows APIs. This article guides you through setting up a cross-compilation toolchain using MinGW-w64 on Linux, enabling you to compile C and C++ code, including graphics applications with OpenGL and GLUT/FreeGLUT, directly for Windows.

Understanding Cross-Compilation with MinGW-w64

Cross-compilation is the process of compiling code on one platform (the host) to run on another platform (the target). For compiling Windows executables on Linux, MinGW-w64 is the de facto standard. MinGW-w64 (Minimalist GNU for Windows 64-bit) provides a complete GCC toolchain that targets Windows, including compilers (gcc, g++), binutils, and Windows API headers and libraries. It supports both 32-bit and 64-bit Windows targets.

flowchart TD
    A[Linux Host System] --> B{MinGW-w64 Toolchain}
    B --> C[Source Code (.c/.cpp)]
    C --> D[Compilation Process]
    D --> E[Windows Executable (.exe)]
    E --> F[Windows Target System]
    B --"Provides"--> G[Windows Headers & Libraries]
    G --"Linked during"--> D

Cross-Compilation Workflow from Linux to Windows

Setting Up the MinGW-w64 Toolchain on Linux

The first step is to install the MinGW-w64 toolchain on your Linux distribution. The package names might vary slightly depending on your distribution, but the core components remain the same. You'll typically look for packages like mingw-w64, gcc-mingw-w64, g++-mingw-w64, and their associated development files.

Debian/Ubuntu

sudo apt update
sudo apt install mingw-w64

This command installs the necessary compilers and development files for both 32-bit and 64-bit Windows targets.

Fedora

sudo dnf install mingw64-gcc mingw64-gcc-c++

This will install the 64-bit cross-compilers. For 32-bit, you might need mingw32-gcc and mingw32-gcc-c++.

Arch Linux

sudo pacman -S mingw-w64-gcc

Arch Linux typically provides a single package that includes both 32-bit and 64-bit toolchains.

Compiling a Basic C++ Application for Windows

Once the toolchain is installed, compiling a simple C++ application is straightforward. You just need to invoke the correct cross-compiler.

// main.cpp
#include <iostream>

int main() {
    std::cout << "Hello from Windows (compiled on Linux)!" << std::endl;
    return 0;
}
# Compile for 64-bit Windows
x86_64-w64-mingw32-g++ main.cpp -o hello_windows_64.exe

# Compile for 32-bit Windows
i686-w64-mingw32-g++ main.cpp -o hello_windows_32.exe

Compiling OpenGL and GLUT/FreeGLUT Applications

Compiling graphical applications that use OpenGL and GLUT/FreeGLUT requires linking against the appropriate Windows libraries. MinGW-w64 includes the necessary headers and stub libraries for OpenGL (via opengl32.lib and gdi32.lib). For GLUT or FreeGLUT, you'll need to obtain the Windows-compatible .lib and .dll files and their corresponding headers.

1. Obtain FreeGLUT for MinGW-w64

Download pre-compiled FreeGLUT binaries for MinGW-w64. You can often find these on the FreeGLUT website or through package managers if available (e.g., mingw-w64-freeglut on Arch Linux). Extract the include directory (for headers) and the lib directory (for .a and .lib files) to a known location, or directly into your MinGW-w64 installation's x86_64-w64-mingw32/include and x86_64-w64-mingw32/lib directories.

2. Write your OpenGL/FreeGLUT code

Create your C++ source file, for example, opengl_cube.cpp, including FreeGLUT headers and using OpenGL functions.

3. Compile the application

Use the cross-compiler and link against opengl32, gdi32, and freeglut (or glut32 if using GLUT). You might need to specify the path to your FreeGLUT libraries using -L and headers using -I if they are not in the default MinGW-w64 paths.

// opengl_cube.cpp
#include <GL/freeglut.h>
#include <GL/gl.h>

void display() {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();
    glTranslatef(0.0f, 0.0f, -5.0f);
    glRotatef(45.0f, 1.0f, 1.0f, 0.0f);
    glutWireCube(2.0f);
    glutSwapBuffers();
}

void reshape(int w, int h) {
    glViewport(0, 0, w, h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(60.0, (double)w / (double)h, 1.0, 100.0);
    glMatrixMode(GL_MODELVIEW);
}

int main(int argc, char** argv) {
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
    glutInitWindowSize(800, 600);
    glutCreateWindow("OpenGL Cube");
    glutDisplayFunc(display);
    glutReshapeFunc(reshape);
    glEnable(GL_DEPTH_TEST);
    glutMainLoop();
    return 0;
}
# Assuming FreeGLUT headers are in /usr/x86_64-w64-mingw32/include/GL
# and libraries are in /usr/x86_64-w64-mingw32/lib

x86_64-w64-mingw32-g++ opengl_cube.cpp -o opengl_cube.exe \
    -I/usr/x86_64-w64-mingw32/include \
    -L/usr/x86_64-w64-mingw32/lib \
    -lfreeglut -lopengl32 -lgdi32 -Wl,--subsystem,windows

# If FreeGLUT is in a custom path, e.g., ~/freeglut-mingw-w64/lib
# x86_64-w64-mingw32-g++ opengl_cube.cpp -o opengl_cube.exe \
#     -I~/freeglut-mingw-w64/include \
#     -L~/freeglut-mingw-w64/lib \
#     -lfreeglut -lopengl32 -lgdi32 -Wl,--subsystem,windows

Deployment Considerations

When deploying your compiled Windows executable, remember that it might depend on certain DLLs that are not present by default on all Windows systems. For FreeGLUT applications, you will typically need to distribute the freeglut.dll (or glut32.dll) alongside your .exe file. You can find this DLL in the bin directory of your MinGW-w64 FreeGLUT distribution.

Hero image for How to compile for Windows on Linux with gcc/g++?

Deployment of a Windows executable with FreeGLUT DLL