Skip to content
This repository was archived by the owner on Mar 19, 2021. It is now read-only.

Commit fc5dbef

Browse files
authored
Add Windows gcc support for model.py
Add msvc 2017 support by importing from `setuptools`. Needs `setuptools >= 34.4.0`. Add compiler keyword (default None). User can choose mingw32, gcc / msvc. On windows, check with subprocess (quietly) if gcc is installed on the system. If found, use it else use 'msvc'.
1 parent 4683bc1 commit fc5dbef

File tree

1 file changed

+40
-5
lines changed

1 file changed

+40
-5
lines changed

pystan/model.py

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,20 @@
2626
import warnings
2727

2828
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
3035

3136
import Cython
3237
from Cython.Build.Inline import _get_build_extension
3338
from Cython.Build.Dependencies import cythonize
3439

40+
# GCC detection
41+
import subprocess
42+
3543
import numpy as np
3644

3745
import pystan.api
@@ -134,7 +142,12 @@ class StanModel:
134142
verbose : boolean, False by default
135143
Indicates whether intermediate output should be piped to the console.
136144
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+
138151
kwargs : keyword arguments
139152
Additional arguments passed to `stanc`.
140153
@@ -202,7 +215,7 @@ class StanModel:
202215
def __init__(self, file=None, charset='utf-8', model_name="anon_model",
203216
model_code=None, stanc_ret=None, boost_lib=None,
204217
eigen_lib=None, verbose=False, obfuscate_model_name=True,
205-
extra_compile_args=None):
218+
extra_compile_args=None, compiler=None):
206219

207220
if stanc_ret is None:
208221
stanc_ret = pystan.api.stanc(file=file,
@@ -274,6 +287,10 @@ def __init__(self, file=None, charset='utf-8', model_name="anon_model",
274287
('BOOST_NO_DECLTYPE', None),
275288
('BOOST_DISABLE_ASSERTS', None),
276289
]
290+
291+
# create here to allow compiler injection on Windows
292+
build_extension = _get_build_extension()
293+
277294
# compile stan models with optimization (-O2)
278295
# (stanc is compiled without optimization (-O0) currently, see #33)
279296
if extra_compile_args is None:
@@ -284,7 +301,25 @@ def __init__(self, file=None, charset='utf-8', model_name="anon_model",
284301
'-Wno-uninitialized',
285302
]
286303
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']
288323

289324
distutils.log.set_verbosity(verbose)
290325
extension = Extension(name=self.module_name,
@@ -295,7 +330,7 @@ def __init__(self, file=None, charset='utf-8', model_name="anon_model",
295330
extra_compile_args=extra_compile_args)
296331

297332
cython_include_dirs = ['.', pystan_dir]
298-
build_extension = _get_build_extension()
333+
299334
build_extension.extensions = cythonize([extension],
300335
include_path=cython_include_dirs,
301336
quiet=not verbose)

0 commit comments

Comments
 (0)