Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
d26e879
win: Update MSVC runtime archive and run g.mkfontcap after runtime in…
wenzeslaus Jul 12, 2026
6e0df5e
CI: Build the Windows standalone installer
wenzeslaus Jul 12, 2026
718f23c
Merge branch 'main' into fix-msvc-runtime-dll-sizes
echoix Jul 12, 2026
2cf5988
CI: Regenerate fontcap before installing GRASS for the Windows installer
wenzeslaus Jul 13, 2026
0b77028
packaging: Add GRASS_PYDIR in env.bat.tmpl to correct windows install…
echoix Jul 14, 2026
7674408
tests: Migrate r.null tests from gunittest to pytest (#7675)
Valyrian-Code Jul 12, 2026
c9fb63a
g.md2man: Expand tests on other cases (#7679)
echoix Jul 13, 2026
bc917ab
docs: Reduce Sphinx build warnings and fix broken links (#7526)
neteler Jul 13, 2026
04af378
temporal: allow STDS object construction without initialized database…
ninsbl Jul 13, 2026
fc8c537
r.reclass.area: add upper and lower option and rewrite with Tools API…
ninsbl Jul 13, 2026
624a2ef
CQ: Fix CodeQL issues "Incorrect return-value check for a 'scanf'-lik…
echoix Jul 13, 2026
7fc7cdb
CI: Set OMP_NUM_THREADS=1 for tests run in parallel (#7680)
echoix Jul 13, 2026
636c1f8
r3.out.vtk: Fix typo in translated string (#7685)
echoix Jul 13, 2026
964b6a1
grass.temporal: Fix swapped rows and cols in map metadata (#7681)
petrasovaa Jul 13, 2026
9a1a3ec
packaging: Update min Python version to 3.11 (#7684)
wenzeslaus Jul 13, 2026
dc0c886
CMake: Build man pages from markdown (#7674)
petrasovaa Jul 14, 2026
d8c0e1f
grass.pygrass: Add the psycopg2 hint as an exception note (#7690)
wenzeslaus Jul 14, 2026
af466a6
grass.gunittest: Add the module name as an exception note (#7689)
wenzeslaus Jul 14, 2026
2c98981
v.class: Fix out-of-bounds read when no records are selected (#7692)
petrasovaa Jul 14, 2026
1ec5371
v.geometry: new tool (v.to.db wrapper) for more obvious access to vec…
petrasovaa Jul 14, 2026
836e7fc
wxGUI: Add the matplotlib hint as an exception note (#7688)
wenzeslaus Jul 14, 2026
0a63917
docs: howto_release.md: update OSGeo server names (#7711)
neteler Jul 14, 2026
3e03a03
packaging: Remove locale fallbacks for Python older than 3.11 (#7697)
wenzeslaus Jul 14, 2026
ea22bb2
Ci: Set makensis verbosity level to level 4 (all)
echoix Jul 14, 2026
868b747
packaging: Add GRASS_PYDIR in env.bat to correct windows installer, m…
echoix Jul 14, 2026
bc77d54
Revert "packaging: Add GRASS_PYDIR in env.bat.tmpl to correct windows…
echoix Jul 14, 2026
8465591
Merge branch 'main' into fix-msvc-runtime-dll-sizes
echoix Jul 14, 2026
5d51fea
Merge branch 'main' into fix-msvc-runtime-dll-sizes
echoix Oct 1, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
192 changes: 192 additions & 0 deletions .github/workflows/windows-installer.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
---
name: Windows installer

on:
push:
branches:
- main
- releasebranch_*
paths:
- mswindows/**
- .github/workflows/windows-installer.yml
pull_request:
paths:
- mswindows/**
- .github/workflows/windows-installer.yml
workflow_dispatch:

permissions: {}

jobs:
build:
name: Build standalone installer

concurrency:
group: >-
${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.head_ref || github.sha }}
cancel-in-progress: true

runs-on: windows-2022

steps:
- name: Set git to use LF
run: |
git config --global core.autocrlf false
git config --global core.eol lf
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
- uses: msys2/setup-msys2@66cd2cce69caa17b53920067426061ca1de3a884 # v2.32.0
id: msys2
with:
path-type: inherit
location: D:\
update: true
msystem: MINGW64
install: >-
bison
diffutils
dos2unix
flex
git
libintl
make
tar
zip
pacboy: >-
bzip2
ccache
fftw
gcc
gettext
libiconv
libsystre
libtre
libwinpthread-git
openblas
pcre
pkgconf
toolchain
zlib

- name: Setup OSGeo4W environment
uses: echoix/setup-OSGeo4W@1e711832882e03603e9013181a87885b10af8a98 # v0.3.0
id: osgeo4w
with:
package-dir: "D:/OSGeo4W_pkg"
packages: |
cairo-devel
freetype-devel
gdal-devel
geos-devel
libjpeg-turbo-devel
liblas-devel
libpng-devel
libpq-devel
libtiff-devel
netcdf-devel
proj-devel
python3-core
python3-jupyter
python3-matplotlib
python3-numpy
python3-pip
python3-pywin32
python3-wxpython
sqlite3-devel
zstd-devel

- name: Set number of cores for compilation
run: |
echo "MAKEFLAGS=-j$(nproc)" >> "${GITHUB_ENV}"
shell: msys2 {0}

- name: Compile GRASS
shell: msys2 {0}
# The OSGeo4W build script is called directly (not through
# .github/workflows/build_osgeo4w.sh) to avoid the UNITTEST additions
# which would end up in the package.
run: |
export OSGEO4W_ROOT_MSYS=/c/OSGeo4W
export SRC=$(pwd)
mswindows/osgeo4w/build_osgeo4w.sh

- name: Install GRASS into the OSGeo4W tree
shell: msys2 {0}
# Mirrors the install and packaging preparation steps of
# mswindows/osgeo4w/package.sh used by the wingrass-maintenance-scripts
# builds (except for the MSVC .lib files which need Visual Studio and
# are not part of the standalone installer).
run: |
export PATH=/c/OSGeo4W/bin:/usr/bin:/mingw64/bin
export PYTHONHOME=/c/OSGeo4W/apps/Python312
# Recreate etc/fontcap in the dist tree; build_osgeo4w.sh removes it
# but make install requires it and cannot rebuild it itself.
make -C general/g.mkfontcap
make install
ver=$(sed -n '/^INST_DIR[ \t]*=/{s/^.*grass//; p}' include/Make/Platform.make)
echo "GRASS_VER=${ver}" >> "${GITHUB_ENV}"
prefix=/c/OSGeo4W/apps/grass/grass${ver}
mv ${prefix}/include/grass/config.h ${prefix}/include/grass/config.h.mingw
cp mswindows/osgeo4w/config.h.switch ${prefix}/include/grass/config.h
cp mswindows/osgeo4w/config.h.vc ${prefix}/include/grass
mv ${prefix}/etc/grass.py ${prefix}/etc/grass${ver}.py
cp -uv $(find ${prefix} -iname "*.dll" -o -iname "*.exe" \
| PATH=${prefix}/lib:/c/OSGeo4W/bin:/mingw64/bin:/usr/bin xargs ldd \
| sed -ne 's#^.* => \(/mingw64/bin/.*\) (.*)$#\1#p' \
| sort -u) ${prefix}/bin

- name: Create standalone package
shell: cmd
working-directory: mswindows
run: call GRASS-Packager.bat

- name: Check package content
shell: msys2 {0}
# xcopy failures do not stop GRASS-Packager.bat, so check that files
# needed by the installer and by the installed GRASS are in place.
run: |
pkg=mswindows/GRASS-${GRASS_VER}-Package
test -f ${pkg}/GPL.TXT
test -d ${pkg}/demolocation
test -f ${pkg}/etc/env.bat
test -f ${pkg}/etc/grass${GRASS_VER}.py
test -f ${pkg}/extrabin/python3.exe
test -d ${pkg}/Python312

- name: Install NSIS plugins
shell: pwsh
working-directory: ${{ runner.temp }}
# The AccessControl and untgz plugins used by GRASS-Installer.nsi are
# not bundled with NSIS; see
# https://trac.osgeo.org/grass/wiki/CompileOnWindows#InstallNSIS
run: |
curl.exe -fsSL -o AccessControl.zip https://nsis.sourceforge.io/mediawiki/images/4/4a/AccessControl.zip
curl.exe -fsSL -o Untgz.zip https://nsis.sourceforge.io/mediawiki/images/9/9d/Untgz.zip
$expected = @{
'AccessControl.zip' = '9aa60f9c5c023fda2808af216514d8913d2673bc522d944ee771da032a1bdc10'
'Untgz.zip' = '3c2a088b82b27b6183ea6479d61a6c0ecc54f52e484577b641ca21867bd81a4b'
}
foreach ($file in $expected.Keys) {
$hash = (Get-FileHash $file -Algorithm SHA256).Hash
if ($hash -ne $expected[$file]) {
throw "Checksum mismatch for ${file}: ${hash}"
}
}
Expand-Archive AccessControl.zip -DestinationPath AccessControl
Expand-Archive Untgz.zip -DestinationPath Untgz
$pluginDir = Join-Path (Split-Path (Get-Command makensis).Source) 'Plugins\x86-unicode'
Copy-Item AccessControl\Plugins\i386-unicode\AccessControl.dll $pluginDir
Copy-Item Untgz\untgz\unicode\untgz.dll $pluginDir

- name: Create installer
shell: pwsh
working-directory: mswindows
run: makensis /V4 GRASS-Installer.nsi

- name: Upload installer
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: wingrass-standalone-installer
path: mswindows/WinGRASS-*-Setup.exe
retention-days: 7
30 changes: 21 additions & 9 deletions mswindows/GRASS-Installer.nsi.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -594,11 +594,9 @@ Section "GRASS" SecGRASS
FileClose $0
done_create_run_gmkfontcap.bat.manifest:

;Run g.mkfontcap outside a grass session during installation to catch all fonts
ExecWait '"$INSTALL_DIR\etc\run_gmkfontcap.bat"'

;set $INSTDIR\etc back to read accessible
AccessControl::SetOnFile "$INSTDIR\etc" "(S-1-5-32-545)" "GenericRead + GenericExecute"
;g.mkfontcap is run later, in the hidden RunMkFontCap section placed after
;the Microsoft runtime section, so that the runtime DLLs it needs are
;already installed (see https://github.com/OSGeo/grass/issues/5663)

;Install demolocation into the GIS_DATABASE directory
SetOutPath "$GIS_DATABASE\demolocation"
Expand Down Expand Up @@ -835,20 +833,34 @@ FunctionEnd
Section "Important Microsoft Runtime DLLs" SecMSRuntime

;Set the size (in KB) of the archive file
StrCpy $ARCHIVE_SIZE_KB 833
StrCpy $ARCHIVE_SIZE_KB 920

;Set the size (in KB) of the unpacked archive file
AddSize 13500
AddSize 2424

StrCpy $HTTP_PATH "http://download.osgeo.org/osgeo4w/v2/${PLATFORM}/release/msvcrt2019/"
StrCpy $ARCHIVE_NAME "msvcrt2019-14.2-1.tar.bz2"
StrCpy $ARCHIVE_NAME "msvcrt2019-14.2-2.tar.bz2"
StrCpy $EXTENDED_ARCHIVE_NAME "Microsoft Visual C++ Redistributable Packages"
StrCpy $ORIGINAL_UNTAR_FOLDER "install_msruntime"

Call DownloadInstallMSRuntime

SectionEnd

;Hidden section which always runs; it is placed after the Microsoft runtime
;section because g.mkfontcap needs the runtime DLLs installed by that section,
;while the runtime section itself needs $INSTALL_DIR set and the GRASS files
;extracted by the GRASS section (https://github.com/OSGeo/grass/issues/5663)
Section "-RunMkFontCap"

;Run g.mkfontcap outside a grass session during installation to catch all fonts
ExecWait '"$INSTALL_DIR\etc\run_gmkfontcap.bat"'

;set $INSTDIR\etc back to read accessible
AccessControl::SetOnFile "$INSTDIR\etc" "(S-1-5-32-545)" "GenericRead + GenericExecute"

SectionEnd

Function DownloadDataSet

; IntOp $ARCHIVE_SIZE_MB $ARCHIVE_SIZE_KB / 1024
Expand Down Expand Up @@ -984,7 +996,7 @@ SectionEnd
;Installer Section Descriptions
!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
!insertmacro MUI_DESCRIPTION_TEXT ${SecGRASS} "Install GRASS ${VERSION_NUMBER}"
!insertmacro MUI_DESCRIPTION_TEXT ${SecMSRuntime} "Some software included in this installer (e.g. GDAL, Python) may need Microsoft's Visual C++ redistributable system libraries.$\r$\nDownload and install the Redistributable Package. (12 MB)"
!insertmacro MUI_DESCRIPTION_TEXT ${SecMSRuntime} "Some software included in this installer (e.g. GDAL, Python) may need Microsoft's Visual C++ redistributable system libraries.$\r$\nDownload and install the Redistributable Package. (1 MB)"
!insertmacro MUI_DESCRIPTION_TEXT ${SecNorthCarolinaSDB} "Download and install the North Carolina (Wake County) sample data set. (141 MB)"
!insertmacro MUI_DESCRIPTION_TEXT ${SecSpearfishSDB} "Download and install the South Dakota (Spearfish County) sample data set. (22 MB)"
!insertmacro MUI_FUNCTION_DESCRIPTION_END
Expand Down
1 change: 1 addition & 0 deletions mswindows/env.bat
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ REM

set GRASS_PYTHON=%GISBASE%\extrabin\python3.exe
set PYTHONHOME=%GISBASE%\Python312
set GRASS_PYDIR=%GISBASE%\etc\python

set GRASS_PROJSHARE=%GISBASE%\share\proj

Expand Down
Loading