source: waflib/Tools/msvc.py @ 0fa325b

feature/autosinkfeature/cnnfeature/cnn_orgfeature/constantqfeature/crepefeature/crepe_orgfeature/pitchshiftfeature/pydocstringsfeature/timestretchfix/ffmpeg5pitchshiftsamplertimestretchyinfft+
Last change on this file since 0fa325b was 0fa325b, checked in by Paul Brossier <piem@piem.org>, 11 years ago

waf: unpack

  • Property mode set to 100644
File size: 26.5 KB
Line 
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
5import os,sys,re,tempfile
6from waflib import Utils,Task,Logs,Options
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')]
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%%
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        if version=='11.0':
76                if lines[0].startswith('Error'):
77                        conf.fatal('msvc: Could not find a valid architecture for building (get_msvc_version_1)')
78        else:
79                for x in('Setting environment','Setting SDK environment','Intel(R) C++ Compiler','Intel Parallel Studio','Intel(R) Parallel Studio','Intel(R) Composer','Intel Corporation. All rights reserved.'):
80                        if lines[0].find(x)>-1:
81                                lines.pop(0)
82                                break
83                else:
84                        debug('msvc: get_msvc_version: %r %r %r -> not found',compiler,version,target)
85                        conf.fatal('msvc: Could not find a valid architecture for building (get_msvc_version_2)')
86        MSVC_PATH=MSVC_INCDIR=MSVC_LIBDIR=None
87        for line in lines:
88                if line.startswith('PATH='):
89                        path=line[5:]
90                        MSVC_PATH=path.split(';')
91                elif line.startswith('INCLUDE='):
92                        MSVC_INCDIR=[i for i in line[8:].split(';')if i]
93                elif line.startswith('LIB='):
94                        MSVC_LIBDIR=[i for i in line[4:].split(';')if i]
95        if None in(MSVC_PATH,MSVC_INCDIR,MSVC_LIBDIR):
96                conf.fatal('msvc: Could not find a valid architecture for building (get_msvc_version_3)')
97        env=dict(os.environ)
98        env.update(PATH=path)
99        compiler_name,linker_name,lib_name=_get_prog_names(conf,compiler)
100        cxx=conf.find_program(compiler_name,path_list=MSVC_PATH)
101        cxx=conf.cmd_to_list(cxx)
102        if'CL'in env:
103                del(env['CL'])
104        try:
105                try:
106                        conf.cmd_and_log(cxx+['/help'],env=env)
107                except Exception ,e:
108                        debug('msvc: get_msvc_version: %r %r %r -> failure'%(compiler,version,target))
109                        debug(str(e))
110                        conf.fatal('msvc: cannot run the compiler (in get_msvc_version)')
111                else:
112                        debug('msvc: get_msvc_version: %r %r %r -> OK',compiler,version,target)
113        finally:
114                conf.env[compiler_name]=''
115        return(MSVC_PATH,MSVC_INCDIR,MSVC_LIBDIR)
116@conf
117def gather_wsdk_versions(conf,versions):
118        version_pattern=re.compile('^v..?.?\...?.?')
119        try:
120                all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Wow6432node\\Microsoft\\Microsoft SDKs\\Windows')
121        except WindowsError:
122                try:
123                        all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows')
124                except WindowsError:
125                        return
126        index=0
127        while 1:
128                try:
129                        version=Utils.winreg.EnumKey(all_versions,index)
130                except WindowsError:
131                        break
132                index=index+1
133                if not version_pattern.match(version):
134                        continue
135                try:
136                        msvc_version=Utils.winreg.OpenKey(all_versions,version)
137                        path,type=Utils.winreg.QueryValueEx(msvc_version,'InstallationFolder')
138                except WindowsError:
139                        continue
140                if os.path.isfile(os.path.join(path,'bin','SetEnv.cmd')):
141                        targets=[]
142                        for target,arch in all_msvc_platforms:
143                                try:
144                                        targets.append((target,(arch,conf.get_msvc_version('wsdk',version,'/'+target,os.path.join(path,'bin','SetEnv.cmd')))))
145                                except conf.errors.ConfigurationError:
146                                        pass
147                        versions.append(('wsdk '+version[1:],targets))
148def gather_wince_supported_platforms():
149        supported_wince_platforms=[]
150        try:
151                ce_sdk=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Wow6432node\\Microsoft\\Windows CE Tools\\SDKs')
152        except WindowsError:
153                try:
154                        ce_sdk=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Microsoft\\Windows CE Tools\\SDKs')
155                except WindowsError:
156                        ce_sdk=''
157        if not ce_sdk:
158                return supported_wince_platforms
159        ce_index=0
160        while 1:
161                try:
162                        sdk_device=Utils.winreg.EnumKey(ce_sdk,ce_index)
163                except WindowsError:
164                        break
165                ce_index=ce_index+1
166                sdk=Utils.winreg.OpenKey(ce_sdk,sdk_device)
167                try:
168                        path,type=Utils.winreg.QueryValueEx(sdk,'SDKRootDir')
169                except WindowsError:
170                        try:
171                                path,type=Utils.winreg.QueryValueEx(sdk,'SDKInformation')
172                                path,xml=os.path.split(path)
173                        except WindowsError:
174                                continue
175                path=str(path)
176                path,device=os.path.split(path)
177                if not device:
178                        path,device=os.path.split(path)
179                for arch,compiler in all_wince_platforms:
180                        platforms=[]
181                        if os.path.isdir(os.path.join(path,device,'Lib',arch)):
182                                platforms.append((arch,compiler,os.path.join(path,device,'Include',arch),os.path.join(path,device,'Lib',arch)))
183                        if platforms:
184                                supported_wince_platforms.append((device,platforms))
185        return supported_wince_platforms
186def gather_msvc_detected_versions():
187        version_pattern=re.compile('^(\d\d?\.\d\d?)(Exp)?$')
188        detected_versions=[]
189        for vcver,vcvar in[('VCExpress','Exp'),('VisualStudio','')]:
190                try:
191                        prefix='SOFTWARE\\Wow6432node\\Microsoft\\'+vcver
192                        all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,prefix)
193                except WindowsError:
194                        try:
195                                prefix='SOFTWARE\\Microsoft\\'+vcver
196                                all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,prefix)
197                        except WindowsError:
198                                continue
199                index=0
200                while 1:
201                        try:
202                                version=Utils.winreg.EnumKey(all_versions,index)
203                        except WindowsError:
204                                break
205                        index=index+1
206                        match=version_pattern.match(version)
207                        if not match:
208                                continue
209                        else:
210                                versionnumber=float(match.group(1))
211                        detected_versions.append((versionnumber,version+vcvar,prefix+"\\"+version))
212        def fun(tup):
213                return tup[0]
214        detected_versions.sort(key=fun)
215        return detected_versions
216@conf
217def gather_msvc_targets(conf,versions,version,vc_path):
218        targets=[]
219        if os.path.isfile(os.path.join(vc_path,'vcvarsall.bat')):
220                for target,realtarget in all_msvc_platforms[::-1]:
221                        try:
222                                targets.append((target,(realtarget,conf.get_msvc_version('msvc',version,target,os.path.join(vc_path,'vcvarsall.bat')))))
223                        except conf.errors.ConfigurationError:
224                                pass
225        elif os.path.isfile(os.path.join(vc_path,'Common7','Tools','vsvars32.bat')):
226                try:
227                        targets.append(('x86',('x86',conf.get_msvc_version('msvc',version,'x86',os.path.join(vc_path,'Common7','Tools','vsvars32.bat')))))
228                except conf.errors.ConfigurationError:
229                        pass
230        elif os.path.isfile(os.path.join(vc_path,'Bin','vcvars32.bat')):
231                try:
232                        targets.append(('x86',('x86',conf.get_msvc_version('msvc',version,'',os.path.join(vc_path,'Bin','vcvars32.bat')))))
233                except conf.errors.ConfigurationError:
234                        pass
235        versions.append(('msvc '+version,targets))
236@conf
237def gather_wince_targets(conf,versions,version,vc_path,vsvars,supported_platforms):
238        for device,platforms in supported_platforms:
239                cetargets=[]
240                for platform,compiler,include,lib in platforms:
241                        winCEpath=os.path.join(vc_path,'ce')
242                        if not os.path.isdir(winCEpath):
243                                continue
244                        try:
245                                common_bindirs,_1,_2=conf.get_msvc_version('msvc',version,'x86',vsvars)
246                        except conf.errors.ConfigurationError:
247                                continue
248                        if os.path.isdir(os.path.join(winCEpath,'lib',platform)):
249                                bindirs=[os.path.join(winCEpath,'bin',compiler),os.path.join(winCEpath,'bin','x86_'+compiler)]+common_bindirs
250                                incdirs=[os.path.join(winCEpath,'include'),os.path.join(winCEpath,'atlmfc','include'),include]
251                                libdirs=[os.path.join(winCEpath,'lib',platform),os.path.join(winCEpath,'atlmfc','lib',platform),lib]
252                                cetargets.append((platform,(platform,(bindirs,incdirs,libdirs))))
253                if cetargets:
254                        versions.append((device+' '+version,cetargets))
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        for version,vc_path in vc_paths:
275                vs_path=os.path.dirname(vc_path)
276                conf.gather_msvc_targets(versions,version,vc_path)
277@conf
278def gather_icl_versions(conf,versions):
279        version_pattern=re.compile('^...?.?\....?.?')
280        try:
281                all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Wow6432node\\Intel\\Compilers\\C++')
282        except WindowsError:
283                try:
284                        all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Intel\\Compilers\\C++')
285                except WindowsError:
286                        return
287        index=0
288        while 1:
289                try:
290                        version=Utils.winreg.EnumKey(all_versions,index)
291                except WindowsError:
292                        break
293                index=index+1
294                if not version_pattern.match(version):
295                        continue
296                targets=[]
297                for target,arch in all_icl_platforms:
298                        try:
299                                if target=='intel64':targetDir='EM64T_NATIVE'
300                                else:targetDir=target
301                                Utils.winreg.OpenKey(all_versions,version+'\\'+targetDir)
302                                icl_version=Utils.winreg.OpenKey(all_versions,version)
303                                path,type=Utils.winreg.QueryValueEx(icl_version,'ProductDir')
304                                batch_file=os.path.join(path,'bin','iclvars.bat')
305                                if os.path.isfile(batch_file):
306                                        try:
307                                                targets.append((target,(arch,conf.get_msvc_version('intel',version,target,batch_file))))
308                                        except conf.errors.ConfigurationError:
309                                                pass
310                        except WindowsError:
311                                pass
312                for target,arch in all_icl_platforms:
313                        try:
314                                icl_version=Utils.winreg.OpenKey(all_versions,version+'\\'+target)
315                                path,type=Utils.winreg.QueryValueEx(icl_version,'ProductDir')
316                                batch_file=os.path.join(path,'bin','iclvars.bat')
317                                if os.path.isfile(batch_file):
318                                        try:
319                                                targets.append((target,(arch,conf.get_msvc_version('intel',version,target,batch_file))))
320                                        except conf.errors.ConfigurationError:
321                                                pass
322                        except WindowsError:
323                                continue
324                major=version[0:2]
325                versions.append(('intel '+major,targets))
326@conf
327def gather_intel_composer_versions(conf,versions):
328        version_pattern=re.compile('^...?.?\...?.?.?')
329        try:
330                all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Wow6432node\\Intel\\Suites')
331        except WindowsError:
332                try:
333                        all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Intel\\Suites')
334                except WindowsError:
335                        return
336        index=0
337        while 1:
338                try:
339                        version=Utils.winreg.EnumKey(all_versions,index)
340                except WindowsError:
341                        break
342                index=index+1
343                if not version_pattern.match(version):
344                        continue
345                targets=[]
346                for target,arch in all_icl_platforms:
347                        try:
348                                if target=='intel64':targetDir='EM64T_NATIVE'
349                                else:targetDir=target
350                                try:
351                                        defaults=Utils.winreg.OpenKey(all_versions,version+'\\Defaults\\C++\\'+targetDir)
352                                except WindowsError:
353                                        if targetDir=='EM64T_NATIVE':
354                                                defaults=Utils.winreg.OpenKey(all_versions,version+'\\Defaults\\C++\\EM64T')
355                                        else:
356                                                raise WindowsError
357                                uid,type=Utils.winreg.QueryValueEx(defaults,'SubKey')
358                                Utils.winreg.OpenKey(all_versions,version+'\\'+uid+'\\C++\\'+targetDir)
359                                icl_version=Utils.winreg.OpenKey(all_versions,version+'\\'+uid+'\\C++')
360                                path,type=Utils.winreg.QueryValueEx(icl_version,'ProductDir')
361                                batch_file=os.path.join(path,'bin','iclvars.bat')
362                                if os.path.isfile(batch_file):
363                                        try:
364                                                targets.append((target,(arch,conf.get_msvc_version('intel',version,target,batch_file))))
365                                        except conf.errors.ConfigurationError ,e:
366                                                pass
367                                compilervars_warning_attr='_compilervars_warning_key'
368                                if version[0:2]=='13'and getattr(conf,compilervars_warning_attr,True):
369                                        setattr(conf,compilervars_warning_attr,False)
370                                        patch_url='http://software.intel.com/en-us/forums/topic/328487'
371                                        compilervars_arch=os.path.join(path,'bin','compilervars_arch.bat')
372                                        vs_express_path=os.environ['VS110COMNTOOLS']+r'..\IDE\VSWinExpress.exe'
373                                        dev_env_path=os.environ['VS110COMNTOOLS']+r'..\IDE\devenv.exe'
374                                        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)):
375                                                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))
376                        except WindowsError:
377                                pass
378                major=version[0:2]
379                versions.append(('intel '+major,targets))
380@conf
381def get_msvc_versions(conf):
382        if not conf.env['MSVC_INSTALLED_VERSIONS']:
383                lst=[]
384                conf.gather_icl_versions(lst)
385                conf.gather_intel_composer_versions(lst)
386                conf.gather_wsdk_versions(lst)
387                conf.gather_msvc_versions(lst)
388                conf.env['MSVC_INSTALLED_VERSIONS']=lst
389        return conf.env['MSVC_INSTALLED_VERSIONS']
390@conf
391def print_all_msvc_detected(conf):
392        for version,targets in conf.env['MSVC_INSTALLED_VERSIONS']:
393                Logs.info(version)
394                for target,l in targets:
395                        Logs.info("\t"+target)
396@conf
397def detect_msvc(conf,arch=False):
398        versions=get_msvc_versions(conf)
399        return setup_msvc(conf,versions,arch)
400@conf
401def find_lt_names_msvc(self,libname,is_static=False):
402        lt_names=['lib%s.la'%libname,'%s.la'%libname,]
403        for path in self.env['LIBPATH']:
404                for la in lt_names:
405                        laf=os.path.join(path,la)
406                        dll=None
407                        if os.path.exists(laf):
408                                ltdict=Utils.read_la_file(laf)
409                                lt_libdir=None
410                                if ltdict.get('libdir',''):
411                                        lt_libdir=ltdict['libdir']
412                                if not is_static and ltdict.get('library_names',''):
413                                        dllnames=ltdict['library_names'].split()
414                                        dll=dllnames[0].lower()
415                                        dll=re.sub('\.dll$','',dll)
416                                        return(lt_libdir,dll,False)
417                                elif ltdict.get('old_library',''):
418                                        olib=ltdict['old_library']
419                                        if os.path.exists(os.path.join(path,olib)):
420                                                return(path,olib,True)
421                                        elif lt_libdir!=''and os.path.exists(os.path.join(lt_libdir,olib)):
422                                                return(lt_libdir,olib,True)
423                                        else:
424                                                return(None,olib,True)
425                                else:
426                                        raise self.errors.WafError('invalid libtool object file: %s'%laf)
427        return(None,None,None)
428@conf
429def libname_msvc(self,libname,is_static=False):
430        lib=libname.lower()
431        lib=re.sub('\.lib$','',lib)
432        if lib in g_msvc_systemlibs:
433                return lib
434        lib=re.sub('^lib','',lib)
435        if lib=='m':
436                return None
437        (lt_path,lt_libname,lt_static)=self.find_lt_names_msvc(lib,is_static)
438        if lt_path!=None and lt_libname!=None:
439                if lt_static==True:
440                        return os.path.join(lt_path,lt_libname)
441        if lt_path!=None:
442                _libpaths=[lt_path]+self.env['LIBPATH']
443        else:
444                _libpaths=self.env['LIBPATH']
445        static_libs=['lib%ss.lib'%lib,'lib%s.lib'%lib,'%ss.lib'%lib,'%s.lib'%lib,]
446        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,]
447        libnames=static_libs
448        if not is_static:
449                libnames=dynamic_libs+static_libs
450        for path in _libpaths:
451                for libn in libnames:
452                        if os.path.exists(os.path.join(path,libn)):
453                                debug('msvc: lib found: %s'%os.path.join(path,libn))
454                                return re.sub('\.lib$','',libn)
455        self.fatal("The library %r could not be found"%libname)
456        return re.sub('\.lib$','',libname)
457@conf
458def check_lib_msvc(self,libname,is_static=False,uselib_store=None):
459        libn=self.libname_msvc(libname,is_static)
460        if not uselib_store:
461                uselib_store=libname.upper()
462        if False and is_static:
463                self.env['STLIB_'+uselib_store]=[libn]
464        else:
465                self.env['LIB_'+uselib_store]=[libn]
466@conf
467def check_libs_msvc(self,libnames,is_static=False):
468        for libname in Utils.to_list(libnames):
469                self.check_lib_msvc(libname,is_static)
470def configure(conf):
471        conf.autodetect(True)
472        conf.find_msvc()
473        conf.msvc_common_flags()
474        conf.cc_load_tools()
475        conf.cxx_load_tools()
476        conf.cc_add_flags()
477        conf.cxx_add_flags()
478        conf.link_add_flags()
479        conf.visual_studio_add_flags()
480@conf
481def no_autodetect(conf):
482        conf.env.NO_MSVC_DETECT=1
483        configure(conf)
484@conf
485def autodetect(conf,arch=False):
486        v=conf.env
487        if v.NO_MSVC_DETECT:
488                return
489        if arch:
490                compiler,version,path,includes,libdirs,arch=conf.detect_msvc(True)
491                v['DEST_CPU']=arch
492        else:
493                compiler,version,path,includes,libdirs=conf.detect_msvc()
494        v['PATH']=path
495        v['INCLUDES']=includes
496        v['LIBPATH']=libdirs
497        v['MSVC_COMPILER']=compiler
498        try:
499                v['MSVC_VERSION']=float(version)
500        except Exception:
501                v['MSVC_VERSION']=float(version[:-3])
502def _get_prog_names(conf,compiler):
503        if compiler=='intel':
504                compiler_name='ICL'
505                linker_name='XILINK'
506                lib_name='XILIB'
507        else:
508                compiler_name='CL'
509                linker_name='LINK'
510                lib_name='LIB'
511        return compiler_name,linker_name,lib_name
512@conf
513def find_msvc(conf):
514        if sys.platform=='cygwin':
515                conf.fatal('MSVC module does not work under cygwin Python!')
516        v=conf.env
517        path=v['PATH']
518        compiler=v['MSVC_COMPILER']
519        version=v['MSVC_VERSION']
520        compiler_name,linker_name,lib_name=_get_prog_names(conf,compiler)
521        v.MSVC_MANIFEST=(compiler=='msvc'and version>=8)or(compiler=='wsdk'and version>=6)or(compiler=='intel'and version>=11)
522        cxx=None
523        if v['CXX']:cxx=v['CXX']
524        elif'CXX'in conf.environ:cxx=conf.environ['CXX']
525        cxx=conf.find_program(compiler_name,var='CXX',path_list=path)
526        cxx=conf.cmd_to_list(cxx)
527        env=dict(conf.environ)
528        if path:env.update(PATH=';'.join(path))
529        if not conf.cmd_and_log(cxx+['/nologo','/help'],env=env):
530                conf.fatal('the msvc compiler could not be identified')
531        v['CC']=v['CXX']=cxx
532        v['CC_NAME']=v['CXX_NAME']='msvc'
533        if not v['LINK_CXX']:
534                link=conf.find_program(linker_name,path_list=path)
535                if link:v['LINK_CXX']=link
536                else:conf.fatal('%s was not found (linker)'%linker_name)
537                v['LINK']=link
538        if not v['LINK_CC']:
539                v['LINK_CC']=v['LINK_CXX']
540        if not v['AR']:
541                stliblink=conf.find_program(lib_name,path_list=path,var='AR')
542                if not stliblink:return
543                v['ARFLAGS']=['/NOLOGO']
544        if v.MSVC_MANIFEST:
545                conf.find_program('MT',path_list=path,var='MT')
546                v['MTFLAGS']=['/NOLOGO']
547        conf.load('winres')
548        if not conf.env['WINRC']:
549                warn('Resource compiler not found. Compiling resource file is disabled')
550@conf
551def visual_studio_add_flags(self):
552        v=self.env
553        try:v.prepend_value('INCLUDES',[x for x in self.environ['INCLUDE'].split(';')if x])
554        except Exception:pass
555        try:v.prepend_value('LIBPATH',[x for x in self.environ['LIB'].split(';')if x])
556        except Exception:pass
557@conf
558def msvc_common_flags(conf):
559        v=conf.env
560        v['DEST_BINFMT']='pe'
561        v.append_value('CFLAGS',['/nologo'])
562        v.append_value('CXXFLAGS',['/nologo'])
563        v['DEFINES_ST']='/D%s'
564        v['CC_SRC_F']=''
565        v['CC_TGT_F']=['/c','/Fo']
566        if v['MSVC_VERSION']>=8:
567                v['CC_TGT_F']=['/FC']+v['CC_TGT_F']
568        v['CXX_SRC_F']=''
569        v['CXX_TGT_F']=['/c','/Fo']
570        if v['MSVC_VERSION']>=8:
571                v['CXX_TGT_F']=['/FC']+v['CXX_TGT_F']
572        v['CPPPATH_ST']='/I%s'
573        v['AR_TGT_F']=v['CCLNK_TGT_F']=v['CXXLNK_TGT_F']='/OUT:'
574        v['CFLAGS_CONSOLE']=v['CXXFLAGS_CONSOLE']=['/SUBSYSTEM:CONSOLE']
575        v['CFLAGS_NATIVE']=v['CXXFLAGS_NATIVE']=['/SUBSYSTEM:NATIVE']
576        v['CFLAGS_POSIX']=v['CXXFLAGS_POSIX']=['/SUBSYSTEM:POSIX']
577        v['CFLAGS_WINDOWS']=v['CXXFLAGS_WINDOWS']=['/SUBSYSTEM:WINDOWS']
578        v['CFLAGS_WINDOWSCE']=v['CXXFLAGS_WINDOWSCE']=['/SUBSYSTEM:WINDOWSCE']
579        v['CFLAGS_CRT_MULTITHREADED']=v['CXXFLAGS_CRT_MULTITHREADED']=['/MT']
580        v['CFLAGS_CRT_MULTITHREADED_DLL']=v['CXXFLAGS_CRT_MULTITHREADED_DLL']=['/MD']
581        v['CFLAGS_CRT_MULTITHREADED_DBG']=v['CXXFLAGS_CRT_MULTITHREADED_DBG']=['/MTd']
582        v['CFLAGS_CRT_MULTITHREADED_DLL_DBG']=v['CXXFLAGS_CRT_MULTITHREADED_DLL_DBG']=['/MDd']
583        v['LIB_ST']='%s.lib'
584        v['LIBPATH_ST']='/LIBPATH:%s'
585        v['STLIB_ST']='%s.lib'
586        v['STLIBPATH_ST']='/LIBPATH:%s'
587        v.append_value('LINKFLAGS',['/NOLOGO'])
588        if v['MSVC_MANIFEST']:
589                v.append_value('LINKFLAGS',['/MANIFEST'])
590        v['CFLAGS_cshlib']=[]
591        v['CXXFLAGS_cxxshlib']=[]
592        v['LINKFLAGS_cshlib']=v['LINKFLAGS_cxxshlib']=['/DLL']
593        v['cshlib_PATTERN']=v['cxxshlib_PATTERN']='%s.dll'
594        v['implib_PATTERN']='%s.lib'
595        v['IMPLIB_ST']='/IMPLIB:%s'
596        v['LINKFLAGS_cstlib']=[]
597        v['cstlib_PATTERN']=v['cxxstlib_PATTERN']='%s.lib'
598        v['cprogram_PATTERN']=v['cxxprogram_PATTERN']='%s.exe'
599@after_method('apply_link')
600@feature('c','cxx')
601def apply_flags_msvc(self):
602        if self.env.CC_NAME!='msvc'or not getattr(self,'link_task',None):
603                return
604        is_static=isinstance(self.link_task,ccroot.stlink_task)
605        subsystem=getattr(self,'subsystem','')
606        if subsystem:
607                subsystem='/subsystem:%s'%subsystem
608                flags=is_static and'ARFLAGS'or'LINKFLAGS'
609                self.env.append_value(flags,subsystem)
610        if not is_static:
611                for f in self.env.LINKFLAGS:
612                        d=f.lower()
613                        if d[1:]=='debug':
614                                pdbnode=self.link_task.outputs[0].change_ext('.pdb')
615                                self.link_task.outputs.append(pdbnode)
616                                try:
617                                        self.install_task.source.append(pdbnode)
618                                except AttributeError:
619                                        pass
620                                break
621@feature('cprogram','cshlib','cxxprogram','cxxshlib')
622@after_method('apply_link')
623def apply_manifest(self):
624        if self.env.CC_NAME=='msvc'and self.env.MSVC_MANIFEST and getattr(self,'link_task',None):
625                out_node=self.link_task.outputs[0]
626                man_node=out_node.parent.find_or_declare(out_node.name+'.manifest')
627                self.link_task.outputs.append(man_node)
628                self.link_task.do_manifest=True
629def exec_mf(self):
630        env=self.env
631        mtool=env['MT']
632        if not mtool:
633                return 0
634        self.do_manifest=False
635        outfile=self.outputs[0].abspath()
636        manifest=None
637        for out_node in self.outputs:
638                if out_node.name.endswith('.manifest'):
639                        manifest=out_node.abspath()
640                        break
641        if manifest is None:
642                return 0
643        mode=''
644        if'cprogram'in self.generator.features or'cxxprogram'in self.generator.features:
645                mode='1'
646        elif'cshlib'in self.generator.features or'cxxshlib'in self.generator.features:
647                mode='2'
648        debug('msvc: embedding manifest in mode %r'%mode)
649        lst=[]
650        lst.append(env['MT'])
651        lst.extend(Utils.to_list(env['MTFLAGS']))
652        lst.extend(['-manifest',manifest])
653        lst.append('-outputresource:%s;%s'%(outfile,mode))
654        lst=[lst]
655        return self.exec_command(*lst)
656def quote_response_command(self,flag):
657        if flag.find(' ')>-1:
658                for x in('/LIBPATH:','/IMPLIB:','/OUT:','/I'):
659                        if flag.startswith(x):
660                                flag='%s"%s"'%(x,flag[len(x):])
661                                break
662                else:
663                        flag='"%s"'%flag
664        return flag
665def exec_response_command(self,cmd,**kw):
666        try:
667                tmp=None
668                if sys.platform.startswith('win')and isinstance(cmd,list)and len(' '.join(cmd))>=8192:
669                        program=cmd[0]
670                        cmd=[self.quote_response_command(x)for x in cmd]
671                        (fd,tmp)=tempfile.mkstemp()
672                        os.write(fd,'\r\n'.join(i.replace('\\','\\\\')for i in cmd[1:]))
673                        os.close(fd)
674                        cmd=[program,'@'+tmp]
675                ret=self.generator.bld.exec_command(cmd,**kw)
676        finally:
677                if tmp:
678                        try:
679                                os.remove(tmp)
680                        except OSError:
681                                pass
682        return ret
683def exec_command_msvc(self,*k,**kw):
684        assert self.env['CC_NAME']=='msvc'
685        if isinstance(k[0],list):
686                lst=[]
687                carry=''
688                for a in k[0]:
689                        if a=='/Fo'or a=='/doc'or a[-1]==':':
690                                carry=a
691                        else:
692                                lst.append(carry+a)
693                                carry=''
694                k=[lst]
695        if self.env['PATH']:
696                env=dict(self.env.env or os.environ)
697                env.update(PATH=';'.join(self.env['PATH']))
698                kw['env']=env
699        bld=self.generator.bld
700        try:
701                if not kw.get('cwd',None):
702                        kw['cwd']=bld.cwd
703        except AttributeError:
704                bld.cwd=kw['cwd']=bld.variant_dir
705        ret=self.exec_response_command(k[0],**kw)
706        if not ret and getattr(self,'do_manifest',None):
707                ret=self.exec_mf()
708        return ret
709def wrap_class(class_name):
710        cls=Task.classes.get(class_name,None)
711        if not cls:
712                return None
713        derived_class=type(class_name,(cls,),{})
714        def exec_command(self,*k,**kw):
715                if self.env['CC_NAME']=='msvc':
716                        return self.exec_command_msvc(*k,**kw)
717                else:
718                        return super(derived_class,self).exec_command(*k,**kw)
719        derived_class.exec_command=exec_command
720        derived_class.exec_response_command=exec_response_command
721        derived_class.quote_response_command=quote_response_command
722        derived_class.exec_command_msvc=exec_command_msvc
723        derived_class.exec_mf=exec_mf
724        return derived_class
725for k in'c cxx cprogram cxxprogram cshlib cxxshlib cstlib cxxstlib'.split():
726        wrap_class(k)
Note: See TracBrowser for help on using the repository browser.