6
6
7
7
import os
8
8
import pathlib
9
+ import subprocess
9
10
import sys
10
11
import sysconfig
12
+ import textwrap
11
13
12
14
__all__ = ['build_and_import_extension' , 'compile_extension_module' ]
13
15
@@ -51,8 +53,6 @@ def build_and_import_extension(
51
53
>>> assert not mod.test_bytes(u'abc')
52
54
>>> assert mod.test_bytes(b'abc')
53
55
"""
54
- from distutils .errors import CompileError
55
-
56
56
body = prologue + _make_methods (functions , modname )
57
57
init = """PyObject *mod = PyModule_Create(&moduledef);
58
58
"""
@@ -67,7 +67,7 @@ def build_and_import_extension(
67
67
try :
68
68
mod_so = compile_extension_module (
69
69
modname , build_dir , include_dirs , source_string )
70
- except CompileError as e :
70
+ except Exception as e :
71
71
# shorten the exception chain
72
72
raise RuntimeError (f"could not compile in { build_dir } :" ) from e
73
73
import importlib .util
@@ -186,9 +186,9 @@ def _c_compile(cfile, outputfilename, include_dirs=[], libraries=[],
186
186
elif sys .platform .startswith ('linux' ):
187
187
compile_extra = [
188
188
"-O0" , "-g" , "-Werror=implicit-function-declaration" , "-fPIC" ]
189
- link_extra = None
189
+ link_extra = []
190
190
else :
191
- compile_extra = link_extra = None
191
+ compile_extra = link_extra = []
192
192
pass
193
193
if sys .platform == 'win32' :
194
194
link_extra = link_extra + ['/DEBUG' ] # generate .pdb file
@@ -202,49 +202,46 @@ def _c_compile(cfile, outputfilename, include_dirs=[], libraries=[],
202
202
library_dirs .append (s + 'lib' )
203
203
204
204
outputfilename = outputfilename .with_suffix (get_so_suffix ())
205
- saved_environ = os .environ .copy ()
206
- try :
207
- build (
208
- cfile , outputfilename ,
209
- compile_extra , link_extra ,
210
- include_dirs , libraries , library_dirs )
211
- finally :
212
- # workaround for a distutils bugs where some env vars can
213
- # become longer and longer every time it is used
214
- for key , value in saved_environ .items ():
215
- if os .environ .get (key ) != value :
216
- os .environ [key ] = value
205
+ build (
206
+ cfile , outputfilename ,
207
+ compile_extra , link_extra ,
208
+ include_dirs , libraries , library_dirs )
217
209
return outputfilename
218
210
219
211
220
212
def build (cfile , outputfilename , compile_extra , link_extra ,
221
213
include_dirs , libraries , library_dirs ):
222
- "cd into the directory where the cfile is, use distutils to build"
223
- from numpy .distutils .ccompiler import new_compiler
224
-
225
- compiler = new_compiler (force = 1 , verbose = 2 )
226
- compiler .customize ('' )
227
- objects = []
228
-
229
- old = os .getcwd ()
230
- os .chdir (cfile .parent )
231
- try :
232
- res = compiler .compile (
233
- [str (cfile .name )],
234
- include_dirs = include_dirs ,
235
- extra_preargs = compile_extra
214
+ "use meson to build"
215
+
216
+ build_dir = cfile .parent / "build"
217
+ os .makedirs (build_dir , exist_ok = True )
218
+ so_name = outputfilename .parts [- 1 ]
219
+ with open (cfile .parent / "meson.build" , "wt" ) as fid :
220
+ includes = ['-I' + d for d in include_dirs ]
221
+ link_dirs = ['-L' + d for d in library_dirs ]
222
+ fid .write (textwrap .dedent (f"""\
223
+ project('foo', 'c')
224
+ shared_module('{ so_name } ', '{ cfile .parts [- 1 ]} ',
225
+ c_args: { includes } + { compile_extra } ,
226
+ link_args: { link_dirs } + { link_extra } ,
227
+ link_with: { libraries } ,
228
+ name_prefix: '',
229
+ name_suffix: 'dummy',
236
230
)
237
- objects += [str (cfile .parent / r ) for r in res ]
238
- finally :
239
- os .chdir (old )
240
-
241
- compiler .link_shared_object (
242
- objects , str (outputfilename ),
243
- libraries = libraries ,
244
- extra_preargs = link_extra ,
245
- library_dirs = library_dirs )
246
-
247
-
231
+ """ ))
232
+ if sys .platform == "win32" :
233
+ subprocess .check_call (["meson" , "setup" ,
234
+ "--buildtype=release" ,
235
+ "--vsenv" , ".." ],
236
+ cwd = build_dir ,
237
+ )
238
+ else :
239
+ subprocess .check_call (["meson" , "setup" , "--vsenv" , ".." ],
240
+ cwd = build_dir
241
+ )
242
+ subprocess .check_call (["meson" , "compile" ], cwd = build_dir )
243
+ os .rename (str (build_dir / so_name ) + ".dummy" , cfile .parent / so_name )
244
+
248
245
def get_so_suffix ():
249
246
ret = sysconfig .get_config_var ('EXT_SUFFIX' )
250
247
assert ret
0 commit comments