26
26
import warnings
27
27
28
28
import distutils
29
- from distutils .core import Extension
29
+
30
+ try :
31
+ # MSVC 2017 support (setuptools >= 34.4.0)
32
+ from setuptools import Extension
33
+ except ImportError :
34
+ from distutils .core import Extension
30
35
31
36
import Cython
32
37
from Cython .Build .Inline import _get_build_extension
33
38
from Cython .Build .Dependencies import cythonize
34
39
40
+ # GCC detection
41
+ import subprocess
42
+
35
43
import numpy as np
36
44
37
45
import pystan .api
@@ -134,7 +142,12 @@ class StanModel:
134
142
verbose : boolean, False by default
135
143
Indicates whether intermediate output should be piped to the console.
136
144
This output may be useful for debugging.
137
-
145
+
146
+ compiler : string, None by default
147
+ Only for Windows. Choose compiler type.
148
+ - for GCC use 'gcc' or 'mingw32',
149
+ - for Microsoft Visual C++ use 'msvc'
150
+
138
151
kwargs : keyword arguments
139
152
Additional arguments passed to `stanc`.
140
153
@@ -202,7 +215,7 @@ class StanModel:
202
215
def __init__ (self , file = None , charset = 'utf-8' , model_name = "anon_model" ,
203
216
model_code = None , stanc_ret = None , boost_lib = None ,
204
217
eigen_lib = None , verbose = False , obfuscate_model_name = True ,
205
- extra_compile_args = None ):
218
+ extra_compile_args = None , compiler = None ):
206
219
207
220
if stanc_ret is None :
208
221
stanc_ret = pystan .api .stanc (file = file ,
@@ -274,6 +287,10 @@ def __init__(self, file=None, charset='utf-8', model_name="anon_model",
274
287
('BOOST_NO_DECLTYPE' , None ),
275
288
('BOOST_DISABLE_ASSERTS' , None ),
276
289
]
290
+
291
+ # create here to allow compiler injection on Windows
292
+ build_extension = _get_build_extension ()
293
+
277
294
# compile stan models with optimization (-O2)
278
295
# (stanc is compiled without optimization (-O0) currently, see #33)
279
296
if extra_compile_args is None :
@@ -284,7 +301,25 @@ def __init__(self, file=None, charset='utf-8', model_name="anon_model",
284
301
'-Wno-uninitialized' ,
285
302
]
286
303
if platform .platform ().startswith ('Win' ):
287
- extra_compile_args = ['/EHsc' , '-DBOOST_DATE_TIME_NO_LIB' ]
304
+ # sanitize input
305
+ if compiler == 'gcc' :
306
+ compiler = 'mingw32'
307
+ # inject the compiler kw
308
+ if compiler is not None :
309
+ build_extension .compiler = compiler
310
+ # inject gcc (mingw32) if found else use msvc
311
+ elif build_extension .compiler is None :
312
+ # run subprocess without output
313
+ with open (os .devnull , 'w' ) as DEVNULL :
314
+ try :
315
+ subprocess .call (["gcc" , "--version" ], stdout = DEVNULL )
316
+ except FileNotFoundError :
317
+ build_extension .compiler = "msvc"
318
+ else :
319
+ build_extension .compiler = "mingw32"
320
+
321
+ if build_extension .compiler == "msvc" :
322
+ extra_compile_args = ['/EHsc' , '-DBOOST_DATE_TIME_NO_LIB' ]
288
323
289
324
distutils .log .set_verbosity (verbose )
290
325
extension = Extension (name = self .module_name ,
@@ -295,7 +330,7 @@ def __init__(self, file=None, charset='utf-8', model_name="anon_model",
295
330
extra_compile_args = extra_compile_args )
296
331
297
332
cython_include_dirs = ['.' , pystan_dir ]
298
- build_extension = _get_build_extension ()
333
+
299
334
build_extension .extensions = cythonize ([extension ],
300
335
include_path = cython_include_dirs ,
301
336
quiet = not verbose )
0 commit comments