|
1 | | -import os |
2 | | -import shutil |
3 | | -import sys |
| 1 | +import subprocess |
4 | 2 |
|
5 | | -from distutils.command.build_ext import build_ext |
6 | | -from distutils.core import Distribution |
7 | | -from distutils.core import Extension |
8 | | -from distutils.errors import CCompilerError |
9 | | -from distutils.errors import DistutilsExecError |
10 | | -from distutils.errors import DistutilsPlatformError |
| 3 | +from pathlib import Path |
11 | 4 |
|
12 | 5 |
|
13 | | -# C Extensions |
14 | | -with_extensions = os.getenv("PENDULUM_EXTENSIONS", None) |
| 6 | +def meson(*args): |
| 7 | + subprocess.call(["meson"] + list(args)) |
15 | 8 |
|
16 | | -if with_extensions == "1" or with_extensions is None: |
17 | | - with_extensions = True |
18 | 9 |
|
19 | | -if with_extensions == "0" or hasattr(sys, "pypy_version_info"): |
20 | | - with_extensions = False |
| 10 | +def _build(): |
| 11 | + build_dir = Path(__file__).parent.joinpath("build") |
| 12 | + build_dir.mkdir(parents=True, exist_ok=True) |
21 | 13 |
|
22 | | -extensions = [] |
23 | | -if with_extensions: |
24 | | - extensions = [ |
25 | | - Extension("pendulum._extensions._helpers", ["pendulum/_extensions/_helpers.c"]), |
26 | | - Extension("pendulum.parsing._iso8601", ["pendulum/parsing/_iso8601.c"]), |
27 | | - ] |
28 | | - |
29 | | - |
30 | | -class BuildFailed(Exception): |
31 | | - |
32 | | - pass |
33 | | - |
34 | | - |
35 | | -class ExtBuilder(build_ext): |
36 | | - # This class allows C extension building to fail. |
37 | | - |
38 | | - built_extensions = [] |
39 | | - |
40 | | - def run(self): |
41 | | - try: |
42 | | - build_ext.run(self) |
43 | | - except (DistutilsPlatformError, FileNotFoundError): |
44 | | - print( |
45 | | - " Unable to build the C extensions, " |
46 | | - "Pendulum will use the pure python code instead." |
47 | | - ) |
48 | | - |
49 | | - def build_extension(self, ext): |
50 | | - try: |
51 | | - build_ext.build_extension(self, ext) |
52 | | - except (CCompilerError, DistutilsExecError, DistutilsPlatformError, ValueError): |
53 | | - print( |
54 | | - f' Unable to build the "{ext.name}" C extension, ' |
55 | | - "Pendulum will use the pure python version of the extension." |
56 | | - ) |
| 14 | + meson("setup", build_dir.as_posix()) |
| 15 | + meson("compile", "-C", build_dir.as_posix()) |
| 16 | + meson("install", "-C", build_dir.as_posix()) |
57 | 17 |
|
58 | 18 |
|
59 | 19 | def build(setup_kwargs): |
60 | 20 | """ |
61 | 21 | This function is mandatory in order to build the extensions. |
62 | 22 | """ |
63 | | - distribution = Distribution({"name": "pendulum", "ext_modules": extensions}) |
64 | | - distribution.package_dir = "pendulum" |
65 | | - |
66 | | - cmd = ExtBuilder(distribution) |
67 | | - cmd.ensure_finalized() |
68 | | - cmd.run() |
69 | | - |
70 | | - # Copy built extensions back to the project |
71 | | - for output in cmd.get_outputs(): |
72 | | - relative_extension = os.path.relpath(output, cmd.build_lib) |
73 | | - if not os.path.exists(output): |
74 | | - continue |
75 | | - |
76 | | - shutil.copyfile(output, relative_extension) |
77 | | - mode = os.stat(relative_extension).st_mode |
78 | | - mode |= (mode & 0o444) >> 2 |
79 | | - os.chmod(relative_extension, mode) |
80 | | - |
81 | | - return setup_kwargs |
| 23 | + try: |
| 24 | + _build() |
| 25 | + except Exception: |
| 26 | + print( |
| 27 | + " Unable to build C extensions, " |
| 28 | + "Pendulum will use the pure python version of the extensions." |
| 29 | + ) |
82 | 30 |
|
83 | 31 |
|
84 | 32 | if __name__ == "__main__": |
|
0 commit comments