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