-
-
Notifications
You must be signed in to change notification settings - Fork 53
/
build.py
81 lines (66 loc) · 2.5 KB
/
build.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
"""optionally builds inside polygon algorithm C extension
Resources:
https://github.com/FirefoxMetzger/mini-extension
https://stackoverflow.com/questions/60073711/how-to-build-c-extensions-via-poetry
https://github.com/libmbd/libmbd/blob/master/build.py
"""
import pathlib
import re
import warnings
import cffi
import cffi.setuptools_ext
import setuptools
EXTENSION_NAME = "inside_polygon_ext"
H_FILE_NAME = "inside_polygon_int.h"
C_FILE_NAME = "inside_polygon_int.c"
# stored in "timezonefinder" package folder for cleaner footprint
EXTENSION_PATH = pathlib.Path().resolve() / "timezonefinder" / "inside_poly_extension"
h_file_path = EXTENSION_PATH / H_FILE_NAME
c_file_path = EXTENSION_PATH / C_FILE_NAME
try:
ffibuilder = cffi.FFI()
except Exception as exc:
warnings.warn(
f"C lang extension cannot be build, since cffi failed with this error: {exc}"
)
# Clang extension should be fully optional
ffibuilder = None
if ffibuilder is not None:
ffibuilder.set_source(
EXTENSION_NAME, # name of the output C extension
f'#include "{h_file_path}"',
sources=[str(c_file_path)],
)
with open(h_file_path) as h_file:
# cffi does not like our preprocessor directives, so we remove them
lns = h_file.read().splitlines()
flt = filter(lambda ln: not re.match(r" *#", ln), lns)
ffibuilder.cdef("\n".join(flt))
# with open(c_file_path) as c_file:
# # cffi does not like our preprocessor directives, so we remove them
# c_file_content = c_file.read()
def build_c_extension():
if ffibuilder is None:
warnings.warn("missing ffibuilder. skipping build process")
return
# not required
# ffibuilder.compile(verbose=True)
# Note: built into "timezonefinder" package folder
distribution = setuptools.Distribution({"package_dir": {"": "timezonefinder"}})
cffi.setuptools_ext.cffi_modules(
distribution, "cffi_modules", ["build.py:ffibuilder"]
)
cmd = distribution.cmdclass["build_ext"](distribution)
cmd.inplace = 1
cmd.ensure_finalized()
try:
cmd.run()
except Exception as exc:
# distutils.errors.CompileError:
# a build failure in the extension (e.g. C compile is not installed) must not abort the build process,
# but instead simply not install the failing extension.
warnings.warn(
f"C lang extension cannot be build, since cmd.run() failed with this error: {exc}"
)
if __name__ == "__main__":
build_c_extension()