diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index 8e0f878..0000000 --- a/MANIFEST.in +++ /dev/null @@ -1,15 +0,0 @@ -include Changes.rst -include LICENSE -graft doc/html -graft Include -graft examples -graft rst -graft util -graft test -prune test/.cache -prune .github -exclude MANIFEST.in -exclude .git* -exclude .readthedocs.yaml -recursive-include src *.pyx *.pyi *.py *.pxi *.pxd *.c *.h -global-exclude *.pyc diff --git a/meson.build b/meson.build new file mode 100644 index 0000000..0fdaf7c --- /dev/null +++ b/meson.build @@ -0,0 +1,22 @@ +project('pyfuse3', 'c', 'cython', + meson_version: '>= 1.1.0', + version: run_command( + [find_program('python3'), '-m', 'setuptools_scm'], + check: true + ).stdout().strip(), + default_options: [ + 'warning_level=2', + ] +) + +# Import Python module +py = import('python').find_installation(pure: false) + +# Check for required dependencies via pkg-config +fuse3_dep = dependency('fuse3', version: '>=3.2.0') + +# Platform detection +host_system = host_machine.system() + +# Process subdirectories +subdir('src') diff --git a/pyproject.toml b/pyproject.toml index 08e04eb..c3f4864 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,11 @@ [build-system] -requires = ["setuptools>=78.1.1", "setuptools_scm>=8.0", "Cython"] -build-backend = "build_backend" -backend-path = ["util"] +requires = [ + "meson-python>=0.16.0", + "meson>=1.1.0", + "setuptools_scm>=8.0", + "Cython>=3.0", +] +build-backend = "mesonpy" [project] name = "pyfuse3" @@ -40,12 +44,7 @@ dev = [ [tool.setuptools_scm] -[tool.setuptools] -include-package-data = true - -[tool.setuptools.packages.find] -where = ["src"] - -[tool.setuptools.package-data] -pyfuse3 = ["py.typed"] +# Meson-python configuration +[tool.meson-python.args] +# Add any meson-specific build arguments if needed diff --git a/src/meson.build b/src/meson.build new file mode 100644 index 0000000..588113c --- /dev/null +++ b/src/meson.build @@ -0,0 +1,48 @@ +# Define the pyfuse3 Cython extension module + +inc_dirs = include_directories('../Include', 'pyfuse3') + +compile_args = [ + '-DFUSE_USE_VERSION=32', + '-Wall', + '-Wextra', + '-Wconversion', + '-Wsign-compare', + '-Wno-unused-function', + '-Wno-implicit-fallthrough', + '-Wno-unused-parameter', +] + +link_args = ['-lpthread'] +sources = ['pyfuse3/__init__.pyx'] + +# Platform-specific configuration +if host_system == 'darwin' + sources += ['pyfuse3/darwin_compat.c'] +elif host_system == 'linux' or host_system == 'gnu' + link_args += ['-lrt'] +endif + +pyfuse3_ext = py.extension_module( + '__init__', + sources: sources, + include_directories: inc_dirs, + c_args: compile_args, + link_args: link_args, + dependencies: fuse3_dep, + install: true, + subdir: 'pyfuse3', + override_options: ['cython_language=c'], + cython_args: ['-I', meson.project_source_root() / 'Include'], +) + +# Install pure Python modules +py.install_sources( + [ + 'pyfuse3/__init__.pyi', + 'pyfuse3/_pyfuse3.py', + 'pyfuse3/asyncio.py', + 'pyfuse3/py.typed', + ], + preserve_path: true, +) diff --git a/util/build_backend.py b/util/build_backend.py deleted file mode 100644 index 5be33c1..0000000 --- a/util/build_backend.py +++ /dev/null @@ -1,148 +0,0 @@ -""" -Custom build backend for pyfuse3. - -This wraps setuptools.build_meta and dynamically configures the Cython -extension based on pkg-config output and platform detection. -""" - -import os -import subprocess -from setuptools import Extension -from setuptools.build_meta import * - -def pkg_config(pkg, cflags=True, ldflags=False, min_ver=None): - """Frontend to pkg-config""" - - if min_ver: - cmd = ['pkg-config', pkg, '--atleast-version', min_ver] - - if subprocess.call(cmd) != 0: - cmd = ['pkg-config', '--modversion', pkg] - proc = subprocess.Popen(cmd, stdout=subprocess.PIPE) - version = proc.communicate()[0].strip() - if not version: - raise SystemExit(2) # pkg-config generates error message already - else: - raise SystemExit('%s version too old (found: %s, required: %s)' - % (pkg, version, min_ver)) - - cmd = ['pkg-config', pkg] - if cflags: - cmd.append('--cflags') - if ldflags: - cmd.append('--libs') - - proc = subprocess.Popen(cmd, stdout=subprocess.PIPE) - cflags = proc.stdout.readline().rstrip() - proc.stdout.close() - if proc.wait() != 0: - raise SystemExit(2) # pkg-config generates error message already - - return cflags.decode('us-ascii').split() - - -def get_extension_modules(): - """Build the Cython extension with platform-specific configuration.""" - - # Get fuse3 flags from pkg-config - compile_args = pkg_config('fuse3', cflags=True, ldflags=False, min_ver='3.2.0') - compile_args += [ - '-DFUSE_USE_VERSION=32', - '-Wall', - '-Wextra', - '-Wconversion', - '-Wsign-compare', - '-Wno-unused-function', - '-Wno-implicit-fallthrough', - '-Wno-unused-parameter', - ] - - link_args = pkg_config('fuse3', cflags=False, ldflags=True, min_ver='3.2.0') - link_args.append('-lpthread') - - # Determine source files based on platform - c_sources = ['src/pyfuse3/__init__.pyx'] - - if os.uname()[0] in ('Linux', 'GNU/kFreeBSD'): - link_args.append('-lrt') - elif os.uname()[0] == 'Darwin': - c_sources.append('src/pyfuse3/darwin_compat.c') - - return [ - Extension( - 'pyfuse3.__init__', - c_sources, - extra_compile_args=compile_args, - extra_link_args=link_args, - include_dirs=['Include'], - ) - ] - - -# Override get_requires_for_build_wheel to ensure we have pkg-config available -def get_requires_for_build_wheel(config_settings=None): - """Return build requirements.""" - from setuptools.build_meta import get_requires_for_build_wheel as orig - return orig(config_settings) - - -# Hook into the build process -_orig_build_wheel = build_wheel -_orig_build_editable = build_editable if 'build_editable' in dir() else None -_orig_build_sdist = build_sdist - - -def build_wheel(wheel_directory, config_settings=None, metadata_directory=None): - """Build wheel with dynamic extension configuration.""" - # Inject our extension modules into the distribution - from setuptools import Distribution - - # Monkey-patch Distribution to include our extensions - orig_init = Distribution.__init__ - - def patched_init(self, attrs=None): - if attrs is None: - attrs = {} - # Add our dynamically configured extension modules - if 'ext_modules' not in attrs: - attrs['ext_modules'] = get_extension_modules() - orig_init(self, attrs) - - Distribution.__init__ = patched_init - - try: - return _orig_build_wheel(wheel_directory, config_settings, metadata_directory) - finally: - Distribution.__init__ = orig_init - - -def build_editable(wheel_directory, config_settings=None, metadata_directory=None): - """Build editable wheel with dynamic extension configuration.""" - if _orig_build_editable is None: - raise NotImplementedError("build_editable not available") - - from setuptools import Distribution - - # Monkey-patch Distribution to include our extensions - orig_init = Distribution.__init__ - - def patched_init(self, attrs=None): - if attrs is None: - attrs = {} - # Add our dynamically configured extension modules - if 'ext_modules' not in attrs: - attrs['ext_modules'] = get_extension_modules() - orig_init(self, attrs) - - Distribution.__init__ = patched_init - - try: - return _orig_build_editable(wheel_directory, config_settings, metadata_directory) - finally: - Distribution.__init__ = orig_init - - -def build_sdist(sdist_directory, config_settings=None): - """Build source distribution.""" - # For sdist, we don't need to configure extensions - return _orig_build_sdist(sdist_directory, config_settings)