5
import TaskGen,Utils,Task,Build
7
from TaskGen import taskgen,feature,before,after,extension
13
open_re=re.compile('open ([a-zA-Z]+);;',re.M)
14
foo=re.compile(r"""(\(\*)|(\*\))|("(\\.|[^"\\])*"|'(\\.|[^'\\])*'|.[^()*"'\\]*)""",re.M)
15
def filter_comments(txt):
18
if m.group(1):meh[0]+=1
19
elif m.group(2):meh[0]-=1
20
elif not meh[0]:return m.group(0)
22
return foo.sub(repl,txt)
25
code=filter_comments(node.read(self.env))
28
import_iterator=open_re.finditer(code)
30
for import_match in import_iterator:
31
names.append(import_match.group(1))
36
for x in self.incpaths:
37
nd=x.find_resource(name.lower()+'.ml')
43
return(found_lst,raw_lst)
44
native_lst=['native','all','c_object']
45
bytecode_lst=['bytecode','all']
46
class ocaml_taskgen(TaskGen.task_gen):
47
def __init__(self,*k,**kw):
48
TaskGen.task_gen.__init__(self,*k,**kw)
51
self._bld_incpaths_lst=[]
56
self.bytecode_tasks=[]
58
self.bytecode_env=None
60
self.compiled_tasks=[]
65
if not self.type in['bytecode','native','all','c_object']:
66
print'type for camlobj is undefined '+self.type
68
TaskGen.bind_feature('ocaml','apply_core')
69
def init_envs_ml(self):
70
self.islibrary=getattr(self,'islibrary',False)
71
global native_lst,bytecode_lst
73
if self.type in native_lst:
74
self.native_env=self.env.copy()
75
if self.islibrary:self.native_env['OCALINKFLAGS']='-a'
76
self.bytecode_env=None
77
if self.type in bytecode_lst:
78
self.bytecode_env=self.env.copy()
79
if self.islibrary:self.bytecode_env['OCALINKFLAGS']='-a'
80
if self.type=='c_object':
81
self.native_env['OCALINK']=self.native_env['OCALINK']+' -output-obj'
82
def apply_incpaths_ml(self):
83
inc_lst=self.includes.split()
84
lst=self._incpaths_lst
87
node=self.path.find_dir(dir)
89
error("node not found: "+str(dir))
91
Build.bld.rescan(node)
92
if not node in lst:lst.append(node)
93
self._bld_incpaths_lst.append(node)
94
def apply_vars_ml(self):
95
for i in self._incpaths_lst:
97
self.bytecode_env.append_value('OCAMLPATH','-I %s'%i.srcpath(self.env))
98
self.bytecode_env.append_value('OCAMLPATH','-I %s'%i.bldpath(self.env))
100
self.native_env.append_value('OCAMLPATH','-I %s'%i.bldpath(self.env))
101
self.native_env.append_value('OCAMLPATH','-I %s'%i.srcpath(self.env))
102
varnames=['INCLUDES','OCAMLFLAGS','OCALINKFLAGS','OCALINKFLAGS_OPT']
103
for name in self.uselib.split():
104
for vname in varnames:
105
cnt=self.env[vname+'_'+name]
107
if self.bytecode_env:self.bytecode_env.append_value(vname,cnt)
108
if self.native_env:self.native_env.append_value(vname,cnt)
109
def apply_link_ml(self):
110
if self.bytecode_env:
111
ext=self.islibrary and'.cma'or'.run'
112
linktask=self.create_task('ocalink')
114
linktask.set_outputs(self.path.find_or_declare(self.target+ext))
116
linktask.env=self.bytecode_env
117
self.linktasks.append(linktask)
119
if getattr(self,'c_objects',''):ext='.o'
120
elif self.islibrary:ext='.cmxa'
122
linktask=self.create_task('ocalinkx')
123
linktask.set_outputs(self.path.find_or_declare(self.target+ext))
125
linktask.env=self.native_env
126
self.linktasks.append(linktask)
127
self.out_nodes+=linktask.outputs
128
if self.type=='c_object':self.compiled_tasks.append(linktask)
129
def mll_hook(self,node):
130
mll_task=self.create_task('ocamllex',self.native_env)
131
mll_task.set_inputs(node)
132
mll_task.set_outputs(node.change_ext('.ml'))
133
self.mlltasks.append(mll_task)
134
self.allnodes.append(mll_task.outputs[0])
135
def mly_hook(self,node):
136
mly_task=self.create_task('ocamlyacc',self.native_env)
137
mly_task.set_inputs(node)
138
mly_task.set_outputs([node.change_ext('.ml'),node.change_ext('.mli')])
139
self._mlytasks.append(mly_task)
140
self.allnodes.append(mly_task.outputs[0])
141
task=self.create_task('ocamlcmi',self.native_env)
142
task.set_inputs(mly_task.outputs[1])
143
task.set_outputs(mly_task.outputs[1].change_ext('.cmi'))
144
def mli_hook(self,node):
145
task=self.create_task('ocamlcmi',self.native_env)
146
task.set_inputs(node)
147
task.set_outputs(node.change_ext('.cmi'))
148
self.mlitasks.append(task)
149
def mlc_hook(self,node):
150
task=self.create_task('ocamlcc',self.native_env)
151
task.set_inputs(node)
152
task.set_outputs(node.change_ext('.o'))
153
self.out_nodes+=task.outputs
154
def ml_hook(self,node):
156
task=self.create_task('ocamlx',self.native_env)
157
task.set_inputs(node)
158
task.set_outputs(node.change_ext('.cmx'))
160
task.incpaths=self._bld_incpaths_lst
161
self.native_tasks.append(task)
162
if self.bytecode_env:
163
task=self.create_task('ocaml',self.bytecode_env)
164
task.set_inputs(node)
167
task.incpaths=self._bld_incpaths_lst
168
task.set_outputs(node.change_ext('.cmo'))
169
self.bytecode_tasks.append(task)
170
def compile_may_start(self):
171
if not getattr(self.obj,'flag_deps',''):
173
if getattr(self,'bytecode',''):alltasks=self.obj.bytecode_tasks
174
else:alltasks=self.obj.native_tasks
178
for node in self.inputs:
179
lst=tree.node_deps[self.unique_id()]
183
if depnode in t.inputs:
184
self.set_run_after(t)
185
delattr(self,'sign_all')
187
return Task.Task.runnable_status(self)
188
b=Task.simple_task_type
189
cls=b('ocamlx','${OCAMLOPT} ${OCAMLPATH} ${OCAMLFLAGS} ${INCLUDES} -c -o ${TGT} ${SRC}',color='GREEN')
190
cls.runnable_status=compile_may_start
192
b=Task.simple_task_type
193
cls=b('ocaml','${OCAMLC} ${OCAMLPATH} ${OCAMLFLAGS} ${INCLUDES} -c -o ${TGT} ${SRC}',color='GREEN')
194
cls.runnable_status=compile_may_start
196
b('ocamlcmi','${OCAMLC} ${OCAMLPATH} ${INCLUDES} -o ${TGT} -c ${SRC}',color='BLUE',before="ocaml ocamlcc")
197
b('ocamlcc','cd ${TGT[0].bld_dir(env)} && ${OCAMLOPT} ${OCAMLFLAGS} ${OCAMLPATH} ${INCLUDES} -c ${SRC[0].abspath(env)}',color='GREEN')
198
b('ocamllex','${OCAMLLEX} ${SRC} -o ${TGT}',color='BLUE',before="ocamlcmi ocaml ocamlcc")
199
b('ocamlyacc','${OCAMLYACC} -b ${TGT[0].bld_base(env)} ${SRC}',color='BLUE',before="ocamlcmi ocaml ocamlcc")
200
def link_may_start(self):
201
if not getattr(self,'order',''):
202
if getattr(self,'bytecode',0):alltasks=self.obj.bytecode_tasks
203
else:alltasks=self.obj.native_tasks
208
if task in seen:continue
209
for x in task.run_after:
215
self.inputs=[x.outputs[0]for x in seen]
217
return Task.Task.runnable_status(self)
218
act=b('ocalink','${OCAMLC} -o ${TGT} ${INCLUDES} ${OCALINKFLAGS} ${SRC}',color='YELLOW',after="ocaml ocamlcc")
219
act.runnable_status=link_may_start
220
act=b('ocalinkx','${OCAMLOPT} -o ${TGT} ${INCLUDES} ${OCALINKFLAGS_OPT} ${SRC}',color='YELLOW',after="ocamlx ocamlcc")
221
act.runnable_status=link_may_start
223
opt=conf.find_program('ocamlopt',var='OCAMLOPT')
224
occ=conf.find_program('ocamlc',var='OCAMLC')
225
if(not opt)or(not occ):
226
conf.fatal('The objective caml compiler was not found:\ninstall it or make it available in your PATH')
227
conf.env['OCAMLC']=occ
228
conf.env['OCAMLOPT']=opt
229
conf.env['OCAMLLEX']=conf.find_program('ocamllex',var='OCAMLLEX')
230
conf.env['OCAMLYACC']=conf.find_program('ocamlyacc',var='OCAMLYACC')
231
conf.env['OCAMLFLAGS']=''
232
conf.env['OCAMLLIB']=Utils.cmd_output(conf.env['OCAMLC']+' -where').strip()+os.sep
233
conf.env['LIBPATH_OCAML']=Utils.cmd_output(conf.env['OCAMLC']+' -where').strip()+os.sep
234
conf.env['CPPPATH_OCAML']=Utils.cmd_output(conf.env['OCAMLC']+' -where').strip()+os.sep
235
conf.env['LIB_OCAML']='camlrun'
237
taskgen(init_envs_ml)
238
feature('ocaml')(init_envs_ml)
239
taskgen(apply_incpaths_ml)
240
feature('ocaml')(apply_incpaths_ml)
241
before('apply_vars_ml')(apply_incpaths_ml)
242
after('init_envs_ml')(apply_incpaths_ml)
243
taskgen(apply_vars_ml)
244
feature('ocaml')(apply_vars_ml)
245
before('apply_core')(apply_vars_ml)
246
taskgen(apply_link_ml)
247
feature('ocaml')(apply_link_ml)
248
after('apply_core')(apply_link_ml)
249
extension(EXT_MLL)(mll_hook)
250
extension(EXT_MLY)(mly_hook)
251
extension(EXT_MLI)(mli_hook)
252
extension(EXT_MLC)(mlc_hook)
253
extension(EXT_ML)(ml_hook)