Changeset 904702d for waflib/Tools/python.py
- Timestamp:
- Mar 14, 2015, 6:06:10 PM (10 years ago)
- 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
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
waflib/Tools/python.py
r5525507 r904702d 4 4 5 5 import os,sys 6 from waflib import Utils,Options,Errors,Logs 6 from waflib import Utils,Options,Errors,Logs,Task,Node 7 7 from waflib.TaskGen import extension,before_method,after_method,feature 8 8 from waflib.Configure import conf … … 27 27 INST=''' 28 28 import sys, py_compile 29 py_compile.compile(sys.argv[1], sys.argv[2], sys.argv[3] )29 py_compile.compile(sys.argv[1], sys.argv[2], sys.argv[3], True) 30 30 ''' 31 31 DISTUTILS_IMP=['from distutils.sysconfig import get_config_var, get_python_lib'] 32 @before_method('process_source') 33 @feature('py') 34 def 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 32 45 @extension('.py') 33 46 def 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) 77 class 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 83 class 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 87 89 @feature('pyext') 88 90 @before_method('propagate_uselib_vars','apply_link') … … 132 134 self.to_log(out) 133 135 return_values=[] 134 for s in out.split ('\n'):136 for s in out.splitlines(): 135 137 s=s.strip() 136 138 if not s: … … 145 147 return return_values 146 148 @conf 147 def check_python_headers(conf): 149 def 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 175 def 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'" 148 178 env=conf.env 149 179 if not env['CC_NAME']and not env['CXX_NAME']: 150 180 conf.fatal('load a compiler first (gcc, g++, ..)') 181 if conf.python_cross_compile(features): 182 return 151 183 if not env['PYTHON_VERSION']: 152 184 conf.check_python_version() 153 pybin= conf.env.PYTHON185 pybin=env.PYTHON 154 186 if not pybin: 155 187 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() 157 189 try: 158 190 lst=conf.get_python_variables(["get_config_var('%s') or ''"%x for x in v]) … … 160 192 conf.fatal("Python development headers not found (-v for details).") 161 193 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))) 163 195 dct=dict(zip(v,lst)) 164 196 x='MACOSX_DEPLOYMENT_TARGET' 165 197 if dct[x]: 166 conf.env[x]=conf.environ[x]=dct[x]198 env[x]=conf.environ[x]=dct[x] 167 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 168 217 all_flags=dct['LDFLAGS']+' '+dct['CFLAGS'] 169 218 conf.parse_flags(all_flags,'PYEMBED') … … 171 220 conf.parse_flags(all_flags,'PYEXT') 172 221 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('.','')): 174 225 if not result and env['LIBPATH_PYEMBED']: 175 226 path=env['LIBPATH_PYEMBED'] … … 195 246 else: 196 247 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']: 198 249 env['LIBPATH_PYEXT']=env['LIBPATH_PYEMBED'] 199 250 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']] 216 254 if env['CC_NAME']=='gcc': 217 255 env.append_value('CFLAGS_PYEMBED',['-fno-strict-aliasing']) … … 227 265 env.append_value('CXXFLAGS_PYEXT',dist_compiler.compile_options) 228 266 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!') 240 268 @conf 241 269 def check_python_version(conf,minver=None): … … 253 281 pyver='.'.join([str(x)for x in pyver_tuple[:2]]) 254 282 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: 256 286 pydir=conf.environ['PYTHONDIR'] 257 287 else: 258 288 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 ''"]) 260 290 else: 261 291 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 ''"]) 263 293 if python_LIBDEST is None: 264 294 if conf.env['LIBDIR']: … … 266 296 else: 267 297 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: 269 301 pyarchdir=conf.environ['PYTHONARCHDIR'] 270 302 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 ''"]) 272 304 if not pyarchdir: 273 305 pyarchdir=pydir … … 289 321 version = getattr(current_module, '__version__', None) 290 322 if version is not None: 291 323 print(str(version)) 292 324 else: 293 325 print('unknown version') 294 326 ''' 295 327 @conf 296 328 def check_python_module(conf,module_name,condition=''): 297 msg= 'Python module %s'%module_name329 msg="Checking for python module '%s'"%module_name 298 330 if condition: 299 331 msg='%s (%s)'%(msg,condition) … … 325 357 conf.end_msg(ret) 326 358 def 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.executable332 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)335 359 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') 337 366 v['PYFLAGS']='' 338 367 v['PYFLAGS_OPT']='-O' 339 368 v['PYC']=getattr(Options.options,'pyc',1) 340 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 341 374 def 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.