How to cross-compile GRASS GIS for MS Windows

This page explains how to cross-compile portable GRASS GIS for MS Windows using these scripts.

See also How to compile GRASS GIS on MS Windows.

1   Building a cross-compiling environment using MXE

The very first step for any cross-compilation project is to set up a cross-compiling environment. I found the MXE (M cross environment) to be very easy to set up. However, some packages are slightly outdated. For example, GDAL is 2.2.4 and PROJ is 5.1.0, but GRASS still supports these versions.

# looks for the MXE root in ~/usr/local/src/mxe by default,
# but you can change this path here and in ~/.grassbuildrc later.
mkdir -p ~/usr/local/src
cd ~/usr/local/src

# download MXE in ~/usr/local/src/mxe
git clone

cd mxe

# build MXE packages required for GRASS GIS
echo MXE_TARGETS=x86_64-w64-mingw32.shared >
make cc blas bzip2 cairo fftw freetype gdal geos lapack netcdf libpng pthreads readline libgnurx sqlite tiff zstd proj

2   Compiling native GRASS GIS first

You need to compile native GRASS GIS first because many document files are generated by binary modules, but cross-compiled binaries cannot be executed.

mkdir -p ~/usr/local/src
cd ~/usr/local/src

# download the GRASS build scripts in ~/usr/local/src/grass-build-scripts
git clone

# download the GRASS source code in ~/usr/local/src/grass
git clone

cd grass-build-scripts

# copy ~/usr/local/src/grass-build-scripts/.grassbuildrc-example to ~/.grassbuildrc
cp .grassbuildrc-example ~/.grassbuildrc

# you can change paths in ~/.grassbuildrc, but this page will use the default ones
vi ~/.grassbuildrc

# build native GRASS

3   Cross-compiling GRASS GIS

# cross-compile GRASS for MS Windows
./ --mxe

# copy document files from the native build

# post-process the cross-compiled build;
# make sure to set up PYTHON_WINDIR in ~/.grassbuildrc correctly before running this script

Now, you should have the ~/usr/local/src/grass/dist.x86_64-w64-mingw32 directory ready to be deployed.

4   Installing GRASS GIS on MS Windows

# package the cross-compiled build

Now, move to your Windows machine and extract ~/usr/local/src/grass-build-scripts/ anywhere.

5   Installing Python 3.9

Install Python 3.9 anywhere with the Add Python 3.9 to PATH option checked. grass\grass.bat will try to detect python.exe automatically within PATH. If you don’t want to use the auto-detection feature for any reasons (python.exe not in PATH, multiple Python installations, or you just don’t like it), you can set GRASS_PYTHON in grass\grass.bat to override this feature. By default, this variable is set to C:\Python39\python.exe, but you don’t have to change it even if your Python is installed somewhere else. Python will still be detected as long as you checked the Add Python 3.9 to PATH option.

If you uncheck Install launcher for all users (recommended), it won’t require administrative rights.

Once Python is installed, open the cmd window and install required modules:

pip3 install six wxPython pywin39

If you want to make GRASS GIS portable with Python installed on the same external drive, you cannot rely on PATH or use a fixed drive letter. Use %~d0 for the changing drive letter in GRASS_PYTHON in grass\grass.bat. For example,

set GRASS_PYTHON=%~d0\Python39\python.exe

6   Starting GRASS GIS

You can start GRASS GIS by running grass\grass.bat. This package includes busybox64.exe as grass/etc/sh.exe and uses it as the default shell.

With busybox64.exe and Firefox as the default browser, g.manual fails with Your Firefox profile cannot be loaded. It may be missing or inaccessible. I tried to set GRASS_HTML_BROWSER to the full path of chrome.exe, but it didn’t work. Setting BROWSER to its full path according to the webbrowser manual worked. By default, these two paths are checked for chrome.exe:

  • C:/Program Files/Google/Chrome/Application/chrome.exe
  • C:/Program Files (x86)/Google/Chrome/Application/chrome.exe

7   Changing the default shell

To change the default shell from grass/etc/sh.exe to something else, define a new environment variable called GRASS_SH:

  1. Control Panel
  2. User Accounts
  3. Change my environment variables
  4. Add a new user variable GRASS_SH=powershell (your choice of a shell)
  5. Start grass.bat

If you just want to use cmd.exe as a shell, either define GRASS_SH=cmd or delete grass/etc/sh.exe.

8   Latest daily build

8.1   How to install it

  1. Extract this zip file anywhere including an external drive for portability
  2. Install Python 3.9 (see above)
  3. Run grass\grass.bat

8.2   Official daily builds

Please note that this build is not an official daily build from the GRASS GIS development team. It is my personal daily build packaged as a ZIP file using This script compiles the latest main branch of the official GRASS GIS repository.