Building and running C++ executables in WSL2 using MinGW requires explicit configuration because the Windows Subsystem for Linux does not natively execute Windows binaries. You must configure the /etc/wsl.conf file to enable interop, ensure the executable is in the path, and launch it from the Linux shell or via a direct call to wsl.exe.
Understanding WSL2 Interoperability
A common misconception is that WSL2 uses Wine to run Windows applications. This is incorrect. WSL2 utilizes a binary translation layer known as interop. This feature allows Linux processes to directly invoke Windows executables, such as those compiled with MinGW, without an emulator. However, this interoperability is disabled by default in many configurations to prevent accidental execution of Windows binaries within the Linux environment, which can cause confusion regarding file paths and permissions. To build and run C++ code effectively, you must explicitly enable this feature.Configuring /etc/wsl.conf
The primary step involves editing the/etc/wsl.conf file inside your Debian distribution. This file controls how WSL interacts with the host Windows system. If the file does not exist, you can create it using a text editor like nano or vim.
Open the terminal in your WSL2 Debian instance and edit the configuration file:
sudo nano /etc/wsl.conf
Add the following section to the file:
[interop]
enabled=true
appendWindowsPath=false
The enabled=true setting turns on the ability to run Windows executables from the Linux shell. The appendWindowsPath=false option is crucial; it prevents WSL from automatically adding Windows directories to the Linux $PATH. Adding Windows paths to the Linux $PATH often leads to conflicts where Windows commands (like type or dir) shadow legitimate Linux utilities, causing build scripts to fail unpredictably. After saving the file, you must restart the WSL instance for changes to take effect. Run the following command in PowerShell:
wsl --shutdown
Then restart your Debian session.
Installing MinGW in Debian
Once interop is configured, you need a cross-compiler that generates Windows PE (Portable Executable) binaries instead of ELF (Executable and Linkable Format) binaries standard to Linux. In Debian, this package is typicallymingw-w64.
Update your package lists and install the compiler:
sudo apt update
sudo apt install mingw-w64
This installation provides both 32-bit (i686-w64-mingw32) and 64-bit (x86_64-w64-mingw32) compilers. For most modern applications, you will use the 64-bit variant. Verify the installation by checking the version of the cross-compiler:
x86_64-w64-mingw32-g++ --version
If this command returns a version number, your toolchain is ready. Note that the compiler name differs from the standard Linux g++. Using g++ will compile Linux binaries, while x86_64-w64-mingw32-g++ compiles Windows binaries.
Compiling and Running the Code
Create a simple test file namedmain.cpp:
#include <iostream>
int main() {
std::cout << "Hello from WSL2 MinGW!" << std::endl;
return 0;
}
Compile this file using the MinGW cross-compiler:
x86_64-w64-mingw32-g++ -o main.exe main.cpp
This command produces a main.exe file in your current directory. Because we enabled interop in /etc/wsl.conf, you can now run this executable directly from the Linux shell:
./main.exe
WSL2 will translate this call, locate the Windows subsystem, and execute the binary. The output will appear in your Linux terminal window. Alternatively, you can launch the executable from Windows PowerShell or Command Prompt if you navigate to the shared drive location (usually /mnt/c/Users/YourName/...).
Troubleshooting Missing DLLs
A frequent issue when running MinGW-compiled binaries is missing dynamic link libraries (DLLs). MinGW links againstlibgcc_s_seh-1.dll and libstdc++-6.dll by default. If these are not present in the same directory as your executable or in the Windows PATH, the program will fail to start with an error about missing modules.
To resolve this, you can copy the required DLLs from the MinGW installation directory (typically /usr/x86_64-w64-mingw32/lib/) to your project folder. Or, you can statically link the libraries during compilation by adding the -static-libgcc and -static-libstdc++ flags:
x86_64-w64-mingw32-g++ -o main.exe main.cpp -static-libgcc -static-libstdc++
Static linking increases the size of your executable but ensures it runs on any Windows machine without needing additional library files.
Best Practices for Development
When developing C++ projects that target Windows from WSL2, consider the following best practices to maintain a clean workflow. First, always use absolute paths or properly mapped symlinks when accessing files between the Linux and Windows filesystems. While WSL2 can access Windows files via/mnt/c/, performance is significantly better when working within the native Linux filesystem (/home/). Therefore, keep your source code in /home/ and only move the final executable to a Windows-accessible location if needed for testing outside WSL.
Second, be aware that graphical user interface (GUI) applications compiled with MinGW may not display correctly if you are using a headless WSL2 instance or a remote SSH connection. GUI apps require a Windows X server or WSLg. For command-line tools, however, the setup described above is fully sufficient. For more complex setups involving GUI dependencies, see our guide on Building Linux GUI Applications in WSL using GCC/Clang and Running Command Prompt.
Finally, remember that debugging MinGW executables requires a Windows-compatible debugger. Standard GDB in WSL2 cannot debug Windows PE binaries directly. You should use Visual Studio Debugger or WinDbg on the Windows side, attaching to the process launched from WSL.
Frequently Asked Questions
Why does my executable say "Permission denied" in WSL?
This usually occurs because the file was created on the Windows side and lacks Unix executable permissions. You can fix this by running chmod +x main.exe in the Linux shell before attempting to run it.
Can I use Clang instead of GCC for MinGW compilation?
Yes, WSL supports clang with MinGW targets. Install the clang package and use x86_64-w64-mingw32-clang++ as the compiler command, following the same linking principles as GCC.
How do I handle large files when compiling?
If you encounter disk space issues during compilation, check your WSL2 virtual hard disk usage. Refer to Failed to Reclaim Disk Space using WSL -- Manage Ubuntu -- set-sparse false for tips on managing storage efficiently.
Does enabling interop slow down WSL2?
Enabling interop has negligible impact on performance for typical development tasks. It only activates when a Windows binary is explicitly called, so it does not affect native Linux operations or compilation times.
What if I get errors about missing headers?
Ensure you have installed the full mingw-w64 package, not just the base compiler. Some headers are located in subdirectories specific to the target architecture. Use apt-cache search mingw to find related development packages if specific libraries are missing.