Skip to content

Conversation

@pheest
Copy link
Collaborator

@pheest pheest commented Sep 5, 2023

In Makehelper.py, replaced use of Linux-specific library path configuration variables with get_python_lib() call.

In Rules.py, added use of xcopy to copy Python files to the install path for Windows use.

In devsupapp/source/dbfield.c, added support capability for lsi record type by:
replacing fixed 40-charachter string limit with variable length.
Calling the 'special' method of lsiRecord.c to set the record string length.

In devsupapp/source/makefile:
A Windows Python loadable module has the file extenstion '.pyd' (not .dll). Overrode the SHRLIB_SUFFIX_BASE variable to apply this.
Added new files _dbapi.dbd, _int64.dbd and _lsilso.dbd. Set these to copy to the same folder as Python files (although they aren't).

In devsupapp/source/devsup:
added _dbapi.dbd, _int64.dbd and _lsilso.dbd
in init.py, replaced use of temporary file with the above static files. _int64 and _lsilso are loaded conditionally on the EPICS base version.

In devsupapp/source/devsup/disect.py:
InstanceType is imported at line 6 for Python 2 usage, and will raise an exception with Python 3.
This is tested at line 84 with elif InstanceType is not None.
But when the excpetion is raised, InstanceType is not None, it is undefined - causing the application to fail.
Added InstanceType = None to ensure this doesn't happen.

In devsuppapp/source added changes to support alarm handling on output PVs, according to the mail sent on 06/07.
To control the stat and sevr record fields.

In pyiocapp/setup.c added the definition PATH_MAX (as _MAX_PATH) for Windows use.
In devsupapp/source/devsup/init.py _init() EPICS base.dbd is loaded on condition 'if not iocMain'.
But In pyiocapp/setup.c passed 'iocMain = True' in pySetupReg() ... so where is EPICS base.dbd loaded in _dbapi?
Changed to iocMain = False.

Copy link
Collaborator

@mdavidsaver mdavidsaver left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good aside from some minor cleanup.

install -m 644 $< $@
else
xcopy /S /Q /Y /F $(subst /,\,$<) $(subst /,\,$@)*
endif
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You (and I...) should use $(INSTALL) as is done by the install rules in Base.

https://github.com/epics-base/epics-base/blob/a74789d9c0e55f6499b66f99cf0a745c681d884f/configure/RULES.Db#L309


LOADABLE_LIBRARY_HOST += _dbapi
ifeq ($(OS),Windows_NT)
SHRLIB_SUFFIX_BASE = .pyd
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be in configure/CONFIG_PY, where the equivalent for Darwin/OSX is set.

ifeq ($(OS_CLASS),WIN32)
LOADABLE_SHRLIB_SUFFIX = .pyd
endif

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, but I get a build error - which I can resolve by setting:
LOADABLE_LIBRARY_HOST_DEFAULT += _dbapi
LOADABLE_LIBRARY_HOST_WIN32 += _dbapi.pyd

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does need to be SHRLIB_SUFFIX_BASE (setting LOADABLE_SHRLIB_SUFFIX does not have the desired effect).
But this can be, as you suggest, in CONFIG.PY.

_dbapi.dbReadDatabase(dbd_name)
# e.g. 3.15.0.2 -> 30000 + 1500 + 0 + 2 = 31502
epics_version_int = EPICS_VERSION * 10000 + EPICS_REVISION * 100 + EPICS_MODIFICATION * 10 + EPICS_PATCH_LEVEL
if epics_version_int >= 31502:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While this will certainly work, fyi. tuple comparison is shorter and easier to understand. (cf. sys.version_info)

epics_version_int = (EPICS_VERSION, EPICS_REVISION, EPICS_MODIFICATION, EPICS_PATCH_LEVEL)
if epics_version_int >= (3, 15, 0, 2):

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Noted.

makehelper.py Outdated
from distutils.sysconfig import get_python_inc, get_python_lib
except ImportError:
def get_python_inc():
return get_config_var('INCLUDEPY') or ''
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is a fallback get_python_lib() needed here as well?

pyIocApp/setup.c Outdated
#include "pydevsup.h"
#ifdef _WIN32
#define PATH_MAX _MAX_PATH
#include <direct.h>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the order of these two lines change the behavior of direct.h?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, I don't think so. It's more appropriate the other way round.
And _MAX_PATH is actually defined in stdlib.h.

pyIocApp/setup.c Outdated

if(PyRun_SimpleString("import devsup\n"
"devsup._init(iocMain=True)\n"
"devsup._init(iocMain=False)\n"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this change necessary now that _init() does not use NamedTemporaryFile?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The two are separate in _init(). I'm not too sure what was intended here, but I do not see any existing call of _init() that caused base to load, and this is still the case.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

base would of course have been loaded by the IOC start-up.
So I'm not sure whether loading it from _dbapi is actually required anyway.

@@ -1,2 +1,3 @@
numpy==1.16.2
nose==1.3.7
#nose==1.3.7
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think references to nose v1 can be entirely removed.

@mdavidsaver
Copy link
Collaborator

Some files which I don't think should be changed/added by this PR.

  • configure/RELEASE
  • configure/RELEASE.windows-x64.common
  • pyDevSup.sln

@mdavidsaver
Copy link
Collaborator

I am not sure why the github actions jobs have not started. Maybe the conflict in makehelper.py. Maybe something to do with an ongoing issue. https://www.githubstatus.com/

pheest and others added 4 commits September 5, 2023 14:57
…CONFIG_BASE for the definition of the INSTALL macro.

epicsThreadExitMain is deprecated by recent EPICS base versions (and resolves to cantProceed). Being unsure as to what best to do about this, I commented it out in devSupMain.cpp.

Python 2.7 has been obsoleted and won't install on the runner without taking special measures.
Being unsure what to do about this, I have commented out builds that invoke 2.7.

Github Windows-latest (i.e. Windows server 2022) is installed with VS2022 (not VS2019).
Use of the debug build configuration will seek to link with the Python debug libraries that are not normally installed. I have a solution to this problem but we should debate how to proceed.

Github Windows server 2019 is, I think, installed with VS2019, this should build OK with default configuration.
@pheest
Copy link
Collaborator Author

pheest commented Sep 12, 2023

Please may I query the intended purpose of the PY_LDLIBS variable that is output from makehelper.py?

@mdavidsaver
Copy link
Collaborator

Please may I query the intended purpose of the PY_LDLIBS variable that is output from makehelper.py?

from sysconfig import get_config_var
print(get_config_var('BLDLIBRARY'))

On linux/debian 12 this prints -lpython3.11.

In *nix convention, LDLIBS contains -l* entries mentioning library names, while LDFLAGS has -L* setting the search path.

In this context, my goal was that PY_LDLIBS contain -lpython* as well as any additional dependencies. Possibly libraries like -ldl, -lz, or maybe winsock.

@pheest
Copy link
Collaborator Author

pheest commented Sep 13, 2023

Thank you, Michael,

My point is that the PY_LDLIBS variable does not appear to have been applied within the build process (unless I'm missing something...).

The variable can be applied with e.g. pyDevSup$(PY_LD_VER)_LDFLAGS += $(PY_LDLIBS), in replacement of e.g. pyDevSup$(PY_LD_VER)_SYS_LIBS += python$(PY_LD_VER).

I've tested this on Red Hat ('-L. -lpython3.6m') and Ubuntu ('-lpython3.10').

The BLDLIBRARY variable is not emitted from Python on Windows.
I've created it in makehelper.py for that case.

Is this your preferred approach?

@pheest
Copy link
Collaborator Author

pheest commented Sep 13, 2023

Where I'm coming from with this is that the Windows build failed because it couldn't locate the .LIB file.
It worked on my PC because I had set LIB=%LIB%;C:\Python310\libs in my win32.bat file. That's not a portable approach, and I removed it.

I have no idea at this time why the Python 3.7 .. 3.9 builds failed - where the 3.10 build succeeded.

On Windows, the library isn't in a system folder so the fully-qualified path is required.
@ralphlange
Copy link
Member

@mdavidsaver: Where are we on this?
To me, it looks as if there are only minor issues remaining. (If any.)

Background: Peter uses this on ITER-related work, so I need to include it in our CODAC packaging of pyDevSup. Obviously, I would prefer an upstream merge, as opposed to something I do only for our CODAC packaging = that I might need to clean up later...

@eddybl
Copy link

eddybl commented Aug 8, 2024

There will be a potential conflict in makehelper.py if #39 is merged

@pheest
Copy link
Collaborator Author

pheest commented Aug 9, 2024

The conflict has been addressed.
This also required to address the numpy 2.0 issue noted by another user.

@eddybl
Copy link

eddybl commented Aug 9, 2024

I actually do not think your fix to makehelper.py will work, as distutils.sysconfig and sysconfig are not replaceable and get_python_inc is not available from sysconfig

But maybe we should just wait for the other PR to be merged (or maybe modified). I just wanted to note down that there might be a potential change required here down the line, depending on the PR resolve order

@pheest
Copy link
Collaborator Author

pheest commented Aug 9, 2024 via email

@pheest
Copy link
Collaborator Author

pheest commented Aug 13, 2024

I confirm that my version does not work with Python 3.12, due to distutils being removed.

@eddybl, I saw your pull request #39 .
That is considerably cleaner, thank you.

I confirm that it works with Linux to 3.12.

It does not work (as it stands) with Windows because:

The library directory is not contained within 'LIBDIR' but within 'LIBDEST'.

'BASECFLAGS' does not exist, so the compiler tries to build a non-existent file called 'Null'.

get_python_version() returns e.g. 3.11 (both Linux and Windows), so the linker tries to use python3.11.lib - but the file is actually python311.lib.
'VERSION' contains '3.11' on Linux but '311' on Windows, so that works for both.

The Windows Python library path is not a system path, so that needs to be explicitly specified.

I have created a merged version from yours, and tested it in my 'devel' branch, with the necessary changes for Windows use.
I have verified that it works for all Python versions to 3.12 on both Linux and Windows.

I have not added this to my pull request, to date.
Should I?

@eddybl
Copy link

eddybl commented Aug 13, 2024

Yes, so i have not considered windows during my changes.

I think it makes sense to push your changes from devel also to this PR.

How the PRs will be resolved is then a question for @mdavidsaver: For example if this PR might get merged soonish, there is no need to merge #39. But if this PR might still be open for a while it might make sense to already merge #39 now, because it is a rather small fix and in that case we most likely have to resolve a small merge conflict for this PR, but that should be doable.

@pheest
Copy link
Collaborator Author

pheest commented Aug 13, 2024

Done, and thank you for your excellent input to this.

@mdavidsaver
Copy link
Collaborator

How the PRs will be resolved is then a question for @mdavidsaver ...

At this point, I think it is apparent to everyone that I don't have sufficient time to act as maintainer of pyDevSup, and it isn't clear when I will. I also don't want my lack of time to be a barrier to other who are willing to contribute.

So what to do?

Are others willing to take over review? Full maintainer? Transfer this repository? A pyDevSup2 fork? (in keeping with my unimaginative naming...)

@pheest
Copy link
Collaborator Author

pheest commented Aug 14, 2024

Thank you @mdavidsaver for being so open.

I am willing to be a maintainer.

My thoughts:
I think there should ideally be more than one maintainer.
I take the view that the module should be hosted in an organizational site, rather than an individual person's.
I believe maintainers should not approve their own pull requests.
I don't see a need to change the module name.

@eddybl eddybl mentioned this pull request Sep 12, 2025
Peter Heesterman added 4 commits October 10, 2025 16:38
Excluded int64 and long string for that reason.
Base 3.14 doesn't work because RuntimeError: Requires Base >=3.15.
Updated the readme file with changed repository location.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants