Skip to content

Commit 2536321

Browse files
author
Peter Heesterman
committed
Tested Windows (and Linux) builds with Base 3.15.
Excluded int64 and long string for that reason. Base 3.14 doesn't work because RuntimeError: Requires Base >=3.15.
1 parent 13e5cbe commit 2536321

7 files changed

Lines changed: 144 additions & 28 deletions

File tree

.github/workflows/ci-scripts-build.yml

Lines changed: 106 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@ env:
1111

1212
jobs:
1313
build-base:
14-
name: ${{ matrix.base }}/${{ matrix.os }}/${{ matrix.python }}/${{ matrix.extra }}
14+
name: ${{ matrix.base }}/${{ matrix.os }}/${{ matrix.profile }}/${{ matrix.python }}/${{ matrix.extra }}
1515
runs-on: ${{ matrix.os }}
16+
container: ${{ matrix.container }}
1617
# Set environment variables from matrix parameters
1718
env:
1819
CMP: ${{ matrix.cmp }}
@@ -27,6 +28,57 @@ jobs:
2728
fail-fast: false
2829
matrix:
2930
include:
31+
- os: ubuntu-latest
32+
cmp: gcc
33+
configuration: default
34+
base: "7.0"
35+
python: "3.7"
36+
profile: deb10
37+
container: "python:3.7"
38+
test: yes
39+
40+
- os: ubuntu-latest
41+
cmp: gcc
42+
configuration: default
43+
base: "7.0"
44+
python: "3.9"
45+
profile: deb11
46+
test: yes
47+
48+
- os: ubuntu-latest
49+
cmp: gcc
50+
configuration: default
51+
base: "7.0"
52+
python: "3.11"
53+
profile: deb12
54+
test: yes
55+
56+
- os: ubuntu-latest
57+
cmp: gcc
58+
configuration: default
59+
base: "7.0"
60+
python: "3.13"
61+
profile: deb13
62+
test: yes
63+
64+
- os: ubuntu-latest
65+
cmp: gcc
66+
configuration: default
67+
base: "7.0"
68+
python: "3.6"
69+
container: "python:3.6"
70+
profile: latest
71+
test: yes
72+
73+
- os: ubuntu-latest
74+
cmp: gcc
75+
configuration: default
76+
base: "7.0"
77+
python: "3.7"
78+
container: "python:3.7"
79+
profile: latest
80+
test: yes
81+
3082
- os: ubuntu-latest
3183
cmp: gcc
3284
configuration: default
@@ -51,6 +103,14 @@ jobs:
51103
profile: latest
52104
test: yes
53105

106+
- os: ubuntu-latest
107+
cmp: gcc
108+
configuration: default
109+
base: "7.0"
110+
python: "3.11"
111+
profile: latest
112+
test: yes
113+
54114
- os: ubuntu-latest
55115
cmp: gcc
56116
configuration: default
@@ -59,6 +119,14 @@ jobs:
59119
profile: latest
60120
test: yes
61121

122+
- os: ubuntu-latest
123+
cmp: gcc
124+
configuration: default
125+
base: "7.0"
126+
python: "3.13"
127+
profile: latest
128+
test: yes
129+
62130
- os: macos-latest
63131
cmp: gcc
64132
configuration: default
@@ -67,6 +135,40 @@ jobs:
67135
profile: latest
68136
test: yes
69137

