source: waflib/Tools/python.py @ c82a034

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

waf, waflib: update to 1.8.7

  • Property mode set to 100644
File size: 15.4 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,Task,Node
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], True)
30'''
31DISTUTILS_IMP=['from distutils.sysconfig import get_config_var, get_python_lib']
32@before_method('process_source')
33@feature('py')
34def feature_py(self):
35        self.install_path=getattr(self,'install_path','${PYTHONDIR}')
36        install_from=getattr(self,'install_from',None)
37        if install_from and not isinstance(install_from,Node.Node):
38                install_from=self.path.find_dir(install_from)
39        self.install_from=install_from
40        ver=self.env.PYTHON_VERSION
41        if not ver:
42                self.bld.fatal('Installing python files requires PYTHON_VERSION, try conf.check_python_version')
43        if int(ver.replace('.',''))>31:
44                self.install_32=True
45@extension('.py')
46def process_py(self,node):
47        assert(node.get_bld_sig())
48        assert(getattr(self,'install_path')),'add features="py"'
49        if self.install_path:
50                if self.install_from:
51                        self.bld.install_files(self.install_path,[node],cwd=self.install_from,relative_trick=True)
52                else:
53                        self.bld.install_files(self.install_path,[node],relative_trick=True)
54        lst=[]
55        if self.env.PYC:
56                lst.append('pyc')
57        if self.env.PYO:
58                lst.append('pyo')
59        if self.install_path:
60                if self.install_from:
61                        pyd=Utils.subst_vars("%s/%s"%(self.install_path,node.path_from(self.install_from)),self.env)
62                else:
63                        pyd=Utils.subst_vars("%s/%s"%(self.install_path,node.path_from(self.path)),self.env)
64        else:
65                pyd=node.abspath()
66        for ext in lst:
67                if self.env.PYTAG:
68                        name=node.name[:-3]
69                        pyobj=node.parent.get_bld().make_node('__pycache__').make_node("%s.%s.%s"%(name,self.env.PYTAG,ext))
70                        pyobj.parent.mkdir()
71                else:
72                        pyobj=node.change_ext(".%s"%ext)
73                tsk=self.create_task(ext,node,pyobj)
74                tsk.pyd=pyd
75                if self.install_path:
76                        self.bld.install_files(os.path.dirname(pyd),pyobj,cwd=node.parent.get_bld(),relative_trick=True)
77class pyc(Task.Task):
78        color='PINK'
79        def run(self):
80                cmd=[Utils.subst_vars('${PYTHON}',self.env),'-c',INST,self.inputs[0].abspath(),self.outputs[0].abspath(),self.pyd]
81                ret=self.generator.bld.exec_command(cmd)
82                return ret
83class pyo(Task.Task):
84        color='PINK'
85        def run(self):
86                cmd=[Utils.subst_vars('${PYTHON}',self.env),Utils.subst_vars('${PYFLAGS_OPT}',self.env),'-c',INST,self.inputs[0].abspath(),self.outputs[0].abspath(),self.pyd]
87                ret=self.generator.bld.exec_command(cmd)
88                return ret
89@feature('pyext')
90@before_method('propagate_uselib_vars','apply_link')
91@after_method('apply_bundle')
92def init_pyext(self):
93        self.uselib=self.to_list(getattr(self,'uselib',[]))
94        if not'PYEXT'in self.uselib:
95                self.uselib.append('PYEXT')
96        self.env.cshlib_PATTERN=self.env.cxxshlib_PATTERN=self.env.macbundle_PATTERN=self.env.pyext_PATTERN
97        self.env.fcshlib_PATTERN=self.env.dshlib_PATTERN=self.env.pyext_PATTERN
98        try:
99                if not self.install_path:
100                        return
101        except AttributeError:
102                self.install_path='${PYTHONARCHDIR}'
103@feature('pyext')
104@before_method('apply_link','apply_bundle')
105def set_bundle(self):
106        if Utils.unversioned_sys_platform()=='darwin':
107                self.mac_bundle=True
108@before_method('propagate_uselib_vars')
109@feature('pyembed')
110def init_pyembed(self):
111        self.uselib=self.to_list(getattr(self,'uselib',[]))
112        if not'PYEMBED'in self.uselib:
113                self.uselib.append('PYEMBED')
114@conf
115def get_python_variables(self,variables,imports=None):
116        if not imports:
117                try:
118                        imports=self.python_imports
119                except AttributeError:
120                        imports=DISTUTILS_IMP
121        program=list(imports)
122        program.append('')
123        for v in variables:
124                program.append("print(repr(%s))"%v)
125        os_env=dict(os.environ)
126        try:
127                del os_env['MACOSX_DEPLOYMENT_TARGET']
128        except KeyError:
129                pass
130        try:
131                out=self.cmd_and_log(self.env.PYTHON+['-c','\n'.join(program)],env=os_env)
132        except Errors.WafError:
133                self.fatal('The distutils module is unusable: install "python-devel"?')
134        self.to_log(out)
135        return_values=[]
136        for s in out.splitlines():
137                s=s.strip()
138                if not s:
139                        continue
140                if s=='None':
141                        return_values.append(None)
142                elif(s[0]=="'"and s[-1]=="'")or(s[0]=='"'and s[-1]=='"'):
143                        return_values.append(eval(s))
144                elif s[0].isdigit():
145                        return_values.append(int(s))
146                else:break
147        return return_values
148@conf
149def python_cross_compile(self,features='pyembed pyext'):
150        features=Utils.to_list(features)
151        if not('PYTHON_LDFLAGS'in self.environ or'PYTHON_PYEXT_LDFLAGS'in self.environ or'PYTHON_PYEMBED_LDFLAGS'in self.environ):
152                return False
153        for x in'PYTHON_VERSION PYTAG pyext_PATTERN'.split():
154                if not x in self.environ:
155                        self.fatal('Please set %s in the os environment'%x)
156                else:
157                        self.env[x]=self.environ[x]
158        xx=self.env.CXX_NAME and'cxx'or'c'
159        if'pyext'in features:
160                flags=self.environ.get('PYTHON_PYEXT_LDFLAGS',self.environ.get('PYTHON_LDFLAGS',None))
161                if flags is None:
162                        self.fatal('No flags provided through PYTHON_PYEXT_LDFLAGS as required')
163                else:
164                        self.parse_flags(flags,'PYEXT')
165                self.check(header_name='Python.h',define_name='HAVE_PYEXT',msg='Testing pyext configuration',features='%s %sshlib pyext'%(xx,xx),fragment=FRAG,errmsg='Could not build python extensions')
166        if'pyembed'in features:
167                flags=self.environ.get('PYTHON_PYEMBED_LDFLAGS',self.environ.get('PYTHON_LDFLAGS',None))
168                if flags is None:
169                        self.fatal('No flags provided through PYTHON_PYEMBED_LDFLAGS as required')
170                else:
171                        self.parse_flags(flags,'PYEMBED')
172                self.check(header_name='Python.h',define_name='HAVE_PYEMBED',msg='Testing pyembed configuration',fragment=FRAG,errmsg='Could not build a python embedded interpreter',features='%s %sprogram pyembed'%(xx,xx))
173        return True
174@conf
175def check_python_headers(conf,features='pyembed pyext'):
176        features=Utils.to_list(features)
177        assert('pyembed'in features)or('pyext'in features),"check_python_headers features must include 'pyembed' and/or 'pyext'"
178        env=conf.env
179        if not env['CC_NAME']and not env['CXX_NAME']:
180                conf.fatal('load a compiler first (gcc, g++, ..)')
181        if conf.python_cross_compile(features):
182                return
183        if not env['PYTHON_VERSION']:
184                conf.check_python_version()
185        pybin=env.PYTHON
186        if not pybin:
187                conf.fatal('Could not find the python executable')
188        v='prefix SO LDFLAGS LIBDIR LIBPL INCLUDEPY Py_ENABLE_SHARED MACOSX_DEPLOYMENT_TARGET LDSHARED CFLAGS LDVERSION'.split()
189        try:
190                lst=conf.get_python_variables(["get_config_var('%s') or ''"%x for x in v])
191        except RuntimeError:
192                conf.fatal("Python development headers not found (-v for details).")
193        vals=['%s = %r'%(x,y)for(x,y)in zip(v,lst)]
194        conf.to_log("Configuration returned from %r:\n%s\n"%(pybin,'\n'.join(vals)))
195        dct=dict(zip(v,lst))
196        x='MACOSX_DEPLOYMENT_TARGET'
197        if dct[x]:
198                env[x]=conf.environ[x]=dct[x]
199        env['pyext_PATTERN']='%s'+dct['SO']
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',msg="python-config",mandatory=False)
202        if env.PYTHON_CONFIG:
203                all_flags=[['--cflags','--libs','--ldflags']]
204                if sys.hexversion<0x2070000:
205                        all_flags=[[k]for k in all_flags[0]]
206                xx=env.CXX_NAME and'cxx'or'c'
207                if'pyembed'in features:
208                        for flags in all_flags:
209                                conf.check_cfg(msg='Asking python-config for pyembed %r flags'%' '.join(flags),path=env.PYTHON_CONFIG,package='',uselib_store='PYEMBED',args=flags)
210                        conf.check(header_name='Python.h',define_name='HAVE_PYEMBED',msg='Getting pyembed flags from python-config',fragment=FRAG,errmsg='Could not build a python embedded interpreter',features='%s %sprogram pyembed'%(xx,xx))
211                if'pyext'in features:
212                        for flags in all_flags:
213                                conf.check_cfg(msg='Asking python-config for pyext %r flags'%' '.join(flags),path=env.PYTHON_CONFIG,package='',uselib_store='PYEXT',args=flags)
214                        conf.check(header_name='Python.h',define_name='HAVE_PYEXT',msg='Getting pyext flags from python-config',features='%s %sshlib pyext'%(xx,xx),fragment=FRAG,errmsg='Could not build python extensions')
215                conf.define('HAVE_PYTHON_H',1)
216                return
217        all_flags=dct['LDFLAGS']+' '+dct['CFLAGS']
218        conf.parse_flags(all_flags,'PYEMBED')
219        all_flags=dct['LDFLAGS']+' '+dct['LDSHARED']+' '+dct['CFLAGS']
220        conf.parse_flags(all_flags,'PYEXT')
221        result=None
222        if not dct["LDVERSION"]:
223                dct["LDVERSION"]=env['PYTHON_VERSION']
224        for name in('python'+dct['LDVERSION'],'python'+env['PYTHON_VERSION']+'m','python'+env['PYTHON_VERSION'].replace('.','')):
225                if not result and env['LIBPATH_PYEMBED']:
226                        path=env['LIBPATH_PYEMBED']
227                        conf.to_log("\n\n# Trying default LIBPATH_PYEMBED: %r\n"%path)
228                        result=conf.check(lib=name,uselib='PYEMBED',libpath=path,mandatory=False,msg='Checking for library %s in LIBPATH_PYEMBED'%name)
229                if not result and dct['LIBDIR']:
230                        path=[dct['LIBDIR']]
231                        conf.to_log("\n\n# try again with -L$python_LIBDIR: %r\n"%path)
232                        result=conf.check(lib=name,uselib='PYEMBED',libpath=path,mandatory=False,msg='Checking for library %s in LIBDIR'%name)
233                if not result and dct['LIBPL']:
234                        path=[dct['LIBPL']]
235                        conf.to_log("\n\n# try again with -L$python_LIBPL (some systems don't install the python library in $prefix/lib)\n")
236                        result=conf.check(lib=name,uselib='PYEMBED',libpath=path,mandatory=False,msg='Checking for library %s in python_LIBPL'%name)
237                if not result:
238                        path=[os.path.join(dct['prefix'],"libs")]
239                        conf.to_log("\n\n# try again with -L$prefix/libs, and pythonXY name rather than pythonX.Y (win32)\n")
240                        result=conf.check(lib=name,uselib='PYEMBED',libpath=path,mandatory=False,msg='Checking for library %s in $prefix/libs'%name)
241                if result:
242                        break
243        if result:
244                env['LIBPATH_PYEMBED']=path
245                env.append_value('LIB_PYEMBED',[name])
246        else:
247                conf.to_log("\n\n### LIB NOT FOUND\n")
248        if Utils.is_win32 or dct['Py_ENABLE_SHARED']:
249                env['LIBPATH_PYEXT']=env['LIBPATH_PYEMBED']
250                env['LIB_PYEXT']=env['LIB_PYEMBED']
251        conf.to_log("Include path for Python extensions (found via distutils module): %r\n"%(dct['INCLUDEPY'],))
252        env['INCLUDES_PYEXT']=[dct['INCLUDEPY']]
253        env['INCLUDES_PYEMBED']=[dct['INCLUDEPY']]
254        if env['CC_NAME']=='gcc':
255                env.append_value('CFLAGS_PYEMBED',['-fno-strict-aliasing'])
256                env.append_value('CFLAGS_PYEXT',['-fno-strict-aliasing'])
257        if env['CXX_NAME']=='gcc':
258                env.append_value('CXXFLAGS_PYEMBED',['-fno-strict-aliasing'])
259                env.append_value('CXXFLAGS_PYEXT',['-fno-strict-aliasing'])
260        if env.CC_NAME=="msvc":
261                from distutils.msvccompiler import MSVCCompiler
262                dist_compiler=MSVCCompiler()
263                dist_compiler.initialize()
264                env.append_value('CFLAGS_PYEXT',dist_compiler.compile_options)
265                env.append_value('CXXFLAGS_PYEXT',dist_compiler.compile_options)
266                env.append_value('LINKFLAGS_PYEXT',dist_compiler.ldflags_shared)
267        conf.check(header_name='Python.h',define_name='HAVE_PYTHON_H',uselib='PYEMBED',fragment=FRAG,errmsg='Distutils not installed? Broken python installation? Get python-config now!')
268@conf
269def check_python_version(conf,minver=None):
270        assert minver is None or isinstance(minver,tuple)
271        pybin=conf.env['PYTHON']
272        if not pybin:
273                conf.fatal('could not find the python executable')
274        cmd=pybin+['-c','import sys\nfor x in sys.version_info: print(str(x))']
275        Logs.debug('python: Running python command %r'%cmd)
276        lines=conf.cmd_and_log(cmd).split()
277        assert len(lines)==5,"found %i lines, expected 5: %r"%(len(lines),lines)
278        pyver_tuple=(int(lines[0]),int(lines[1]),int(lines[2]),lines[3],int(lines[4]))
279        result=(minver is None)or(pyver_tuple>=minver)
280        if result:
281                pyver='.'.join([str(x)for x in pyver_tuple[:2]])
282                conf.env['PYTHON_VERSION']=pyver
283                if'PYTHONDIR'in conf.env:
284                        pydir=conf.env['PYTHONDIR']
285                elif'PYTHONDIR'in conf.environ:
286                        pydir=conf.environ['PYTHONDIR']
287                else:
288                        if Utils.is_win32:
289                                (python_LIBDEST,pydir)=conf.get_python_variables(["get_config_var('LIBDEST') or ''","get_python_lib(standard_lib=0) or ''"])
290                        else:
291                                python_LIBDEST=None
292                                (pydir,)=conf.get_python_variables(["get_python_lib(standard_lib=0) or ''"])
293                        if python_LIBDEST is None:
294                                if conf.env['LIBDIR']:
295                                        python_LIBDEST=os.path.join(conf.env['LIBDIR'],"python"+pyver)
296                                else:
297                                        python_LIBDEST=os.path.join(conf.env['PREFIX'],"lib","python"+pyver)
298                if'PYTHONARCHDIR'in conf.env:
299                        pyarchdir=conf.env['PYTHONARCHDIR']
300                elif'PYTHONARCHDIR'in conf.environ:
301                        pyarchdir=conf.environ['PYTHONARCHDIR']
302                else:
303                        (pyarchdir,)=conf.get_python_variables(["get_python_lib(plat_specific=1, standard_lib=0) or ''"])
304                        if not pyarchdir:
305                                pyarchdir=pydir
306                if hasattr(conf,'define'):
307                        conf.define('PYTHONDIR',pydir)
308                        conf.define('PYTHONARCHDIR',pyarchdir)
309                conf.env['PYTHONDIR']=pydir
310                conf.env['PYTHONARCHDIR']=pyarchdir
311        pyver_full='.'.join(map(str,pyver_tuple[:3]))
312        if minver is None:
313                conf.msg('Checking for python version',pyver_full)
314        else:
315                minver_str='.'.join(map(str,minver))
316                conf.msg('Checking for python version',pyver_tuple,">= %s"%(minver_str,)and'GREEN'or'YELLOW')
317        if not result:
318                conf.fatal('The python version is too old, expecting %r'%(minver,))
319PYTHON_MODULE_TEMPLATE='''
320import %s as current_module
321version = getattr(current_module, '__version__', None)
322if version is not None:
323        print(str(version))
324else:
325        print('unknown version')
326'''
327@conf
328def check_python_module(conf,module_name,condition=''):
329        msg="Checking for python module '%s'"%module_name
330        if condition:
331                msg='%s (%s)'%(msg,condition)
332        conf.start_msg(msg)
333        try:
334                ret=conf.cmd_and_log(conf.env['PYTHON']+['-c',PYTHON_MODULE_TEMPLATE%module_name])
335        except Exception:
336                conf.end_msg(False)
337                conf.fatal('Could not find the python module %r'%module_name)
338        ret=ret.strip()
339        if condition:
340                conf.end_msg(ret)
341                if ret=='unknown version':
342                        conf.fatal('Could not check the %s version'%module_name)
343                from distutils.version import LooseVersion
344                def num(*k):
345                        if isinstance(k[0],int):
346                                return LooseVersion('.'.join([str(x)for x in k]))
347                        else:
348                                return LooseVersion(k[0])
349                d={'num':num,'ver':LooseVersion(ret)}
350                ev=eval(condition,{},d)
351                if not ev:
352                        conf.fatal('The %s version does not satisfy the requirements'%module_name)
353        else:
354                if ret=='unknown version':
355                        conf.end_msg(True)
356                else:
357                        conf.end_msg(ret)
358def configure(conf):
359        v=conf.env
360        v['PYTHON']=Options.options.python or os.environ.get('PYTHON',sys.executable)
361        if Options.options.pythondir:
362                v['PYTHONDIR']=Options.options.pythondir
363        if Options.options.pythonarchdir:
364                v['PYTHONARCHDIR']=Options.options.pythonarchdir
365        conf.find_program('python',var='PYTHON')
366        v['PYFLAGS']=''
367        v['PYFLAGS_OPT']='-O'
368        v['PYC']=getattr(Options.options,'pyc',1)
369        v['PYO']=getattr(Options.options,'pyo',1)
370        try:
371                v.PYTAG=conf.cmd_and_log(conf.env.PYTHON+['-c',"import imp;print(imp.get_tag())"]).strip()
372        except Errors.WafError:
373                pass
374def options(opt):
375        pyopt=opt.add_option_group("Python Options")
376        pyopt.add_option('--nopyc',dest='pyc',action='store_false',default=1,help='Do not install bytecode compiled .pyc files (configuration) [Default:install]')
377        pyopt.add_option('--nopyo',dest='pyo',action='store_false',default=1,help='Do not install optimised compiled .pyo files (configuration) [Default:install]')
378        pyopt.add_option('--python',dest="python",help='python binary to be used [Default: %s]'%sys.executable)
379        pyopt.add_option('--pythondir',dest='pythondir',help='Installation path for python modules (py, platform-independent .py and .pyc files)')
380        pyopt.add_option('--pythonarchdir',dest='pythonarchdir',help='Installation path for python extension (pyext, platform-dependent .so or .dylib files)')
Note: See TracBrowser for help on using the repository browser.