def __init__(self, cc=None, x64=False, ver0=None): self.x64 = x64 patch_os_env(self.externals) self.c_environ = os.environ.copy() if cc is None: # prefer compiler used to build host. Python2 only if ver0 is None: ver0 = _get_vcver0() msvc_compiler_environ, self.vsver = find_msvc_env(x64, ver0=ver0) Platform.__init__(self, 'cl.exe') if msvc_compiler_environ: self.c_environ.update(msvc_compiler_environ) if x64: self.externals_branch = 'win34_%d' % self.vsver else: self.externals_branch = 'win32_%d' % self.vsver else: self.cc = cc # detect version of current compiler try: returncode, stdout, stderr = _run_subprocess(self.cc, [], env=self.c_environ) except EnvironmentError: log.msg('Could not run %s using PATH=\n%s' %(self.cc, '\n'.join(self.c_environ['PATH'].split(';')))) raise r = re.search(r'Microsoft.+C/C\+\+.+\s([0-9]+)\.([0-9]+).*', stderr) if r is not None: self.version = int(''.join(r.groups())) / 10 - 60 else: # Probably not a msvc compiler... self.version = 0 # Try to find a masm assembler returncode, stdout, stderr = _run_subprocess('ml.exe', [], env=self.c_environ) r = re.search('Macro Assembler', stderr) if r is None and os.path.exists('c:/masm32/bin/ml.exe'): masm32 = 'c:/masm32/bin/ml.exe' masm64 = 'c:/masm64/bin/ml64.exe' else: masm32 = 'ml.exe' masm64 = 'ml64.exe' if x64: self.masm = masm64 else: self.masm = masm32 # Install debug options only when interpreter is in debug mode if sys.executable.lower().endswith('_d.exe'): self.cflags = ['/MDd', '/Z7', '/Od'] # Increase stack size, for the linker and the stack check code. stack_size = 8 << 20 # 8 Mb self.link_flags = self.link_flags + ('/STACK:%d' % stack_size,) # The following symbol is used in c/src/stack.h self.cflags.append('/DMAX_STACK_SIZE=%d' % (stack_size - 1024))
def _get_msvc_env(vsver, x64flag): vcdict = None toolsdir = None try: if vsver < 140: toolsdir = os.environ['VS%sCOMNTOOLS' % vsver] else: raise KeyError('always use registry values') except KeyError: # use setuptools from python3 to find tools try: vcdict = _find_vcvarsall(vsver, x64flag) except Exception as e: return None else: if x64flag: vsinstalldir = os.path.abspath(os.path.join(toolsdir, '..', '..')) vcinstalldir = os.path.join(vsinstalldir, 'VC') vcbindir = os.path.join(vcinstalldir, 'BIN') vcvars = os.path.join(vcbindir, 'amd64', 'vcvarsamd64.bat') else: vcvars = os.path.join(toolsdir, 'vsvars32.bat') if not os.path.exists(vcvars): # even msdn does not know which to run # see https://msdn.microsoft.com/en-us/library/1700bbwd(v=vs.90).aspx # wich names both vcvars = os.path.join(toolsdir, 'vcvars32.bat') import subprocess try: popen = subprocess.Popen('"%s" & set' % (vcvars,), stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = popen.communicate() if popen.wait() != 0: return None except: return None stdout = stdout.replace("\r\n", "\n") vcdict = {} for line in stdout.split("\n"): if '=' not in line: continue key, value = line.split('=', 1) vcdict[key] = value env = {} for key, value in vcdict.items(): if key.upper() in ['PATH', 'INCLUDE', 'LIB']: env[key.upper()] = value log.msg("Updated environment with vsver %d, using x64 %s" % (vsver, x64flag,)) return env
def _get_msvc_env(vsver, x64flag): vcdict = None toolsdir = None try: toolsdir = os.environ['VS%sCOMNTOOLS' % vsver] except KeyError: # use setuptools from python3 to find tools try: vcdict = _find_vcvarsall(vsver, x64flag) except ImportError as e: if 'setuptools' in str(e): log.error( 'is setuptools installed (perhaps try %s -mensurepip)?' % sys.executable) log.error('looking for compiler %s raised exception "%s' % (vsver, str(e))) except Exception as e: log.error('looking for compiler %s raised exception "%s' % (vsver, str(e))) return None else: if x64flag: vsinstalldir = os.path.abspath(os.path.join(toolsdir, '..', '..')) vcinstalldir = os.path.join(vsinstalldir, 'VC') vcbindir = os.path.join(vcinstalldir, 'BIN') vcvars = os.path.join(vcbindir, 'amd64', 'vcvarsamd64.bat') else: vcvars = os.path.join(toolsdir, 'vsvars32.bat') if not os.path.exists(vcvars): # even msdn does not know which to run # see https://msdn.microsoft.com/en-us/library/1700bbwd(v=vs.90).aspx # which names both vcvars = os.path.join(toolsdir, 'vcvars32.bat') import subprocess try: popen = subprocess.Popen('"%s" & set' % (vcvars, ), stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = popen.communicate() if popen.wait() != 0 or stdout[:5].lower() == 'error': log.msg( 'Running "%s" errored: \n\nstdout:\n%s\n\nstderr:\n%s' % (vcvars, stdout.split()[0], stderr)) return None else: log.msg('Running "%s" succeeded' % (vcvars, )) except Exception as e: log.msg('Running "%s" failed: "%s"' % (vcvars, str(e))) return None stdout = stdout.replace("\r\n", "\n") vcdict = {} for line in stdout.split("\n"): if '=' not in line: continue key, value = line.split('=', 1) vcdict[key] = value env = {} for key, value in vcdict.items(): if key.upper() in ['PATH', 'INCLUDE', 'LIB']: env[key.upper()] = value if 'PATH' not in env: log.msg('Did not find "PATH" in stdout\n%s' % (stdout)) if not _find_executable('mt.exe', env['PATH']): # For some reason the sdk bin path is missing? # put it together from some other env variables that happened to exist # on the buildbot where this occurred if 'WindowsSDKVersion' in vcdict and 'WindowsSdkDir' in vcdict: binpath = vcdict['WindowsSdkDir'] + '\\bin\\' + vcdict[ 'WindowsSDKVersion'] + 'x86' env['PATH'] += ';' + binpath if not _find_executable('mt.exe', env['PATH']): log.msg('Could not find mt.exe on path=%s' % env['PATH']) log.msg('Running vsver %s set this env' % vsver) for key, value in vcdict.items(): log.msg('%s=%s' % (key, value)) log.msg("Updated environment with vsver %d, using x64 %s" % ( vsver, x64flag, )) return env