linking to libpari within the sage environment

61 views
Skip to first unread message

Nils Bruin

unread,
12:13 PM (11 hours ago) 12:13 PM
to sage-devel
I ran into an issue with https://github.com/nbruin/RiemannTheta where installing it into modern sage completes without an error but where I get:

sage: import riemann_theta.riemann_theta
ImportError: /usr/local/sage/sage-git/local/var/lib/sage/venv-python3.13/lib64/python3.13/site-packages/riemann_theta/riemann_theta.cpython-313-x86_64-linux-gnu.so: undefined symbol: pari_err

Clearly, libpari doesn't get linked. Previously it did, so this is probably due to some tightening of dependency determination in cython or python's setup machinery.

The setup.py for this project is below. This used to work. Is there an obvious way in which I should change it? Particularly is there something sage-specific that can help here? The package in question really depends quite closely on a lot of sage so it would need to be built within its venv anyway.

--------------------------------------
import setuptools
from Cython.Build import cythonize
import numpy

with open("README.md", "r") as fh:
    long_description = fh.read()

setuptools.setup(
    name='RiemannTheta',
    version="1.0.0",
    author="Nils Bruin, Sohrab Ganjian",
    author_email="nbr...@sfu.ca",
    license="GPL2+",
    description="Evaluate Riemann Theta function numerically in Sagemath",
    long_description=long_description,
    long_description_content_type="text/markdown",
    url="",
    packages=setuptools.find_packages(),
    ext_modules=cythonize("riemann_theta/riemann_theta.pyx"),
    include_dirs=[numpy.get_include()],
    zip_safe=False,
)
-----------------------------------------------

I guess there need to be some "libraries" and possibly "library_dirs" added to the config but hardcoding them is probably not a good idea. Suggestions? (ChatGPT suggests running "pari-config" but I think it just came up with that because it looked convenient)

There may be other third party packages out there that quietly broke due to some backwards incompatible changes in the python/sage build system.

Nils Bruin

unread,
12:26 PM (11 hours ago) 12:26 PM
to sage-devel
OK, it seems like a "# distutils: libraries = pari" at the top of the pyx file does the trick, as suggested by the cython docs. Still interested in hearing if it's a good idea to solve it like that.

Tobia...@gmx.de

unread,
1:26 PM (10 hours ago) 1:26 PM
to sage-devel
The most future-proof version would be to convince the maintainers of Pari to include a pkg-config file (Pari is one of the few dependencies without one...)

Dima Pasechnik

unread,
1:59 PM (9 hours ago) 1:59 PM
to sage-...@googlegroups.com
You should follow the modern guidelines to specify the dependencies etc, with pyproject.toml
<https://packaging.python.org/en/latest/guides/section-build-and-publish/>
AFAIK, # distutils tags in Cython header is
the usual setuptools way.

I would also say, switch from setuptools to meson or pybind11/nanobind

Dima

Nils Bruin

unread,
2:02 PM (9 hours ago) 2:02 PM
to sage-devel
Thanks. As far as I understood, the setuptools way allowed "cythonize" to figure everything out for me, which meant I could use just some boilerplate setup.py. Is that now deprecated? That would be unfortunate. It would make packaging vanilla cython packages much harder.

Dima Pasechnik

unread,
4:09 PM (7 hours ago) 4:09 PM
to sage-...@googlegroups.com
On Mon, Jan 12, 2026 at 1:02 PM Nils Bruin <nbr...@sfu.ca> wrote:
>
> Thanks. As far as I understood, the setuptools way allowed "cythonize" to figure everything out for me, which meant I could use just some boilerplate setup.py. Is that now deprecated? That would be unfortunate. It would make packaging vanilla cython packages much harder.

I'm not sure about "much harder", why?
I don't know the current status of setuptools in this regard is.
Tobias has switched cysignals, memory_allocator, cypari2 and
primecountpy to use meson,
and it didn't look like a huge change, code-wise.
> --
> You received this message because you are subscribed to the Google Groups "sage-devel" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to sage-devel+...@googlegroups.com.
> To view this discussion visit https://groups.google.com/d/msgid/sage-devel/0b461a48-36fe-4bac-926e-50559d5670b7n%40googlegroups.com.

Nils Bruin

unread,
4:14 PM (7 hours ago) 4:14 PM
to sage-devel
On Monday, 12 January 2026 at 13:09:01 UTC-8 dim...@gmail.com wrote:
I'm not sure about "much harder", why?
I don't know the current status of setuptools in this regard is.
Tobias has switched cysignals, memory_allocator, cypari2 and
primecountpy to use meson,
and it didn't look like a huge change, code-wise.

