source: waflib/Tools/python.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: 12.9 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
6from waflib import Utils,Options,Errors,Logs
7from waflib.TaskGen import extension,before_method,after_method,feature
8from waflib.Configure import conf
9FRAG='''
10#include <Python.h>
11#ifdef __cplusplus
12extern "C" {
13#endif
14        void Py_Initialize(void);
15        void Py_Finalize(void);
16#ifdef __cplusplus
17}
18#endif
19int main(int argc, char **argv)
20{
21   (void)argc; (void)argv;
22   Py_Initialize();
23   Py_Finalize();
24   return 0;
25}
26'''
27INST='''
28import sys, py_compile
29py_compile.compile(sys.argv[1], sys.argv[2], sys.argv[3])
30'''
31DISTUTILS_IMP=['from distutils.sysconfig import get_config_var, get_python_lib']
32@extension('.py')
33def process_py(self,node):
34        try:
35                if not self.bld.is_install:
36                        return
37        except AttributeError:
38                return
39        try:
40                if not self.install_path:
41                        return
42        except AttributeError:
43                self.install_path='${PYTHONDIR}'
44        def inst_py(ctx):
45                install_from=getattr(self,'install_from',None)
46                if install_from:
47                        install_from=self.path.find_dir(install_from)
48                install_pyfile(self,node,install_from)
49        self.bld.add_post_fun(inst_py)
50def install_pyfile(self,node,install_from=None):
51        from_node=install_from or node.parent
52        tsk=self.bld.install_as(self.install_path+'/'+node.path_from(from_node),node,postpone=False)
53        path=tsk.get_install_path()
54        if self.bld.is_install<0:
55                Logs.info("+ removing byte compiled python files")
56                for x in'co':
57                        try:
58                                os.remove(path+x)
59                        except OSError:
60                                pass
61        if self.bld.is_install>0:
62                try:
63                        st1=os.stat(path)
64                except OSError:
65                        Logs.error('The python file is missing, this should not happen')
66                for x in['c','o']:
67                        do_inst=self.env['PY'+x.upper()]
68                        try:
69                                st2=os.stat(path+x)
70                        except OSError:
71                                pass
72                        else:
73                                if st1.st_mtime<=st2.st_mtime:
74                                        do_inst=False
75                        if do_inst:
76                                lst=(x=='o')and[self.env['PYFLAGS_OPT']]or[]
77                                (a,b,c)=(path,path+x,tsk.get_install_path(destdir=False)+x)
78                                argv=self.env['PYTHON']+lst+['-c',INST,a,b,c]
79                                Logs.info('+ byte compiling %r'%(path+x))
80                                env=self.env.env or None
81                                ret=Utils.subprocess.Popen(argv,env=env).wait()
82                                if ret:
83                                        raise Errors.WafError('py%s compilation failed %r'%(x,path))
84@feature('py')
85def feature_py(self):
86        pass
87@feature('pyext')
88@before_method('propagate_uselib_vars','apply_link')
89@after_method('apply_bundle')
90def init_pyext(self):
91        self.uselib=self.to_list(getattr(self,'uselib',[]))
92        if not'PYEXT'in self.uselib:
93                self.uselib.append('PYEXT')
94        self.env.cshlib_PATTERN=self.env.cxxshlib_PATTERN=self.env.macbundle_PATTERN=self.env.pyext_PATTERN
95        self.env.fcshlib_PATTERN=self.env.dshlib_PATTERN=self.env.pyext_PATTERN
96        try:
97                if not self.install_path:
98                        return
99        except AttributeError:
100                self.install_path='${PYTHONARCHDIR}'
101@feature('pyext')
102@before_method('apply_link','apply_bundle')
103def set_bundle(self):
104        if Utils.unversioned_sys_platform()=='darwin':
105                self.mac_bundle=True
106@before_method('propagate_uselib_vars')
107@feature('pyembed')
108def init_pyembed(self):
109        self.uselib=self.to_list(getattr(self,'uselib',[]))
110        if not'PYEMBED'in self.uselib:
111                self.uselib.append('PYEMBED')
112@conf
113def get_python_variables(self,variables,imports=None):
114        if not imports:
115                try:
116                        imports=self.python_imports
117                except AttributeError:
118                        imports=DISTUTILS_IMP
119        program=list(imports)
120        program.append('')
121        for v in variables:
122                program.append("print(repr(%s))"%v)
123        os_env=dict(os.environ)
124        try:
125                del os_env['MACOSX_DEPLOYMENT_TARGET']
126        except KeyError:
127                pass
128        try:
129                out=self.cmd_and_log(self.env.PYTHON+['-c','\n'.join(program)],env=os_env)
130        except Errors.WafError:
131                self.fatal('The distutils module is unusable: install "python-devel"?')
132        self.to_log(out)
133        return_values=[]
134        for s in out.split('\n'):
135                s=s.strip()
136                if not s:
137                        continue
138                if s=='None':
139                        return_values.append(None)
140                elif(s[0]=="'"and s[-1]=="'")or(s[0]=='"'and s[-1]=='"'):
141                        return_values.append(eval(s))
142                elif s[0].isdigit():
143                        return_values.append(int(s))
144                else:break
145        return return_values
146@conf
147def check_python_headers(conf):
148        env=conf.env
149        if not env['CC_NAME']and not env['CXX_NAME']:
150                conf.fatal('load a compiler first (gcc, g++, ..)')
151        if not env['PYTHON_VERSION']:
152                conf.check_python_version()
153        pybin=conf.env.PYTHON
154        if not pybin:
155                conf.fatal('Could not find the python executable')
156        v='prefix SO LDFLAGS LIBDIR LIBPL INCLUDEPY Py_ENABLE_SHARED MACOSX_DEPLOYMENT_TARGET LDSHARED CFLAGS'.split()
157        try:
158                lst=conf.get_python_variables(["get_config_var('%s') or ''"%x for x in v])
159        except RuntimeError:
160                conf.fatal("Python development headers not found (-v for details).")
161        vals=['%s = %r'%(x,y)for(x,y)in zip(v,lst)]
162        conf.to_log("Configuration returned from %r:\n%r\n"%(pybin,'\n'.join(vals)))
163        dct=dict(zip(v,lst))
164        x='MACOSX_DEPLOYMENT_TARGET'
165        if dct[x]:
166                conf.env[x]=conf.environ[x]=dct[x]
167        env['pyext_PATTERN']='%s'+dct['SO']
168        all_flags=dct['LDFLAGS']+' '+dct['CFLAGS']
169        conf.parse_flags(all_flags,'PYEMBED')
170        all_flags=dct['LDFLAGS']+' '+dct['LDSHARED']+' '+dct['CFLAGS']
171        conf.parse_flags(all_flags,'PYEXT')
172        result=None
173        for name in('python'+env['PYTHON_VERSION'],'python'+env['PYTHON_VERSION'].replace('.','')):
174                if not result and env['LIBPATH_PYEMBED']:
175                        path=env['LIBPATH_PYEMBED']
176                        conf.to_log("\n\n# Trying default LIBPATH_PYEMBED: %r\n"%path)
177                        result=conf.check(lib=name,uselib='PYEMBED',libpath=path,mandatory=False,msg='Checking for library %s in LIBPATH_PYEMBED'%name)
178                if not result and dct['LIBDIR']:
179                        path=[dct['LIBDIR']]
180                        conf.to_log("\n\n# try again with -L$python_LIBDIR: %r\n"%path)
181                        result=conf.check(lib=name,uselib='PYEMBED',libpath=path,mandatory=False,msg='Checking for library %s in LIBDIR'%name)
182                if not result and dct['LIBPL']:
183                        path=[dct['LIBPL']]
184                        conf.to_log("\n\n# try again with -L$python_LIBPL (some systems don't install the python library in $prefix/lib)\n")
185                        result=conf.check(lib=name,uselib='PYEMBED',libpath=path,mandatory=False,msg='Checking for library %s in python_LIBPL'%name)
186                if not result:
187                        path=[os.path.join(dct['prefix'],"libs")]
188                        conf.to_log("\n\n# try again with -L$prefix/libs, and pythonXY name rather than pythonX.Y (win32)\n")
189                        result=conf.check(lib=name,uselib='PYEMBED',libpath=path,mandatory=False,msg='Checking for library %s in $prefix/libs'%name)
190                if result:
191                        break
192        if result:
193                env['LIBPATH_PYEMBED']=path
194                env.append_value('LIB_PYEMBED',[name])
195        else:
196                conf.to_log("\n\n### LIB NOT FOUND\n")
197        if(Utils.is_win32 or sys.platform.startswith('os2')or dct['Py_ENABLE_SHARED']):
198                env['LIBPATH_PYEXT']=env['LIBPATH_PYEMBED']
199                env['LIB_PYEXT']=env['LIB_PYEMBED']
200        num='.'.join(env['PYTHON_VERSION'].split('.')[:2])
201        conf.find_program([''.join(pybin)+'-config','python%s-config'%num,'python-config-%s'%num,'python%sm-config'%num],var='PYTHON_CONFIG',mandatory=False)
202        includes=[]
203        if conf.env.PYTHON_CONFIG:
204                for incstr in conf.cmd_and_log([conf.env.PYTHON_CONFIG,'--includes']).strip().split():
205                        if(incstr.startswith('-I')or incstr.startswith('/I')):
206                                incstr=incstr[2:]
207                        if incstr not in includes:
208                                includes.append(incstr)
209                conf.to_log("Include path for Python extensions (found via python-config --includes): %r\n"%(includes,))
210                env['INCLUDES_PYEXT']=includes
211                env['INCLUDES_PYEMBED']=includes
212        else:
213                conf.to_log("Include path for Python extensions ""(found via distutils module): %r\n"%(dct['INCLUDEPY'],))
214                env['INCLUDES_PYEXT']=[dct['INCLUDEPY']]
215                env['INCLUDES_PYEMBED']=[dct['INCLUDEPY']]
216        if env['CC_NAME']=='gcc':
217                env.append_value('CFLAGS_PYEMBED',['-fno-strict-aliasing'])
218                env.append_value('CFLAGS_PYEXT',['-fno-strict-aliasing'])
219        if env['CXX_NAME']=='gcc':
220                env.append_value('CXXFLAGS_PYEMBED',['-fno-strict-aliasing'])
221                env.append_value('CXXFLAGS_PYEXT',['-fno-strict-aliasing'])
222        if env.CC_NAME=="msvc":
223                from distutils.msvccompiler import MSVCCompiler
224                dist_compiler=MSVCCompiler()
225                dist_compiler.initialize()
226                env.append_value('CFLAGS_PYEXT',dist_compiler.compile_options)
227                env.append_value('CXXFLAGS_PYEXT',dist_compiler.compile_options)
228                env.append_value('LINKFLAGS_PYEXT',dist_compiler.ldflags_shared)
229        try:
230                conf.check(header_name='Python.h',define_name='HAVE_PYTHON_H',uselib='PYEMBED',fragment=FRAG,errmsg=':-(')
231        except conf.errors.ConfigurationError:
232                xx=conf.env.CXX_NAME and'cxx'or'c'
233                conf.check_cfg(msg='Asking python-config for the flags (pyembed)',path=conf.env.PYTHON_CONFIG,package='',uselib_store='PYEMBED',args=['--cflags','--libs','--ldflags'])
234                conf.check(header_name='Python.h',define_name='HAVE_PYTHON_H',msg='Getting pyembed flags from python-config',fragment=FRAG,errmsg='Could not build a python embedded interpreter',features='%s %sprogram pyembed'%(xx,xx))
235                conf.check_cfg(msg='Asking python-config for the flags (pyext)',path=conf.env.PYTHON_CONFIG,package='',uselib_store='PYEXT',args=['--cflags','--libs','--ldflags'])
236                conf.check(header_name='Python.h',define_name='HAVE_PYTHON_H',msg='Getting pyext flags from python-config',features='%s %sshlib pyext'%(xx,xx),fragment=FRAG,errmsg='Could not build python extensions')
237@conf
238def check_python_version(conf,minver=None):
239        assert minver is None or isinstance(minver,tuple)
240        pybin=conf.env['PYTHON']
241        if not pybin:
242                conf.fatal('could not find the python executable')
243        cmd=pybin+['-c','import sys\nfor x in sys.version_info: print(str(x))']
244        Logs.debug('python: Running python command %r'%cmd)
245        lines=conf.cmd_and_log(cmd).split()
246        assert len(lines)==5,"found %i lines, expected 5: %r"%(len(lines),lines)
247        pyver_tuple=(int(lines[0]),int(lines[1]),int(lines[2]),lines[3],int(lines[4]))
248        result=(minver is None)or(pyver_tuple>=minver)
249        if result:
250                pyver='.'.join([str(x)for x in pyver_tuple[:2]])
251                conf.env['PYTHON_VERSION']=pyver
252                if'PYTHONDIR'in conf.environ:
253                        pydir=conf.environ['PYTHONDIR']
254                else:
255                        if Utils.is_win32:
256                                (python_LIBDEST,pydir)=conf.get_python_variables(["get_config_var('LIBDEST') or ''","get_python_lib(standard_lib=0, prefix=%r) or ''"%conf.env['PREFIX']])
257                        else:
258                                python_LIBDEST=None
259                                (pydir,)=conf.get_python_variables(["get_python_lib(standard_lib=0, prefix=%r) or ''"%conf.env['PREFIX']])
260                        if python_LIBDEST is None:
261                                if conf.env['LIBDIR']:
262                                        python_LIBDEST=os.path.join(conf.env['LIBDIR'],"python"+pyver)
263                                else:
264                                        python_LIBDEST=os.path.join(conf.env['PREFIX'],"lib","python"+pyver)
265                if'PYTHONARCHDIR'in conf.environ:
266                        pyarchdir=conf.environ['PYTHONARCHDIR']
267                else:
268                        (pyarchdir,)=conf.get_python_variables(["get_python_lib(plat_specific=1, standard_lib=0, prefix=%r) or ''"%conf.env['PREFIX']])
269                        if not pyarchdir:
270                                pyarchdir=pydir
271                if hasattr(conf,'define'):
272                        conf.define('PYTHONDIR',pydir)
273                        conf.define('PYTHONARCHDIR',pyarchdir)
274                conf.env['PYTHONDIR']=pydir
275                conf.env['PYTHONARCHDIR']=pyarchdir
276        pyver_full='.'.join(map(str,pyver_tuple[:3]))
277        if minver is None:
278                conf.msg('Checking for python version',pyver_full)
279        else:
280                minver_str='.'.join(map(str,minver))
281                conf.msg('Checking for python version',pyver_tuple,">= %s"%(minver_str,)and'GREEN'or'YELLOW')
282        if not result:
283                conf.fatal('The python version is too old, expecting %r'%(minver,))
284PYTHON_MODULE_TEMPLATE='''
285import %s as current_module
286version = getattr(current_module, '__version__', None)
287if version is not None:
288    print(str(version))
289else:
290    print('unknown version')
291'''
292@conf
293def check_python_module(conf,module_name,condition=''):
294        msg='Python module %s'%module_name
295        if condition:
296                msg='%s (%s)'%(msg,condition)
297        conf.start_msg(msg)
298        try:
299                ret=conf.cmd_and_log(conf.env['PYTHON']+['-c',PYTHON_MODULE_TEMPLATE%module_name])
300        except Exception:
301                conf.end_msg(False)
302                conf.fatal('Could not find the python module %r'%module_name)
303        ret=ret.strip()
304        if condition:
305                conf.end_msg(ret)
306                if ret=='unknown version':
307                        conf.fatal('Could not check the %s version'%module_name)
308                from distutils.version import LooseVersion
309                def num(*k):
310                        if isinstance(k[0],int):
311                                return LooseVersion('.'.join([str(x)for x in k]))
312                        else:
313                                return LooseVersion(k[0])
314                d={'num':num,'ver':LooseVersion(ret)}
315                ev=eval(condition,{},d)
316                if not ev:
317                        conf.fatal('The %s version does not satisfy the requirements'%module_name)
318        else:
319                if ret=='unknown version':
320                        conf.end_msg(True)
321                else:
322                        conf.end_msg(ret)
323def configure(conf):
324        try:
325                conf.find_program('python',var='PYTHON')
326        except conf.errors.ConfigurationError:
327                Logs.warn("could not find a python executable, setting to sys.executable '%s'"%sys.executable)
328                conf.env.PYTHON=sys.executable
329        if conf.env.PYTHON!=sys.executable:
330                Logs.warn("python executable %r differs from system %r"%(conf.env.PYTHON,sys.executable))
331        conf.env.PYTHON=conf.cmd_to_list(conf.env.PYTHON)
332        v=conf.env
333        v['PYCMD']='"import sys, py_compile;py_compile.compile(sys.argv[1], sys.argv[2])"'
334        v['PYFLAGS']=''
335        v['PYFLAGS_OPT']='-O'
336        v['PYC']=getattr(Options.options,'pyc',1)
337        v['PYO']=getattr(Options.options,'pyo',1)
338def options(opt):
339        opt.add_option('--nopyc',action='store_false',default=1,help='Do not install bytecode compiled .pyc files (configuration) [Default:install]',dest='pyc')
340        opt.add_option('--nopyo',action='store_false',default=1,help='Do not install optimised compiled .pyo files (configuration) [Default:install]',dest='pyo')
Note: See TracBrowser for help on using the repository browser.