summaryrefslogtreecommitdiff
path: root/waflib/Tools/ccroot.py
diff options
context:
space:
mode:
Diffstat (limited to 'waflib/Tools/ccroot.py')
-rw-r--r--waflib/Tools/ccroot.py479
1 files changed, 479 insertions, 0 deletions
diff --git a/waflib/Tools/ccroot.py b/waflib/Tools/ccroot.py
new file mode 100644
index 0000000..bb807ec
--- /dev/null
+++ b/waflib/Tools/ccroot.py
@@ -0,0 +1,479 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
+
+import os,re
+from waflib import Task,Utils,Node,Errors,Logs
+from waflib.TaskGen import after_method,before_method,feature,taskgen_method,extension
+from waflib.Tools import c_aliases,c_preproc,c_config,c_osx,c_tests
+from waflib.Configure import conf
+SYSTEM_LIB_PATHS=['/usr/lib64','/usr/lib','/usr/local/lib64','/usr/local/lib']
+USELIB_VARS=Utils.defaultdict(set)
+USELIB_VARS['c']=set(['INCLUDES','FRAMEWORKPATH','DEFINES','CPPFLAGS','CCDEPS','CFLAGS','ARCH'])
+USELIB_VARS['cxx']=set(['INCLUDES','FRAMEWORKPATH','DEFINES','CPPFLAGS','CXXDEPS','CXXFLAGS','ARCH'])
+USELIB_VARS['d']=set(['INCLUDES','DFLAGS'])
+USELIB_VARS['includes']=set(['INCLUDES','FRAMEWORKPATH','ARCH'])
+USELIB_VARS['cprogram']=USELIB_VARS['cxxprogram']=set(['LIB','STLIB','LIBPATH','STLIBPATH','LINKFLAGS','RPATH','LINKDEPS','FRAMEWORK','FRAMEWORKPATH','ARCH','LDFLAGS'])
+USELIB_VARS['cshlib']=USELIB_VARS['cxxshlib']=set(['LIB','STLIB','LIBPATH','STLIBPATH','LINKFLAGS','RPATH','LINKDEPS','FRAMEWORK','FRAMEWORKPATH','ARCH','LDFLAGS'])
+USELIB_VARS['cstlib']=USELIB_VARS['cxxstlib']=set(['ARFLAGS','LINKDEPS'])
+USELIB_VARS['dprogram']=set(['LIB','STLIB','LIBPATH','STLIBPATH','LINKFLAGS','RPATH','LINKDEPS'])
+USELIB_VARS['dshlib']=set(['LIB','STLIB','LIBPATH','STLIBPATH','LINKFLAGS','RPATH','LINKDEPS'])
+USELIB_VARS['dstlib']=set(['ARFLAGS','LINKDEPS'])
+USELIB_VARS['asm']=set(['ASFLAGS'])
+@taskgen_method
+def create_compiled_task(self,name,node):
+ out='%s.%d.o'%(node.name,self.idx)
+ task=self.create_task(name,node,node.parent.find_or_declare(out))
+ try:
+ self.compiled_tasks.append(task)
+ except AttributeError:
+ self.compiled_tasks=[task]
+ return task
+@taskgen_method
+def to_incnodes(self,inlst):
+ lst=[]
+ seen=set()
+ for x in self.to_list(inlst):
+ if x in seen or not x:
+ continue
+ seen.add(x)
+ if isinstance(x,Node.Node):
+ lst.append(x)
+ else:
+ if os.path.isabs(x):
+ lst.append(self.bld.root.make_node(x)or x)
+ else:
+ if x[0]=='#':
+ p=self.bld.bldnode.make_node(x[1:])
+ v=self.bld.srcnode.make_node(x[1:])
+ else:
+ p=self.path.get_bld().make_node(x)
+ v=self.path.make_node(x)
+ if p.is_child_of(self.bld.bldnode):
+ p.mkdir()
+ lst.append(p)
+ lst.append(v)
+ return lst
+@feature('c','cxx','d','asm','fc','includes')
+@after_method('propagate_uselib_vars','process_source')
+def apply_incpaths(self):
+ lst=self.to_incnodes(self.to_list(getattr(self,'includes',[]))+self.env.INCLUDES)
+ self.includes_nodes=lst
+ cwd=self.get_cwd()
+ self.env.INCPATHS=[x.path_from(cwd)for x in lst]
+class link_task(Task.Task):
+ color='YELLOW'
+ weight=3
+ inst_to=None
+ chmod=Utils.O755
+ def add_target(self,target):
+ if isinstance(target,str):
+ base=self.generator.path
+ if target.startswith('#'):
+ target=target[1:]
+ base=self.generator.bld.bldnode
+ pattern=self.env[self.__class__.__name__+'_PATTERN']
+ if not pattern:
+ pattern='%s'
+ folder,name=os.path.split(target)
+ if self.__class__.__name__.find('shlib')>0 and getattr(self.generator,'vnum',None):
+ nums=self.generator.vnum.split('.')
+ if self.env.DEST_BINFMT=='pe':
+ name=name+'-'+nums[0]
+ elif self.env.DEST_OS=='openbsd':
+ pattern='%s.%s'%(pattern,nums[0])
+ if len(nums)>=2:
+ pattern+='.%s'%nums[1]
+ if folder:
+ tmp=folder+os.sep+pattern%name
+ else:
+ tmp=pattern%name
+ target=base.find_or_declare(tmp)
+ self.set_outputs(target)
+ def exec_command(self,*k,**kw):
+ ret=super(link_task,self).exec_command(*k,**kw)
+ if not ret and self.env.DO_MANIFEST:
+ ret=self.exec_mf()
+ return ret
+ def exec_mf(self):
+ if not self.env.MT:
+ return 0
+ manifest=None
+ for out_node in self.outputs:
+ if out_node.name.endswith('.manifest'):
+ manifest=out_node.abspath()
+ break
+ else:
+ return 0
+ mode=''
+ for x in Utils.to_list(self.generator.features):
+ if x in('cprogram','cxxprogram','fcprogram','fcprogram_test'):
+ mode=1
+ elif x in('cshlib','cxxshlib','fcshlib'):
+ mode=2
+ Logs.debug('msvc: embedding manifest in mode %r',mode)
+ lst=[]+self.env.MT
+ lst.extend(Utils.to_list(self.env.MTFLAGS))
+ lst.extend(['-manifest',manifest])
+ lst.append('-outputresource:%s;%s'%(self.outputs[0].abspath(),mode))
+ return super(link_task,self).exec_command(lst)
+class stlink_task(link_task):
+ run_str='${AR} ${ARFLAGS} ${AR_TGT_F}${TGT} ${AR_SRC_F}${SRC}'
+ chmod=Utils.O644
+def rm_tgt(cls):
+ old=cls.run
+ def wrap(self):
+ try:
+ os.remove(self.outputs[0].abspath())
+ except OSError:
+ pass
+ return old(self)
+ setattr(cls,'run',wrap)
+rm_tgt(stlink_task)
+@feature('c','cxx','d','fc','asm')
+@after_method('process_source')
+def apply_link(self):
+ for x in self.features:
+ if x=='cprogram'and'cxx'in self.features:
+ x='cxxprogram'
+ elif x=='cshlib'and'cxx'in self.features:
+ x='cxxshlib'
+ if x in Task.classes:
+ if issubclass(Task.classes[x],link_task):
+ link=x
+ break
+ else:
+ return
+ objs=[t.outputs[0]for t in getattr(self,'compiled_tasks',[])]
+ self.link_task=self.create_task(link,objs)
+ self.link_task.add_target(self.target)
+ try:
+ inst_to=self.install_path
+ except AttributeError:
+ inst_to=self.link_task.inst_to
+ if inst_to:
+ self.install_task=self.add_install_files(install_to=inst_to,install_from=self.link_task.outputs[:],chmod=self.link_task.chmod,task=self.link_task)
+@taskgen_method
+def use_rec(self,name,**kw):
+ if name in self.tmp_use_not or name in self.tmp_use_seen:
+ return
+ try:
+ y=self.bld.get_tgen_by_name(name)
+ except Errors.WafError:
+ self.uselib.append(name)
+ self.tmp_use_not.add(name)
+ return
+ self.tmp_use_seen.append(name)
+ y.post()
+ y.tmp_use_objects=objects=kw.get('objects',True)
+ y.tmp_use_stlib=stlib=kw.get('stlib',True)
+ try:
+ link_task=y.link_task
+ except AttributeError:
+ y.tmp_use_var=''
+ else:
+ objects=False
+ if not isinstance(link_task,stlink_task):
+ stlib=False
+ y.tmp_use_var='LIB'
+ else:
+ y.tmp_use_var='STLIB'
+ p=self.tmp_use_prec
+ for x in self.to_list(getattr(y,'use',[])):
+ if self.env["STLIB_"+x]:
+ continue
+ try:
+ p[x].append(name)
+ except KeyError:
+ p[x]=[name]
+ self.use_rec(x,objects=objects,stlib=stlib)
+@feature('c','cxx','d','use','fc')
+@before_method('apply_incpaths','propagate_uselib_vars')
+@after_method('apply_link','process_source')
+def process_use(self):
+ use_not=self.tmp_use_not=set()
+ self.tmp_use_seen=[]
+ use_prec=self.tmp_use_prec={}
+ self.uselib=self.to_list(getattr(self,'uselib',[]))
+ self.includes=self.to_list(getattr(self,'includes',[]))
+ names=self.to_list(getattr(self,'use',[]))
+ for x in names:
+ self.use_rec(x)
+ for x in use_not:
+ if x in use_prec:
+ del use_prec[x]
+ out=self.tmp_use_sorted=[]
+ tmp=[]
+ for x in self.tmp_use_seen:
+ for k in use_prec.values():
+ if x in k:
+ break
+ else:
+ tmp.append(x)
+ while tmp:
+ e=tmp.pop()
+ out.append(e)
+ try:
+ nlst=use_prec[e]
+ except KeyError:
+ pass
+ else:
+ del use_prec[e]
+ for x in nlst:
+ for y in use_prec:
+ if x in use_prec[y]:
+ break
+ else:
+ tmp.append(x)
+ if use_prec:
+ raise Errors.WafError('Cycle detected in the use processing %r'%use_prec)
+ out.reverse()
+ link_task=getattr(self,'link_task',None)
+ for x in out:
+ y=self.bld.get_tgen_by_name(x)
+ var=y.tmp_use_var
+ if var and link_task:
+ if var=='LIB'or y.tmp_use_stlib or x in names:
+ self.env.append_value(var,[y.target[y.target.rfind(os.sep)+1:]])
+ self.link_task.dep_nodes.extend(y.link_task.outputs)
+ tmp_path=y.link_task.outputs[0].parent.path_from(self.get_cwd())
+ self.env.append_unique(var+'PATH',[tmp_path])
+ else:
+ if y.tmp_use_objects:
+ self.add_objects_from_tgen(y)
+ if getattr(y,'export_includes',None):
+ self.includes=self.includes+y.to_incnodes(y.export_includes)
+ if getattr(y,'export_defines',None):
+ self.env.append_value('DEFINES',self.to_list(y.export_defines))
+ for x in names:
+ try:
+ y=self.bld.get_tgen_by_name(x)
+ except Errors.WafError:
+ if not self.env['STLIB_'+x]and not x in self.uselib:
+ self.uselib.append(x)
+ else:
+ for k in self.to_list(getattr(y,'use',[])):
+ if not self.env['STLIB_'+k]and not k in self.uselib:
+ self.uselib.append(k)
+@taskgen_method
+def accept_node_to_link(self,node):
+ return not node.name.endswith('.pdb')
+@taskgen_method
+def add_objects_from_tgen(self,tg):
+ try:
+ link_task=self.link_task
+ except AttributeError:
+ pass
+ else:
+ for tsk in getattr(tg,'compiled_tasks',[]):
+ for x in tsk.outputs:
+ if self.accept_node_to_link(x):
+ link_task.inputs.append(x)
+@taskgen_method
+def get_uselib_vars(self):
+ _vars=set()
+ for x in self.features:
+ if x in USELIB_VARS:
+ _vars|=USELIB_VARS[x]
+ return _vars
+@feature('c','cxx','d','fc','javac','cs','uselib','asm')
+@after_method('process_use')
+def propagate_uselib_vars(self):
+ _vars=self.get_uselib_vars()
+ env=self.env
+ app=env.append_value
+ feature_uselib=self.features+self.to_list(getattr(self,'uselib',[]))
+ for var in _vars:
+ y=var.lower()
+ val=getattr(self,y,[])
+ if val:
+ app(var,self.to_list(val))
+ for x in feature_uselib:
+ val=env['%s_%s'%(var,x)]
+ if val:
+ app(var,val)
+@feature('cshlib','cxxshlib','fcshlib')
+@after_method('apply_link')
+def apply_implib(self):
+ if not self.env.DEST_BINFMT=='pe':
+ return
+ dll=self.link_task.outputs[0]
+ if isinstance(self.target,Node.Node):
+ name=self.target.name
+ else:
+ name=os.path.split(self.target)[1]
+ implib=self.env.implib_PATTERN%name
+ implib=dll.parent.find_or_declare(implib)
+ self.env.append_value('LINKFLAGS',self.env.IMPLIB_ST%implib.bldpath())
+ self.link_task.outputs.append(implib)
+ if getattr(self,'defs',None)and self.env.DEST_BINFMT=='pe':
+ node=self.path.find_resource(self.defs)
+ if not node:
+ raise Errors.WafError('invalid def file %r'%self.defs)
+ if self.env.def_PATTERN:
+ self.env.append_value('LINKFLAGS',self.env.def_PATTERN%node.path_from(self.get_cwd()))
+ self.link_task.dep_nodes.append(node)
+ else:
+ self.link_task.inputs.append(node)
+ if getattr(self,'install_task',None):
+ try:
+ inst_to=self.install_path_implib
+ except AttributeError:
+ try:
+ inst_to=self.install_path
+ except AttributeError:
+ inst_to='${IMPLIBDIR}'
+ self.install_task.install_to='${BINDIR}'
+ if not self.env.IMPLIBDIR:
+ self.env.IMPLIBDIR=self.env.LIBDIR
+ self.implib_install_task=self.add_install_files(install_to=inst_to,install_from=implib,chmod=self.link_task.chmod,task=self.link_task)
+re_vnum=re.compile('^([1-9]\\d*|0)([.]([1-9]\\d*|0)){0,2}?$')
+@feature('cshlib','cxxshlib','dshlib','fcshlib','vnum')
+@after_method('apply_link','propagate_uselib_vars')
+def apply_vnum(self):
+ if not getattr(self,'vnum','')or os.name!='posix'or self.env.DEST_BINFMT not in('elf','mac-o'):
+ return
+ link=self.link_task
+ if not re_vnum.match(self.vnum):
+ raise Errors.WafError('Invalid vnum %r for target %r'%(self.vnum,getattr(self,'name',self)))
+ nums=self.vnum.split('.')
+ node=link.outputs[0]
+ cnum=getattr(self,'cnum',str(nums[0]))
+ cnums=cnum.split('.')
+ if len(cnums)>len(nums)or nums[0:len(cnums)]!=cnums:
+ raise Errors.WafError('invalid compatibility version %s'%cnum)
+ libname=node.name
+ if libname.endswith('.dylib'):
+ name3=libname.replace('.dylib','.%s.dylib'%self.vnum)
+ name2=libname.replace('.dylib','.%s.dylib'%cnum)
+ else:
+ name3=libname+'.'+self.vnum
+ name2=libname+'.'+cnum
+ if self.env.SONAME_ST:
+ v=self.env.SONAME_ST%name2
+ self.env.append_value('LINKFLAGS',v.split())
+ if self.env.DEST_OS!='openbsd':
+ outs=[node.parent.make_node(name3)]
+ if name2!=name3:
+ outs.append(node.parent.make_node(name2))
+ self.create_task('vnum',node,outs)
+ if getattr(self,'install_task',None):
+ self.install_task.hasrun=Task.SKIPPED
+ path=self.install_task.install_to
+ if self.env.DEST_OS=='openbsd':
+ libname=self.link_task.outputs[0].name
+ t1=self.add_install_as(install_to='%s/%s'%(path,libname),install_from=node,chmod=self.link_task.chmod)
+ self.vnum_install_task=(t1,)
+ else:
+ t1=self.add_install_as(install_to=path+os.sep+name3,install_from=node,chmod=self.link_task.chmod)
+ t3=self.add_symlink_as(install_to=path+os.sep+libname,install_from=name3)
+ if name2!=name3:
+ t2=self.add_symlink_as(install_to=path+os.sep+name2,install_from=name3)
+ self.vnum_install_task=(t1,t2,t3)
+ else:
+ self.vnum_install_task=(t1,t3)
+ if'-dynamiclib'in self.env.LINKFLAGS:
+ try:
+ inst_to=self.install_path
+ except AttributeError:
+ inst_to=self.link_task.inst_to
+ if inst_to:
+ p=Utils.subst_vars(inst_to,self.env)
+ path=os.path.join(p,name2)
+ self.env.append_value('LINKFLAGS',['-install_name',path])
+ self.env.append_value('LINKFLAGS','-Wl,-compatibility_version,%s'%cnum)
+ self.env.append_value('LINKFLAGS','-Wl,-current_version,%s'%self.vnum)
+class vnum(Task.Task):
+ color='CYAN'
+ ext_in=['.bin']
+ def keyword(self):
+ return'Symlinking'
+ def run(self):
+ for x in self.outputs:
+ path=x.abspath()
+ try:
+ os.remove(path)
+ except OSError:
+ pass
+ try:
+ os.symlink(self.inputs[0].name,path)
+ except OSError:
+ return 1
+class fake_shlib(link_task):
+ def runnable_status(self):
+ for t in self.run_after:
+ if not t.hasrun:
+ return Task.ASK_LATER
+ return Task.SKIP_ME
+class fake_stlib(stlink_task):
+ def runnable_status(self):
+ for t in self.run_after:
+ if not t.hasrun:
+ return Task.ASK_LATER
+ return Task.SKIP_ME
+@conf
+def read_shlib(self,name,paths=[],export_includes=[],export_defines=[]):
+ return self(name=name,features='fake_lib',lib_paths=paths,lib_type='shlib',export_includes=export_includes,export_defines=export_defines)
+@conf
+def read_stlib(self,name,paths=[],export_includes=[],export_defines=[]):
+ return self(name=name,features='fake_lib',lib_paths=paths,lib_type='stlib',export_includes=export_includes,export_defines=export_defines)
+lib_patterns={'shlib':['lib%s.so','%s.so','lib%s.dylib','lib%s.dll','%s.dll'],'stlib':['lib%s.a','%s.a','lib%s.dll','%s.dll','lib%s.lib','%s.lib'],}
+@feature('fake_lib')
+def process_lib(self):
+ node=None
+ names=[x%self.name for x in lib_patterns[self.lib_type]]
+ for x in self.lib_paths+[self.path]+SYSTEM_LIB_PATHS:
+ if not isinstance(x,Node.Node):
+ x=self.bld.root.find_node(x)or self.path.find_node(x)
+ if not x:
+ continue
+ for y in names:
+ node=x.find_node(y)
+ if node:
+ try:
+ Utils.h_file(node.abspath())
+ except EnvironmentError:
+ raise ValueError('Could not read %r'%y)
+ break
+ else:
+ continue
+ break
+ else:
+ raise Errors.WafError('could not find library %r'%self.name)
+ self.link_task=self.create_task('fake_%s'%self.lib_type,[],[node])
+ self.target=self.name
+class fake_o(Task.Task):
+ def runnable_status(self):
+ return Task.SKIP_ME
+@extension('.o','.obj')
+def add_those_o_files(self,node):
+ tsk=self.create_task('fake_o',[],node)
+ try:
+ self.compiled_tasks.append(tsk)
+ except AttributeError:
+ self.compiled_tasks=[tsk]
+@feature('fake_obj')
+@before_method('process_source')
+def process_objs(self):
+ for node in self.to_nodes(self.source):
+ self.add_those_o_files(node)
+ self.source=[]
+@conf
+def read_object(self,obj):
+ if not isinstance(obj,self.path.__class__):
+ obj=self.path.find_resource(obj)
+ return self(features='fake_obj',source=obj,name=obj.name)
+@feature('cxxprogram','cprogram')
+@after_method('apply_link','process_use')
+def set_full_paths_hpux(self):
+ if self.env.DEST_OS!='hp-ux':
+ return
+ base=self.bld.bldnode.abspath()
+ for var in['LIBPATH','STLIBPATH']:
+ lst=[]
+ for x in self.env[var]:
+ if x.startswith('/'):
+ lst.append(x)
+ else:
+ lst.append(os.path.normpath(os.path.join(base,x)))
+ self.env[var]=lst