|
18 | 18 | # You should have received a copy of the GNU Lesser General Public License |
19 | 19 | # along with this program; if not, see <https://www.gnu.org/licenses/>. |
20 | 20 | # |
21 | | -from distutils.command.sdist import sdist |
22 | | -from distutils.command.build import build |
23 | | -from distutils.util import get_platform |
24 | | -from importlib.util import find_spec |
| 21 | +import sys |
25 | 22 | from pathlib import Path |
26 | 23 | from setuptools import setup, Extension |
| 24 | +from setuptools.command.build_ext import build_ext as _build_ext |
27 | 25 |
|
28 | 26 |
|
29 | | -class _sdist(sdist): |
30 | | - def finalize_options(self): |
31 | | - super().finalize_options() |
32 | | - self.distribution.data_files.append(('lib', ['INCHI/libinchi.so', 'INCHI/libinchi.dll'])) |
33 | | - |
34 | | - |
35 | | -cmd_class = {'sdist': _sdist} |
36 | | - |
37 | | - |
38 | | -if find_spec('wheel'): |
39 | | - from wheel.bdist_wheel import bdist_wheel |
40 | | - |
41 | | - class _bdist_wheel(bdist_wheel): |
42 | | - def finalize_options(self): |
43 | | - super().finalize_options() |
44 | | - self.root_is_pure = False |
45 | | - platform = get_platform() |
46 | | - if platform == 'win-amd64': |
47 | | - self.distribution.data_files.append(('lib', ['INCHI/libinchi.dll'])) |
48 | | - elif platform == 'linux-x86_64': |
49 | | - self.distribution.data_files.append(('lib', ['INCHI/libinchi.so'])) |
| 27 | +class build_ext(_build_ext): |
| 28 | + """Custom build_ext to handle Cython compilation.""" |
| 29 | + |
| 30 | + def run(self): |
| 31 | + # Import Cython here and compile just before building |
| 32 | + try: |
| 33 | + from Cython.Build import cythonize |
| 34 | + if self.distribution.ext_modules: |
| 35 | + self.distribution.ext_modules = cythonize( |
| 36 | + self.distribution.ext_modules, |
| 37 | + language_level=3, |
| 38 | + compiler_directives={'embedsignature': True} |
| 39 | + ) |
| 40 | + except ImportError: |
| 41 | + # If Cython is not available during build, look for pre-generated C files |
| 42 | + print("Cython not found. Looking for pre-generated C files...", file=sys.stderr) |
| 43 | + c_file = Path('CGRtools/containers/_unpack.c') |
| 44 | + if c_file.exists() and self.distribution.ext_modules: |
| 45 | + # Replace .pyx with .c in sources |
| 46 | + for ext in self.distribution.ext_modules: |
| 47 | + ext.sources = [src.replace('.pyx', '.c') for src in ext.sources] |
| 48 | + else: |
| 49 | + print("Warning: Neither Cython nor pre-generated C files found. " |
| 50 | + "Extension modules will not be built.", file=sys.stderr) |
| 51 | + self.distribution.ext_modules = [] |
| 52 | + |
| 53 | + super().run() |
50 | 54 |
|
51 | | - cmd_class['bdist_wheel'] = _bdist_wheel |
52 | 55 |
|
| 56 | +def get_data_files(): |
| 57 | + """Get platform-specific INCHI library files for wheel.""" |
| 58 | + import platform |
| 59 | + |
| 60 | + data_files = [] |
| 61 | + system = platform.system() |
| 62 | + machine = platform.machine() |
| 63 | + |
| 64 | + # Include INCHI libraries based on platform |
| 65 | + if system == 'Windows' and machine in ('AMD64', 'x86_64'): |
| 66 | + dll_path = Path('INCHI/libinchi.dll') |
| 67 | + if dll_path.exists(): |
| 68 | + data_files.append(('lib', ['INCHI/libinchi.dll'])) |
| 69 | + elif system == 'Linux' and machine in ('x86_64',): |
| 70 | + so_path = Path('INCHI/libinchi.so') |
| 71 | + if so_path.exists(): |
| 72 | + data_files.append(('lib', ['INCHI/libinchi.so'])) |
| 73 | + |
| 74 | + return data_files |
53 | 75 |
|
54 | | -if find_spec('cython'): |
55 | | - class _build(build): |
56 | | - def finalize_options(self): |
57 | | - super().finalize_options() |
58 | | - from Cython.Build import cythonize |
59 | | - self.distribution.ext_modules = cythonize(self.distribution.ext_modules, language_level=3) |
60 | 76 |
|
61 | | - cmd_class['build'] = _build |
| 77 | +# Extension modules |
| 78 | +ext_modules = [ |
| 79 | + Extension( |
| 80 | + 'CGRtools.containers._unpack', |
| 81 | + ['CGRtools/containers/_unpack.pyx'], |
| 82 | + extra_compile_args=['-O3'] |
| 83 | + ) |
| 84 | +] |
62 | 85 |
|
| 86 | +# For source distributions, include both library files |
| 87 | +if 'sdist' in sys.argv: |
| 88 | + data_files = [('lib', ['INCHI/libinchi.so', 'INCHI/libinchi.dll'])] |
| 89 | +else: |
| 90 | + data_files = get_data_files() |
63 | 91 |
|
64 | 92 | setup( |
65 | | - name='CGRtools', |
66 | | - version='4.1.35', |
67 | | - packages=['CGRtools', 'CGRtools.algorithms', 'CGRtools.algorithms.calculate2d', 'CGRtools.algorithms.components', |
68 | | - 'CGRtools.algorithms.standardize', 'CGRtools.containers', 'CGRtools.files', 'CGRtools.files._mdl', |
69 | | - 'CGRtools.periodictable', 'CGRtools.periodictable.element', 'CGRtools.reactor', 'CGRtools.utils', |
70 | | - 'CGRtools.attributes'], |
71 | | - url='https://github.com/cimm-kzn/CGRtools', |
72 | | - license='LGPLv3', |
73 | | - author='Dr. Ramil Nugmanov, Dr. Timur Madzhidov, Valentina Afonina', |
74 | | - author_email='tmadzhidov@gmail.com', |
75 | | - python_requires='>=3.6.1', |
76 | | - cmdclass=cmd_class, |
77 | | - ext_modules=[Extension('CGRtools.containers._unpack', ['CGRtools/containers/_unpack.pyx'], |
78 | | - extra_compile_args=['-O3'])], |
79 | | - setup_requires=['wheel', 'cython'], |
80 | | - install_requires=['CachedMethods>=0.1.4,<0.2'], |
81 | | - extras_require={'mrv': ['lxml>=4.1'], 'clean2d': ['py-mini-racer>=0.4.0'], 'jit': ['numpy>=1.18', 'numba>=0.50']}, |
82 | | - package_data={'CGRtools.algorithms.calculate2d': ['clean2d.js'], 'CGRtools.containers': ['_unpack.pyx']}, |
83 | | - data_files=[], |
| 93 | + ext_modules=ext_modules, |
| 94 | + data_files=data_files, |
| 95 | + cmdclass={'build_ext': build_ext}, |
84 | 96 | zip_safe=False, |
85 | | - long_description=(Path(__file__).parent / 'README.rst').read_text(), |
86 | | - classifiers=['Environment :: Plugins', |
87 | | - 'Intended Audience :: Science/Research', |
88 | | - 'License :: OSI Approved :: GNU Lesser General Public License v3 or later (LGPLv3+)', |
89 | | - 'Operating System :: OS Independent', |
90 | | - 'Programming Language :: Python', |
91 | | - 'Programming Language :: Python :: 3 :: Only', |
92 | | - 'Programming Language :: Python :: 3.7', |
93 | | - 'Programming Language :: Python :: 3.8', |
94 | | - 'Programming Language :: Python :: 3.9', |
95 | | - 'Programming Language :: Python :: 3.10', |
96 | | - 'Topic :: Scientific/Engineering', |
97 | | - 'Topic :: Scientific/Engineering :: Chemistry', |
98 | | - 'Topic :: Scientific/Engineering :: Information Analysis', |
99 | | - 'Topic :: Software Development', |
100 | | - 'Topic :: Software Development :: Libraries', |
101 | | - 'Topic :: Software Development :: Libraries :: Python Modules'], |
102 | | - command_options={'build_sphinx': {'source_dir': ('setup.py', 'doc'), |
103 | | - 'build_dir': ('setup.py', 'build/doc'), |
104 | | - 'all_files': ('setup.py', True)}} |
105 | 97 | ) |
0 commit comments