Ignore:
Timestamp:
Mar 14, 2015, 6:06:10 PM (10 years ago)
Author:
Paul Brossier <piem@piem.org>
Branches:
feature/autosink, feature/cnn, feature/cnn_org, feature/constantq, feature/crepe, feature/crepe_org, feature/pitchshift, feature/pydocstrings, feature/timestretch, fix/ffmpeg5, master, pitchshift, sampler, timestretch, yinfft+
Children:
6d7acc8
Parents:
5525507
Message:

waf, waflib: update to 1.8.7

File:
1 edited

Legend:

Unmodified
Added
Removed
  • waflib/Tools/python.py

    r5525507 r904702d  
    44
    55import os,sys
    6 from waflib import Utils,Options,Errors,Logs
     6from waflib import Utils,Options,Errors,Logs,Task,Node
    77from waflib.TaskGen import extension,before_method,after_method,feature
    88from waflib.Configure import conf
     
    2727INST='''
    2828import sys, py_compile
    29 py_compile.compile(sys.argv[1], sys.argv[2], sys.argv[3])
     29py_compile.compile(sys.argv[1], sys.argv[2], sys.argv[3], True)
    3030'''
    3131DISTUTILS_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
    3245@extension('.py')
    3346def 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)
    50 def 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')
    85 def feature_py(self):
    86         pass
     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
    8789@feature('pyext')
    8890@before_method('propagate_uselib_vars','apply_link')
     
    132134        self.to_log(out)
    133135        return_values=[]
    134         for s in out.split('\n'):
     136        for s in out.splitlines():
    135137                s=s.strip()
    136138                if not s:
     
    145147        return return_values
    146148@conf
    147 def check_python_headers(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'"
    148178        env=conf.env
    149179        if not env['CC_NAME']and not env['CXX_NAME']:
    150180                conf.fatal('load a compiler first (gcc, g++, ..)')
     181        if conf.python_cross_compile(features):
     182                return
    151183        if not env['PYTHON_VERSION']:
    152184                conf.check_python_version()
    153         pybin=conf.env.PYTHON
     185        pybin=env.PYTHON
    154186        if not pybin:
    155187                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()
     188        v='prefix SO LDFLAGS LIBDIR LIBPL INCLUDEPY Py_ENABLE_SHARED MACOSX_DEPLOYMENT_TARGET LDSHARED CFLAGS LDVERSION'.split()
    157189        try:
    158190                lst=conf.get_python_variables(["get_config_var('%s') or ''"%x for x in v])
     
    160192                conf.fatal("Python development headers not found (-v for details).")
    161193        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)))
     194        conf.to_log("Configuration returned from %r:\n%s\n"%(pybin,'\n'.join(vals)))
    163195        dct=dict(zip(v,lst))
    164196        x='MACOSX_DEPLOYMENT_TARGET'
    165197        if dct[x]:
    166                 conf.env[x]=conf.environ[x]=dct[x]
     198                env[x]=conf.environ[x]=dct[x]
    167199        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
    168217        all_flags=dct['LDFLAGS']+' '+dct['CFLAGS']
    169218        conf.parse_flags(all_flags,'PYEMBED')
     
    171220        conf.parse_flags(all_flags,'PYEXT')
    172221        result=None
    173         for name in('python'+env['PYTHON_VERSION'],'python'+env['PYTHON_VERSION']+'m','python'+env['PYTHON_VERSION'].replace('.','')):
     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('.','')):
    174225                if not result and env['LIBPATH_PYEMBED']:
    175226                        path=env['LIBPATH_PYEMBED']
     
    195246        else:
    196247                conf.to_log("\n\n### LIB NOT FOUND\n")
    197         if(Utils.is_win32 or sys.platform.startswith('os2')or dct['Py_ENABLE_SHARED']):
     248        if Utils.is_win32 or dct['Py_ENABLE_SHARED']:
    198249                env['LIBPATH_PYEXT']=env['LIBPATH_PYEMBED']
    199250                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']]
     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']]
    216254        if env['CC_NAME']=='gcc':
    217255                env.append_value('CFLAGS_PYEMBED',['-fno-strict-aliasing'])
     
    227265                env.append_value('CXXFLAGS_PYEXT',dist_compiler.compile_options)
    228266                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                 flags=['--cflags','--libs','--ldflags']
    234                 for f in flags:
    235                         conf.check_cfg(msg='Asking python-config for pyembed %s flags'%f,path=conf.env.PYTHON_CONFIG,package='',uselib_store='PYEMBED',args=[f])
    236                 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))
    237                 for f in flags:
    238                         conf.check_cfg(msg='Asking python-config for pyext %s flags'%f,path=conf.env.PYTHON_CONFIG,package='',uselib_store='PYEXT',args=[f])
    239                 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')
     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!')
    240268@conf
    241269def check_python_version(conf,minver=None):
     
    253281                pyver='.'.join([str(x)for x in pyver_tuple[:2]])
    254282                conf.env['PYTHON_VERSION']=pyver
    255                 if'PYTHONDIR'in conf.environ:
     283                if'PYTHONDIR'in conf.env:
     284                        pydir=conf.env['PYTHONDIR']
     285                elif'PYTHONDIR'in conf.environ:
    256286                        pydir=conf.environ['PYTHONDIR']
    257287                else:
    258288                        if Utils.is_win32:
    259                                 (python_LIBDEST,pydir)=conf.get_python_variables(["get_config_var('LIBDEST') or ''","get_python_lib(standard_lib=0, prefix=%r) or ''"%conf.env['PREFIX']])
     289                                (python_LIBDEST,pydir)=conf.get_python_variables(["get_config_var('LIBDEST') or ''","get_python_lib(standard_lib=0) or ''"])
    260290                        else:
    261291                                python_LIBDEST=None
    262                                 (pydir,)=conf.get_python_variables(["get_python_lib(standard_lib=0, prefix=%r) or ''"%conf.env['PREFIX']])
     292                                (pydir,)=conf.get_python_variables(["get_python_lib(standard_lib=0) or ''"])
    263293                        if python_LIBDEST is None:
    264294                                if conf.env['LIBDIR']:
     
    266296                                else:
    267297                                        python_LIBDEST=os.path.join(conf.env['PREFIX'],"lib","python"+pyver)
    268                 if'PYTHONARCHDIR'in conf.environ:
     298                if'PYTHONARCHDIR'in conf.env:
     299                        pyarchdir=conf.env['PYTHONARCHDIR']
     300                elif'PYTHONARCHDIR'in conf.environ:
    269301                        pyarchdir=conf.environ['PYTHONARCHDIR']
    270302                else:
    271                         (pyarchdir,)=conf.get_python_variables(["get_python_lib(plat_specific=1, standard_lib=0, prefix=%r) or ''"%conf.env['PREFIX']])
     303                        (pyarchdir,)=conf.get_python_variables(["get_python_lib(plat_specific=1, standard_lib=0) or ''"])
    272304                        if not pyarchdir:
    273305                                pyarchdir=pydir
     
    289321version = getattr(current_module, '__version__', None)
    290322if version is not None:
    291     print(str(version))
     323        print(str(version))
    292324else:
    293     print('unknown version')
     325        print('unknown version')
    294326'''
    295327@conf
    296328def check_python_module(conf,module_name,condition=''):
    297         msg='Python module %s'%module_name
     329        msg="Checking for python module '%s'"%module_name
    298330        if condition:
    299331                msg='%s (%s)'%(msg,condition)
     
    325357                        conf.end_msg(ret)
    326358def configure(conf):
    327         try:
    328                 conf.find_program('python',var='PYTHON')
    329         except conf.errors.ConfigurationError:
    330                 Logs.warn("could not find a python executable, setting to sys.executable '%s'"%sys.executable)
    331                 conf.env.PYTHON=sys.executable
    332         if conf.env.PYTHON!=sys.executable:
    333                 Logs.warn("python executable %r differs from system %r"%(conf.env.PYTHON,sys.executable))
    334         conf.env.PYTHON=conf.cmd_to_list(conf.env.PYTHON)
    335359        v=conf.env
    336         v['PYCMD']='"import sys, py_compile;py_compile.compile(sys.argv[1], sys.argv[2])"'
     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')
    337366        v['PYFLAGS']=''
    338367        v['PYFLAGS_OPT']='-O'
    339368        v['PYC']=getattr(Options.options,'pyc',1)
    340369        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
    341374def options(opt):
    342         opt.add_option('--nopyc',action='store_false',default=1,help='Do not install bytecode compiled .pyc files (configuration) [Default:install]',dest='pyc')
    343         opt.add_option('--nopyo',action='store_false',default=1,help='Do not install optimised compiled .pyo files (configuration) [Default:install]',dest='pyo')
     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 TracChangeset for help on using the changeset viewer.