diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index 7c7baa2..0000000 --- a/MANIFEST.in +++ /dev/null @@ -1,11 +0,0 @@ -include README.rst LICENSE.txt CHANGES.txt pyproject.toml setup.py setup.cfg tox.ini -recursive-include ppl *.pxd *.pyx *.py -recursive-include tests *.pyx *.py -include ppl/ppl_shim.cc -include ppl/ppl_shim.hh -include docs/Makefile -include docs/source/conf.py -include docs/source/index.rst - -recursive-exclude ppl *.so *.c *.cpp -recursive-exclude tests *.so *.c *.cpp diff --git a/VERSION b/VERSION new file mode 100644 index 0000000..ef50561 --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +0.8.10 diff --git a/meson.build b/meson.build new file mode 100644 index 0000000..fb66543 --- /dev/null +++ b/meson.build @@ -0,0 +1,64 @@ +project('pplpy', + ['c', 'cpp', 'cython'], + version: files('VERSION'), + license: 'GPL v3', + default_options: ['cpp_std=c++17', 'python.install_env=auto'], + meson_version: '>=1.2', +) + +# Python module +# https://mesonbuild.com/Python-module.html +py = import('python').find_installation(pure: false) + +# Compilers +cc = meson.get_compiler('c') +cpp = meson.get_compiler('cpp') +cython = meson.get_compiler('cython') +# Workaround as described in https://cython.readthedocs.io/en/latest/src/userguide/special_methods.html#arithmetic-methods +add_project_arguments('-X c_api_binop_methods=True', language: 'cython') + +# Dependencies +inc_cysignals = run_command( + py, + [ + '-c', + ''' +from os.path import relpath +import cysignals +path = cysignals.__file__.replace('__init__.py', '') +try: + print(relpath(path)) +except Exception: + print(path) + '''.strip(), + ], + check: true, +).stdout().strip() +cysignals = declare_dependency(include_directories: inc_cysignals) + +# Find gmpy2 include directory +inc_gmpy2 = run_command( + py, + [ + '-c', + ''' +from os.path import relpath +import gmpy2 +path = gmpy2.__file__.replace('__init__.py', '') +try: + print(relpath(path)) +except Exception: + print(path) + '''.strip(), + ], + check: true, +).stdout().strip() +gmpy2_dep = declare_dependency(include_directories: inc_gmpy2) + +# Find PPL library +ppl = cpp.find_library('ppl', required: true) + +# Find GMP library +gmp = cc.find_library('gmp', required: true) + +subdir('ppl') diff --git a/ppl/meson.build b/ppl/meson.build new file mode 100644 index 0000000..c47d182 --- /dev/null +++ b/ppl/meson.build @@ -0,0 +1,43 @@ +py.install_sources( + '__init__.py', + 'bit_arrays.pxd', + 'congruence.pxd', + 'constraint.pxd', + 'generator.pxd', + 'linear_algebra.pxd', + 'mip_problem.pxd', + 'polyhedron.pxd', + 'ppl_decl.pxd', + 'ppl_shim.hh', + subdir: 'ppl' +) + +# Shared C++ source file +ppl_shim_lib = static_library( + 'ppl_shim', + 'ppl_shim.cc', + dependencies: [ppl, gmp], + cpp_args: [], +) + +extension_data = { + 'linear_algebra': files('linear_algebra.pyx'), + 'mip_problem': files('mip_problem.pyx'), + 'polyhedron': files('polyhedron.pyx'), + 'generator': files('generator.pyx'), + 'constraint': files('constraint.pyx'), + 'congruence': files('congruence.pyx'), + 'bit_arrays': files('bit_arrays.pyx'), +} + +foreach name, pyx : extension_data + py.extension_module( + name, + sources: pyx, + subdir: 'ppl', + install: true, + dependencies: [cysignals, gmpy2_dep, ppl, gmp], + link_with: ppl_shim_lib, + override_options : ['cython_language=cpp'], + ) +endforeach diff --git a/pyproject.toml b/pyproject.toml index 5a92e93..3f3a6a3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,11 +1,10 @@ [build-system] requires = [ - "setuptools>=61.2", - "Cython", - "cysignals", - "gmpy2>=2.1.0b1", + "meson-python>=0.18.0", + "Cython>=3.0", + "cysignals>=1.11.3", ] -build-backend = "setuptools.build_meta" +build-backend = "mesonpy" [project] name = "pplpy" @@ -36,7 +35,7 @@ keywords = [ "linear-programming", ] dependencies = [ - "cysignals", + "cysignals>=1.11.3", "gmpy2>=2.1.0b1", ] dynamic = ["version"] @@ -49,14 +48,3 @@ doc = [ [project.urls] Homepage = "https://github.com/sagemath/pplpy" Download = "https://pypi.org/project/pplpy/#files" - -[tool.setuptools] -packages = ["ppl"] -platforms = ["any"] -include-package-data = false - -[tool.setuptools.dynamic] -version = {attr = "ppl.__version__"} - -[tool.setuptools.package-data] -ppl = ["*.pxd", "*.h", "*.hh"] diff --git a/setup.py b/setup.py deleted file mode 100755 index ee4d84d..0000000 --- a/setup.py +++ /dev/null @@ -1,92 +0,0 @@ -#!/usr/bin/env python - -import os -import sys - -from setuptools import setup, Command -from setuptools.extension import Extension - -# NOTE: setuptools build_ext does not work properly with Cython code -from distutils.command.build_ext import build_ext as _build_ext - -# Adapted from Cython's new_build_ext -class build_ext(_build_ext): - def run(self): - # Check dependencies - try: - from Cython.Build.Dependencies import cythonize - except ImportError as E: - sys.stderr.write("Error: {0}\n".format(E)) - sys.stderr.write("The installation of ppl requires Cython\n") - sys.exit(1) - - try: - # We need the header files for cysignals at compile-time - import cysignals - except ImportError as E: - sys.stderr.write("Error: {0}\n".format(E)) - sys.stderr.write("The installation of ppl requires cysignals\n") - sys.exit(1) - - try: - # We need the header files for gmpy2 at compile-time - import gmpy2 - except ImportError as E: - sys.stderr.write("Error: {0}\n".format(E)) - sys.stderr.write("The installation of ppl requires gmpy2\n") - sys.exit(1) - - self.extensions[:] = cythonize( - self.extensions, - include_path=sys.path, - compiler_directives={'embedsignature': True, - 'language_level': '3'}) - - _build_ext.run(self) - -class TestCommand(Command): - user_options = [] - - def initialize_options(self): - pass - - def finalize_options(self): - pass - - def run(self): - import subprocess, os, tempfile, shutil - - old_path = os.getcwd() - tempdir_path = tempfile.mkdtemp() - try: - shutil.copytree('./tests', tempdir_path, dirs_exist_ok=True) - os.chdir(tempdir_path) - - if subprocess.call([sys.executable, 'runtests.py']): - raise SystemExit("Doctest failures") - - if subprocess.call([sys.executable, 'setup.py', 'build_ext', '--inplace']) or \ - subprocess.call([sys.executable, '-c', "import testpplpy; testpplpy.test(); testpplpy.example()"]): - raise SystemExit("Cython test 1 failure") - - if subprocess.call([sys.executable, 'setup2.py', 'build_ext', '--inplace']) or \ - subprocess.call([sys.executable, '-c', "import testpplpy2; testpplpy2.test(); testpplpy2.example()"]): - raise SystemExit("Cython test 2 failure") - finally: - os.chdir(old_path) - shutil.rmtree(tempdir_path) - -extensions = [ - Extension('ppl.linear_algebra', sources=['ppl/linear_algebra.pyx', 'ppl/ppl_shim.cc']), - Extension('ppl.mip_problem', sources=['ppl/mip_problem.pyx', 'ppl/ppl_shim.cc']), - Extension('ppl.polyhedron', sources = ['ppl/polyhedron.pyx', 'ppl/ppl_shim.cc']), - Extension('ppl.generator', sources = ['ppl/generator.pyx', 'ppl/ppl_shim.cc']), - Extension('ppl.constraint', sources = ['ppl/constraint.pyx', 'ppl/ppl_shim.cc']), - Extension('ppl.congruence', sources=['ppl/congruence.pyx', 'ppl/ppl_shim.cc']), - Extension('ppl.bit_arrays', sources = ['ppl/bit_arrays.pyx', 'ppl/ppl_shim.cc']), - ] - -setup( - ext_modules = extensions, - cmdclass = {'build_ext': build_ext, 'test': TestCommand}, -)