PageRenderTime 52ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/guitarix-0.23.2/wafadmin/Tools/d.py

#
Python | 368 lines | 366 code | 0 blank | 2 comment | 1 complexity | b3a7595f31e2bafdfa1791ea6f1d3948 MD5 | raw file
Possible License(s): GPL-3.0
  1. #! /usr/bin/env python
  2. # encoding: utf-8
  3. import sys
  4. if sys.hexversion < 0x020400f0: from sets import Set as set
  5. import os,sys,re,optparse
  6. import ccroot
  7. import TaskGen,Utils,Task,Configure,Logs,Build
  8. from Logs import debug,error
  9. from TaskGen import taskgen,feature,after,before,extension
  10. from Configure import conftest
  11. EXT_D=['.d','.di','.D']
  12. D_METHS=['apply_core','apply_vnum','apply_objdeps']
  13. DLIB="""
  14. version(D_Version2) {
  15. import std.stdio;
  16. int main() {
  17. writefln("phobos2");
  18. return 0;
  19. }
  20. } else {
  21. version(Tango) {
  22. import tango.stdc.stdio;
  23. int main() {
  24. printf("tango");
  25. return 0;
  26. }
  27. } else {
  28. import std.stdio;
  29. int main() {
  30. writefln("phobos1");
  31. return 0;
  32. }
  33. }
  34. }
  35. """
  36. def filter_comments(filename):
  37. txt=Utils.readf(filename)
  38. i=0
  39. buf=[]
  40. max=len(txt)
  41. begin=0
  42. while i<max:
  43. c=txt[i]
  44. if c=='"'or c=="'":
  45. buf.append(txt[begin:i])
  46. delim=c
  47. i+=1
  48. while i<max:
  49. c=txt[i]
  50. if c==delim:break
  51. elif c=='\\':
  52. i+=1
  53. i+=1
  54. i+=1
  55. begin=i
  56. elif c=='/':
  57. buf.append(txt[begin:i])
  58. i+=1
  59. if i==max:break
  60. c=txt[i]
  61. if c=='+':
  62. i+=1
  63. nesting=1
  64. c=None
  65. while i<max:
  66. prev=c
  67. c=txt[i]
  68. if prev=='/'and c=='+':
  69. nesting+=1
  70. c=None
  71. elif prev=='+'and c=='/':
  72. nesting-=1
  73. if nesting==0:break
  74. c=None
  75. i+=1
  76. elif c=='*':
  77. i+=1
  78. c=None
  79. while i<max:
  80. prev=c
  81. c=txt[i]
  82. if prev=='*'and c=='/':break
  83. i+=1
  84. elif c=='/':
  85. i+=1
  86. while i<max and txt[i]!='\n':
  87. i+=1
  88. else:
  89. begin=i-1
  90. continue
  91. i+=1
  92. begin=i
  93. buf.append(' ')
  94. else:
  95. i+=1
  96. buf.append(txt[begin:])
  97. return buf
  98. class d_parser(object):
  99. def __init__(self,env,incpaths):
  100. self.allnames=[]
  101. self.re_module=re.compile("module\s+([^;]+)")
  102. self.re_import=re.compile("import\s+([^;]+)")
  103. self.re_import_bindings=re.compile("([^:]+):(.*)")
  104. self.re_import_alias=re.compile("[^=]+=(.+)")
  105. self.env=env
  106. self.nodes=[]
  107. self.names=[]
  108. self.incpaths=incpaths
  109. def tryfind(self,filename):
  110. found=0
  111. for n in self.incpaths:
  112. found=n.find_resource(filename.replace('.','/')+'.d')
  113. if found:
  114. self.nodes.append(found)
  115. self.waiting.append(found)
  116. break
  117. if not found:
  118. if not filename in self.names:
  119. self.names.append(filename)
  120. def get_strings(self,code):
  121. self.module=''
  122. lst=[]
  123. mod_name=self.re_module.search(code)
  124. if mod_name:
  125. self.module=re.sub('\s+','',mod_name.group(1))
  126. import_iterator=self.re_import.finditer(code)
  127. if import_iterator:
  128. for import_match in import_iterator:
  129. import_match_str=re.sub('\s+','',import_match.group(1))
  130. bindings_match=self.re_import_bindings.match(import_match_str)
  131. if bindings_match:
  132. import_match_str=bindings_match.group(1)
  133. matches=import_match_str.split(',')
  134. for match in matches:
  135. alias_match=self.re_import_alias.match(match)
  136. if alias_match:
  137. match=alias_match.group(1)
  138. lst.append(match)
  139. return lst
  140. def start(self,node):
  141. self.waiting=[node]
  142. while self.waiting:
  143. nd=self.waiting.pop(0)
  144. self.iter(nd)
  145. def iter(self,node):
  146. path=node.abspath(self.env)
  147. code="".join(filter_comments(path))
  148. names=self.get_strings(code)
  149. for x in names:
  150. if x in self.allnames:continue
  151. self.allnames.append(x)
  152. self.tryfind(x)
  153. def scan(self):
  154. env=self.env
  155. gruik=d_parser(env,env['INC_PATHS'])
  156. gruik.start(self.inputs[0])
  157. if Logs.verbose:
  158. debug('deps: nodes found for %s: %s %s'%(str(self.inputs[0]),str(gruik.nodes),str(gruik.names)))
  159. return(gruik.nodes,gruik.names)
  160. def get_target_name(self):
  161. v=self.env
  162. tp='program'
  163. for x in self.features:
  164. if x in['dshlib','dstaticlib']:
  165. tp=x.lstrip('d')
  166. return v['D_%s_PATTERN'%tp]%self.target
  167. d_params={'dflags':'','importpaths':'','libs':'','libpaths':'','generate_headers':False,}
  168. def init_d(self):
  169. for x in d_params:
  170. setattr(self,x,getattr(self,x,d_params[x]))
  171. class d_taskgen(TaskGen.task_gen):
  172. def __init__(self,*k,**kw):
  173. TaskGen.task_gen.__init__(self,*k,**kw)
  174. if len(k)>1:
  175. self.features.append('d'+k[1])
  176. TaskGen.bind_feature('d',D_METHS)
  177. def init_d(self):
  178. Utils.def_attrs(self,dflags='',importpaths='',libs='',libpaths='',uselib='',uselib_local='',generate_headers=False,compiled_tasks=[],add_objects=[],link_task=None)
  179. def apply_d_libs(self):
  180. env=self.env
  181. self.uselib=self.to_list(self.uselib)
  182. names=self.to_list(self.uselib_local)
  183. seen=set([])
  184. tmp=Utils.deque(names)
  185. while tmp:
  186. lib_name=tmp.popleft()
  187. if lib_name in seen:
  188. continue
  189. y=self.name_to_obj(lib_name)
  190. if not y:
  191. raise Utils.WafError('object %r was not found in uselib_local (required by %r)'%(lib_name,self.name))
  192. y.post()
  193. seen.add(lib_name)
  194. if getattr(y,'uselib_local',None):
  195. lst=y.to_list(y.uselib_local)
  196. if'dshlib'in y.features or'dprogram'in y.features:
  197. lst=[x for x in lst if not'dstaticlib'in self.name_to_obj(x).features]
  198. tmp.extend(lst)
  199. if getattr(y,'link_task',None):
  200. link_name=y.target[y.target.rfind(os.sep)+1:]
  201. if'dstaticlib'in y.features or'dshlib'in y.features:
  202. env.append_unique('DLINKFLAGS',env.DLIB_ST%link_name)
  203. env.append_unique('DLINKFLAGS',env.DLIBPATH_ST%y.link_task.outputs[0].parent.bldpath(env))
  204. self.link_task.set_run_after(y.link_task)
  205. dep_nodes=getattr(self.link_task,'dep_nodes',[])
  206. self.link_task.dep_nodes=dep_nodes+y.link_task.outputs
  207. for v in self.to_list(y.uselib):
  208. if not v in self.uselib:
  209. self.uselib.insert(0,v)
  210. if getattr(y,'export_incdirs',None):
  211. for x in self.to_list(y.export_incdirs):
  212. node=y.path.find_dir(x)
  213. if not node:
  214. raise Utils.WafError('object %r: invalid folder %r in export_incdirs'%(y.target,x))
  215. self.env.append_unique('INC_PATHS',node)
  216. def apply_d_link(self):
  217. link=getattr(self,'link',None)
  218. if not link:
  219. if'dstaticlib'in self.features:link='static_link'
  220. else:link='d_link'
  221. outputs=[t.outputs[0]for t in self.compiled_tasks]
  222. self.link_task=self.create_task(link,outputs,self.path.find_or_declare(get_target_name(self)))
  223. def apply_d_vars(self):
  224. env=self.env
  225. dpath_st=env['DPATH_ST']
  226. lib_st=env['DLIB_ST']
  227. libpath_st=env['DLIBPATH_ST']
  228. importpaths=self.to_list(self.importpaths)
  229. libpaths=[]
  230. libs=[]
  231. uselib=self.to_list(self.uselib)
  232. for i in uselib:
  233. if env['DFLAGS_'+i]:
  234. env.append_unique('DFLAGS',env['DFLAGS_'+i])
  235. for x in self.features:
  236. if not x in['dprogram','dstaticlib','dshlib']:
  237. continue
  238. x.lstrip('d')
  239. d_shlib_dflags=env['D_'+x+'_DFLAGS']
  240. if d_shlib_dflags:
  241. env.append_unique('DFLAGS',d_shlib_dflags)
  242. for i in uselib:
  243. if env['DPATH_'+i]:
  244. for entry in self.to_list(env['DPATH_'+i]):
  245. if not entry in importpaths:
  246. importpaths.append(entry)
  247. for path in importpaths:
  248. if os.path.isabs(path):
  249. env.append_unique('_DIMPORTFLAGS',dpath_st%path)
  250. else:
  251. node=self.path.find_dir(path)
  252. self.env.append_unique('INC_PATHS',node)
  253. env.append_unique('_DIMPORTFLAGS',dpath_st%node.srcpath(env))
  254. env.append_unique('_DIMPORTFLAGS',dpath_st%node.bldpath(env))
  255. for i in uselib:
  256. if env['LIBPATH_'+i]:
  257. for entry in self.to_list(env['LIBPATH_'+i]):
  258. if not entry in libpaths:
  259. libpaths.append(entry)
  260. libpaths=self.to_list(self.libpaths)+libpaths
  261. for path in libpaths:
  262. if not os.path.isabs(path):
  263. node=self.path.find_resource(path)
  264. if not node:
  265. raise Utils.WafError('could not find libpath %r from %r'%(path,self))
  266. path=node.abspath(self.env)
  267. env.append_unique('DLINKFLAGS',libpath_st%path)
  268. for i in uselib:
  269. if env['LIB_'+i]:
  270. for entry in self.to_list(env['LIB_'+i]):
  271. if not entry in libs:
  272. libs.append(entry)
  273. libs.extend(self.to_list(self.libs))
  274. for flag in self.to_list(self.dflags):
  275. env.append_unique('DFLAGS',flag)
  276. for lib in libs:
  277. env.append_unique('DLINKFLAGS',lib_st%lib)
  278. for i in uselib:
  279. dlinkflags=env['DLINKFLAGS_'+i]
  280. if dlinkflags:
  281. for linkflag in dlinkflags:
  282. env.append_unique('DLINKFLAGS',linkflag)
  283. def add_shlib_d_flags(self):
  284. for linkflag in self.env['D_shlib_LINKFLAGS']:
  285. self.env.append_unique('DLINKFLAGS',linkflag)
  286. def d_hook(self,node):
  287. task=self.create_task(self.generate_headers and'd_with_header'or'd')
  288. try:obj_ext=self.obj_ext
  289. except AttributeError:obj_ext='_%d.o'%self.idx
  290. task.inputs=[node]
  291. task.outputs=[node.change_ext(obj_ext)]
  292. self.compiled_tasks.append(task)
  293. if self.generate_headers:
  294. header_node=node.change_ext(self.env['DHEADER_ext'])
  295. task.outputs+=[header_node]
  296. d_str='${D_COMPILER} ${DFLAGS} ${_DIMPORTFLAGS} ${D_SRC_F}${SRC} ${D_TGT_F}${TGT}'
  297. d_with_header_str='${D_COMPILER} ${DFLAGS} ${_DIMPORTFLAGS} \
  298. ${D_HDR_F}${TGT[1].bldpath(env)} \
  299. ${D_SRC_F}${SRC} \
  300. ${D_TGT_F}${TGT[0].bldpath(env)}'
  301. link_str='${D_LINKER} ${DLNK_SRC_F}${SRC} ${DLNK_TGT_F}${TGT} ${DLINKFLAGS}'
  302. def override_exec(cls):
  303. old_exec=cls.exec_command
  304. def exec_command(self,*k,**kw):
  305. if isinstance(k[0],list):
  306. lst=k[0]
  307. for i in xrange(len(lst)):
  308. if lst[i]=='-of':
  309. del lst[i]
  310. lst[i]='-of'+lst[i]
  311. break
  312. return old_exec(self,*k,**kw)
  313. cls.exec_command=exec_command
  314. cls=Task.simple_task_type('d',d_str,'GREEN',before='static_link d_link',shell=False)
  315. cls.scan=scan
  316. override_exec(cls)
  317. cls=Task.simple_task_type('d_with_header',d_with_header_str,'GREEN',before='static_link d_link',shell=False)
  318. override_exec(cls)
  319. cls=Task.simple_task_type('d_link',link_str,color='YELLOW',shell=False)
  320. override_exec(cls)
  321. def generate_header(self,filename,install_path):
  322. if not hasattr(self,'header_lst'):self.header_lst=[]
  323. self.meths.append('process_header')
  324. self.header_lst.append([filename,install_path])
  325. def process_header(self):
  326. env=self.env
  327. for i in getattr(self,'header_lst',[]):
  328. node=self.path.find_resource(i[0])
  329. if not node:
  330. raise Utils.WafError('file not found on d obj '+i[0])
  331. task=self.create_task('d_header')
  332. task.set_inputs(node)
  333. task.set_outputs(node.change_ext('.di'))
  334. d_header_str='${D_COMPILER} ${D_HEADER} ${SRC}'
  335. Task.simple_task_type('d_header',d_header_str,color='BLUE',shell=False)
  336. def d_platform_flags(conf):
  337. v=conf.env
  338. binfmt=v.DEST_BINFMT or Utils.unversioned_sys_platform_to_binary_format(v.DEST_OS or Utils.unversioned_sys_platform())
  339. if binfmt=='pe':
  340. v['D_program_PATTERN']='%s.exe'
  341. v['D_shlib_PATTERN']='lib%s.dll'
  342. v['D_staticlib_PATTERN']='lib%s.a'
  343. else:
  344. v['D_program_PATTERN']='%s'
  345. v['D_shlib_PATTERN']='lib%s.so'
  346. v['D_staticlib_PATTERN']='lib%s.a'
  347. def check_dlibrary(conf):
  348. ret=conf.check_cc(features='d dprogram',fragment=DLIB,mandatory=True,compile_filename='test.d',execute=True)
  349. conf.env.DLIBRARY=ret.strip()
  350. feature('d')(init_d)
  351. before('apply_type_vars')(init_d)
  352. feature('d')(init_d)
  353. before('apply_d_libs')(init_d)
  354. feature('d')(apply_d_libs)
  355. after('apply_d_link','init_d')(apply_d_libs)
  356. before('apply_vnum','apply_d_vars')(apply_d_libs)
  357. feature('dprogram','dshlib','dstaticlib')(apply_d_link)
  358. after('apply_core')(apply_d_link)
  359. feature('d')(apply_d_vars)
  360. after('apply_core')(apply_d_vars)
  361. feature('dshlib')(add_shlib_d_flags)
  362. after('apply_d_vars')(add_shlib_d_flags)
  363. extension(EXT_D)(d_hook)
  364. taskgen(generate_header)
  365. before('apply_core')(process_header)
  366. conftest(d_platform_flags)
  367. conftest(check_dlibrary)