diff --git a/.gitignore b/.gitignore index 5647313e..514914b3 100644 --- a/.gitignore +++ b/.gitignore @@ -61,3 +61,4 @@ thirdparty/pyplot_module.F90 .claude docs/_build/ build*/ +.venv/ diff --git a/Makefile b/Makefile index f4934ab6..b9e1e3e6 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,7 @@ NVHPC_HPCX := $(NVHPC_ROOT)/comm_libs/13.0/hpcx/hpcx-2.25.1/ompi NVHPC_BUILD_DIR := build_nvfortran NVHPC_ACC_BUILD_DIR := build_nvfortran_acc -.PHONY: all configure reconfigure build build-deterministic build-deterministic-nopy test test-nopy test-fast test-slow test-regression test-all test-golden-main test-golden-tag test-golden install clean nvfortran nvfortran-test nvfortran-test-nopy nvfortran-configure nvfortran-clean +.PHONY: all configure reconfigure build build-deterministic build-deterministic-nopy test test-nopy test-fast test-slow test-regression test-all test-golden-main test-golden-tag test-golden install clean venv nvfortran nvfortran-test nvfortran-test-nopy nvfortran-configure nvfortran-clean .PHONY: nvfortran-acc nvfortran-acc-test nvfortran-acc-test-nopy nvfortran-acc-configure nvfortran-acc-clean all: build @@ -98,6 +98,12 @@ test-golden: build-deterministic-nopy test-golden-fast: build cd $(BUILD_DIR) && ctest --output-on-failure $(if $(filter 1,$(VERBOSE)),-V) -L "golden_record" $(if $(TEST),-R "$(TEST)") +venv: + ./setup-venv.sh + +venv-nopy: + ./setup-venv.sh --no-pysimple + doc: configure cmake --build --preset default --target doc diff --git a/pyproject.toml b/pyproject.toml index aa572f45..39698a3e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,6 +17,3 @@ cmake.define.CMAKE_CACHE_DIR = "build" wheel.packages = ["python/pysimple"] wheel.install-dir = "pysimple" wheel.exclude = [] - -[project.package-data] -pysimple = ["data/*.dat"] diff --git a/requirements.txt b/requirements.txt index 77fb5fe1..8aa97c79 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,19 +1,20 @@ # Python dependencies for SIMPLE -# Pin exact versions for reproducibility in CI +# Use minimum versions for compatibility across Python releases. +# Exact pins break on newer Python versions that lack prebuilt wheels. # Core dependencies -numpy==2.2.6 -scikit-build-core==0.10.0 +numpy>=2.2 +scikit-build-core>=0.10 -# F90wrap - pinned to release version +# F90wrap - pinned to release version (API-sensitive) f90wrap==0.2.16 -# Optional dependencies for testing -pytest==7.4.3 -pytest-cov==6.2.1 -netCDF4==1.7.2 +# Testing +pytest>=7.4 +pytest-cov>=6.0 +netCDF4>=1.7 -# Optional dependencies for examples/plotting -matplotlib==3.9.4 -scipy==1.15.2 -shapely==2.0.5 +# Plotting and examples +matplotlib>=3.9 +scipy>=1.15 +shapely>=2.0 diff --git a/setup-venv.sh b/setup-venv.sh new file mode 100755 index 00000000..90f4cfda --- /dev/null +++ b/setup-venv.sh @@ -0,0 +1,65 @@ +#!/bin/bash +# Create and populate a Python virtual environment for SIMPLE. +# Usage: ./setup-venv.sh [--no-pysimple] +# +# Options: +# --no-pysimple Skip building pysimple (Fortran-Python bindings). +# Use this if you only need Python test/plot dependencies. +# +# Prerequisites (system packages): +# - python3 (>= 3.9) with venv module +# - gfortran, cmake, ninja-build +# - libnetcdff-dev (or netcdf-fortran-devel), liblapack-dev +# See docs/PREREQUISITES.md for distro-specific install commands. + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +VENV_DIR="${SCRIPT_DIR}/.venv" +BUILD_PYSIMPLE=1 + +for arg in "$@"; do + case "$arg" in + --no-pysimple) BUILD_PYSIMPLE=0 ;; + -h|--help) + sed -n '2,/^$/s/^# //p' "$0" + exit 0 + ;; + *) + echo "Unknown option: $arg" >&2 + exit 1 + ;; + esac +done + +echo "Creating virtual environment in ${VENV_DIR} ..." +python3 -m venv "$VENV_DIR" +# shellcheck disable=SC1091 +source "${VENV_DIR}/bin/activate" + +echo "Upgrading pip ..." +pip install --upgrade pip + +echo "Installing Python dependencies from requirements.txt ..." +pip install --prefer-binary -r "${SCRIPT_DIR}/requirements.txt" + +if [ "$BUILD_PYSIMPLE" -eq 1 ]; then + echo "Building pysimple (Fortran-Python bindings) ..." + # Build SIMPLE first if not already built + if [ ! -f "${SCRIPT_DIR}/build/build.ninja" ]; then + echo " Configuring CMake ..." + cmake -S "$SCRIPT_DIR" -B"${SCRIPT_DIR}/build" -GNinja \ + -DCMAKE_BUILD_TYPE=Release -DCMAKE_COLOR_DIAGNOSTICS=ON + fi + echo " Building Fortran library ..." + cmake --build "${SCRIPT_DIR}/build" --config Release + + echo " Installing pysimple in editable mode ..." + pip install --no-build-isolation -e "$SCRIPT_DIR" +else + echo "Skipping pysimple build (--no-pysimple)." +fi + +echo "" +echo "Done. Activate with:" +echo " source .venv/bin/activate"