forked from chainer/chainer
-
Notifications
You must be signed in to change notification settings - Fork 1
/
chainerx_build_helper.py
131 lines (107 loc) · 4.13 KB
/
chainerx_build_helper.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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# This script is based on pybind11's example script. See the original via the
# following URL: https://github.com/pybind/cmake_example/blob/master/setup.py
import distutils
import os
import platform
import re
import subprocess
import sys
import setuptools
from setuptools.command import build_ext
def emit_build_info(build_chainerx):
dirname = os.path.dirname(__file__)
filename = os.path.join(dirname, 'chainerx/_build_info.py')
with open(filename, mode='w') as f:
f.write('build_chainerx = {}\n'.format(build_chainerx))
class CMakeExtension(setuptools.Extension):
def __init__(self, name, build_targets, sourcedir=''):
setuptools.Extension.__init__(self, name, sources=[])
self.sourcedir = os.path.abspath(sourcedir)
self.build_targets = build_targets
class CMakeBuild(build_ext.build_ext):
def run(self):
try:
out = subprocess.check_output(['cmake', '--version'])
except OSError:
raise RuntimeError('CMake must be installed to build ChainerX')
cmake_version = distutils.version.LooseVersion(
re.search(r'version\s*([\d.]+)', out.decode()).group(1))
if cmake_version < '3.1.0':
raise RuntimeError('CMake >= 3.1.0 is required to build ChainerX')
for ext in self.extensions:
self.build_extension(ext)
def build_extension(self, ext):
# Decide the build type: release/debug
build_type = os.getenv('CHAINERX_BUILD_TYPE', None)
if build_type is not None:
# Use environment variable
pass
elif self.debug:
# Being built with `python setup.py build --debug`
build_type = 'Debug'
elif os.getenv('READTHEDOCS', None) == 'True':
# on ReadTheDocs
build_type = 'Debug'
else:
# default
build_type = 'Release'
extdir = os.path.abspath(
os.path.dirname(self.get_ext_fullpath(ext.name)))
cmake_args = [
'-DCHAINERX_BUILD_PYTHON=1',
'-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=' + extdir,
'-DPYTHON_EXECUTABLE=' + sys.executable,
'-DCHAINERX_BUILD_TEST=OFF',
'-DCMAKE_BUILD_TYPE=' + build_type,
]
build_args = ['--config', build_type]
if platform.system() == 'Windows':
cmake_args += [
'-DCMAKE_LIBRARY_OUTPUT_DIRECTORY_{}={}'.format(
build_type.upper(), extdir)]
if sys.maxsize > 2**32:
cmake_args += ['-A', 'x64']
build_args += ['--', '/m']
else:
build_args += ['--']
build_args += ext.build_targets
env = os.environ.copy()
env['CXXFLAGS'] = '{} -DVERSION_INFO=\\"{}\\"'.format(
env.get('CXXFLAGS', ''), self.distribution.get_version())
if not os.path.exists(self.build_temp):
os.makedirs(self.build_temp)
subprocess.check_call(
['cmake', ext.sourcedir] + cmake_args, cwd=self.build_temp,
env=env)
subprocess.check_call(
['cmake', '--build', '.'] + build_args, cwd=self.build_temp)
def config_setup_kwargs(setup_kwargs, build_chainerx):
# TODO(imanishi): Call this function with setuptools.
emit_build_info(build_chainerx)
if not build_chainerx:
# `chainerx` package needs to be able to be imported even if ChainerX
# is unavailable.
setup_kwargs['packages'] += ['chainerx']
return
if sys.version_info < (3, 5):
raise RuntimeError(
'ChainerX is only available for Python 3.5 or later.')
setup_kwargs['packages'] += [
'chainerx',
'chainerx._docs',
'chainerx.creation',
'chainerx.manipulation',
'chainerx.math',
'chainerx.random',
'chainerx.testing',
]
setup_kwargs['package_data'] = {
'chainerx': ['py.typed', '*.pyi'],
}
setup_kwargs.update(dict(
cmdclass={'build_ext': CMakeBuild},
ext_modules=[CMakeExtension(
name='chainerx._core',
build_targets=['_core.so'],
sourcedir='chainerx_cc')],
))