forked from pybamm-team/PyBaMM
-
Notifications
You must be signed in to change notification settings - Fork 0
/
CMakeBuild.py
107 lines (93 loc) · 4.14 KB
/
CMakeBuild.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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import os
import sys
import subprocess
from pathlib import Path
from platform import system
try:
from setuptools.command.build_ext import build_ext
except ImportError:
from distutils.command.build_ext import build_ext
default_lib_dir = (
"" if system() == "Windows" else os.path.join(os.getenv("HOME"), ".local")
)
class CMakeBuild(build_ext):
user_options = build_ext.user_options + [
("suitesparse-root=", None, "suitesparse source location"),
("sundials-root=", None, "sundials source location"),
]
def initialize_options(self):
build_ext.initialize_options(self)
self.suitesparse_root = None
self.sundials_root = None
def finalize_options(self):
build_ext.finalize_options(self)
# Determine the calling command to get the
# undefined options from.
# If build_ext was called directly then this
# doesn't matter.
try:
self.get_finalized_command("install", create=0)
calling_cmd = "install"
except AttributeError:
calling_cmd = "bdist_wheel"
self.set_undefined_options(
calling_cmd,
("suitesparse_root", "suitesparse_root"),
("sundials_root", "sundials_root"),
)
if not self.suitesparse_root:
self.suitesparse_root = os.path.join(default_lib_dir)
if not self.sundials_root:
self.sundials_root = os.path.join(default_lib_dir)
def run(self):
if not self.extensions:
return
cmake_args = ["-DPYTHON_EXECUTABLE={}".format(sys.executable)]
if self.suitesparse_root:
cmake_args.append(
"-DSuiteSparse_ROOT={}".format(os.path.abspath(self.suitesparse_root))
)
if self.sundials_root:
cmake_args.append(
"-DSUNDIALS_ROOT={}".format(os.path.abspath(self.sundials_root))
)
if not os.path.exists(self.build_temp):
os.makedirs(self.build_temp)
# The CMakeError.log file is generated by cmake is the configure step
# encounters error. In the following the existence of this file is used
# to determine whether or not the cmake configure step went smoothly.
# So must make sure this file does not remain from a previous failed build.
if os.path.isfile(os.path.join(self.build_temp, "CMakeError.log")):
os.remove(os.path.join(self.build_temp, "CMakeError.log"))
cmake_list_dir = os.path.abspath(os.path.dirname(__file__))
print("-" * 10, "Running CMake for idaklu solver", "-" * 40)
subprocess.run(["cmake", cmake_list_dir] + cmake_args, cwd=self.build_temp)
if os.path.isfile(os.path.join(self.build_temp, "CMakeError.log")):
msg = (
"cmake configuration steps encountered errors, and the idaklu module"
" could not be built. Make sure dependencies are correctly "
"installed. See "
"https://github.com/pybamm-team/PyBaMM/tree/develop"
"INSTALL-LINUX-MAC.md"
)
raise RuntimeError(msg)
else:
print("-" * 10, "Building idaklu module", "-" * 40)
subprocess.run(["cmake", "--build", "."], cwd=self.build_temp)
# Move from build temp to final position
for ext in self.extensions:
self.move_output(ext)
def move_output(self, ext):
# Copy built module to dist/ directory
build_temp = Path(self.build_temp).resolve()
source_path = build_temp / self.get_ext_filename(ext.name)
# Get destination location
# self.get_ext_fullpath(ext.name) -->
# build/lib.linux-x86_64-3.5/idaklu.cpython-37m-x86_64-linux-gnu.so
# using resolve() with python < 3.6 will result in a FileNotFoundError
# since the location does not yet exists.
dest_path = Path(self.get_ext_fullpath(ext.name)).resolve()
source_path = build_temp / self.get_ext_filename(ext.name)
dest_directory = dest_path.parents[0]
dest_directory.mkdir(parents=True, exist_ok=True)
self.copy_file(source_path, dest_path)