138+
- os: ubuntu-latest
139+
cmp: gcc
140+
configuration: default
141+
base: "3.15"
142+
python: "3.7"
143+
container: "python:3.7"
144+
profile: deb10
145+
test: yes
146+
147+
- os: ubuntu-latest
148+
cmp: gcc
149+
configuration: default
150+
base: "3.15"
151+
python: "3.13"
152+
profile: deb13
153+
test: yes
154+
155+
#- os: ubuntu-latest
156+
# cmp: gcc
157+
# configuration: default
158+
# base: "3.14" # RuntimeError: Requires Base >=3.15 ??
159+
# python: "3.7"
160+
# container: "python:3.7"
161+
# profile: deb10
162+
# test: yes
163+
164+
- os: windows-latest
165+
cmp: vs2022
166+
configuration: default
167+
base: "3.15"
168+
python: "3.11"
169+
profile: latest
170+
test: yes
171+
70172
- os: windows-latest
71173
cmp: vs2022
72174
configuration: default
@@ -96,6 +198,7 @@ jobs:
96198
with:
97199
submodules: true
98200
- name: Set up Python ${{ matrix.python }}
201+
if: ${{ !matrix.container }}
99202
uses: actions/setup-python@v4
100203
with:
101204
python-version: ${{ matrix.python }}
@@ -110,13 +213,8 @@ jobs:
110213
EOF
111214
echo === configure/CONFIG_SITE.local ===
112215
cat configure/CONFIG_SITE.local
113-
- name: makehelper.py
114-
run: python makehelper.py
115-
- name: DSOs
116-
shell: bash
117-
run: find ${Python_ROOT_DIR} -name '*.dll' -o -name '*.so' -o -name '*.dylib'
118-
- name: get_config_vars
119-
run: python -c 'from sysconfig import get_config_vars; from pprint import pprint; pprint(get_config_vars())'
216+
- name: Python sysconfig
217+
run: python -m sysconfig
120218
- name: Prepare and compile dependencies
121219
run: python .ci/cue.py prepare
122220
- name: Build main module

devsupApp/src/dbfield.c

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,9 @@
33
#undef _POSIX_C_SOURCE
44
#undef _XOPEN_SOURCE
55

6-
#ifdef _DEBUG
7-
#undef _DEBUG
86
#include <Python.h>
97
#ifdef HAVE_NUMPY
10-
#include <numpy/ndarrayobject.h>
11-
#endif
12-
#define _DEBUG
13-
#else
14-
#include <Python.h>
15-
#include <numpy/ndarrayobject.h>
8+
#include <_numpy/ndarrayobject.h>
169
#endif
1710

1811
#include <epicsVersion.h>
@@ -29,6 +22,11 @@
2922
#endif
3023

