akmhoque | fa8ee9b | 2014-03-14 09:06:24 -0500 | [diff] [blame^] | 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 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 |
| 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 | 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') |
| 607 | def 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') |
| 629 | def 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 |
| 635 | def 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) |
| 662 | def 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 |
| 671 | def 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 |
| 689 | def 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 |
| 714 | def 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 |
| 730 | for k in'c cxx cprogram cxxprogram cshlib cxxshlib cstlib cxxstlib'.split(): |
| 731 | wrap_class(k) |
| 732 | def 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') |
| 742 | def 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') |
| 749 | def make_windows_app(self): |
| 750 | make_winapp(self,'WINAPI_FAMILY_DESKTOP_APP') |