Skip to content

Conversation

tobiasdiez
Copy link
Contributor

@tobiasdiez tobiasdiez commented Sep 19, 2025

  • Use uv instead of the old-style requirements.txt
  • Build wheels directly on top of the manylinux images using the usual workflow (essentially following https://learn.scientific-python.org/development/guides/gha-wheels/), instead of using sage to setup the build env
  • Using this simplification, also build wheels for windows (I was not able to build win32 wheels, but I don't think that's very important)
  • Use https://pypi.org/project/pkgconf/ to make it simpler for other projects to use cysignals by shipping a pc file (the example is also updated to make use of this simplification - in meson it's now simply cysignals = dependency('cysignals').

@tobiasdiez tobiasdiez force-pushed the wheel branch 10 times, most recently from efa2e14 to 7c919b3 Compare September 20, 2025 14:36
@tobiasdiez tobiasdiez force-pushed the wheel branch 2 times, most recently from fa152f0 to b3336aa Compare September 21, 2025 07:40
@dimpase
Copy link
Member

dimpase commented Sep 21, 2025

cysignals is a Python package - why would it need to ship a .pc file? To help cython headers discovery?

@dimpase
Copy link
Member

dimpase commented Sep 22, 2025

without --no-build-isolation:

$ uv pip install .
Using Python 3.13.5 environment at: /home/dima/software/cysignals/.venv
Resolved 1 package in 1ms
  × Failed to build `cysignals-example @ file:///home/dima/software/cysignals/example`
  ├─▶ The build backend returned an error
  ╰─▶ Call to `mesonpy.build_wheel` failed (exit status: 1)

      [stdout]
      + meson setup /home/dima/software/cysignals/example
      /home/dima/software/cysignals/example/.mesonpy-1911l3h9
      -Dbuildtype=release -Db_ndebug=if-release -Db_vscrt=md
      --native-file=/home/dima/software/cysignals/example/.mesonpy-1911l3h9/meson-python-native-file.ini
      The Meson build system
      Version: 1.9.0
      Source dir: /home/dima/software/cysignals/example
      Build dir: /home/dima/software/cysignals/example/.mesonpy-1911l3h9
      Build type: native build
      Project name: cysignals_example
      Project version: undefined
      C++ compiler for the host machine: ccache c++ (gcc 15.1.1 "c++ (Gentoo 15.1.1_p20250705-r1 p2) 15.1.1
      20250705")
      C++ linker for the host machine: c++ ld.bfd 2.44
      Cython compiler for the host machine: cython (cython 3.1.4)
      Host machine cpu family: x86_64
      Host machine cpu: x86_64
      Program python found: YES (/home/dima/.cache/uv/builds-v0/.tmpix4Ge5/bin/python)
      Found pkg-config: YES (/home/dima/.cache/uv/builds-v0/.tmpix4Ge5/bin/pkg-config) 2.4.3
      Found CMake: /usr/bin/cmake (4.1.1)
      Run-time dependency cysignals found: NO (tried pkgconfig and cmake)

      ../meson.build:5:12: ERROR: Dependency "cysignals" not found, tried pkgconfig and cmake

      A full log can be found at
      /home/dima/software/cysignals/example/.mesonpy-1911l3h9/meson-logs/meson-log.txt

@dimpase
Copy link
Member

dimpase commented Sep 22, 2025

we can also do the numpy-style way, adding a get_include() function.
(this still needs --no-build-isolation)

diff --git a/example/meson.build b/example/meson.build
index 04cc3ef..945e9eb 100644
--- a/example/meson.build
+++ b/example/meson.build
@@ -2,12 +2,22 @@ project('cysignals_example', 'cython', 'cpp')
 
 py = import('python').find_installation()
 
-cysignals = dependency('cysignals')
+incdir_cysignals = run_command(py,
+  ['-c',
+  '''import os
+import cysignals as csi
+print(csi.get_include())
+  '''
+  ],
+  check : true
+).stdout().strip()
+
+inc_cysignals = include_directories(incdir_cysignals)
 
 py.extension_module('cysignals_example',
   sources: ['cysignals_example.pyx'],
   install: true,
-  dependencies: [cysignals],
+  include_directories: inc_cysignals,
   override_options: ['cython_language=cpp'],
   subdir: 'cysignals_example'
 )
diff --git a/example/pyproject.toml b/example/pyproject.toml
index eb839e6..438c758 100644
--- a/example/pyproject.toml
+++ b/example/pyproject.toml
@@ -1,5 +1,5 @@
 [build-system]
-requires = ["meson-python", "cython>=0.28", "pkgconf"]
+requires = ["meson-python", "cython>=0.28", "cysignals"]
 build-backend = "mesonpy"
 
 [project]
diff --git a/src/cysignals/__init__.py b/src/cysignals/__init__.py
index 81efe32..931243e 100644
--- a/src/cysignals/__init__.py
+++ b/src/cysignals/__init__.py
@@ -1,3 +1,7 @@
 from .signals import AlarmInterrupt, SignalError, init_cysignals  # noqa
 
 init_cysignals()
+
+def get_include():
+    import os
+    return os.path.dirname(__file__)
diff --git a/src/cysignals/cysignals.pc b/src/cysignals/cysignals.pc
deleted file mode 100644
index d14a6b8..0000000
--- a/src/cysignals/cysignals.pc
+++ /dev/null
@@ -1,6 +0,0 @@
-includedir=${pcfiledir}
-
-Name: cysignals
-Description: cysignals library
-Version: 1.0.0
-Cflags: -I${includedir}
diff --git a/src/cysignals/meson.build b/src/cysignals/meson.build
index e9aa9eb..062ebfe 100644
--- a/src/cysignals/meson.build
+++ b/src/cysignals/meson.build
@@ -2,7 +2,6 @@ configure_file(output: 'cysignals_config.h', configuration: config, install_dir:
 
 py.install_sources(
     '__init__.py',
-    'cysignals.pc',
     'cysignals-CSI-helper.py',
     'memory.pxd',
     'pysignals.pxd',

It's a bit more verbose, but more conformant to what is around.

As far as the example is concerned, it's a bit meaningless. its README says that it's tested, but I fail to see any trace of it.

@tobiasdiez
Copy link
Contributor Author

cysignals is a Python package - why would it need to ship a .pc file? To help cython headers discovery?

Yes, to make it easier to be used downstream (e.g in sage). For cysignals it's indeed only the headers, but cypari2 should also specify where pari is located. Numpy is also shipping a pc file for the same reason: https://github.com/numpy/numpy/blob/main/numpy/_core/numpy.pc.in. The get_include method might be a good addition for setuptools projects, but in meson the pc file is the easiest.

without --no-build-isolation:

Yes, to make it with build isolation one needs to properly setup a uv workspace so that the example is correctly using the cysignals in the root and not from pypi. I don't think the example is super important... It's build is tested though (

test('example', py, args: ['-m', 'build', '--no-isolation', 'example'], workdir: meson.current_source_dir())
) as part of meson test (which is run by CI).

@dimpase
Copy link
Member

dimpase commented Sep 22, 2025

Could you explain how to invoke

test('example', py, args: ['-m', 'build', '--no-isolation', 'example'], workdir: meson.current_source_dir())
at the command line?

I am getting, by looking what CI does:

$ uv run --no-editable meson test --print-errorlogs -C build

ERROR: No such build data file as '/home/dp/cysignals/build/meson-private/build.dat'.

@tobiasdiez
Copy link
Contributor Author

tobiasdiez commented Sep 23, 2025

I also had that issue sometimes, but it disappeared after deleting the venv. The following commands should work on a clean checkout:

uv sync --frozen --inexact -v --no-install-project
uv sync --frozen --inexact -v --no-build-isolation --no-editable --config-settings=builddir=builddir
uv run --no-editable meson test --print-errorlogs -C builddir

It's a bit more complicated than I would like, but uv doesn't have good support for no-build-isolation of the main project but meson needs it...

@dimpase
Copy link
Member

dimpase commented Sep 23, 2025

right, it seems to be caused by an external to the venv installation of cysignals.

Can you put these 3 lines somewhere in the docs?

uv sync --frozen --inexact -v --no-install-project
uv sync --frozen --inexact -v --no-build-isolation --no-editable --config-settings=builddir=builddir
uv run --no-editable meson test --print-errorlogs -C builddir

@dimpase dimpase merged commit dc26dc8 into sagemath:main Sep 23, 2025
24 checks passed
@tobiasdiez tobiasdiez deleted the wheel branch September 23, 2025 03:30
@tobiasdiez
Copy link
Contributor Author

Thanks for the review, and for adding the instructions.

What do you think about issuing a new release so that those new shiny wheels are used?

This was referenced Sep 23, 2025
@dimpase
Copy link
Member

dimpase commented Sep 23, 2025

good idea - past 23:00 here, tomorrow?

@dimpase
Copy link
Member

dimpase commented Sep 23, 2025

@tobiasdiez - what's the release procedure in the presence of uv.lock?
Does one need to run uv version 1.12.5 ?

@dimpase
Copy link
Member

dimpase commented Sep 23, 2025

uv version 1.12.5 does seem to do the trick of updating pyproject.toml and uv.lock at the same time.

I wonder whether one should also need to do something with the package versions locked in uv.lock. Would it make sense to update these too?

@tobiasdiez
Copy link
Contributor Author

uv version is the right command. No need to update the other packages in the lock file, this would be done in a separate PR to make sure it doesn't break anything (ideally automated by things like renovate).

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.

2 participants