@@ -28,6 +28,8 @@ class build_rust(Command):
28
28
"Force debug to false for all rust extensions " ),
29
29
('qbuild' , None ,
30
30
"Force enable quiet option for all rust extensions " ),
31
+ ('build-temp' , 't' ,
32
+ "directory for temporary files (cargo 'target' directory) " ),
31
33
]
32
34
boolean_options = ['inplace' , 'debug' , 'release' , 'qbuild' ]
33
35
@@ -37,24 +39,38 @@ def initialize_options(self):
37
39
self .debug = None
38
40
self .release = None
39
41
self .qbuild = None
42
+ self .build_temp = None
40
43
41
44
def finalize_options (self ):
42
45
self .extensions = [ext for ext in self .distribution .rust_extensions
43
46
if isinstance (ext , RustExtension )]
44
47
48
+ # Inherit settings from the `build_ext` command
49
+ self .set_undefined_options ('build_ext' ,
50
+ ('build_temp' , 'build_temp' ),
51
+ ('debug' , 'debug' ),
52
+ ('inplace' , 'inplace' ),
53
+ )
54
+
45
55
def build_extension (self , ext ):
46
56
executable = ext .binding == Binding .Exec
47
57
48
58
# Make sure that if pythonXX-sys is used, it builds against the current
49
59
# executing python interpreter.
50
60
bindir = os .path .dirname (sys .executable )
51
61
62
+ # Find where to put the temporary build files created by `cargo`
63
+ targetdir = os .environ .get ('CARGO_TARGET_DIR' ) \
64
+ or os .path .join (self .build_temp , self .distribution .get_name ())
65
+
52
66
env = os .environ .copy ()
53
67
env .update ({
68
+ 'CARGO_TARGET_DIR' : targetdir ,
69
+
54
70
# disables rust's pkg-config seeking for specified packages,
55
71
# which causes pythonXX-sys to fall back to detecting the
56
72
# interpreter from the path.
57
- "PATH" : bindir + os .pathsep + os .environ .get ("PATH" , "" )
73
+ "PATH" : os .path . join ( bindir , os .environ .get ("PATH" , "" )),
58
74
})
59
75
60
76
if not os .path .exists (ext .path ):
@@ -64,11 +80,7 @@ def build_extension(self, ext):
64
80
features = set (ext .features )
65
81
features .update (cpython_feature (binding = ext .binding ))
66
82
67
- if ext .debug is None :
68
- debug_build = self .inplace
69
- else :
70
- debug_build = ext .debug
71
-
83
+ debug_build = ext .debug if ext .debug is not None else self .inplace
72
84
debug_build = self .debug if self .debug is not None else debug_build
73
85
if self .release :
74
86
debug_build = False
@@ -136,20 +148,14 @@ def build_extension(self, ext):
136
148
else :
137
149
suffix = "release"
138
150
139
- # location of files
140
- dir = os .environ .get ('CARGO_TARGET_DIR' , '' ).strip ()
141
- if dir :
142
- target_dir = os .path .join (dir , suffix )
143
- else :
144
- target_dir = os .path .join (
145
- os .path .dirname (ext .path ), "target/" , suffix )
146
-
151
+ # location of cargo compiled files
152
+ artifactsdir = os .path .join (targetdir , suffix )
147
153
dylib_paths = []
148
154
149
155
if executable :
150
156
for name , dest in ext .target .items ():
151
157
if name :
152
- path = os .path .join (target_dir , name )
158
+ path = os .path .join (artifactsdir , name )
153
159
if os .access (path , os .X_OK ):
154
160
dylib_paths .append ((dest , path ))
155
161
continue
@@ -160,8 +166,8 @@ def build_extension(self, ext):
160
166
name , target_dir ))
161
167
else :
162
168
# search executable
163
- for name in os .listdir (target_dir ):
164
- path = os .path .join (target_dir , name )
169
+ for name in os .listdir (artifactsdir ):
170
+ path = os .path .join (artifactsdir , name )
165
171
if name .startswith ("." ) or not os .path .isfile (path ):
166
172
continue
167
173
@@ -175,20 +181,23 @@ def build_extension(self, ext):
175
181
target_dir )
176
182
else :
177
183
if sys .platform == "win32" :
178
- wildcard_so = "*. dll"
184
+ dylib_ext = "dll"
179
185
elif sys .platform == "darwin" :
180
- wildcard_so = "*. dylib"
186
+ dylib_ext = "dylib"
181
187
else :
182
- wildcard_so = "*.so"
188
+ dylib_ext = "so"
189
+
190
+ wildcard_so = "*{}.{}" .format (ext .get_lib_name (), dylib_ext )
183
191
184
192
try :
185
- dylib_paths .append (
186
- (ext .name , glob .glob (
187
- os .path .join (target_dir , wildcard_so ))[0 ]))
188
- except IndexError :
193
+ dylib_paths .append ((
194
+ ext .name ,
195
+ next (glob .iglob (os .path .join (artifactsdir , wildcard_so )))
196
+ ))
197
+ except StopIteration :
189
198
raise DistutilsExecError (
190
199
"rust build failed; unable to find any %s in %s" %
191
- (wildcard_so , target_dir ))
200
+ (wildcard_so , artifactsdir ))
192
201
193
202
# Ask build_ext where the shared library would go if it had built it,
194
203
# then copy it there.
0 commit comments