Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
34 changes: 34 additions & 0 deletions .github/workflows/ci-scripts-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -169,6 +202,7 @@ jobs:
with:
python-version: ${{ matrix.python }}
- name: More Setup Python
shell: bash
run: |
python --version
python -m pip --version
Expand Down
4 changes: 4 additions & 0 deletions configure/CONFIG_PY
Original file line number Diff line number Diff line change
Expand Up @@ -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
8 changes: 4 additions & 4 deletions configure/RULES_PY
Original file line number Diff line number Diff line change
@@ -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)

Expand Down
7 changes: 7 additions & 0 deletions devsupApp/src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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...
Expand Down
4 changes: 3 additions & 1 deletion devsupApp/src/dbdset.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include <aSubRecord.h>

#include "pydevsup.h"
#include <shareLib.h>

static int inshutdown;

Expand Down Expand Up @@ -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)
{
Expand Down
51 changes: 25 additions & 26 deletions devsupApp/src/devsup/__init__.py
Original file line number Diff line number Diff line change
@@ -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(f"Failed to add DLL directory: {error}")

from . import _dbapi

from ._dbapi import (EPICS_VERSION_STRING,
Expand Down Expand Up @@ -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):
Expand Down
21 changes: 21 additions & 0 deletions devsupApp/src/devsup/_dbapi.dbd
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@

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")
5 changes: 3 additions & 2 deletions devsupApp/src/devsup/test/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
4 changes: 2 additions & 2 deletions iocBoot/iocFPM/Makefile
Original file line number Diff line number Diff line change
@@ -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
4 changes: 2 additions & 2 deletions iocBoot/iocapplmon/Makefile
Original file line number Diff line number Diff line change
@@ -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
2 changes: 1 addition & 1 deletion iocBoot/iocapplmon/st.cmd
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!../../bin/linux-x86/softIocPy3.6
#!../../bin/linux-x86_64/softIocPy3.6

< envPaths

Expand Down
4 changes: 2 additions & 2 deletions iocBoot/iocarchivemon/Makefile
Original file line number Diff line number Diff line change
@@ -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
2 changes: 1 addition & 1 deletion iocBoot/iocarchivemon/st.cmd
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!../../bin/linux-x86/softIocPy3.6
#!../../bin/linux-x86_64/softIocPy3.6

< envPaths

Expand Down
4 changes: 2 additions & 2 deletions iocBoot/ioccaputlog/Makefile
Original file line number Diff line number Diff line change
@@ -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
4 changes: 2 additions & 2 deletions iocBoot/iocweatherbnl/Makefile
Original file line number Diff line number Diff line change
@@ -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
29 changes: 9 additions & 20 deletions makehelper.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()]
Expand All @@ -54,8 +43,8 @@
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)
ldver = get_config_var('LDVERSION')
Expand Down Expand Up @@ -84,4 +73,4 @@

print('PY_OK := YES', file=out)

out.close()
out.close()
2 changes: 2 additions & 0 deletions pyIocApp/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand All @@ -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
Expand Down
4 changes: 4 additions & 0 deletions pyIocApp/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@
#include <alarm.h>

#include "pydevsup.h"
#ifdef _WIN32
#include <direct.h>
#define PATH_MAX _MAX_PATH
#endif

static void cleanupPy(void *junk)
{
Expand Down
Loading