@@ -36,6 +36,15 @@ def create_makefile_regex(name):
3636 r'([0-9]+\.[0-9a-z.+]+)' # version
3737)
3838
39+ # Parse 'Microsoft (R) C/C++ Optimizing Compiler Version 19.51.36260 for ARM64'
40+ CL_VERSION_REGEX = re .compile (r'Compiler Version ([0-9]+).([0-9]+).[0-9]+ for (.*)' )
41+ CL_VERSION_SUFFIX = {
42+ 'x86' : "32 bit (Intel)" ,
43+ 'x64' : "64 bit (AMD64)" ,
44+ 'ARM' : "32 bit (ARM)" ,
45+ 'ARM64' : "64 bit (ARM64)" ,
46+ }
47+
3948
4049def log (msg ):
4150 print (f"{ SCRIPT_NAME } : { msg } " )
@@ -127,16 +136,23 @@ def parse_args():
127136 parser .add_argument ('--git-tag' , type = str )
128137 parser .add_argument ('--git-branch' , type = str )
129138 parser .add_argument ('--getcompiler-program' , type = str )
139+ parser .add_argument ('--c-compiler' , type = str )
130140 parser .add_argument ('--compiler' , type = str )
131141 parser .add_argument ('--free-threading' , type = int )
132142 return parser .parse_args ()
133143
134144
135- def run_command (cmd , * , check = True ):
145+ def run_command (cmd , * , check = True , stderr = False ):
136146 cmd_str = shlex .join (cmd )
137147 log (f"+ { cmd_str } " )
148+ kwargs = {}
149+ if stderr :
150+ kwargs ['stderr' ] = subprocess .STDOUT
138151 try :
139- proc = subprocess .run (cmd , stdout = subprocess .PIPE , text = True )
152+ proc = subprocess .run (cmd ,
153+ stdout = subprocess .PIPE ,
154+ text = True ,
155+ ** kwargs )
140156 except OSError as exc :
141157 error = f'with: { exc !r} '
142158 else :
@@ -157,7 +173,45 @@ def run_command(cmd, *, check=True):
157173 return proc .stdout .rstrip ()
158174
159175
160- def _get_compiler (getcompiler = None ):
176+ def get_c_compiler_version_windows (c_compiler ):
177+ cmd = [c_compiler ]
178+ output = run_command (cmd , check = False , stderr = True )
179+ if not output :
180+ return None
181+
182+ # Get the first line
183+ line = output .splitlines ()[0 ]
184+ match = CL_VERSION_REGEX .search (line )
185+ if not match :
186+ exit_error (f"Unable to parse cl.exe version: { output !r} " )
187+
188+ major = match .group (1 )
189+ minor = match .group (2 )
190+ platform = match .group (3 )
191+ suffix = CL_VERSION_SUFFIX .get (platform )
192+ if not suffix :
193+ exit_error (f"Unknown cl.exe platform: { platform !r} " )
194+
195+ return f"MSC v.{ major } { minor } { suffix } "
196+
197+
198+ def get_c_compiler_version_unix (c_compiler = None ):
199+ CC = get_makefile_cc ()
200+ if not CC :
201+ exit_error (f"ERROR: Unable to locate CC in Makefile" )
202+
203+ cmd = shlex .split (CC )
204+ cmd = [* cmd , '--version' ]
205+
206+ output = run_command (cmd , check = False )
207+ if output :
208+ # Get the first line
209+ return output .splitlines ()[0 ]
210+
211+ return None
212+
213+
214+ def _get_compiler (getcompiler = None , c_compiler = None ):
161215 # Run _getcompiler program
162216 if not getcompiler :
163217 getcompiler = os .path .join ('Programs' , '_getcompiler' )
@@ -174,21 +228,13 @@ def _get_compiler(getcompiler=None):
174228 if compiler :
175229 return compiler
176230
231+ # Running _getcompiler failed, get the C compiler version
177232 if MS_WINDOWS :
233+ if c_compiler :
234+ return get_c_compiler_version_windows (c_compiler )
178235 return None
179-
180- # Running _getcompiler failed, run the compiler with --version
181- CC = get_makefile_cc ()
182- if not CC :
183- exit_error (f"ERROR: Unable to locate CC in Makefile" )
184-
185- cmd = shlex .split (CC )
186- output = run_command ([* cmd , '--version' ], check = False )
187- if output :
188- # Get the first line
189- return output .splitlines ()[0 ]
190-
191- return None
236+ else :
237+ return get_c_compiler_version_unix ()
192238
193239
194240def compact_compiler (compiler ):
@@ -215,9 +261,9 @@ def compact_compiler(compiler):
215261 return compiler
216262
217263
218- def get_compiler (compiler , getcompiler_program = None ):
264+ def get_compiler (compiler , getcompiler = None , c_compiler = None ):
219265 if not compiler :
220- compiler = _get_compiler (getcompiler_program )
266+ compiler = _get_compiler (getcompiler , c_compiler )
221267 if not compiler :
222268 # Default compiler name when everything else failed
223269 # (see Programs/_getcompiler.c)
@@ -263,7 +309,7 @@ def main():
263309 if not platform :
264310 platform = "unknown"
265311
266- compiler = get_compiler (args .compiler , args .getcompiler_program )
312+ compiler = get_compiler (args .compiler , args .getcompiler_program , args . c_compiler )
267313
268314 build_info , git_id = get_build_info (git_tag , git_branch , git_version )
269315
0 commit comments