src/aubiopitch~.c: refix aubiopitch_tilde_del
[pd-aubio.git] / waflib / Tools / msvc.py
1 #! /usr/bin/env python
2 # encoding: utf-8
3 # WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
4
5 import os,sys,re,tempfile
6 from waflib import Utils,Task,Logs,Options,Errors
7 from waflib.Logs import debug,warn
8 from waflib.TaskGen import after_method,feature
9 from waflib.Configure import conf
10 from waflib.Tools import ccroot,c,cxx,ar,winres
11 g_msvc_systemlibs='''
12 aclui activeds ad1 adptif adsiid advapi32 asycfilt authz bhsupp bits bufferoverflowu cabinet
13 cap certadm certidl ciuuid clusapi comctl32 comdlg32 comsupp comsuppd comsuppw comsuppwd comsvcs
14 credui crypt32 cryptnet cryptui d3d8thk daouuid dbgeng dbghelp dciman32 ddao35 ddao35d
15 ddao35u ddao35ud delayimp dhcpcsvc dhcpsapi dlcapi dnsapi dsprop dsuiext dtchelp
16 faultrep fcachdll fci fdi framedyd framedyn gdi32 gdiplus glauxglu32 gpedit gpmuuid
17 gtrts32w gtrtst32hlink htmlhelp httpapi icm32 icmui imagehlp imm32 iphlpapi iprop
18 kernel32 ksguid ksproxy ksuser libcmt libcmtd libcpmt libcpmtd loadperf lz32 mapi
19 mapi32 mgmtapi minidump mmc mobsync mpr mprapi mqoa mqrt msacm32 mscms mscoree
20 msdasc msimg32 msrating mstask msvcmrt msvcurt msvcurtd mswsock msxml2 mtx mtxdm
21 netapi32 nmapinmsupp npptools ntdsapi ntdsbcli ntmsapi ntquery odbc32 odbcbcp
22 odbccp32 oldnames ole32 oleacc oleaut32 oledb oledlgolepro32 opends60 opengl32
23 osptk parser pdh penter pgobootrun pgort powrprof psapi ptrustm ptrustmd ptrustu
24 ptrustud qosname rasapi32 rasdlg rassapi resutils riched20 rpcndr rpcns4 rpcrt4 rtm
25 rtutils runtmchk scarddlg scrnsave scrnsavw secur32 sensapi setupapi sfc shell32
26 shfolder shlwapi sisbkup snmpapi sporder srclient sti strsafe svcguid tapi32 thunk32
27 traffic unicows url urlmon user32 userenv usp10 uuid uxtheme vcomp vcompd vdmdbg
28 version vfw32 wbemuuid  webpost wiaguid wininet winmm winscard winspool winstrm
29 wintrust wldap32 wmiutils wow32 ws2_32 wsnmp32 wsock32 wst wtsapi32 xaswitch xolehlp
30 '''.split()
31 all_msvc_platforms=[('x64','amd64'),('x86','x86'),('ia64','ia64'),('x86_amd64','amd64'),('x86_ia64','ia64'),('x86_arm','arm')]
32 all_wince_platforms=[('armv4','arm'),('armv4i','arm'),('mipsii','mips'),('mipsii_fp','mips'),('mipsiv','mips'),('mipsiv_fp','mips'),('sh4','sh'),('x86','cex86')]
33 all_icl_platforms=[('intel64','amd64'),('em64t','amd64'),('ia32','x86'),('Itanium','ia64')]
34 def options(opt):
35         opt.add_option('--msvc_version',type='string',help='msvc version, eg: "msvc 10.0,msvc 9.0"',default='')
36         opt.add_option('--msvc_targets',type='string',help='msvc targets, eg: "x64,arm"',default='')
37 def setup_msvc(conf,versions,arch=False):
38         platforms=getattr(Options.options,'msvc_targets','').split(',')
39         if platforms==['']:
40                 platforms=Utils.to_list(conf.env['MSVC_TARGETS'])or[i for i,j in all_msvc_platforms+all_icl_platforms+all_wince_platforms]
41         desired_versions=getattr(Options.options,'msvc_version','').split(',')
42         if desired_versions==['']:
43                 desired_versions=conf.env['MSVC_VERSIONS']or[v for v,_ in versions][::-1]
44         versiondict=dict(versions)
45         for version in desired_versions:
46                 try:
47                         targets=dict(versiondict[version])
48                         for target in platforms:
49                                 try:
50                                         arch,(p1,p2,p3)=targets[target]
51                                         compiler,revision=version.rsplit(' ',1)
52                                         if arch:
53                                                 return compiler,revision,p1,p2,p3,arch
54                                         else:
55                                                 return compiler,revision,p1,p2,p3
56                                 except KeyError:continue
57                 except KeyError:continue
58         conf.fatal('msvc: Impossible to find a valid architecture for building (in setup_msvc)')
59 @conf
60 def get_msvc_version(conf,compiler,version,target,vcvars):
61         debug('msvc: get_msvc_version: %r %r %r',compiler,version,target)
62         batfile=conf.bldnode.make_node('waf-print-msvc.bat')
63         batfile.write("""@echo off
64 set INCLUDE=
65 set LIB=
66 call "%s" %s
67 echo PATH=%%PATH%%
68 echo INCLUDE=%%INCLUDE%%
69 echo LIB=%%LIB%%;%%LIBPATH%%
70 """%(vcvars,target))
71         sout=conf.cmd_and_log(['cmd','/E:on','/V:on','/C',batfile.abspath()])
72         lines=sout.splitlines()
73         if not lines[0]:
74                 lines.pop(0)
75         MSVC_PATH=MSVC_INCDIR=MSVC_LIBDIR=None
76         for line in lines:
77                 if line.startswith('PATH='):
78                         path=line[5:]
79                         MSVC_PATH=path.split(';')
80                 elif line.startswith('INCLUDE='):
81                         MSVC_INCDIR=[i for i in line[8:].split(';')if i]
82                 elif line.startswith('LIB='):
83                         MSVC_LIBDIR=[i for i in line[4:].split(';')if i]
84         if None in(MSVC_PATH,MSVC_INCDIR,MSVC_LIBDIR):
85                 conf.fatal('msvc: Could not find a valid architecture for building (get_msvc_version_3)')
86         env=dict(os.environ)
87         env.update(PATH=path)
88         compiler_name,linker_name,lib_name=_get_prog_names(conf,compiler)
89         cxx=conf.find_program(compiler_name,path_list=MSVC_PATH)
90         cxx=conf.cmd_to_list(cxx)
91         if'CL'in env:
92                 del(env['CL'])
93         try:
94                 try:
95                         conf.cmd_and_log(cxx+['/help'],env=env)
96                 except Exception ,e:
97                         debug('msvc: get_msvc_version: %r %r %r -> failure'%(compiler,version,target))
98                         debug(str(e))
99                         conf.fatal('msvc: cannot run the compiler (in get_msvc_version)')
100                 else:
101                         debug('msvc: get_msvc_version: %r %r %r -> OK',compiler,version,target)
102         finally:
103                 conf.env[compiler_name]=''
104         return(MSVC_PATH,MSVC_INCDIR,MSVC_LIBDIR)
105 @conf
106 def gather_wsdk_versions(conf,versions):
107         version_pattern=re.compile('^v..?.?\...?.?')
108         try:
109                 all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Wow6432node\\Microsoft\\Microsoft SDKs\\Windows')
110         except WindowsError:
111                 try:
112                         all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows')
113                 except WindowsError:
114                         return
115         index=0
116         while 1:
117                 try:
118                         version=Utils.winreg.EnumKey(all_versions,index)
119                 except WindowsError:
120                         break
121                 index=index+1
122                 if not version_pattern.match(version):
123                         continue
124                 try:
125                         msvc_version=Utils.winreg.OpenKey(all_versions,version)
126                         path,type=Utils.winreg.QueryValueEx(msvc_version,'InstallationFolder')
127                 except WindowsError:
128                         continue
129                 if os.path.isfile(os.path.join(path,'bin','SetEnv.cmd')):
130                         targets=[]
131                         for target,arch in all_msvc_platforms:
132                                 try:
133                                         targets.append((target,(arch,conf.get_msvc_version('wsdk',version,'/'+target,os.path.join(path,'bin','SetEnv.cmd')))))
134                                 except conf.errors.ConfigurationError:
135                                         pass
136                         versions.append(('wsdk '+version[1:],targets))
137 def gather_wince_supported_platforms():
138         supported_wince_platforms=[]
139         try:
140                 ce_sdk=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Wow6432node\\Microsoft\\Windows CE Tools\\SDKs')
141         except WindowsError:
142                 try:
143                         ce_sdk=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Microsoft\\Windows CE Tools\\SDKs')
144                 except WindowsError:
145                         ce_sdk=''
146         if not ce_sdk:
147                 return supported_wince_platforms
148         ce_index=0
149         while 1:
150                 try:
151                         sdk_device=Utils.winreg.EnumKey(ce_sdk,ce_index)
152                 except WindowsError:
153                         break
154                 ce_index=ce_index+1
155                 sdk=Utils.winreg.OpenKey(ce_sdk,sdk_device)
156                 try:
157                         path,type=Utils.winreg.QueryValueEx(sdk,'SDKRootDir')
158                 except WindowsError:
159                         try:
160                                 path,type=Utils.winreg.QueryValueEx(sdk,'SDKInformation')
161                                 path,xml=os.path.split(path)
162                         except WindowsError:
163                                 continue
164                 path=str(path)
165                 path,device=os.path.split(path)
166                 if not device:
167                         path,device=os.path.split(path)
168                 for arch,compiler in all_wince_platforms:
169                         platforms=[]
170                         if os.path.isdir(os.path.join(path,device,'Lib',arch)):
171                                 platforms.append((arch,compiler,os.path.join(path,device,'Include',arch),os.path.join(path,device,'Lib',arch)))
172                         if platforms:
173                                 supported_wince_platforms.append((device,platforms))
174         return supported_wince_platforms
175 def gather_msvc_detected_versions():
176         version_pattern=re.compile('^(\d\d?\.\d\d?)(Exp)?$')
177         detected_versions=[]
178         for vcver,vcvar in[('VCExpress','Exp'),('VisualStudio','')]:
179                 try:
180                         prefix='SOFTWARE\\Wow6432node\\Microsoft\\'+vcver
181                         all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,prefix)
182                 except WindowsError:
183                         try:
184                                 prefix='SOFTWARE\\Microsoft\\'+vcver
185                                 all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,prefix)
186                         except WindowsError:
187                                 continue
188                 index=0
189                 while 1:
190                         try:
191                                 version=Utils.winreg.EnumKey(all_versions,index)
192                         except WindowsError:
193                                 break
194                         index=index+1
195                         match=version_pattern.match(version)
196                         if not match:
197                                 continue
198                         else:
199                                 versionnumber=float(match.group(1))
200                         detected_versions.append((versionnumber,version+vcvar,prefix+"\\"+version))
201         def fun(tup):
202                 return tup[0]
203         detected_versions.sort(key=fun)
204         return detected_versions
205 @conf
206 def gather_msvc_targets(conf,versions,version,vc_path):
207         targets=[]
208         if os.path.isfile(os.path.join(vc_path,'vcvarsall.bat')):
209                 for target,realtarget in all_msvc_platforms[::-1]:
210                         try:
211                                 targets.append((target,(realtarget,conf.get_msvc_version('msvc',version,target,os.path.join(vc_path,'vcvarsall.bat')))))
212                         except conf.errors.ConfigurationError:
213                                 pass
214         elif os.path.isfile(os.path.join(vc_path,'Common7','Tools','vsvars32.bat')):
215                 try:
216                         targets.append(('x86',('x86',conf.get_msvc_version('msvc',version,'x86',os.path.join(vc_path,'Common7','Tools','vsvars32.bat')))))
217                 except conf.errors.ConfigurationError:
218                         pass
219         elif os.path.isfile(os.path.join(vc_path,'Bin','vcvars32.bat')):
220                 try:
221                         targets.append(('x86',('x86',conf.get_msvc_version('msvc',version,'',os.path.join(vc_path,'Bin','vcvars32.bat')))))
222                 except conf.errors.ConfigurationError:
223                         pass
224         if targets:
225                 versions.append(('msvc '+version,targets))
226 @conf
227 def gather_wince_targets(conf,versions,version,vc_path,vsvars,supported_platforms):
228         for device,platforms in supported_platforms:
229                 cetargets=[]
230                 for platform,compiler,include,lib in platforms:
231                         winCEpath=os.path.join(vc_path,'ce')
232                         if not os.path.isdir(winCEpath):
233                                 continue
234                         try:
235                                 common_bindirs,_1,_2=conf.get_msvc_version('msvc',version,'x86',vsvars)
236                         except conf.errors.ConfigurationError:
237                                 continue
238                         if os.path.isdir(os.path.join(winCEpath,'lib',platform)):
239                                 bindirs=[os.path.join(winCEpath,'bin',compiler),os.path.join(winCEpath,'bin','x86_'+compiler)]+common_bindirs
240                                 incdirs=[os.path.join(winCEpath,'include'),os.path.join(winCEpath,'atlmfc','include'),include]
241                                 libdirs=[os.path.join(winCEpath,'lib',platform),os.path.join(winCEpath,'atlmfc','lib',platform),lib]
242                                 cetargets.append((platform,(platform,(bindirs,incdirs,libdirs))))
243                 if cetargets:
244                         versions.append((device+' '+version,cetargets))
245 @conf
246 def gather_winphone_targets(conf,versions,version,vc_path,vsvars):
247         targets=[]
248         for target,realtarget in all_msvc_platforms[::-1]:
249                 try:
250                         targets.append((target,(realtarget,conf.get_msvc_version('winphone',version,target,vsvars))))
251                 except conf.errors.ConfigurationError ,e:
252                         pass
253         if targets:
254                 versions.append(('winphone '+version,targets))
255 @conf
256 def gather_msvc_versions(conf,versions):
257         vc_paths=[]
258         for(v,version,reg)in gather_msvc_detected_versions():
259                 try:
260                         try:
261                                 msvc_version=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,reg+"\\Setup\\VC")
262                         except WindowsError:
263                                 msvc_version=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,reg+"\\Setup\\Microsoft Visual C++")
264                         path,type=Utils.winreg.QueryValueEx(msvc_version,'ProductDir')
265                         vc_paths.append((version,os.path.abspath(str(path))))
266                 except WindowsError:
267                         continue
268         wince_supported_platforms=gather_wince_supported_platforms()
269         for version,vc_path in vc_paths:
270                 vs_path=os.path.dirname(vc_path)
271                 vsvars=os.path.join(vs_path,'Common7','Tools','vsvars32.bat')
272                 if wince_supported_platforms and os.path.isfile(vsvars):
273                         conf.gather_wince_targets(versions,version,vc_path,vsvars,wince_supported_platforms)
274                 vsvars=os.path.join(vs_path,'VC','WPSDK','WP80','vcvarsphoneall.bat')
275                 if os.path.isfile(vsvars):
276                         conf.gather_winphone_targets(versions,'8.0',vc_path,vsvars)
277         for version,vc_path in vc_paths:
278                 vs_path=os.path.dirname(vc_path)
279                 conf.gather_msvc_targets(versions,version,vc_path)
280 @conf
281 def gather_icl_versions(conf,versions):
282         version_pattern=re.compile('^...?.?\....?.?')
283         try:
284                 all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Wow6432node\\Intel\\Compilers\\C++')
285         except WindowsError:
286                 try:
287                         all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Intel\\Compilers\\C++')
288                 except WindowsError:
289                         return
290         index=0
291         while 1:
292                 try:
293                         version=Utils.winreg.EnumKey(all_versions,index)
294                 except WindowsError:
295                         break
296                 index=index+1
297                 if not version_pattern.match(version):
298                         continue
299                 targets=[]
300                 for target,arch in all_icl_platforms:
301                         try:
302                                 if target=='intel64':targetDir='EM64T_NATIVE'
303                                 else:targetDir=target
304                                 Utils.winreg.OpenKey(all_versions,version+'\\'+targetDir)
305                                 icl_version=Utils.winreg.OpenKey(all_versions,version)
306                                 path,type=Utils.winreg.QueryValueEx(icl_version,'ProductDir')
307                                 batch_file=os.path.join(path,'bin','iclvars.bat')
308                                 if os.path.isfile(batch_file):
309                                         try:
310                                                 targets.append((target,(arch,conf.get_msvc_version('intel',version,target,batch_file))))
311                                         except conf.errors.ConfigurationError:
312                                                 pass
313                         except WindowsError:
314                                 pass
315                 for target,arch in all_icl_platforms:
316                         try:
317                                 icl_version=Utils.winreg.OpenKey(all_versions,version+'\\'+target)
318                                 path,type=Utils.winreg.QueryValueEx(icl_version,'ProductDir')
319                                 batch_file=os.path.join(path,'bin','iclvars.bat')
320                                 if os.path.isfile(batch_file):
321                                         try:
322                                                 targets.append((target,(arch,conf.get_msvc_version('intel',version,target,batch_file))))
323                                         except conf.errors.ConfigurationError:
324                                                 pass
325                         except WindowsError:
326                                 continue
327                 major=version[0:2]
328                 versions.append(('intel '+major,targets))
329 @conf
330 def gather_intel_composer_versions(conf,versions):
331         version_pattern=re.compile('^...?.?\...?.?.?')
332         try:
333                 all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Wow6432node\\Intel\\Suites')
334         except WindowsError:
335                 try:
336                         all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Intel\\Suites')
337                 except WindowsError:
338                         return
339         index=0
340         while 1:
341                 try:
342                         version=Utils.winreg.EnumKey(all_versions,index)
343                 except WindowsError:
344                         break
345                 index=index+1
346                 if not version_pattern.match(version):
347                         continue
348                 targets=[]
349                 for target,arch in all_icl_platforms:
350                         try:
351                                 if target=='intel64':targetDir='EM64T_NATIVE'
352                                 else:targetDir=target
353                                 try:
354                                         defaults=Utils.winreg.OpenKey(all_versions,version+'\\Defaults\\C++\\'+targetDir)
355                                 except WindowsError:
356                                         if targetDir=='EM64T_NATIVE':
357                                                 defaults=Utils.winreg.OpenKey(all_versions,version+'\\Defaults\\C++\\EM64T')
358                                         else:
359                                                 raise WindowsError
360                                 uid,type=Utils.winreg.QueryValueEx(defaults,'SubKey')
361                                 Utils.winreg.OpenKey(all_versions,version+'\\'+uid+'\\C++\\'+targetDir)
362                                 icl_version=Utils.winreg.OpenKey(all_versions,version+'\\'+uid+'\\C++')
363                                 path,type=Utils.winreg.QueryValueEx(icl_version,'ProductDir')
364                                 batch_file=os.path.join(path,'bin','iclvars.bat')
365                                 if os.path.isfile(batch_file):
366                                         try:
367                                                 targets.append((target,(arch,conf.get_msvc_version('intel',version,target,batch_file))))
368                                         except conf.errors.ConfigurationError ,e:
369                                                 pass
370                                 compilervars_warning_attr='_compilervars_warning_key'
371                                 if version[0:2]=='13'and getattr(conf,compilervars_warning_attr,True):
372                                         setattr(conf,compilervars_warning_attr,False)
373                                         patch_url='http://software.intel.com/en-us/forums/topic/328487'
374                                         compilervars_arch=os.path.join(path,'bin','compilervars_arch.bat')
375                                         for vscomntool in['VS110COMNTOOLS','VS100COMNTOOLS']:
376                                                 if vscomntool in os.environ:
377                                                         vs_express_path=os.environ[vscomntool]+r'..\IDE\VSWinExpress.exe'
378                                                         dev_env_path=os.environ[vscomntool]+r'..\IDE\devenv.exe'
379                                                         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)):
380                                                                 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))
381                         except WindowsError:
382                                 pass
383                 major=version[0:2]
384                 versions.append(('intel '+major,targets))
385 @conf
386 def get_msvc_versions(conf):
387         if not conf.env['MSVC_INSTALLED_VERSIONS']:
388                 lst=[]
389                 conf.gather_icl_versions(lst)
390                 conf.gather_intel_composer_versions(lst)
391                 conf.gather_wsdk_versions(lst)
392                 conf.gather_msvc_versions(lst)
393                 conf.env['MSVC_INSTALLED_VERSIONS']=lst
394         return conf.env['MSVC_INSTALLED_VERSIONS']
395 @conf
396 def print_all_msvc_detected(conf):
397         for version,targets in conf.env['MSVC_INSTALLED_VERSIONS']:
398                 Logs.info(version)
399                 for target,l in targets:
400                         Logs.info("\t"+target)
401 @conf
402 def detect_msvc(conf,arch=False):
403         versions=get_msvc_versions(conf)
404         return setup_msvc(conf,versions,arch)
405 @conf
406 def find_lt_names_msvc(self,libname,is_static=False):
407         lt_names=['lib%s.la'%libname,'%s.la'%libname,]
408         for path in self.env['LIBPATH']:
409                 for la in lt_names:
410                         laf=os.path.join(path,la)
411                         dll=None
412                         if os.path.exists(laf):
413                                 ltdict=Utils.read_la_file(laf)
414                                 lt_libdir=None
415                                 if ltdict.get('libdir',''):
416                                         lt_libdir=ltdict['libdir']
417                                 if not is_static and ltdict.get('library_names',''):
418                                         dllnames=ltdict['library_names'].split()
419                                         dll=dllnames[0].lower()
420                                         dll=re.sub('\.dll$','',dll)
421                                         return(lt_libdir,dll,False)
422                                 elif ltdict.get('old_library',''):
423                                         olib=ltdict['old_library']
424                                         if os.path.exists(os.path.join(path,olib)):
425                                                 return(path,olib,True)
426                                         elif lt_libdir!=''and os.path.exists(os.path.join(lt_libdir,olib)):
427                                                 return(lt_libdir,olib,True)
428                                         else:
429                                                 return(None,olib,True)
430                                 else:
431                                         raise self.errors.WafError('invalid libtool object file: %s'%laf)
432         return(None,None,None)
433 @conf
434 def libname_msvc(self,libname,is_static=False):
435         lib=libname.lower()
436         lib=re.sub('\.lib$','',lib)
437         if lib in g_msvc_systemlibs:
438                 return lib
439         lib=re.sub('^lib','',lib)
440         if lib=='m':
441                 return None
442         (lt_path,lt_libname,lt_static)=self.find_lt_names_msvc(lib,is_static)
443         if lt_path!=None and lt_libname!=None:
444                 if lt_static==True:
445                         return os.path.join(lt_path,lt_libname)
446         if lt_path!=None:
447                 _libpaths=[lt_path]+self.env['LIBPATH']
448         else:
449                 _libpaths=self.env['LIBPATH']
450         static_libs=['lib%ss.lib'%lib,'lib%s.lib'%lib,'%ss.lib'%lib,'%s.lib'%lib,]
451         dynamic_libs=['lib%s.dll.lib'%lib,'lib%s.dll.a'%lib,'%s.dll.lib'%lib,'%s.dll.a'%lib,'lib%s_d.lib'%lib,'%s_d.lib'%lib,'%s.lib'%lib,]
452         libnames=static_libs
453         if not is_static:
454                 libnames=dynamic_libs+static_libs
455         for path in _libpaths:
456                 for libn in libnames:
457                         if os.path.exists(os.path.join(path,libn)):
458                                 debug('msvc: lib found: %s'%os.path.join(path,libn))
459                                 return re.sub('\.lib$','',libn)
460         self.fatal("The library %r could not be found"%libname)
461         return re.sub('\.lib$','',libname)
462 @conf
463 def check_lib_msvc(self,libname,is_static=False,uselib_store=None):
464         libn=self.libname_msvc(libname,is_static)
465         if not uselib_store:
466                 uselib_store=libname.upper()
467         if False and is_static:
468                 self.env['STLIB_'+uselib_store]=[libn]
469         else:
470                 self.env['LIB_'+uselib_store]=[libn]
471 @conf
472 def check_libs_msvc(self,libnames,is_static=False):
473         for libname in Utils.to_list(libnames):
474                 self.check_lib_msvc(libname,is_static)
475 def configure(conf):
476         conf.autodetect(True)
477         conf.find_msvc()
478         conf.msvc_common_flags()
479         conf.cc_load_tools()
480         conf.cxx_load_tools()
481         conf.cc_add_flags()
482         conf.cxx_add_flags()
483         conf.link_add_flags()
484         conf.visual_studio_add_flags()
485 @conf
486 def no_autodetect(conf):
487         conf.env.NO_MSVC_DETECT=1
488         configure(conf)
489 @conf
490 def autodetect(conf,arch=False):
491         v=conf.env
492         if v.NO_MSVC_DETECT:
493                 return
494         if arch:
495                 compiler,version,path,includes,libdirs,arch=conf.detect_msvc(True)
496                 v['DEST_CPU']=arch
497         else:
498                 compiler,version,path,includes,libdirs=conf.detect_msvc()
499         v['PATH']=path
500         v['INCLUDES']=includes
501         v['LIBPATH']=libdirs
502         v['MSVC_COMPILER']=compiler
503         try:
504                 v['MSVC_VERSION']=float(version)
505         except Exception:
506                 v['MSVC_VERSION']=float(version[:-3])
507 def _get_prog_names(conf,compiler):
508         if compiler=='intel':
509                 compiler_name='ICL'
510                 linker_name='XILINK'
511                 lib_name='XILIB'
512         else:
513                 compiler_name='CL'
514                 linker_name='LINK'
515                 lib_name='LIB'
516         return compiler_name,linker_name,lib_name
517 @conf
518 def find_msvc(conf):
519         if sys.platform=='cygwin':
520                 conf.fatal('MSVC module does not work under cygwin Python!')
521         v=conf.env
522         path=v['PATH']
523         compiler=v['MSVC_COMPILER']
524         version=v['MSVC_VERSION']
525         compiler_name,linker_name,lib_name=_get_prog_names(conf,compiler)
526         v.MSVC_MANIFEST=(compiler=='msvc'and version>=8)or(compiler=='wsdk'and version>=6)or(compiler=='intel'and version>=11)
527         cxx=None
528         if v['CXX']:cxx=v['CXX']
529         elif'CXX'in conf.environ:cxx=conf.environ['CXX']
530         cxx=conf.find_program(compiler_name,var='CXX',path_list=path)
531         cxx=conf.cmd_to_list(cxx)
532         env=dict(conf.environ)
533         if path:env.update(PATH=';'.join(path))
534         if not conf.cmd_and_log(cxx+['/nologo','/help'],env=env):
535                 conf.fatal('the msvc compiler could not be identified')
536         v['CC']=v['CXX']=cxx
537         v['CC_NAME']=v['CXX_NAME']='msvc'
538         if not v['LINK_CXX']:
539                 link=conf.find_program(linker_name,path_list=path)
540                 if link:v['LINK_CXX']=link
541                 else:conf.fatal('%s was not found (linker)'%linker_name)
542                 v['LINK']=link
543         if not v['LINK_CC']:
544                 v['LINK_CC']=v['LINK_CXX']
545         if not v['AR']:
546                 stliblink=conf.find_program(lib_name,path_list=path,var='AR')
547                 if not stliblink:return
548                 v['ARFLAGS']=['/NOLOGO']
549         if v.MSVC_MANIFEST:
550                 conf.find_program('MT',path_list=path,var='MT')
551                 v['MTFLAGS']=['/NOLOGO']
552         try:
553                 conf.load('winres')
554         except Errors.WafError:
555                 warn('Resource compiler not found. Compiling resource file is disabled')
556 @conf
557 def visual_studio_add_flags(self):
558         v=self.env
559         try:v.prepend_value('INCLUDES',[x for x in self.environ['INCLUDE'].split(';')if x])
560         except Exception:pass
561         try:v.prepend_value('LIBPATH',[x for x in self.environ['LIB'].split(';')if x])
562         except Exception:pass
563 @conf
564 def msvc_common_flags(conf):
565         v=conf.env
566         v['DEST_BINFMT']='pe'
567         v.append_value('CFLAGS',['/nologo'])
568         v.append_value('CXXFLAGS',['/nologo'])
569         v['DEFINES_ST']='/D%s'
570         v['CC_SRC_F']=''
571         v['CC_TGT_F']=['/c','/Fo']
572         v['CXX_SRC_F']=''
573         v['CXX_TGT_F']=['/c','/Fo']
574         if(v.MSVC_COMPILER=='msvc'and v.MSVC_VERSION>=8)or(v.MSVC_COMPILER=='wsdk'and v.MSVC_VERSION>=6):
575                 v['CC_TGT_F']=['/FC']+v['CC_TGT_F']
576                 v['CXX_TGT_F']=['/FC']+v['CXX_TGT_F']
577         v['CPPPATH_ST']='/I%s'
578         v['AR_TGT_F']=v['CCLNK_TGT_F']=v['CXXLNK_TGT_F']='/OUT:'
579         v['CFLAGS_CONSOLE']=v['CXXFLAGS_CONSOLE']=['/SUBSYSTEM:CONSOLE']
580         v['CFLAGS_NATIVE']=v['CXXFLAGS_NATIVE']=['/SUBSYSTEM:NATIVE']
581         v['CFLAGS_POSIX']=v['CXXFLAGS_POSIX']=['/SUBSYSTEM:POSIX']
582         v['CFLAGS_WINDOWS']=v['CXXFLAGS_WINDOWS']=['/SUBSYSTEM:WINDOWS']
583         v['CFLAGS_WINDOWSCE']=v['CXXFLAGS_WINDOWSCE']=['/SUBSYSTEM:WINDOWSCE']
584         v['CFLAGS_CRT_MULTITHREADED']=v['CXXFLAGS_CRT_MULTITHREADED']=['/MT']
585         v['CFLAGS_CRT_MULTITHREADED_DLL']=v['CXXFLAGS_CRT_MULTITHREADED_DLL']=['/MD']
586         v['CFLAGS_CRT_MULTITHREADED_DBG']=v['CXXFLAGS_CRT_MULTITHREADED_DBG']=['/MTd']
587         v['CFLAGS_CRT_MULTITHREADED_DLL_DBG']=v['CXXFLAGS_CRT_MULTITHREADED_DLL_DBG']=['/MDd']
588         v['LIB_ST']='%s.lib'
589         v['LIBPATH_ST']='/LIBPATH:%s'
590         v['STLIB_ST']='%s.lib'
591         v['STLIBPATH_ST']='/LIBPATH:%s'
592         v.append_value('LINKFLAGS',['/NOLOGO'])
593         if v['MSVC_MANIFEST']:
594                 v.append_value('LINKFLAGS',['/MANIFEST'])
595         v['CFLAGS_cshlib']=[]
596         v['CXXFLAGS_cxxshlib']=[]
597         v['LINKFLAGS_cshlib']=v['LINKFLAGS_cxxshlib']=['/DLL']
598         v['cshlib_PATTERN']=v['cxxshlib_PATTERN']='%s.dll'
599         v['implib_PATTERN']='%s.lib'
600         v['IMPLIB_ST']='/IMPLIB:%s'
601         v['LINKFLAGS_cstlib']=[]
602         v['cstlib_PATTERN']=v['cxxstlib_PATTERN']='%s.lib'
603         v['cprogram_PATTERN']=v['cxxprogram_PATTERN']='%s.exe'
604 @after_method('apply_link')
605 @feature('c','cxx')
606 def apply_flags_msvc(self):
607         if self.env.CC_NAME!='msvc'or not getattr(self,'link_task',None):
608                 return
609         is_static=isinstance(self.link_task,ccroot.stlink_task)
610         subsystem=getattr(self,'subsystem','')
611         if subsystem:
612                 subsystem='/subsystem:%s'%subsystem
613                 flags=is_static and'ARFLAGS'or'LINKFLAGS'
614                 self.env.append_value(flags,subsystem)
615         if not is_static:
616                 for f in self.env.LINKFLAGS:
617                         d=f.lower()
618                         if d[1:]=='debug':
619                                 pdbnode=self.link_task.outputs[0].change_ext('.pdb')
620                                 self.link_task.outputs.append(pdbnode)
621                                 try:
622                                         self.install_task.source.append(pdbnode)
623                                 except AttributeError:
624                                         pass
625                                 break
626 @feature('cprogram','cshlib','cxxprogram','cxxshlib')
627 @after_method('apply_link')
628 def apply_manifest(self):
629         if self.env.CC_NAME=='msvc'and self.env.MSVC_MANIFEST and getattr(self,'link_task',None):
630                 out_node=self.link_task.outputs[0]
631                 man_node=out_node.parent.find_or_declare(out_node.name+'.manifest')
632                 self.link_task.outputs.append(man_node)
633                 self.link_task.do_manifest=True
634 def exec_mf(self):
635         env=self.env
636         mtool=env['MT']
637         if not mtool:
638                 return 0
639         self.do_manifest=False
640         outfile=self.outputs[0].abspath()
641         manifest=None
642         for out_node in self.outputs:
643                 if out_node.name.endswith('.manifest'):
644                         manifest=out_node.abspath()
645                         break
646         if manifest is None:
647                 return 0
648         mode=''
649         if'cprogram'in self.generator.features or'cxxprogram'in self.generator.features:
650                 mode='1'
651         elif'cshlib'in self.generator.features or'cxxshlib'in self.generator.features:
652                 mode='2'
653         debug('msvc: embedding manifest in mode %r'%mode)
654         lst=[]
655         lst.append(env['MT'])
656         lst.extend(Utils.to_list(env['MTFLAGS']))
657         lst.extend(['-manifest',manifest])
658         lst.append('-outputresource:%s;%s'%(outfile,mode))
659         lst=[lst]
660         return self.exec_command(*lst)
661 def quote_response_command(self,flag):
662         if flag.find(' ')>-1:
663                 for x in('/LIBPATH:','/IMPLIB:','/OUT:','/I'):
664                         if flag.startswith(x):
665                                 flag='%s"%s"'%(x,flag[len(x):])
666                                 break
667                 else:
668                         flag='"%s"'%flag
669         return flag
670 def exec_response_command(self,cmd,**kw):
671         try:
672                 tmp=None
673                 if sys.platform.startswith('win')and isinstance(cmd,list)and len(' '.join(cmd))>=8192:
674                         program=cmd[0]
675                         cmd=[self.quote_response_command(x)for x in cmd]
676                         (fd,tmp)=tempfile.mkstemp()
677                         os.write(fd,'\r\n'.join(i.replace('\\','\\\\')for i in cmd[1:]))
678                         os.close(fd)
679                         cmd=[program,'@'+tmp]
680                 ret=self.generator.bld.exec_command(cmd,**kw)
681         finally:
682                 if tmp:
683                         try:
684                                 os.remove(tmp)
685                         except OSError:
686                                 pass
687         return ret
688 def exec_command_msvc(self,*k,**kw):
689         if isinstance(k[0],list):
690                 lst=[]
691                 carry=''
692                 for a in k[0]:
693                         if a=='/Fo'or a=='/doc'or a[-1]==':':
694                                 carry=a
695                         else:
696                                 lst.append(carry+a)
697                                 carry=''
698                 k=[lst]
699         if self.env['PATH']:
700                 env=dict(self.env.env or os.environ)
701                 env.update(PATH=';'.join(self.env['PATH']))
702                 kw['env']=env
703         bld=self.generator.bld
704         try:
705                 if not kw.get('cwd',None):
706                         kw['cwd']=bld.cwd
707         except AttributeError:
708                 bld.cwd=kw['cwd']=bld.variant_dir
709         ret=self.exec_response_command(k[0],**kw)
710         if not ret and getattr(self,'do_manifest',None):
711                 ret=self.exec_mf()
712         return ret
713 def wrap_class(class_name):
714         cls=Task.classes.get(class_name,None)
715         if not cls:
716                 return None
717         derived_class=type(class_name,(cls,),{})
718         def exec_command(self,*k,**kw):
719                 if self.env['CC_NAME']=='msvc':
720                         return self.exec_command_msvc(*k,**kw)
721                 else:
722                         return super(derived_class,self).exec_command(*k,**kw)
723         derived_class.exec_command=exec_command
724         derived_class.exec_response_command=exec_response_command
725         derived_class.quote_response_command=quote_response_command
726         derived_class.exec_command_msvc=exec_command_msvc
727         derived_class.exec_mf=exec_mf
728         return derived_class
729 for k in'c cxx cprogram cxxprogram cshlib cxxshlib cstlib cxxstlib'.split():
730         wrap_class(k)
731 def make_winapp(self,family):
732         append=self.env.append_unique
733         append('DEFINES','WINAPI_FAMILY=%s'%family)
734         append('CXXFLAGS','/ZW')
735         append('CXXFLAGS','/TP')
736         for lib_path in self.env.LIBPATH:
737                 append('CXXFLAGS','/AI%s'%lib_path)
738 @feature('winphoneapp')
739 @after_method('process_use')
740 @after_method('propagate_uselib_vars')
741 def make_winphone_app(self):
742         make_winapp(self,'WINAPI_FAMILY_PHONE_APP')
743         conf.env.append_unique('LINKFLAGS','/NODEFAULTLIB:ole32.lib')
744         conf.env.append_unique('LINKFLAGS','PhoneAppModelHost.lib')
745 @feature('winapp')
746 @after_method('process_use')
747 @after_method('propagate_uselib_vars')
748 def make_windows_app(self):
749         make_winapp(self,'WINAPI_FAMILY_DESKTOP_APP')