blob: 9ac0a59fb60da01eccb0785ad2ba7673a752d136 [file] [log] [blame]
akmhoquefa8ee9b2014-03-14 09:06:24 -05001#! /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
5import os,sys,re,tempfile
6from waflib import Utils,Task,Logs,Options,Errors
7from waflib.Logs import debug,warn
8from waflib.TaskGen import after_method,feature
9from waflib.Configure import conf
10from waflib.Tools import ccroot,c,cxx,ar,winres
11g_msvc_systemlibs='''
12aclui activeds ad1 adptif adsiid advapi32 asycfilt authz bhsupp bits bufferoverflowu cabinet
13cap certadm certidl ciuuid clusapi comctl32 comdlg32 comsupp comsuppd comsuppw comsuppwd comsvcs
14credui crypt32 cryptnet cryptui d3d8thk daouuid dbgeng dbghelp dciman32 ddao35 ddao35d
15ddao35u ddao35ud delayimp dhcpcsvc dhcpsapi dlcapi dnsapi dsprop dsuiext dtchelp
16faultrep fcachdll fci fdi framedyd framedyn gdi32 gdiplus glauxglu32 gpedit gpmuuid
17gtrts32w gtrtst32hlink htmlhelp httpapi icm32 icmui imagehlp imm32 iphlpapi iprop
18kernel32 ksguid ksproxy ksuser libcmt libcmtd libcpmt libcpmtd loadperf lz32 mapi
19mapi32 mgmtapi minidump mmc mobsync mpr mprapi mqoa mqrt msacm32 mscms mscoree
20msdasc msimg32 msrating mstask msvcmrt msvcurt msvcurtd mswsock msxml2 mtx mtxdm
21netapi32 nmapinmsupp npptools ntdsapi ntdsbcli ntmsapi ntquery odbc32 odbcbcp
22odbccp32 oldnames ole32 oleacc oleaut32 oledb oledlgolepro32 opends60 opengl32
23osptk parser pdh penter pgobootrun pgort powrprof psapi ptrustm ptrustmd ptrustu
24ptrustud qosname rasapi32 rasdlg rassapi resutils riched20 rpcndr rpcns4 rpcrt4 rtm
25rtutils runtmchk scarddlg scrnsave scrnsavw secur32 sensapi setupapi sfc shell32
26shfolder shlwapi sisbkup snmpapi sporder srclient sti strsafe svcguid tapi32 thunk32
27traffic unicows url urlmon user32 userenv usp10 uuid uxtheme vcomp vcompd vdmdbg
28version vfw32 wbemuuid webpost wiaguid wininet winmm winscard winspool winstrm
29wintrust wldap32 wmiutils wow32 ws2_32 wsnmp32 wsock32 wst wtsapi32 xaswitch xolehlp
30'''.split()
31all_msvc_platforms=[('x64','amd64'),('x86','x86'),('ia64','ia64'),('x86_amd64','amd64'),('x86_ia64','ia64'),('x86_arm','arm')]
32all_wince_platforms=[('armv4','arm'),('armv4i','arm'),('mipsii','mips'),('mipsii_fp','mips'),('mipsiv','mips'),('mipsiv_fp','mips'),('sh4','sh'),('x86','cex86')]
33all_icl_platforms=[('intel64','amd64'),('em64t','amd64'),('ia32','x86'),('Itanium','ia64')]
34def 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='')
37def 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
60def 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
64set INCLUDE=
65set LIB=
66call "%s" %s
67echo PATH=%%PATH%%
68echo INCLUDE=%%INCLUDE%%
69echo 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
106def 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))
137def 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
175def 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
206def 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
227def 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
246def 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
256def 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
281def 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
330def 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 vscomntools in['VS110COMNTOOLS','VS100COMNTOOLS']:
376 if os.environ.has_key(vscomntools):
377 vs_express_path=os.environ[vscomntools]+r'..\IDE\VSWinExpress.exe'
378 dev_env_path=os.environ[vscomntools]+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
386def 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
396def 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
402def detect_msvc(conf,arch=False):
403 versions=get_msvc_versions(conf)
404 return setup_msvc(conf,versions,arch)
405@conf
406def 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
434def 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
463def 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
472def check_libs_msvc(self,libnames,is_static=False):
473 for libname in Utils.to_list(libnames):
474 self.check_lib_msvc(libname,is_static)
475def 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
486def no_autodetect(conf):
487 conf.env.NO_MSVC_DETECT=1
488 configure(conf)
489@conf
490def 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])
507def _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
518def 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
557def 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
564def 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 if v['MSVC_VERSION']>=8:
573 v['CC_TGT_F']=['/FC']+v['CC_TGT_F']
574 v['CXX_SRC_F']=''
575 v['CXX_TGT_F']=['/c','/Fo']
576 if v['MSVC_VERSION']>=8:
577 v['CXX_TGT_F']=['/FC']+v['CXX_TGT_F']
578 v['CPPPATH_ST']='/I%s'
579 v['AR_TGT_F']=v['CCLNK_TGT_F']=v['CXXLNK_TGT_F']='/OUT:'
580 v['CFLAGS_CONSOLE']=v['CXXFLAGS_CONSOLE']=['/SUBSYSTEM:CONSOLE']
581 v['CFLAGS_NATIVE']=v['CXXFLAGS_NATIVE']=['/SUBSYSTEM:NATIVE']
582 v['CFLAGS_POSIX']=v['CXXFLAGS_POSIX']=['/SUBSYSTEM:POSIX']
583 v['CFLAGS_WINDOWS']=v['CXXFLAGS_WINDOWS']=['/SUBSYSTEM:WINDOWS']
584 v['CFLAGS_WINDOWSCE']=v['CXXFLAGS_WINDOWSCE']=['/SUBSYSTEM:WINDOWSCE']
585 v['CFLAGS_CRT_MULTITHREADED']=v['CXXFLAGS_CRT_MULTITHREADED']=['/MT']
586 v['CFLAGS_CRT_MULTITHREADED_DLL']=v['CXXFLAGS_CRT_MULTITHREADED_DLL']=['/MD']
587 v['CFLAGS_CRT_MULTITHREADED_DBG']=v['CXXFLAGS_CRT_MULTITHREADED_DBG']=['/MTd']
588 v['CFLAGS_CRT_MULTITHREADED_DLL_DBG']=v['CXXFLAGS_CRT_MULTITHREADED_DLL_DBG']=['/MDd']
589 v['LIB_ST']='%s.lib'
590 v['LIBPATH_ST']='/LIBPATH:%s'
591 v['STLIB_ST']='%s.lib'
592 v['STLIBPATH_ST']='/LIBPATH:%s'
593 v.append_value('LINKFLAGS',['/NOLOGO'])
594 if v['MSVC_MANIFEST']:
595 v.append_value('LINKFLAGS',['/MANIFEST'])
596 v['CFLAGS_cshlib']=[]
597 v['CXXFLAGS_cxxshlib']=[]
598 v['LINKFLAGS_cshlib']=v['LINKFLAGS_cxxshlib']=['/DLL']
599 v['cshlib_PATTERN']=v['cxxshlib_PATTERN']='%s.dll'
600 v['implib_PATTERN']='%s.lib'
601 v['IMPLIB_ST']='/IMPLIB:%s'
602 v['LINKFLAGS_cstlib']=[]
603 v['cstlib_PATTERN']=v['cxxstlib_PATTERN']='%s.lib'
604 v['cprogram_PATTERN']=v['cxxprogram_PATTERN']='%s.exe'
605@after_method('apply_link')
606@feature('c','cxx')
607def apply_flags_msvc(self):
608 if self.env.CC_NAME!='msvc'or not getattr(self,'link_task',None):
609 return
610 is_static=isinstance(self.link_task,ccroot.stlink_task)
611 subsystem=getattr(self,'subsystem','')
612 if subsystem:
613 subsystem='/subsystem:%s'%subsystem
614 flags=is_static and'ARFLAGS'or'LINKFLAGS'
615 self.env.append_value(flags,subsystem)
616 if not is_static:
617 for f in self.env.LINKFLAGS:
618 d=f.lower()
619 if d[1:]=='debug':
620 pdbnode=self.link_task.outputs[0].change_ext('.pdb')
621 self.link_task.outputs.append(pdbnode)
622 try:
623 self.install_task.source.append(pdbnode)
624 except AttributeError:
625 pass
626 break
627@feature('cprogram','cshlib','cxxprogram','cxxshlib')
628@after_method('apply_link')
629def apply_manifest(self):
630 if self.env.CC_NAME=='msvc'and self.env.MSVC_MANIFEST and getattr(self,'link_task',None):
631 out_node=self.link_task.outputs[0]
632 man_node=out_node.parent.find_or_declare(out_node.name+'.manifest')
633 self.link_task.outputs.append(man_node)
634 self.link_task.do_manifest=True
635def exec_mf(self):
636 env=self.env
637 mtool=env['MT']
638 if not mtool:
639 return 0
640 self.do_manifest=False
641 outfile=self.outputs[0].abspath()
642 manifest=None
643 for out_node in self.outputs:
644 if out_node.name.endswith('.manifest'):
645 manifest=out_node.abspath()
646 break
647 if manifest is None:
648 return 0
649 mode=''
650 if'cprogram'in self.generator.features or'cxxprogram'in self.generator.features:
651 mode='1'
652 elif'cshlib'in self.generator.features or'cxxshlib'in self.generator.features:
653 mode='2'
654 debug('msvc: embedding manifest in mode %r'%mode)
655 lst=[]
656 lst.append(env['MT'])
657 lst.extend(Utils.to_list(env['MTFLAGS']))
658 lst.extend(['-manifest',manifest])
659 lst.append('-outputresource:%s;%s'%(outfile,mode))
660 lst=[lst]
661 return self.exec_command(*lst)
662def quote_response_command(self,flag):
663 if flag.find(' ')>-1:
664 for x in('/LIBPATH:','/IMPLIB:','/OUT:','/I'):
665 if flag.startswith(x):
666 flag='%s"%s"'%(x,flag[len(x):])
667 break
668 else:
669 flag='"%s"'%flag
670 return flag
671def exec_response_command(self,cmd,**kw):
672 try:
673 tmp=None
674 if sys.platform.startswith('win')and isinstance(cmd,list)and len(' '.join(cmd))>=8192:
675 program=cmd[0]
676 cmd=[self.quote_response_command(x)for x in cmd]
677 (fd,tmp)=tempfile.mkstemp()
678 os.write(fd,'\r\n'.join(i.replace('\\','\\\\')for i in cmd[1:]))
679 os.close(fd)
680 cmd=[program,'@'+tmp]
681 ret=self.generator.bld.exec_command(cmd,**kw)
682 finally:
683 if tmp:
684 try:
685 os.remove(tmp)
686 except OSError:
687 pass
688 return ret
689def exec_command_msvc(self,*k,**kw):
690 if isinstance(k[0],list):
691 lst=[]
692 carry=''
693 for a in k[0]:
694 if a=='/Fo'or a=='/doc'or a[-1]==':':
695 carry=a
696 else:
697 lst.append(carry+a)
698 carry=''
699 k=[lst]
700 if self.env['PATH']:
701 env=dict(self.env.env or os.environ)
702 env.update(PATH=';'.join(self.env['PATH']))
703 kw['env']=env
704 bld=self.generator.bld
705 try:
706 if not kw.get('cwd',None):
707 kw['cwd']=bld.cwd
708 except AttributeError:
709 bld.cwd=kw['cwd']=bld.variant_dir
710 ret=self.exec_response_command(k[0],**kw)
711 if not ret and getattr(self,'do_manifest',None):
712 ret=self.exec_mf()
713 return ret
714def wrap_class(class_name):
715 cls=Task.classes.get(class_name,None)
716 if not cls:
717 return None
718 derived_class=type(class_name,(cls,),{})
719 def exec_command(self,*k,**kw):
720 if self.env['CC_NAME']=='msvc':
721 return self.exec_command_msvc(*k,**kw)
722 else:
723 return super(derived_class,self).exec_command(*k,**kw)
724 derived_class.exec_command=exec_command
725 derived_class.exec_response_command=exec_response_command
726 derived_class.quote_response_command=quote_response_command
727 derived_class.exec_command_msvc=exec_command_msvc
728 derived_class.exec_mf=exec_mf
729 return derived_class
730for k in'c cxx cprogram cxxprogram cshlib cxxshlib cstlib cxxstlib'.split():
731 wrap_class(k)
732def make_winapp(self,family):
733 append=self.env.append_unique
734 append('DEFINES','WINAPI_FAMILY=%s'%family)
735 append('CXXFLAGS','/ZW')
736 append('CXXFLAGS','/TP')
737 for lib_path in self.env.LIBPATH:
738 append('CXXFLAGS','/AI%s'%lib_path)
739@feature('winphoneapp')
740@after_method('process_use')
741@after_method('propagate_uselib_vars')
742def make_winphone_app(self):
743 make_winapp(self,'WINAPI_FAMILY_PHONE_APP')
744 conf.env.append_unique('LINKFLAGS','/NODEFAULTLIB:ole32.lib')
745 conf.env.append_unique('LINKFLAGS','PhoneAppModelHost.lib')
746@feature('winapp')
747@after_method('process_use')
748@after_method('propagate_uselib_vars')
749def make_windows_app(self):
750 make_winapp(self,'WINAPI_FAMILY_DESKTOP_APP')