Runtime Guide

library(gdalraster.windows)

This guide covers how the GDAL runtime is located, activated, and used from day to day: session activation, configuration, source builds of gdalraster, startup hooks, and embedded-python algorithms. For the build internals behind the runtime bundle, see the Architecture article.

How the runtime home is resolved

Every helper in this package resolves the runtime location (gdal_home) through the same precedence chain:

  1. options(gdalraster.windows.gdal_home = "...")
  2. the GDALRASTER_WINDOWS_GDAL_HOME environment variable
  3. the package-managed user data directory (tools::R_user_dir("gdalraster.windows", "data"))
# where the active runtime lives
gdalraster.windows::gdal_home()

# point the session at a different runtime (option or env var, not persisted)
gdalraster.windows::configure_gdal_home("D:/gdal/custom-runtime", mode = "option")

configure_gdal_home() is session-scoped by design — it never writes to profile files or machine state.

Session activation

Windows resolves a DLL’s imports at load time, so the bundle’s bin/ directory must be discoverable before gdalraster.dll loads. activate_gdal_runtime() prepares the session:

  • prepends <gdal_home>/bin to PATH
  • sets GDAL_DATA, PROJ_LIB, and PROJ_DATA to the bundle’s share/ data trees (GDAL and PROJ need their runtime data for CRS operations)
  • prepends <gdal_home>/python to PYTHONPATH for embedded-python algorithms
  • preloads libgdal-*.dll into the process (when preload = TRUE, the default), so the DLL is already mapped when gdalraster asks for it

All of this is session-scoped: no machine or user environment variables are modified. When preloading fails — most commonly because a dependency DLL is missing — activation fails immediately with an informative error instead of deferring to library(gdalraster), where the Windows loader would only report a generic “module could not be found”.

gdalraster.windows::activate_gdal_runtime()
#> v gdal runtime activated from C:/Users/you/AppData/Roaming/R/data/R/gdalraster.windows/...

load_gdal_dll() is a convenience wrapper that activates with preload = TRUE:

gdalraster.windows::load_gdal_dll()

Automatic activation on load

Attaching the package triggers a bootstrap that activates an installed runtime and prepends the isolated gdalraster library to .libPaths(), so in an already-set-up session this is all you need:

library(gdalraster.windows)
library(gdalraster)

Two options control this behavior:

# disable the load-time bootstrap entirely
options(gdalraster.windows.auto_bootstrap = FALSE)

# additionally auto-attach gdalraster from the isolated library at load time
options(gdalraster.windows.auto_load_gdalraster = TRUE)

Building gdalraster against the runtime

install_gdalraster() downloads (or accepts) a gdalraster source tarball from firelab/gdalraster and builds it against the bundle’s headers and import library:

# default: latest source from firelab/gdalraster, into the isolated library
gdalraster.windows::install_gdalraster()

# pin a specific ref, or build from a local tarball
gdalraster.windows::install_gdalraster(ref = "v2.1.0")
gdalraster.windows::install_gdalraster(source_tarball = "C:/tmp/gdalraster_2.1.0.tar.gz")

# pre-install gdalraster's R dependencies from CRAN before the source build
gdalraster.windows::install_gdalraster(upgrade = TRUE)

Compile and link flags (GDAL_HOME, PKG_CPPFLAGS, PKG_LIBS) are applied through a scoped Makevars file via withr::with_makevars(), and the runtime’s bin/ and data directories are exposed through scoped environment variables for the duration of the install. Nothing leaks into your persistent configuration.

The default destination is an isolated library (<user data dir>/library), so an existing CRAN gdalraster is left untouched. Loading from that isolated library is what load_gdalraster() does:

# activates the runtime, prepends the isolated library, attaches gdalraster
gdalraster.windows::load_gdalraster()

To make the source build your regular gdalraster instead, install it into your user library — accepting that it replaces whatever gdalraster is there:

gdalraster.windows::install_gdalraster(lib = .libPaths()[1])

Startup hooks

For sessions that should bootstrap without attaching this package, a managed .Rprofile hook loads the bundled GDAL DLL and prepends the isolated library at startup:

# preview the generated code without writing anything
cat(gdalraster.windows::gdal_rprofile_snippet())

# write (or update) the managed block in ~/.Rprofile
gdalraster.windows::add_gdal_rprofile_hook()

# preview the resulting file contents without writing
gdalraster.windows::add_gdal_rprofile_hook(dry_run = TRUE)

The hook is wrapped in # >>> gdalraster.windows hook >>> / # <<< gdalraster.windows hook <<< markers, guards itself with requireNamespace() and an OS check, and is updated in place on subsequent calls rather than appended repeatedly.

Embedded-python algorithms

Some GDAL algorithms (e.g. gdal driver gpkg validate) are thin C++ entry points around Python implementations: libgdal embeds a CPython interpreter at first use and imports the pure-python osgeo_utils package. The runtime bundle ships osgeo_utils under <gdal_home>/python, version-locked to the built GDAL, and activation exposes it via PYTHONPATH:

library(gdalraster.windows)
library(gdalraster)

alg <- gdalraster::gdal_alg(cmd = "driver gpkg validate")
alg$setArg("dataset", "path/to/file.gpkg")
alg$setArg("full-check", TRUE)
alg$run()
alg$output()
#> [1] "Checking gpkg_spatial_ref_sys\n...\nValidation succeeded"

A python.exe must be discoverable on PATH for GDAL to embed an interpreter at all — Rtools’ UCRT64 python works, as does any system python. The compiled osgeo SWIG bindings are deliberately not bundled (they would pin the bundle to a single CPython ABI); the python-implemented validators degrade gracefully without them.

Upgrading the runtime

After a new GDAL runtime release, reinstall the bundle and rebuild gdalraster against it — the previous gdalraster.dll is bound to the previous GDAL’s ABI and import names:

# in a fresh session, before gdalraster is loaded
gdalraster.windows::install_gdal_runtime(overwrite = TRUE)
gdalraster.windows::install_gdalraster()
gdalraster.windows::verify_gdalraster_runtime()

Overwriting is refused while gdalraster is loaded, because its DLL pins the runtime files in the current process; restart R first. See the Troubleshooting article if deletion still fails.