Repository navigation
Expand file tree
/
Copy pathsetup.py
More file actions
73 lines (62 loc) · 2.88 KB
/
Copy pathsetup.py
File metadata and controls
73 lines (62 loc) · 2.88 KB
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
# copyright ################################# #
# This file is part of the PyECLOUD Package. #
# Copyright (c) CERN, 2011. #
# ########################################### #
"""Native extension builds; package metadata lives in pyproject.toml."""
from pathlib import Path
import shutil
import subprocess
import sys
import tempfile
import numpy
from setuptools import Extension, setup
from setuptools.command.build_ext import build_ext
from setuptools.errors import CompileError
class F2PyBuildExt(build_ext):
"""Let setuptools manage placement and editable installs of F2PY modules."""
def build_extension(self, ext):
if not all(Path(source).suffix == '.f' for source in ext.sources):
return super().build_extension(ext)
module_name = ext.name.rsplit('.', 1)[-1]
sources = [str(Path(source).resolve()) for source in ext.sources]
destination = Path(self.get_ext_fullpath(ext.name)).resolve()
build_dir = Path(self.build_temp).resolve()
build_dir.mkdir(parents=True, exist_ok=True)
# A fresh directory prevents an old binary from masking a failed build.
with tempfile.TemporaryDirectory(prefix=ext.name + '-', dir=build_dir) as tmp:
command = [sys.executable, '-m', 'numpy.f2py', '-c',
'--backend', 'meson', '-m', module_name, *sources]
try:
subprocess.run(command, cwd=tmp, check=True)
except subprocess.CalledProcessError as exc:
raise CompileError(
f'Failed to build {ext.name}. A C and Fortran compiler '
'must be available; see README.md for installation details.'
) from exc
binary = Path(tmp) / self.get_ext_filename(module_name)
if not binary.is_file():
raise CompileError(f'F2PY did not produce the expected file: {binary}')
destination.parent.mkdir(parents=True, exist_ok=True)
shutil.copy2(binary, destination)
extensions = [
Extension('PyECLOUD.' + name, ['PyECLOUD/fortran/' + source])
for name, source in [
('rhocompute', 'compute_rho.f'),
('int_field_for', 'interp_field_for.f'),
('hist_for', 'compute_hist.f'),
('seg_impact', 'update_seg_impact.f'),
('boris_step', 'boris_step.f'),
('vectsum', 'vectsum.f'),
('errffor', 'errfff.f'),
]
]
extensions += [
Extension('PyECLOUD.boris_cython',
['PyECLOUD/boris_cython.pyx', 'PyECLOUD/boris_c_function.c'],
depends=['PyECLOUD/boris_cython.pxd', 'PyECLOUD/boris_c_function.h'],
include_dirs=[numpy.get_include(), 'PyECLOUD']),
Extension('PyECLOUD.geom_impact_poly_cython',
['PyECLOUD/geom_impact_poly_cython.pyx'],
include_dirs=[numpy.get_include()]),
]
setup(ext_modules=extensions, cmdclass={'build_ext': F2PyBuildExt})