1
1
from __future__ import print_function
2
- from os import getenv , path
2
+ from os import getenv , path , makedirs
3
+ import os
3
4
import subprocess
4
5
import sys
5
6
20
21
print ("Value {} for USE_DISTUTILS treated as False" .\
21
22
format (use_distutils ))
22
23
24
+ from distutils .command .build_ext import build_ext as _build_ext
23
25
from distutils .command .build import build as _build
24
26
25
27
if use_setuptools :
40
42
def process_opts (opts ):
41
43
return ['-D' + '=' .join (o ) for o in opts ]
42
44
45
+ def get_build_dir (dist ):
46
+ source_dir = path .dirname (path .realpath (__file__ ))
47
+ build = dist .get_command_obj ('build' )
48
+ build_ext = dist .get_command_obj ('build_ext' )
49
+ return source_dir if build_ext .inplace else build .build_platlib
50
+
51
+ global_user_options = [
52
+ ('symengine-dir=' , None , 'path to symengine installation or build directory' ),
53
+ ('generator=' , None , 'cmake build generator' ),
54
+ ('build-type=' , None , 'build type: Release or Debug' ),
55
+ ('define=' , 'D' ,
56
+ 'options to cmake <var>:<type>=<value>' ),
57
+ ]
58
+
43
59
class BuildWithCmake (_build ):
44
- _build_opts = _build .user_options
45
- user_options = [
46
- ('symengine-dir=' , None , 'path to symengine installation or build directory' ),
47
- ('generator=' , None , 'cmake build generator' ),
48
- ('build-type=' , None , 'build type: Release or Debug' ),
49
- ('define=' , 'D' ,
50
- 'options to cmake <var>:<type>=<value>' )
51
- ]
60
+ sub_commands = [('build_ext' , None )]
61
+
62
+ class BuildExtWithCmake (_build_ext ):
63
+ _build_opts = _build_ext .user_options
64
+ user_options = list (global_user_options )
52
65
user_options .extend (_build_opts )
53
66
54
67
def initialize_options (self ):
55
- _build .initialize_options (self )
68
+ _build_ext .initialize_options (self )
56
69
self .define = None
57
70
self .symengine_dir = None
58
71
self .generator = None
59
72
self .build_type = "Release"
60
73
61
74
def finalize_options (self ):
62
- _build .finalize_options (self )
75
+ _build_ext .finalize_options (self )
63
76
# The argument parsing will result in self.define being a string, but
64
77
# it has to be a list of 2-tuples.
65
78
# Multiple symbols can be separated with semi-colons.
@@ -78,15 +91,22 @@ def finalize_options(self):
78
91
cmake_build_type [0 ] = self .build_type
79
92
80
93
def cmake_build (self ):
81
- dir = path .dirname (path .realpath (__file__ ))
82
- cmake_cmd = ["cmake" , dir , "-DCMAKE_BUILD_TYPE=" + cmake_build_type [0 ]]
94
+ source_dir = path .dirname (path .realpath (__file__ ))
95
+ build_dir = get_build_dir (self .distribution )
96
+ if not path .exists (build_dir ):
97
+ makedirs (build_dir )
98
+ if build_dir != source_dir and path .exists ("CMakeCache.txt" ):
99
+ os .remove ("CMakeCache.txt" )
100
+
101
+ cmake_cmd = ["cmake" , source_dir , "-DCMAKE_BUILD_TYPE=" + cmake_build_type [0 ]]
83
102
cmake_cmd .extend (process_opts (cmake_opts ))
84
- if not path .exists ("CMakeCache.txt" ):
103
+ if not path .exists (path . join ( build_dir , "CMakeCache.txt" ) ):
85
104
cmake_cmd .extend (self .get_generator ())
86
- if subprocess .call (cmake_cmd ) != 0 :
105
+ if subprocess .call (cmake_cmd , cwd = build_dir ) != 0 :
87
106
raise EnvironmentError ("error calling cmake" )
88
107
89
- if subprocess .call (["cmake" , "--build" , "." , "--config" , cmake_build_type [0 ]]) != 0 :
108
+ if subprocess .call (["cmake" , "--build" , "." , "--config" , cmake_build_type [0 ]],
109
+ cwd = build_dir ) != 0 :
90
110
raise EnvironmentError ("error building project" )
91
111
92
112
def get_generator (self ):
@@ -108,25 +128,17 @@ def get_generator(self):
108
128
109
129
def run (self ):
110
130
self .cmake_build ()
111
- # can't use super() here because _build is an old style class in 2.7
112
- _build .run (self )
131
+ # can't use super() here because _build_ext is an old style class in 2.7
132
+ _build_ext .run (self )
113
133
114
134
class InstallWithCmake (_install ):
115
135
_install_opts = _install .user_options
116
- user_options = [
117
- ('symengine-dir=' , None , 'path to symengine installation or build directory' ),
118
- ('generator=' , None , 'cmake build generator' ),
119
- ('build-type=' , None , 'build type: Release or Debug' ),
120
- ('define=' , 'D' ,
121
- 'options to cmake <var>:<type>=<value>' )
122
- ]
136
+ user_options = list (global_user_options )
123
137
user_options .extend (_install_opts )
124
138
125
139
def initialize_options (self ):
126
140
_install .initialize_options (self )
127
141
self .define = None
128
- self .symengine_dir = None
129
- self .generator = None
130
142
self .build_type = "Release"
131
143
132
144
def finalize_options (self ):
@@ -140,27 +152,24 @@ def finalize_options(self):
140
152
tuple (ss .strip () for ss in s .split ('=' ))
141
153
for s in defines ]
142
154
cmake_opts .extend (self .define )
143
- if self .symengine_dir :
144
- cmake_opts .extend ([('SymEngine_DIR' , self .symengine_dir )])
145
-
146
- if self .generator :
147
- cmake_generator [0 ] = self .generator
148
155
149
156
cmake_build_type [0 ] = self .build_type
150
157
cmake_opts .extend ([('PYTHON_INSTALL_PATH' , self .install_platlib )])
151
158
cmake_opts .extend ([('PYTHON_INSTALL_HEADER_PATH' , self .install_headers )])
152
159
153
160
def cmake_install (self ):
154
- dir = path .dirname (path .realpath (__file__ ))
155
- cmake_cmd = ["cmake" , dir ]
161
+ source_dir = path .dirname (path .realpath (__file__ ))
162
+ build_dir = get_build_dir (self .distribution )
163
+ cmake_cmd = ["cmake" , source_dir ]
156
164
cmake_cmd .extend (process_opts (cmake_opts ))
157
165
158
166
# CMake has to be called here to update PYTHON_INSTALL_PATH
159
167
# if build and install were called separately by the user
160
- if subprocess .call (cmake_cmd ) != 0 :
168
+ if subprocess .call (cmake_cmd , cwd = build_dir ) != 0 :
161
169
raise EnvironmentError ("error calling cmake" )
162
170
163
- if subprocess .call (["cmake" , "--build" , "." , "--config" , cmake_build_type [0 ], "--target" , "install" ]) != 0 :
171
+ if subprocess .call (["cmake" , "--build" , "." , "--config" , cmake_build_type [0 ], "--target" , "install" ],
172
+ cwd = build_dir ) != 0 :
164
173
raise EnvironmentError ("error installing" )
165
174
166
175
import compileall
@@ -187,6 +196,7 @@ def run(self):
187
196
url = "https://github.com/symengine/symengine.py" ,
188
197
cmdclass = {
189
198
'build' : BuildWithCmake ,
199
+ 'build_ext' : BuildExtWithCmake ,
190
200
'install' : InstallWithCmake ,
191
201
},
192
202
classifiers = [
0 commit comments