3124
#ifdef HAVE_NUMPY
25+
/* See https://numpy.org/devdocs/reference/c-api/array.html */
26+
/* Allow compiling on NumPy 1.x */
27+
#if NPY_ABI_VERSION < 0x02000000
28+
#define PyArray_DescrProto PyArray_Descr
29+
#endif
3230
static const int dbf2np_map[DBF_MENU+1] = {
3331
NPY_STRING, // DBF_STRING
3432
NPY_BYTE, // DBF_CHAR
@@ -46,7 +44,7 @@ static const int dbf2np_map[DBF_MENU+1] = {
4644
NPY_INT16, // DBF_ENUM
4745
NPY_INT16, // DBF_MENU
4846
};
49-
static PyArray_Descr* dbf2np[DBF_MENU+1];
47+
static PyArray_DescrProto* dbf2np[DBF_MENU+1];
5048
#endif
5149

5250
typedef struct {
@@ -126,23 +124,24 @@ static int assign_array(DBADDR *paddr, PyObject *arr)
126124
#ifdef HAVE_NUMPY
127125
void *rawfield = paddr->pfield;
128126
rset *prset;
129-
PyObject *aval;
127+
PyArrayObject *aval;
128+
PyArrayObject * array = (PyArrayObject *)arr;
130129
unsigned elemsize = dbValueSize(paddr->field_type);
131130
unsigned long maxlen = paddr->no_elements, insize;
132131
PyArray_Descr *desc = dbf2np[paddr->field_type];
133132

134133
if(paddr->field_type==DBF_STRING &&
135-
(PyArray_NDIM(arr)!=2 || PyArray_DIM(arr,0)>maxlen || PyArray_DIM(arr,1)!=MAX_STRING_SIZE))
134+
(PyArray_NDIM(array)!=2 || PyArray_DIM(array,0)>maxlen || PyArray_DIM(array,1)!=MAX_STRING_SIZE))
136135
{
137136
PyErr_Format(PyExc_ValueError, "String array has incorrect shape or is too large");
138137
return 1;
139138

140-
} else if(PyArray_NDIM(arr)!=1 || PyArray_DIM(arr,0)>maxlen) {
139+
} else if(PyArray_NDIM(array)!=1 || PyArray_DIM(array,0)>maxlen) {
141140
PyErr_Format(PyExc_ValueError, "Array has incorrect shape or is too large");
142141
return 1;
143142
}
144143

145-
insize = PyArray_DIM(arr, 0);
144+
insize = PyArray_DIM(array, 0);
146145

147146
if(paddr->special==SPC_DBADDR &&
148147
(prset=dbGetRset(paddr)) &&

devsupApp/src/devsup/__init__.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@
5858
__all__ = []
5959

6060

61+
def epics_version_int():
62+
return (EPICS_VERSION, EPICS_REVISION, EPICS_MODIFICATION, EPICS_PATCH_LEVEL)
63+
6164
def _init(iocMain=False):
6265
if not iocMain:
6366
# we haven't read/register base.dbd
@@ -68,11 +71,12 @@ def _init(iocMain=False):
6871
dirname = os.path.dirname(__file__)
6972
dbd_name = dirname + "/_dbapi.dbd"
7073
_dbapi.dbReadDatabase(dbd_name)
71-
epics_version_int = (EPICS_VERSION, EPICS_REVISION, EPICS_MODIFICATION, EPICS_PATCH_LEVEL)
72-
if epics_version_int >= (3, 15, 0, 2):
74+
if epics_version_int() >= (3, 15, 0, 2):
75+
# Long strings are impletemented.
7376
dbd_name = dirname + "/_lsilso.dbd"
7477
_dbapi.dbReadDatabase(dbd_name)
75-
if epics_version_int >= (3, 16, 1, 0):
78+
if epics_version_int() >= (3, 16, 1, 0):
79+
# Long ints are impletemented.
7680
dbd_name = dirname + "/_int64.dbd"
7781
_dbapi.dbReadDatabase(dbd_name)
7882
_dbapi._dbd_setup()

devsupApp/src/devsup/test/test_db.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
from ..db import getRecord
1111
from .. import _dbapi
12-
from .. import _init
12+
from .. import _init, epics_version_int
1313

1414
from .util import IOCHelper
1515

@@ -142,8 +142,15 @@ class TestLongStringField(IOCHelper):
142142
field(OMSL, "closed_loop")
143143
}
144144
"""
145+
if epics_version_int() < (3, 15, 0, 2):
146+
# Long strings not impletemented yet.
147+
db = None
145148

146149
def test_lsilso(self):
150+
if epics_version_int() < (3, 15, 0, 2):
151+
# Long strings not impletemented yet.
152+
return
153+
147154
lsi = getRecord("rec:lsi")
148155
lso = getRecord("rec:lso")
149156

@@ -176,8 +183,14 @@ class TestInt64Field(IOCHelper):
176183
field(OMSL, "closed_loop")
177184
}
178185
"""
186+
if epics_version_int() < (3, 16, 1, 0):
187+
# Long ints not impletemented yet.
188+
db = None
179189

180190
def testint64(self):
191+
if epics_version_int() < (3, 16, 1, 0):
192+
# Long ints not impletemented yet.
193+
return
181194
in64 = getRecord("rec:in64")
182195
out64 = getRecord("rec:out64")
183196

makehelper.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
print('PY_INCDIRS :=',' '.join(incdirs), file=out)
5454
print('PY_LIBDIRS :=',libdir, file=out)
5555
if sys.platform == 'win32':
56-
print('PY_LDLIBS :=', '/LIBPATH:' + os.path.join(sys.prefix, 'libs'), file=out)
56+
print('PY_LDLIBS :=', '-LIBPATH:' + os.path.join(sys.prefix, 'libs'), file=out)
5757
print('HAVE_NUMPY :=',have_np, file=out)
5858

5959
try:

pyIocApp/devsupMain.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ int main(int argc, char *argv[])
205205
iocsh(NULL);
206206
} else {
207207
if (loadedDb) {
208-
//epicsThreadExitMain();
208+
epicsThreadExitMain();
209209
} else {
210210
printf("%s: Nothing to do!\n", arg0);
211211
usage(EXIT_FAILURE);

pyIocApp/setup.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424

2525
#include "pydevsup.h"
2626
#ifdef _WIN32
27-
#include <stdlib.h>
2827
#define PATH_MAX _MAX_PATH
2928
#endif
3029

@@ -134,7 +133,10 @@ static void cleanupPrep(initHookState state)
134133
static void pySetupReg(void)
135134
{
136135
Py_InitializeEx(0);
136+
#if NPY_TARGET_VERSION < NPY_1_9_API_VERSION
137+
/* See https://docs.python.org/3/whatsnew/3.9.html */
137138
PyEval_InitThreads();
139+
#endif
138140

139141
setupPyPath();
140142

0 commit comments

Comments
 (0)