I'm trying to compile the [pyo~] external that comes with the Pyo module for DSP in Python http://ajaxsoundstudio.com/software/pyo/. The object uses Pd's old Makefile and does compile, giving me a pyo~.l_ia64 binary file (I'm on Linux, UbuntuStudio 22.04). When I try to load the object in Pd, I get the following error:
/home/alexandros/Documents/Pd/externals/pyo/pyo~.l_ia64: /home/alexandros/Documents/Pd/externals/pyo/pyo~.l_ia64: undefined symbol: _Py_NoneStruct
The same object compiles fine on a Rasbperry Pi 3 and 4.
I also tried to compile it with pd-lib-builder. Here's the Makefile I used, based on the existing Makefile that comes with pyo~.c:
lib.name= pyo~
class.sources= pyo~.c
common.sources= m_pyo.h
cflags= -I"$(PD_INCLUDE)" -I.. -Wno-cast-function-type
-Wno-unused-parameter $(shell python-config --cflags)
ldflags= $(shell python-config --ldflags)
libs= $(shell python-config --libs)
datafiles= pyo-help.pd README.md
PDLIBBUILDER_DIR=../pd-lib-builder/
include$(PDLIBBUILDER_DIR)/Makefile.pdlibbuilder
And here's the output when I type make
:
++++ info: using Makefile.pdlibbuilder version 0.6.0
++++ info: using Pd API /usr/include/pd/m_pd.h
++++ info: making target all in lib pyo~
++++ info: making pyo~.o in lib pyo~
cc -DPD -I "/usr/include/pd" -DUNIX -fPIC -I"" -I..
-Wno-cast-function-type -Wno-unused-parameter -I/usr/include/python3.10
-I/usr/include/python3.10 -Wno-unused-result -Wsign-compare -g
-fstack-protector-strong -Wformat -Werror=
format-security -DNDEBUG -g -fwrapv -O2 -Wall -Wall -Wextra -Wshadow
-Winline -Wstrict-aliasing -O3 -ffast-math -funroll-loops
-fomit-frame-pointer -march=core2 -mfpmath=sse -msse -msse2 -msse3 -o
pyo~.o -c pyo~.c
make: *** No rule to make target 'm_pyo.o', needed by 'pyo~.pd_linux'.
Stop.
In the pyo~.c file there's a #include "Python.h"
. Does this mean that
I should direct the Makefile to find this file? Because no Python.h file
comes with the source code.
Can anyone help?
Am 21. Februar 2023 08:41:48 MEZ schrieb Alexandros adrcki@gmail.com:
ldflags= $(shell python-config --ldflags) libs= $(shell python-config --libs)
[...]
In the pyo~.c file there's a
#include "Python.h"
. Does this mean that I should direct the Makefile to find this file? Because no Python.h file comes with the source code.
Hopefully so. python.h is a file provided by python, and it is paramount that you build against the header file that matches your python installation. So you must install the python development files (python3-dev, or somesuch).
I'm not up-to-date when it comes to python C-development, but I 'python-config' smells like a deprecated tool.
mfg.sfg.jfd IOhannes
On 21/2/23 20:41, IOhannes m zmölnig wrote:
Am 21. Februar 2023 08:41:48 MEZ schrieb Alexandros adrcki@gmail.com:
ldflags= $(shell python-config --ldflags) libs= $(shell python-config --libs)
[...]
In the pyo~.c file there's a
#include "Python.h"
. Does this mean that I should direct the Makefile to find this file? Because no Python.h file comes with the source code.Hopefully so. python.h is a file provided by python, and it is paramount that you build against the header file that matches your python installation. So you must install the python development files (python3-dev, or somesuch).
I'm not up-to-date when it comes to python C-development, but I 'python-config' smells like a deprecated tool.
Initially that was python3-config, but in my system, python
is
Python3, so I thought I change it to python-config
. Is this still a
deprecated tool?
On 2/21/23 20:21, Alexandros wrote:
On 21/2/23 20:41, IOhannes m zmölnig wrote:
Am 21. Februar 2023 08:41:48 MEZ schrieb Alexandros adrcki@gmail.com:
ldflags= $(shell python-config --ldflags) libs= $(shell python-config --libs)
[...]
In the pyo~.c file there's a
#include "Python.h"
. Does this mean that I should direct the Makefile to find this file? Because no Python.h file comes with the source code.Hopefully so. python.h is a file provided by python, and it is paramount that you build against the header file that matches your python installation. So you must install the python development files (python3-dev, or somesuch).
I'm not up-to-date when it comes to python C-development, but I
'python-config' smells like a deprecated tool.Initially that was python3-config, but in my system,
python
is Python3, so I thought I change it topython-config
. Is this still a deprecated tool?
it creates ad-hoc tools with non-normalized interfaces. typically, a preferred way is to use pkg-config or similar tools (that provide a standard way to query compiler/linker flags to build things). this is a general observation, but of course the Python folks can still ship (and prefer) their own tool (hence my "I'm not up-to-date when it comes to python C-development")
you should not arbitrarily change that just becaues you happen to have a 'python-config' script lying somewhere on your disk. (afaict, this script can be installed on Debian via the 'python-dev-is-python3' convenience package. i would *not* recommend relying on this, and use canonical names instead (but again, "I'm not up-to-date when it comes to python C-development" so i might be wrong about what the canonical name is).
it turns out that 'pkg-config --cflags python3' resp 'pkg-config --libs python3' should do the trick as well.
in any case, your real problem is, that your library does not link against the python dynamic library (e.g. libpython3.11). i don't know why "python3-config --libs" does not report the apropriate linker flags ("I'm not up-to-date when it comes to python C-development"), but "python3-config --embed --libs" (and you probably should add the '--embed' flag to all invocations of python3-config), as well as "pkg-config --libs python3-embed".
finally: there's an issuetracker for pyo on https://github.com/belangeo/pyo/issues which might be a better place to ask such specific questions.
mfg IOhannes
I'm reviving this thread as I again took on trying to open the [pyo~] external object in Pd. I know that Pyo has its own channels, but there's too little to no activity there. I've already posted quite some time ago, but I don't think I'll get an answer there.
I've changed the Makefile to the following (maybe there are mistakes, like where the -rdynamic should go or others):
# 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)
datafiles = pyo-help.pd README.md
PDLIBBUILDER_DIR=../pd-lib-builder/
include $(PDLIBBUILDER_DIR)/Makefile.pdlibbuilder
The object builds, but I'm still getting the undefined symbol: _Py_NoneStruct
error when I'm trying to load the object. All online
sources mentioning _Py_NoneStruct refer to the Python shared object,
which, in my system, is located in
/usr/lib/python3.11/config-3.11-x86_64-linux-gnu/.
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);
Anyone savvy in Python-C bindings can help me out?
On 2/23/23 00:01, IOhannes m zmölnig wrote:
On 2/21/23 20:21, Alexandros wrote:
On 21/2/23 20:41, IOhannes m zmölnig wrote:
Am 21. Februar 2023 08:41:48 MEZ schrieb Alexandros adrcki@gmail.com:
ldflags= $(shell python-config --ldflags) libs= $(shell python-config --libs)
[...]
In the pyo~.c file there's a
#include "Python.h"
. Does this mean that I should direct the Makefile to find this file? Because no Python.h file comes with the source code.Hopefully so. python.h is a file provided by python, and it is paramount that you build against the header file that matches your python installation. So you must install the python development files (python3-dev, or somesuch).
I'm not up-to-date when it comes to python C-development, but I 'python-config' smells like a deprecated tool.
Initially that was python3-config, but in my system,
python
is Python3, so I thought I change it topython-config
. Is this still a deprecated tool?
- i was referring to "<foo>-config" being frowned upon in general, as
it creates ad-hoc tools with non-normalized interfaces. typically, a preferred way is to use pkg-config or similar tools (that provide a standard way to query compiler/linker flags to build things). this is a general observation, but of course the Python folks can still ship (and prefer) their own tool (hence my "I'm not up-to-date when it comes to python C-development")
- i *think* the canonical name for the tool is 'python3-config', and
you should not arbitrarily change that just becaues you happen to have a 'python-config' script lying somewhere on your disk. (afaict, this script can be installed on Debian via the 'python-dev-is-python3' convenience package. i would *not* recommend relying on this, and use canonical names instead (but again, "I'm not up-to-date when it comes to python C-development" so i might be wrong about what the canonical name is).
it turns out that 'pkg-config --cflags python3' resp 'pkg-config --libs python3' should do the trick as well.
in any case, your real problem is, that your library does not link against the python dynamic library (e.g. libpython3.11). i don't know why "python3-config --libs" does not report the apropriate linker flags ("I'm not up-to-date when it comes to python C-development"), but "python3-config --embed --libs" (and you probably should add the '--embed' flag to all invocations of python3-config), as well as "pkg-config --libs python3-embed".
finally: there's an issuetracker for pyo on https://github.com/belangeo/pyo/issues which might be a better place to ask such specific questions.
mfg IOhannes
Pd-list@lists.iem.at mailing list UNSUBSCRIBE and account-management -> https://lists.puredata.info/listinfo/pd-list
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