waf/waflib/Tools/msvc.py

219 lines
7.1 KiB
Python

#!/usr/bin/env python
# encoding: utf-8
# Carlos Rafael Giani, 2006 (dv)
# Tamas Pal, 2007 (folti)
# Nicolas Mercier, 2009
# Matt Clarkson, 2012
"""
Microsoft Visual C++/Intel C++ compiler support
If you get detection problems, first try any of the following::
chcp 65001
set PYTHONIOENCODING=...
set PYTHONLEGACYWINDOWSSTDIO=1
Usage::
$ waf configure --msvc_version="msvc 10.0,msvc 9.0" --msvc_target="x64"
or::
def configure(conf):
conf.env.MSVC_VERSIONS = ['msvc 10.0', 'msvc 9.0', 'msvc 8.0', 'msvc 7.1', 'msvc 7.0', 'msvc 6.0', 'wsdk 7.0', 'intel 11']
conf.env.MSVC_TARGETS = ['x64']
conf.load('msvc')
or::
def configure(conf):
conf.load('msvc', funs='no_autodetect')
conf.check_lib_msvc('gdi32')
conf.check_libs_msvc('kernel32 user32')
def build(bld):
tg = bld.program(source='main.c', target='app', use='KERNEL32 USER32 GDI32')
Platforms and targets will be tested in the order they appear;
the first good configuration will be used.
To force testing all the configurations that are not used, use the ``--no-msvc-lazy`` option
or set ``conf.env.MSVC_LAZY_AUTODETECT=False``.
Supported platforms: ia64, x64, x86, x86_amd64, x86_ia64, x86_arm, amd64_x86, amd64_arm
Compilers supported:
* msvc => Visual Studio, versions 6.0 (VC 98, VC .NET 2002) to 15 (Visual Studio 2017)
* wsdk => Windows SDK, versions 6.0, 6.1, 7.0, 7.1, 8.0
* icl => Intel compiler, versions 9, 10, 11, 13
To use WAF in a VS2008 Make file project (see http://code.google.com/p/waf/issues/detail?id=894)
You may consider to set the environment variable "VS_UNICODE_OUTPUT" to nothing before calling waf.
So in your project settings use something like 'cmd.exe /C "set VS_UNICODE_OUTPUT=& set PYTHONUNBUFFERED=true & waf build"'.
cmd.exe /C "chcp 1252 & set PYTHONUNBUFFERED=true && set && waf configure"
Setting PYTHONUNBUFFERED gives the unbuffered output.
"""
import os, re
from waflib import Utils, Logs
from waflib.Configure import conf
from waflib.Tools import ccroot, c, cxx, ar, msvc_common
def options(opt):
msvc_common.options(opt)
@conf
def gather_icl_versions(conf, versions):
"""
Checks ICL compilers
:param versions: list to modify
:type versions: list
"""
version_pattern = re.compile(r'^...?.?\....?.?')
try:
all_versions = Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\Wow6432node\\Intel\\Compilers\\C++')
except OSError:
try:
all_versions = Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\Intel\\Compilers\\C++')
except OSError:
return
index = 0
while 1:
try:
version = Utils.winreg.EnumKey(all_versions, index)
except OSError:
break
index += 1
if not version_pattern.match(version):
continue
targets = {}
for target,arch in msvc_common.all_icl_platforms:
if target=='intel64':
targetDir='EM64T_NATIVE'
else:
targetDir=target
try:
Utils.winreg.OpenKey(all_versions,version+'\\'+targetDir)
icl_version=Utils.winreg.OpenKey(all_versions,version)
path,type=Utils.winreg.QueryValueEx(icl_version,'ProductDir')
except OSError:
pass
else:
batch_file=os.path.join(path,'bin','iclvars.bat')
if os.path.isfile(batch_file):
targets[target] = target_compiler(conf, 'intel', arch, version, target, batch_file)
for target,arch in msvc_common.all_icl_platforms:
try:
icl_version = Utils.winreg.OpenKey(all_versions, version+'\\'+target)
path,type = Utils.winreg.QueryValueEx(icl_version,'ProductDir')
except OSError:
continue
else:
batch_file=os.path.join(path,'bin','iclvars.bat')
if os.path.isfile(batch_file):
targets[target] = target_compiler(conf, 'intel', arch, version, target, batch_file)
major = version[0:2]
versions['intel ' + major] = targets
@conf
def gather_intel_composer_versions(conf, versions):
"""
Checks ICL compilers that are part of Intel Composer Suites
:param versions: list to modify
:type versions: list
"""
version_pattern = re.compile(r'^...?.?\...?.?.?')
try:
all_versions = Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\Wow6432node\\Intel\\Suites')
except OSError:
try:
all_versions = Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\Intel\\Suites')
except OSError:
return
index = 0
while 1:
try:
version = Utils.winreg.EnumKey(all_versions, index)
except OSError:
break
index += 1
if not version_pattern.match(version):
continue
targets = {}
for target,arch in msvc_common.all_icl_platforms:
if target=='intel64':
targetDir='EM64T_NATIVE'
else:
targetDir=target
try:
try:
defaults = Utils.winreg.OpenKey(all_versions,version+'\\Defaults\\C++\\'+targetDir)
except OSError:
if targetDir == 'EM64T_NATIVE':
defaults = Utils.winreg.OpenKey(all_versions,version+'\\Defaults\\C++\\EM64T')
else:
raise
uid,type = Utils.winreg.QueryValueEx(defaults, 'SubKey')
Utils.winreg.OpenKey(all_versions,version+'\\'+uid+'\\C++\\'+targetDir)
icl_version=Utils.winreg.OpenKey(all_versions,version+'\\'+uid+'\\C++')
path,type=Utils.winreg.QueryValueEx(icl_version,'ProductDir')
except OSError:
pass
else:
batch_file=os.path.join(path,'bin','iclvars.bat')
if os.path.isfile(batch_file):
targets[target] = target_compiler(conf, 'intel', arch, version, target, batch_file)
# The intel compilervar_arch.bat is broken when used with Visual Studio Express 2012
# http://software.intel.com/en-us/forums/topic/328487
compilervars_warning_attr = '_compilervars_warning_key'
if version[0:2] == '13' and getattr(conf, compilervars_warning_attr, True):
setattr(conf, compilervars_warning_attr, False)
patch_url = 'http://software.intel.com/en-us/forums/topic/328487'
compilervars_arch = os.path.join(path, 'bin', 'compilervars_arch.bat')
for vscomntool in ('VS110COMNTOOLS', 'VS100COMNTOOLS'):
if vscomntool in os.environ:
vs_express_path = os.environ[vscomntool] + r'..\IDE\VSWinExpress.exe'
dev_env_path = os.environ[vscomntool] + r'..\IDE\devenv.exe'
if (r'if exist "%VS110COMNTOOLS%..\IDE\VSWinExpress.exe"' in Utils.readf(compilervars_arch) and
not os.path.exists(vs_express_path) and not os.path.exists(dev_env_path)):
Logs.warn(('The Intel compilervar_arch.bat only checks for one Visual Studio SKU '
'(VSWinExpress.exe) but it does not seem to be installed at %r. '
'The intel command line set up will fail to configure unless the file %r'
'is patched. See: %s') % (vs_express_path, compilervars_arch, patch_url))
major = version[0:2]
versions['intel ' + major] = targets
@conf
def get_icl_versions(self):
"""
:return: platform to compiler configurations
:rtype: dict
"""
dct = Utils.ordered_iter_dict()
self.gather_icl_versions(dct)
self.gather_intel_composer_versions(dct)
return dct
def configure(conf):
"""
Configuration methods to call for detecting msvc
"""
conf.autodetect(True, get_icl_versions)
conf.find_msvc()
conf.msvc_common_flags()
conf.cc_load_tools()
conf.cxx_load_tools()
conf.cc_add_flags()
conf.cxx_add_flags()
conf.link_add_flags()
conf.visual_studio_add_flags()
@conf
def no_autodetect(conf):
conf.env.NO_MSVC_DETECT = 1
configure(conf)