From 594fc76f687aa5574a80dbd55deef238ebe2bcd7 Mon Sep 17 00:00:00 2001 From: Peter Heesterman Date: Wed, 29 Jul 2026 21:30:54 +0100 Subject: [PATCH 1/5] Enables support for Windows use. Separated out from the devel branch. --- .ci | 2 +- .github/workflows/ci-scripts-build.yml | 34 +++++++++++++++++ configure/CONFIG_PY | 4 ++ configure/RELEASE.windows-x64.common | 42 +++++++++++++++++++++ configure/RULES_PY | 8 ++-- devsupApp/src/Makefile | 7 ++++ devsupApp/src/dbdset.c | 4 +- devsupApp/src/devsup/__init__.py | 51 +++++++++++++------------- devsupApp/src/devsup/test/util.py | 5 ++- iocBoot/iocFPM/Makefile | 4 +- iocBoot/iocapplmon/Makefile | 4 +- iocBoot/iocapplmon/st.cmd | 2 +- iocBoot/iocarchivemon/Makefile | 4 +- iocBoot/iocarchivemon/st.cmd | 2 +- iocBoot/ioccaputlog/Makefile | 4 +- iocBoot/iocweatherbnl/Makefile | 4 +- makehelper.py | 31 +++++----------- pyIocApp/Makefile | 2 + pyIocApp/setup.c | 3 ++ 19 files changed, 150 insertions(+), 67 deletions(-) create mode 100644 configure/RELEASE.windows-x64.common diff --git a/.ci b/.ci index 4e4f33e..a32a1da 160000 --- a/.ci +++ b/.ci @@ -1 +1 @@ -Subproject commit 4e4f33e54f59343c77342200a95800073661e7ac +Subproject commit a32a1dab0586dde3f5b2990506d54950e61ce25b diff --git a/.github/workflows/ci-scripts-build.yml b/.github/workflows/ci-scripts-build.yml index c46ce43..a2056aa 100644 --- a/.github/workflows/ci-scripts-build.yml +++ b/.github/workflows/ci-scripts-build.yml @@ -159,6 +159,39 @@ jobs: python: "3.7" container: "python:3.7" profile: deb10 + + - os: windows-latest + cmp: vs2026 + configuration: default + base: "3.15" + python: "3.11" + profile: latest + test: yes + + - os: windows-latest + cmp: vs2026 + configuration: default + base: "7.0" + python: "3.11" + profile: latest + test: yes + + - os: windows-latest + cmp: vs2026 + configuration: default + base: "7.0" + python: "3.12" + profile: latest + test: yes + + - os: windows-latest + cmp: vs2026 + configuration: default + base: "7.0" + python: "3.13" + profile: latest + test: yes + steps: - uses: actions/checkout@v3 with: @@ -169,6 +202,7 @@ jobs: with: python-version: ${{ matrix.python }} - name: More Setup Python + shell: bash run: | python --version python -m pip --version diff --git a/configure/CONFIG_PY b/configure/CONFIG_PY index f2edef8..0eeb5f3 100644 --- a/configure/CONFIG_PY +++ b/configure/CONFIG_PY @@ -48,6 +48,10 @@ LOADABLE_SHRLIB_LDFLAGS = -bundle -flat_namespace -undefined dynamic_lookup LOADABLE_SHRLIB_SUFFIX = .so endif +ifeq ($(OS_CLASS),WIN32) +SHRLIB_SUFFIX_BASE = .pyd +endif + endif endif diff --git a/configure/RELEASE.windows-x64.common b/configure/RELEASE.windows-x64.common new file mode 100644 index 0000000..35661a6 --- /dev/null +++ b/configure/RELEASE.windows-x64.common @@ -0,0 +1,42 @@ +# RELEASE - Location of external support modules +# +# IF YOU MAKE ANY CHANGES to this file you must subsequently +# do a "gnumake rebuild" in this application's top level +# directory. +# +# The build process does not check dependencies against files +# that are outside this application, thus you should do a +# "gnumake rebuild" in the top level directory after EPICS_BASE +# or any other external module pointed to below is rebuilt. +# +# Host- or target-specific settings can be given in files named +# RELEASE.$(EPICS_HOST_ARCH).Common +# RELEASE.Common.$(T_A) +# RELEASE.$(EPICS_HOST_ARCH).$(T_A) +# +# This file should ONLY define paths to other support modules, +# or include statements that pull in similar RELEASE files. +# Build settings that are NOT module paths should appear in a +# CONFIG_SITE file. + +TEMPLATE_TOP=$(EPICS_BASE)/templates/makeBaseApp/top + +## Optional Modules ## +# Comment out if not present + +# IOC statistics (cpu and mem usage, ...) +#DEVIOCSTATS=$(EPICS_BASE) + +# automatic save with restore on boot +#AUTOSAVE=$(EPICS_BASE) + +# logging of remote settings changes +#CAPUTLOG=$(EPICS_BASE) + +## Required Modules ## + +# EPICS_BASE usually appears last so other apps can override stuff: +#EPICS_BASE=C:/epics/base + +-include $(TOP)/configure/RELEASE.local +-include $(TOP)/../RELEASE.local diff --git a/configure/RULES_PY b/configure/RULES_PY index c635d51..9f15b01 100644 --- a/configure/RULES_PY +++ b/configure/RULES_PY @@ -1,15 +1,15 @@ ifneq ($(T_A),) - ifndef PY_VER $(error Must include CONFIG_PY) endif +include $(CONFIG)/CONFIG_BASE + PY_FILES += $(PY:%=$(PY_INSTALL_DIR)/%) $(PY_FILES) : $(PY_INSTALL_DIR)/%: ../% - @[ -d $(dir $@) ] || install -d $(dir $@) - @echo "Install PY $@" - install -m 644 $< $@ + $(ECHO) "Install PY $@" + @$(INSTALL) -d -m $(INSTALL_PERMISSIONS) $< $(@D) build: $(PY_FILES) diff --git a/devsupApp/src/Makefile b/devsupApp/src/Makefile index 9f1b468..d995155 100644 --- a/devsupApp/src/Makefile +++ b/devsupApp/src/Makefile @@ -29,8 +29,11 @@ _dbapi_SRCS += utest.c _dbapi_SRCS += pyDevSupCommon_registerRecordDeviceDriver.cpp _dbapi_LIBS += $(EPICS_BASE_IOC_LIBS) +_dbapi_LDFLAGS_WIN32 += -LIBPATH:$(PY_LIBDIRS) +_dbapi_SYS_LIBS_WIN32 += ws2_32 Advapi32 Dbghelp PY += devsup/__init__.py +PY += devsup/_dbapi.dbd PY += devsup/db.py PY += devsup/dset.py PY += devsup/hooks.py @@ -61,7 +64,11 @@ pyconfig: ifneq (,$(T_A)) nose: +ifeq ($(OS),Windows_NT) + pushd "$(abspath $(TOP))/python$(PY_LD_VER)/$(EPICS_HOST_ARCH)" && $(PYTHON) -m nose2 -v devsup $(NOSEFLAGS) && popd +else PYTHONPATH="${PYTHONPATH}:$(abspath $(TOP))/python$(PY_LD_VER)/$(EPICS_HOST_ARCH)" $(PYTHON) -m nose2 -v devsup $(NOSEFLAGS) +endif # bounce back down to the sphinx generated Makefile # aren't Makefiles fun... diff --git a/devsupApp/src/dbdset.c b/devsupApp/src/dbdset.c index 68d76e4..954d0c5 100644 --- a/devsupApp/src/dbdset.c +++ b/devsupApp/src/dbdset.c @@ -24,6 +24,7 @@ #include #include "pydevsup.h" +#include static int inshutdown; @@ -449,7 +450,8 @@ static long python_asub(aSubRecord* prec) } /* uglyness to detect aSubRecord */ -extern rset* pvar_rset_aSubRSET; +epicsShareExtern +rset* pvar_rset_aSubRSET; int isPyRecord(dbCommon *prec) { diff --git a/devsupApp/src/devsup/__init__.py b/devsupApp/src/devsup/__init__.py index dd8da5a..16898f7 100644 --- a/devsupApp/src/devsup/__init__.py +++ b/devsupApp/src/devsup/__init__.py @@ -1,7 +1,29 @@ import os +import ctypes +import sys import atexit import tempfile +if sys.platform == 'win32': + # See https://stackoverflow.com/questions/72858093/how-to-specify-pyd-dll-dependencies-search-paths-at-runtime-with-python + # This is required for use of e.g. nose testing, but + # not when running as an IOC, since the IOC will already have loaded EPICS base DLLs. + epics_base = os.getenv('EPICS_BASE') + epics_host_arch = os.getenv('EPICS_HOST_ARCH') + if epics_base is not None and epics_host_arch is not None: + epics_base = epics_base.replace("/",'\\') + dll_path = epics_base + "\\bin\\" + epics_host_arch + try: + os.add_dll_directory(dll_path) + except AttributeError: + # See https://stackoverflow.com/questions/75794403/attributeerror-module-os-has-no-attribute-add-dll-directory + import ctypes + kernel32 = ctypes.WinDLL('kernel32', use_last_error=True) + cookie = kernel32.AddDllDirectory(dll_path) + if not cookie: + error = ctypes.get_last_error() + raise OSError("Failed to add DLL directory: {error}") + from . import _dbapi from ._dbapi import (EPICS_VERSION_STRING, @@ -52,32 +74,9 @@ def _init(iocMain=False): path=os.path.join(XEPICS_BASE, "dbd")) _dbapi._dbd_rrd_base() - with tempfile.NamedTemporaryFile() as F: - F.write(""" -device(longin, INST_IO, pydevsupComIn, "Python Device") -device(longout, INST_IO, pydevsupComOut, "Python Device") - -device(ai, INST_IO, pydevsupComIn, "Python Device") -device(ao, INST_IO, pydevsupComOut, "Python Device") - -device(stringin, INST_IO, pydevsupComIn, "Python Device") -device(stringout, INST_IO, pydevsupComOut, "Python Device") - -device(bi, INST_IO, pydevsupComIn, "Python Device") -device(bo, INST_IO, pydevsupComOut, "Python Device") - -device(mbbi, INST_IO, pydevsupComIn, "Python Device") -device(mbbo, INST_IO, pydevsupComOut, "Python Device") - -device(mbbiDirect, INST_IO, pydevsupComIn, "Python Device") -device(mbboDirect, INST_IO, pydevsupComOut, "Python Device") - -device(waveform, INST_IO, pydevsupComIn, "Python Device") -device(aai, INST_IO, pydevsupComIn, "Python Device") -device(aao, INST_IO, pydevsupComOut, "Python Device") -""".encode('ascii')) - F.flush() - _dbapi.dbReadDatabase(F.name) + dirname = os.path.dirname(__file__) + dbd_name = dirname + "/_dbapi.dbd" + _dbapi.dbReadDatabase(dbd_name) _dbapi._dbd_setup() def _fini(iocMain=False): diff --git a/devsupApp/src/devsup/test/util.py b/devsupApp/src/devsup/test/util.py index 6177a4b..70d1ff6 100644 --- a/devsupApp/src/devsup/test/util.py +++ b/devsupApp/src/devsup/test/util.py @@ -43,10 +43,11 @@ def setUp(self): _init(iocMain=False) # load base.dbd if self.db is not None: - with tempfile.NamedTemporaryFile() as F: + with tempfile.NamedTemporaryFile(delete=False) as F: F.write(self.db.encode('ascii')) - F.flush() + F.close() _dbapi.dbReadDatabase(F.name) + os.unlink(F.name) if self.autostart: self.iocInit() diff --git a/iocBoot/iocFPM/Makefile b/iocBoot/iocFPM/Makefile index 79c4ce6..25b7be6 100644 --- a/iocBoot/iocFPM/Makefile +++ b/iocBoot/iocFPM/Makefile @@ -1,5 +1,5 @@ TOP = ../.. include $(TOP)/configure/CONFIG -ARCH = linux-x86_64 -TARGETS = envPaths +ARCH = $(EPICS_HOST_ARCH) +TARGETS = envPaths dllPath.bat include $(TOP)/configure/RULES.ioc diff --git a/iocBoot/iocapplmon/Makefile b/iocBoot/iocapplmon/Makefile index 79c4ce6..25b7be6 100644 --- a/iocBoot/iocapplmon/Makefile +++ b/iocBoot/iocapplmon/Makefile @@ -1,5 +1,5 @@ TOP = ../.. include $(TOP)/configure/CONFIG -ARCH = linux-x86_64 -TARGETS = envPaths +ARCH = $(EPICS_HOST_ARCH) +TARGETS = envPaths dllPath.bat include $(TOP)/configure/RULES.ioc diff --git a/iocBoot/iocapplmon/st.cmd b/iocBoot/iocapplmon/st.cmd index 142d051..f345464 100755 --- a/iocBoot/iocapplmon/st.cmd +++ b/iocBoot/iocapplmon/st.cmd @@ -1,4 +1,4 @@ -#!../../bin/linux-x86/softIocPy3.6 +#!../../bin/linux-x86_64/softIocPy3.6 < envPaths diff --git a/iocBoot/iocarchivemon/Makefile b/iocBoot/iocarchivemon/Makefile index 79c4ce6..25b7be6 100644 --- a/iocBoot/iocarchivemon/Makefile +++ b/iocBoot/iocarchivemon/Makefile @@ -1,5 +1,5 @@ TOP = ../.. include $(TOP)/configure/CONFIG -ARCH = linux-x86_64 -TARGETS = envPaths +ARCH = $(EPICS_HOST_ARCH) +TARGETS = envPaths dllPath.bat include $(TOP)/configure/RULES.ioc diff --git a/iocBoot/iocarchivemon/st.cmd b/iocBoot/iocarchivemon/st.cmd index be83af7..632e7a6 100755 --- a/iocBoot/iocarchivemon/st.cmd +++ b/iocBoot/iocarchivemon/st.cmd @@ -1,4 +1,4 @@ -#!../../bin/linux-x86/softIocPy3.6 +#!../../bin/linux-x86_64/softIocPy3.6 < envPaths diff --git a/iocBoot/ioccaputlog/Makefile b/iocBoot/ioccaputlog/Makefile index 79c4ce6..25b7be6 100644 --- a/iocBoot/ioccaputlog/Makefile +++ b/iocBoot/ioccaputlog/Makefile @@ -1,5 +1,5 @@ TOP = ../.. include $(TOP)/configure/CONFIG -ARCH = linux-x86_64 -TARGETS = envPaths +ARCH = $(EPICS_HOST_ARCH) +TARGETS = envPaths dllPath.bat include $(TOP)/configure/RULES.ioc diff --git a/iocBoot/iocweatherbnl/Makefile b/iocBoot/iocweatherbnl/Makefile index 79c4ce6..25b7be6 100644 --- a/iocBoot/iocweatherbnl/Makefile +++ b/iocBoot/iocweatherbnl/Makefile @@ -1,5 +1,5 @@ TOP = ../.. include $(TOP)/configure/CONFIG -ARCH = linux-x86_64 -TARGETS = envPaths +ARCH = $(EPICS_HOST_ARCH) +TARGETS = envPaths dllPath.bat include $(TOP)/configure/RULES.ioc diff --git a/makehelper.py b/makehelper.py index 05fd147..b396dcc 100644 --- a/makehelper.py +++ b/makehelper.py @@ -26,26 +26,15 @@ pass out = open(sys.argv[1], 'w') -""" -3.2 sysconfig -3.10 sysconfig.get_path -3.10.13 distutils is deprecated. -3.12 distutils was removed. -""" -if sys.version_info >= (3,10,): - from sysconfig import get_config_var, get_path - incdirs = [get_path("include")] -else: - from distutils.sysconfig import get_config_var, get_python_inc - incdirs = [get_python_inc()] +from sysconfig import get_config_var, get_path, get_python_version -libdir = get_config_var('LIBDIR') or '' +incdirs = [get_path("include")] +if sys.platform == 'win32': + libdir = os.path.join(sys.prefix, 'libs') +else: + libdir = get_config_var('LIBDIR') or '' have_np='NO' - -""" -numpy 1.18, numpy.get_include() -""" try: from numpy import get_include numpy_dir = [get_include()] @@ -54,10 +43,10 @@ except ImportError: pass -print('TARGET_CFLAGS +=',get_config_var('BASECFLAGS'), file=out) -print('TARGET_CXXFLAGS +=',get_config_var('BASECFLAGS'), file=out) +print('TARGET_CFLAGS +=',get_config_var('BASECFLAGS') or '', file=out) +print('TARGET_CXXFLAGS +=',get_config_var('BASECFLAGS') or '', file=out) -print('PY_VER :=',get_config_var('VERSION'), file=out) +print('PY_VER :=',get_python_version(), file=out) ldver = get_config_var('LDVERSION') if ldver is None: ldver = get_config_var('VERSION') @@ -84,4 +73,4 @@ print('PY_OK := YES', file=out) -out.close() +out.close() \ No newline at end of file diff --git a/pyIocApp/Makefile b/pyIocApp/Makefile index 198e833..3dc3914 100644 --- a/pyIocApp/Makefile +++ b/pyIocApp/Makefile @@ -19,6 +19,7 @@ SHRLIB_VERSION = 0 DBD += pyDevSup.dbd pyDevSup$(PY_LD_VER)_SYS_LIBS += python$(PY_LD_VER) +pyDevSup$(PY_LD_VER)_LDFLAGS_WIN32 += -LIBPATH:$(PY_LIBDIRS) pyDevSup$(PY_LD_VER)_LIBS += $(EPICS_BASE_IOC_LIBS) @@ -43,6 +44,7 @@ softIocPy_DBD += system.dbd softIocPy$(PY_VER)_LIBS += pyDevSup$(PY_LD_VER) softIocPy$(PY_VER)_SYS_LIBS += python$(PY_LD_VER) +softIocPy$(PY_VER)_LDFLAGS_WIN32 += -LIBPATH:$(PY_LIBDIRS) # softIocPy_registerRecordDeviceDriver.cpp derives from softIocPy.dbd softIocPy$(PY_VER)_SRCS += softIocPy_registerRecordDeviceDriver.cpp diff --git a/pyIocApp/setup.c b/pyIocApp/setup.c index 61c3861..617661f 100644 --- a/pyIocApp/setup.c +++ b/pyIocApp/setup.c @@ -23,6 +23,9 @@ #include #include "pydevsup.h" +#ifdef _WIN32 +#define PATH_MAX _MAX_PATH +#endif static void cleanupPy(void *junk) { From e27643fea729b1f3cc8d5e07156824b90348e93b Mon Sep 17 00:00:00 2001 From: Peter Heesterman Date: Wed, 29 Jul 2026 21:34:48 +0100 Subject: [PATCH 2/5] Added missing file. --- devsupApp/src/devsup/_dbapi.dbd | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 devsupApp/src/devsup/_dbapi.dbd diff --git a/devsupApp/src/devsup/_dbapi.dbd b/devsupApp/src/devsup/_dbapi.dbd new file mode 100644 index 0000000..0d791aa --- /dev/null +++ b/devsupApp/src/devsup/_dbapi.dbd @@ -0,0 +1,22 @@ + +device(longin, INST_IO, pydevsupComIn, "Python Device") +device(longout, INST_IO, pydevsupComOut, "Python Device") + +device(ai, INST_IO, pydevsupComIn, "Python Device") +device(ao, INST_IO, pydevsupComOut, "Python Device") + +device(stringin, INST_IO, pydevsupComIn, "Python Device") +device(stringout, INST_IO, pydevsupComOut, "Python Device") + +device(bi, INST_IO, pydevsupComIn, "Python Device") +device(bo, INST_IO, pydevsupComOut, "Python Device") + +device(mbbi, INST_IO, pydevsupComIn, "Python Device") +device(mbbo, INST_IO, pydevsupComOut, "Python Device") + +device(mbbiDirect, INST_IO, pydevsupComIn, "Python Device") +device(mbboDirect, INST_IO, pydevsupComOut, "Python Device") + +device(waveform, INST_IO, pydevsupComIn, "Python Device") +device(aai, INST_IO, pydevsupComIn, "Python Device") +device(aao, INST_IO, pydevsupComOut, "Python Device") From b955d0aa22cc1a2d2f79ea25d78519cc9740f0e8 Mon Sep 17 00:00:00 2001 From: Peter Heesterman Date: Thu, 30 Jul 2026 16:05:19 +0100 Subject: [PATCH 3/5] Added the calcout record because @andrewstarritt wants it. --- devsupApp/src/devsup/_dbapi.dbd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/devsupApp/src/devsup/_dbapi.dbd b/devsupApp/src/devsup/_dbapi.dbd index 0d791aa..32aae22 100644 --- a/devsupApp/src/devsup/_dbapi.dbd +++ b/devsupApp/src/devsup/_dbapi.dbd @@ -1,13 +1,13 @@ device(longin, INST_IO, pydevsupComIn, "Python Device") device(longout, INST_IO, pydevsupComOut, "Python Device") +device(calcout, INST_IO, pydevsupComOut, "Python Device") device(ai, INST_IO, pydevsupComIn, "Python Device") device(ao, INST_IO, pydevsupComOut, "Python Device") device(stringin, INST_IO, pydevsupComIn, "Python Device") device(stringout, INST_IO, pydevsupComOut, "Python Device") - device(bi, INST_IO, pydevsupComIn, "Python Device") device(bo, INST_IO, pydevsupComOut, "Python Device") From abe794bc6baa823b05d6c5e155bc2564f05ebc58 Mon Sep 17 00:00:00 2001 From: Peter Heesterman Date: Tue, 4 Aug 2026 17:24:20 +0100 Subject: [PATCH 4/5] Removed Windows-specific RELEASE file. Removed the calcout type from _dbdapi.dbd Reverted use of get_pyhon_version to use of get_config_var('VERSION'). Added use of to setup.c to resolve a compiler warning. --- configure/RELEASE.windows-x64.common | 42 ---------------------------- devsupApp/src/devsup/_dbapi.dbd | 1 - makehelper.py | 2 +- pyIocApp/setup.c | 1 + 4 files changed, 2 insertions(+), 44 deletions(-) delete mode 100644 configure/RELEASE.windows-x64.common diff --git a/configure/RELEASE.windows-x64.common b/configure/RELEASE.windows-x64.common deleted file mode 100644 index 35661a6..0000000 --- a/configure/RELEASE.windows-x64.common +++ /dev/null @@ -1,42 +0,0 @@ -# RELEASE - Location of external support modules -# -# IF YOU MAKE ANY CHANGES to this file you must subsequently -# do a "gnumake rebuild" in this application's top level -# directory. -# -# The build process does not check dependencies against files -# that are outside this application, thus you should do a -# "gnumake rebuild" in the top level directory after EPICS_BASE -# or any other external module pointed to below is rebuilt. -# -# Host- or target-specific settings can be given in files named -# RELEASE.$(EPICS_HOST_ARCH).Common -# RELEASE.Common.$(T_A) -# RELEASE.$(EPICS_HOST_ARCH).$(T_A) -# -# This file should ONLY define paths to other support modules, -# or include statements that pull in similar RELEASE files. -# Build settings that are NOT module paths should appear in a -# CONFIG_SITE file. - -TEMPLATE_TOP=$(EPICS_BASE)/templates/makeBaseApp/top - -## Optional Modules ## -# Comment out if not present - -# IOC statistics (cpu and mem usage, ...) -#DEVIOCSTATS=$(EPICS_BASE) - -# automatic save with restore on boot -#AUTOSAVE=$(EPICS_BASE) - -# logging of remote settings changes -#CAPUTLOG=$(EPICS_BASE) - -## Required Modules ## - -# EPICS_BASE usually appears last so other apps can override stuff: -#EPICS_BASE=C:/epics/base - --include $(TOP)/configure/RELEASE.local --include $(TOP)/../RELEASE.local diff --git a/devsupApp/src/devsup/_dbapi.dbd b/devsupApp/src/devsup/_dbapi.dbd index 32aae22..b42785a 100644 --- a/devsupApp/src/devsup/_dbapi.dbd +++ b/devsupApp/src/devsup/_dbapi.dbd @@ -1,7 +1,6 @@ device(longin, INST_IO, pydevsupComIn, "Python Device") device(longout, INST_IO, pydevsupComOut, "Python Device") -device(calcout, INST_IO, pydevsupComOut, "Python Device") device(ai, INST_IO, pydevsupComIn, "Python Device") device(ao, INST_IO, pydevsupComOut, "Python Device") diff --git a/makehelper.py b/makehelper.py index b396dcc..e281f39 100644 --- a/makehelper.py +++ b/makehelper.py @@ -46,7 +46,7 @@ print('TARGET_CFLAGS +=',get_config_var('BASECFLAGS') or '', file=out) print('TARGET_CXXFLAGS +=',get_config_var('BASECFLAGS') or '', file=out) -print('PY_VER :=',get_python_version(), file=out) +print('PY_VER :=',get_config_var('VERSION'), file=out) ldver = get_config_var('LDVERSION') if ldver is None: ldver = get_config_var('VERSION') diff --git a/pyIocApp/setup.c b/pyIocApp/setup.c index 617661f..0e75d51 100644 --- a/pyIocApp/setup.c +++ b/pyIocApp/setup.c @@ -24,6 +24,7 @@ #include "pydevsup.h" #ifdef _WIN32 +#include #define PATH_MAX _MAX_PATH #endif From 565446df05da2f222c4312e7cec97abb9fbabbb3 Mon Sep 17 00:00:00 2001 From: Peter Heesterman Date: Sat, 8 Aug 2026 10:45:57 +0100 Subject: [PATCH 5/5] Added f-string prefix to text with parameter parsing. --- devsupApp/src/devsup/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/devsupApp/src/devsup/__init__.py b/devsupApp/src/devsup/__init__.py index 16898f7..8bb090b 100644 --- a/devsupApp/src/devsup/__init__.py +++ b/devsupApp/src/devsup/__init__.py @@ -22,7 +22,7 @@ cookie = kernel32.AddDllDirectory(dll_path) if not cookie: error = ctypes.get_last_error() - raise OSError("Failed to add DLL directory: {error}") + raise OSError(f"Failed to add DLL directory: {error}") from . import _dbapi