3333from cmdstanpy import _DOT_CMDSTAN , _DOT_CMDSTANPY
3434from cmdstanpy .utils import get_logger , pushd , validate_dir , wrap_progress_hook
3535
36+ MAKE = os .getenv (
37+ 'MAKE' , 'make' if platform .system () != 'Windows' else 'mingw32-make'
38+ )
3639EXTENSION = '.exe' if platform .system () == 'Windows' else ''
3740
3841
@@ -63,6 +66,114 @@ def usage() -> None:
6366 print (msg )
6467
6568
69+ def clean_all (verbose : bool = False ) -> None :
70+ """
71+ Run `make clean-all` in the current directory (must be a cmdstan library).
72+
73+ :param verbose: when ``True``, print build msgs to stdout.
74+ """
75+ cmd = [MAKE , 'clean-all' ]
76+ proc = subprocess .Popen (
77+ cmd ,
78+ cwd = None ,
79+ stdin = subprocess .DEVNULL ,
80+ stdout = subprocess .PIPE ,
81+ stderr = subprocess .PIPE ,
82+ env = os .environ ,
83+ )
84+ while proc .poll () is None :
85+ if proc .stdout :
86+ output = proc .stdout .readline ().decode ('utf-8' ).strip ()
87+ if verbose and output :
88+ print (output , flush = True )
89+ _ , stderr = proc .communicate ()
90+ if proc .returncode :
91+ msgs = ['Command "make clean-all" failed' ]
92+ if stderr :
93+ msgs .append (stderr .decode ('utf-8' ).strip ())
94+ raise CmdStanInstallError ('\n ' .join (msgs ))
95+
96+
97+ def build (verbose : bool = False ) -> None :
98+ """
99+ Run `make build` in the current directory (must be a cmdstan library)
100+
101+ :param verbose: when ``True``, print build msgs to stdout.
102+ """
103+ cmd = [MAKE , 'build' ]
104+ proc = subprocess .Popen (
105+ cmd ,
106+ cwd = None ,
107+ stdin = subprocess .DEVNULL ,
108+ stdout = subprocess .PIPE ,
109+ stderr = subprocess .PIPE ,
110+ env = os .environ ,
111+ )
112+ while proc .poll () is None :
113+ if proc .stdout :
114+ output = proc .stdout .readline ().decode ('utf-8' ).strip ()
115+ if verbose and output :
116+ print (output , flush = True )
117+ _ , stderr = proc .communicate ()
118+ if proc .returncode :
119+ msgs = ['Command "make build" failed' ]
120+ if stderr :
121+ msgs .append (stderr .decode ('utf-8' ).strip ())
122+ raise CmdStanInstallError ('\n ' .join (msgs ))
123+ if not os .path .exists (os .path .join ('bin' , 'stansummary' + EXTENSION )):
124+ raise CmdStanInstallError (
125+ f'bin/stansummary{ EXTENSION } not found'
126+ ', please rebuild or report a bug!'
127+ )
128+ if not os .path .exists (os .path .join ('bin' , 'diagnose' + EXTENSION )):
129+ raise CmdStanInstallError (
130+ f'bin/stansummary{ EXTENSION } not found'
131+ ', please rebuild or report a bug!'
132+ )
133+ if platform .system () == 'Windows' :
134+ # Add tbb to the $PATH on Windows
135+ libtbb = os .path .join (
136+ os .getcwd (), 'stan' , 'lib' , 'stan_math' , 'lib' , 'tbb'
137+ )
138+ os .environ ['PATH' ] = ';' .join (
139+ list (
140+ OrderedDict .fromkeys (
141+ [libtbb ] + os .environ .get ('PATH' , '' ).split (';' )
142+ )
143+ )
144+ )
145+
146+
147+ def compile_example () -> None :
148+ """
149+ Compile the example model.
150+ The current directory must be a cmdstan library.
151+ """
152+ cmd = [
153+ MAKE ,
154+ Path (
155+ os .path .join ('examples' , 'bernoulli' , 'bernoulli' + EXTENSION )
156+ ).as_posix (),
157+ ]
158+ proc = subprocess .Popen (
159+ cmd ,
160+ cwd = None ,
161+ stdin = subprocess .DEVNULL ,
162+ stdout = subprocess .PIPE ,
163+ stderr = subprocess .PIPE ,
164+ env = os .environ ,
165+ )
166+ while proc .poll () is None :
167+ if proc .stdout :
168+ proc .stdout .readline ().decode ('utf-8' )
169+ _ , stderr = proc .communicate ()
170+ if proc .returncode :
171+ msgs = ['Failed to compile example model bernoulli.stan' ]
172+ if stderr :
173+ msgs .append (stderr .decode ('utf-8' ).strip ())
174+ raise CmdStanInstallError ('\n ' .join (msgs ))
175+
176+
66177def install_version (
67178 cmdstan_version : str , overwrite : bool = False , verbose : bool = False
68179) -> None :
@@ -76,103 +187,17 @@ def install_version(
76187 :param verbose: when ``True``, print build msgs to stdout.
77188 """
78189 with pushd (cmdstan_version ):
79- make = os .getenv (
80- 'MAKE' , 'make' if platform .system () != 'Windows' else 'mingw32-make'
81- )
82190 print ('Building version {}' .format (cmdstan_version ))
83191 if overwrite :
84192 print (
85193 'Overwrite requested, remove existing build of version '
86194 '{}' .format (cmdstan_version )
87195 )
88- cmd = [make , 'clean-all' ]
89- proc = subprocess .Popen (
90- cmd ,
91- cwd = None ,
92- stdin = subprocess .DEVNULL ,
93- stdout = subprocess .PIPE ,
94- stderr = subprocess .PIPE ,
95- env = os .environ ,
96- )
97- while proc .poll () is None :
98- if proc .stdout :
99- output = proc .stdout .readline ().decode ('utf-8' ).strip ()
100- if verbose and output :
101- print (output , flush = True )
102- _ , stderr = proc .communicate ()
103- if proc .returncode :
104- msgs = ['Command "make clean-all" failed' ]
105- if stderr :
106- msgs .append (stderr .decode ('utf-8' ).strip ())
107- raise CmdStanInstallError ('\n ' .join (msgs ))
196+ clean_all (verbose )
108197 print ('Rebuilding version {}' .format (cmdstan_version ))
109- cmd = [make , 'build' ]
110- proc = subprocess .Popen (
111- cmd ,
112- cwd = None ,
113- stdin = subprocess .DEVNULL ,
114- stdout = subprocess .PIPE ,
115- stderr = subprocess .PIPE ,
116- env = os .environ ,
117- )
118- while proc .poll () is None :
119- if proc .stdout :
120-
121- output = proc .stdout .readline ().decode ('utf-8' ).strip ()
122- if verbose and output :
123- print (output , flush = True )
124- _ , stderr = proc .communicate ()
125- if proc .returncode :
126- msgs = ['Command "make build" failed' ]
127- if stderr :
128- msgs .append (stderr .decode ('utf-8' ).strip ())
129- raise CmdStanInstallError ('\n ' .join (msgs ))
130- if not os .path .exists (os .path .join ('bin' , 'stansummary' + EXTENSION )):
131- raise CmdStanInstallError (
132- f"bin/stansummary{ EXTENSION } not found"
133- ", please rebuild or report a bug!"
134- )
135- if not os .path .exists (os .path .join ('bin' , 'diagnose' + EXTENSION )):
136- raise CmdStanInstallError (
137- f"bin/stansummary{ EXTENSION } not found"
138- ", please rebuild or report a bug!"
139- )
198+ build (verbose )
140199 print ('Test model compilation' )
141- cmd = [
142- make ,
143- Path (
144- os .path .join ('examples' , 'bernoulli' , 'bernoulli' + EXTENSION )
145- ).as_posix (),
146- ]
147- if platform .system () == "Windows" :
148- # Add tbb to the $PATH on Windows
149- libtbb = os .path .join (
150- os .getcwd (), 'stan' , 'lib' , 'stan_math' , 'lib' , 'tbb'
151- )
152- os .environ ['PATH' ] = ';' .join (
153- list (
154- OrderedDict .fromkeys (
155- [libtbb ] + os .environ .get ('PATH' , '' ).split (';' )
156- )
157- )
158- )
159- proc = subprocess .Popen (
160- cmd ,
161- cwd = None ,
162- stdin = subprocess .DEVNULL ,
163- stdout = subprocess .PIPE ,
164- stderr = subprocess .PIPE ,
165- env = os .environ ,
166- )
167- while proc .poll () is None :
168- if proc .stdout :
169- proc .stdout .readline ().decode ('utf-8' )
170- _ , stderr = proc .communicate ()
171- if proc .returncode :
172- msgs = ['Failed to compile example model bernoulli.stan' ]
173- if stderr :
174- msgs .append (stderr .decode ('utf-8' ).strip ())
175- raise CmdStanInstallError ('\n ' .join (msgs ))
200+ compile_example ()
176201 print ('Installed {}' .format (cmdstan_version ))
177202
178203
0 commit comments