On 5/31/25 11:07, Alexandros Drymonitis wrote:
I've changed the Makefile to the following (maybe there are mistakes, like where the -rdynamic should go or others):
why is it there in the first place?
# Makefile for pyo~ lib.name = pyo~ class.sources = pyo~.c cflags = -rdynamic -I"$(PD_INCLUDE)" -I.. -Wno-cast-function-type -Wno- unused-parameter -I/usr/include/python3.11 $(shell pkg-config --cflags --embed python3.11) ldflags = -lpython3.11 $(shell pkg-config --ldflags --embed python3.11) libs = -L/usr/lib/ $(shell pkg-config --libs --embed python3.11)
that appears to do an awful lot of unneeded ('-I"$(PD_INCLUDE")' is already handled by pd-lib-builder), redundant (e.g. why is "-L/usr/lib/" there in the first place? if it is not searched for by default, then there's probably a good reason; why do you have *both* the hardcoded "/usr/include/python3.11" and a call to pkg-config?) and broken (I don't know of any pkg-config that accepts the "--embed" flag) stuff.
anyhow, i've cleaned up the Makefile, like so:
# Makefile for pyo~
lib.name = pyo~
class.sources = pyo~.c
PKG_CONFIG := pkg-config
PYTHON=python3
PY_CFLAGS := $(shell $(PKG_CONFIG) --cflags $(PYTHON))
PY_LIBS := $(shell $(PKG_CONFIG) --libs $(PYTHON))
cflags += $(PY_CFLAGS) -I../
ldlibs += $(PY_LIBS)
datafiles = pyo-help.pd README.md
PDLIBBUILDER_DIR=../pd-lib-builder/
include $(PDLIBBUILDER_DIR)/Makefile.pdlibbuilder
if your python installation does not provide pkgconf scripts for "python3", you can pass it on the cmdline like so:
make PYTHON=python3.11
if you are still not happy with the flags provided by pkgconf, you can pass them manually, like so:
make PY_CFLAGS="$(python3.11-config --embed --cflags)"
PY_LIBS="$(python3.11-config --embed --libs)"
having said that, I've compiled the external with python3.13 (Debian/trixie/sid), but...
The object builds, but I'm still getting the
undefined symbol: _Py_NoneStruct
error
and I get the same error as well.
as said previously, "I'm not up-to-date when it comes to python C-development". however, force-loading the python-library apparently fixes the problem for me:
LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libpython3.13.so pd pyo~-help.pd
(the help-patch depends on cyclone, but anyhow).
apparently, you should adjust the path to the libpython.so on your system.
also note, that LD_PRELOAD is general not a good idea (and you should *definitely not* set the environment variable globally, unless you are really into kneecapping and the like)
In a filed used to create the object, called m_pyo.h, line 71 reads:
#ifdef __linux__ libpython_handle = dlopen("libpython3.11.so", RTLD_LAZY | RTLD_GLOBAL);
no idea where you got the sources from, but afaict current [master] says "libpython3.9.so".
in any case, the idea of the code is that it will dynamically load the python runtime library to resolve all the symbols. but this is broken. afaict, that's because the binaries *really* use the "_Py_NoneStruct" symbol directly, rather than deferring the symbol resolution till the dlopen() succeeded. (the consequence is, that fixing the numbers in the dlopen() call, won't help).
this wouldn't be a problem is the myo~.pd_linux was linked directly
against the libpython.
however, pkg-config --libs python3
does not tell the linker to do so,
for whatever reasons (afaict, the idea is really to use dlopen() to open
the library at runtime, rather than adding a hard dependency on the lib).
so my take is, that there is simply some bug on pyo (and probably it doesn't show on macOS, because they allow weak-linkage)
in any case, overriding the linker flags fixes this easily:
make PY_LIBS="-lpython3.13"
alternatively, using "python3.13-config --embed" should also give you the correct flags:
make PDLIBBUILDER_DIR=/usr/share/pd-lib-builder/
PY_CFLAGS="$(python3.13-config --embed --cflags)"
PY_LIBS="$(python3.13-config --embed --libs)"
(this line is basically just repeating what i already wrote above)
gmasdr IOhannes
[master] https://github.com/belangeo/pyo/blob/a7cbe87a52330defdede1f31d29ed719712a08a8/embedded/m_pyo.h#L71