The "harder" is in comparison to what you do for setup.py: just copy-paste from the cython documentation:

it's not clear to me where to find such a straightforward solution for pyproject.toml
If it's declarative I wouldn't expect that calling "cythonize" is still an option, since that's basically executing arbitrary python code (at least as far as the build system is concerned).

Dima Pasechnik

unread,
6:41 PM (5 hours ago) 6:41 PM
to sage-...@googlegroups.com
On Mon, Jan 12, 2026 at 3:15 PM Nils Bruin <nbr...@sfu.ca> wrote:
>
>
> On Monday, 12 January 2026 at 13:09:01 UTC-8 dim...@gmail.com wrote:
>
> I'm not sure about "much harder", why?
> I don't know the current status of setuptools in this regard is.
> Tobias has switched cysignals, memory_allocator, cypari2 and
> primecountpy to use meson,
> and it didn't look like a huge change, code-wise.
>
>
> The "harder" is in comparison to what you do for setup.py: just copy-paste from the cython documentation:
> https://cython.readthedocs.io/en/latest/src/quickstart/build.html

:facepalm:
cython is living in the past. Often their advice is outdated. Let's
copy/paste some outdated stuff around and hope it works,
it's so easy...
pythonproject.toml is STRONGLY RECOMMENDED for a reason
>
> it's not clear to me where to find such a straightforward solution for pyproject.toml

we have enough examples; suggect one for cython folks.

> If it's declarative I wouldn't expect that calling "cythonize" is still an option, since that's basically executing arbitrary python code (at least as far as the build system is concerned).

It's declarative, thanks goodness! You don't have to call stuff,
unless pressed hard to do so. mesonpy is clever
enough to understand how to deal with Cython.

I suggest to have a look at the simplest example we have:
https://github.com/sagemath/memory_allocator/blob/main/pyproject.toml
https://github.com/sagemath/memory_allocator/blob/main/meson.build



>
> --
> You received this message because you are subscribed to the Google Groups "sage-devel" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to sage-devel+...@googlegroups.com.
> To view this discussion visit https://groups.google.com/d/msgid/sage-devel/200e4ef4-bb54-4e3a-b0f9-3aadc68e22dfn%40googlegroups.com.

Michael Orlitzky

unread,
6:43 PM (4 hours ago) 6:43 PM
to sage-...@googlegroups.com
On 2026-01-12 13:14:58, Nils Bruin wrote:
>
> The "harder" is in comparison to what you do for setup.py: just copy-paste
> from the cython documentation:
> https://cython.readthedocs.io/en/latest/src/quickstart/build.html

What is really missing is "big picture" documentation. Essentially you
are using meson as the build system, and pyproject.toml as a minimal
interface between the real build system (meson) and the python
packaging infrastructure. Otherwise, pip wouldn't know what to do.

There are some decent docs for using meson to build cython extensions,
but in the long run (i.e. after you forget all the time you wasted
learning a new build system), what is nice is that you're just writing
meson. Using it for a cython project is not much different than using
it for any other project.

There are also some decent docs for pyproject.toml files, which will
end up containing some metadata and not much else. Here you can copy &
paste. Any of the independent cython projects under the SageMath
umbrella should serve well as a template.

It's a headache in the short term, but there are many unfixable
problems with the old distutils approach that disappear when meson is
used: no way to detect C libraries and their compiler/linker flags, no
support for other languages, bad support for parallel builds, etc.

You can start writing a meson.build file without messing anything else
up, and attempt to build the project by running the meson setup /
compile / install commands manually. When that works, replacing
setup.py by a pyproject.toml that punts to meson is a trivial step.

Dima Pasechnik

unread,
7:25 PM (4 hours ago) 7:25 PM
to sage-...@googlegroups.com
another question is why does one need a direct interface to libpari in cython code, instead of cypari2?

Nils Bruin

unread,
7:34 PM (4 hours ago) 7:34 PM
to sage-devel
On Monday, 12 January 2026 at 16:25:15 UTC-8 dim...@gmail.com wrote:
another question is why does one need a direct interface to libpari in cython code, instead of cypari2?
 
I don't think I need that. I just need to be able to access some `Gen` objects from a pari data structure efficiently. I didn't ask for the pari_err symbol. But yet, the cython generated code wants to link it in. And the symbol resolved fine before (although probably in a bit underlinked situation). With some (recent? post 10.4?) changes, that's no longer the case. In fact, cypari2 may be the problem: how is setuptools able to derive from the cimport of cypari that libpari.so needs to be linked in as well? The distutils directive seems to do the trick, though, and that's a very minor change.
Reply all
Reply to author
Forward
0 new messages