How the Python binding is created¶
Simplified overview¶
Detailed steps¶
libnopegl → nodes.specs¶
libnopegl writes the nodes.specs specifications in JSON using a
dedicated tool (gen_specs.c) crawling the internal node C
definitions.
This generated nodes.specs file (see updatespecs build rule in libnopegl’s
generated Makefile) is installed on the system or targeted environment by the
install rule.
nodes.specs ← pynopegl¶
In its setup.py, pynopegl uses pkg-config to query the
libnopegl installation data directory, in order to obtain the path to the
installed nodes.specs file. The file is then loaded as JSON file.
pynopegl → nodes_def.pyx¶
Using the loaded nodes.specs as JSON, setup.py writes the Cython code
definitions into a nodes_def.pyx file.
nodes_def.pyx ← Cython¶
The setuptools module used to package pynopegl calls Cython to read the
generated .pyx file (along with _pynopegl.pyx).
Cython → _pynopegl.c¶
From the .pyx files, Cython will generate a C source code using the C
Python API. This source file declares the Python classes calling the libnopegl
C functions, based on the rules contained in the .pyx files.
_pynopegl.c ← C compiler¶
In the Cython toolchain triggered by the setuptools, a C compiler will compile
the generated C source.
C compiler → _pynopegl.so¶
Compiled source ends up being linked against Python library to create a
_pynopegl.so loadable Python module.
pynopegl ← _pynopegl.so¶
The final binding exposed to the user is a traditional pure Python module,
which imports the native _pynopegl module. All the nodes and their methods
are dynamically generated into that module at runtime.