1
2
3
4
5 "base for all c/c++ programs and libraries"
6
7 import os, sys, re
8 import TaskGen, Utils, preproc, Logs, Build, Options
9 from Logs import error, debug, warn
10 from Utils import md5
11 from TaskGen import taskgen, after, before, feature
12 from Constants import *
13
14 import config_c
15
16 get_version_re = re.compile('\d+\.\d+(\.?\d+)*')
18 v = conf.env
19 output = Utils.cmd_output('%s -dumpversion' % cc)
20 if output:
21 match = get_version_re.search(output)
22 if match:
23 v[version_var] = match.group(0)
24 conf.check_message('compiler', 'version', 1, v[version_var])
25 return v[version_var]
26 warn('could not determine the compiler version')
27
36
38 "look for .h the .cpp need"
39 debug('ccroot: _scan_preprocessor(self, node, env, path_lst)')
40 all_nodes = []
41 all_names = []
42 seen = []
43 for node in self.inputs:
44 gruik = preproc.c_parser(nodepaths = self.env['INC_PATHS'], defines = self.defines)
45 gruik.start(node, self.env)
46 if Logs.verbose:
47 debug('deps: nodes found for %s: %s %s' % (str(node), str(gruik.nodes), str(gruik.names)))
48 debug('deps: deps found for %s: %s' % (str(node), str(gruik.deps)))
49 for x in gruik.nodes:
50 if id(x) in seen: continue
51 seen.append(id(x))
52 all_nodes.append(x)
53 for x in gruik.names:
54 if not x in all_names:
55 all_names.append(x)
56 return (all_nodes, gruik.names)
57
59 "Parent class for programs and libraries in languages c, c++ and moc (Qt)"
61 TaskGen.task_gen.__init__(self, *k)
62
63
64 if len(k)>1: self.type = k[1]
65 else: self.type = ''
66 if self.type:
67 self.features.append('c' + self.type)
68
69
70 self.includes=''
71
72 self.defines = ''
73 self.rpaths = ''
74
75 self.uselib = ''
76
77
78
79 self.uselib_local=''
80
81
82 self.add_objects = ''
83
84
85
86
87
88
89
90
91 self.p_flag_vars = []
92 self.p_type_vars = []
93
94
95
96 self.scanner_defines = {}
97
98 self.compiled_tasks = []
99 self.link_task = None
100
101
102
103
112
114 name = self.target
115 pattern = self.env[self.type+'_PATTERN']
116 if not pattern: pattern = '%s'
117
118
119 k = name.rfind('/')
120 return name[0:k+1] + pattern % name[k+1:]
121
124 if not 'objects' in self.features:
125 if not self.source:
126 raise Utils.WafError('no source files specified for %s' % self)
127 if not self.target:
128 raise Utils.WafError('no target for %s' % self)
129
131 nums = self.vnum.split('.')
132
133 path = self.install_path
134 libname = self.outputs[0].name
135
136 name3 = libname+'.'+self.vnum
137 name2 = libname+'.'+nums[0]
138 name1 = libname
139
140 filename = self.outputs[0].abspath(self.env)
141 bld = Build.bld
142 bld.install_as(os.path.join(path, name3), filename, env=self.env)
143 bld.symlink_as(os.path.join(path, name2), name3)
144 bld.symlink_as(os.path.join(path, name1), name3)
145
146
147
148 @taskgen
149 @feature('cprogram', 'dprogram')
150 @before('apply_core')
151 -def vars_target_cprogram(self):
152 self.default_install_path = '${PREFIX}/bin'
153
154 @taskgen
155 @feature('cstaticlib', 'dstaticlib')
156 @before('apply_core')
157 -def vars_target_cstaticlib(self):
158 self.default_install_path = '${PREFIX}/lib'
159
160 @taskgen
161 @feature('cshlib', 'dshlib')
162 @before('apply_core')
163 -def vars_target_cshlib(self):
164 self.default_install_path = '${PREFIX}/lib'
165
175
182
183 @taskgen
184 @feature('cshlib', 'dshlib')
185 @after('apply_objdeps')
186 -def install_target_cshlib(self):
194
198 "used by the scanner"
199 lst = []
200 for lib in self.to_list(self.uselib):
201 for path in self.env['CPPPATH_' + lib]:
202 if not path in lst:
203 lst.append(path)
204 if preproc.go_absolute:
205 for path in preproc.standard_includes:
206 if not path in lst:
207 lst.append(path)
208 for path in self.to_list(self.includes):
209 if not path in lst:
210 lst.append(path)
211 if (not preproc.go_absolute) and os.path.isabs(path):
212 self.env.prepend_value('CPPPATH', path)
213
214 tree = Build.bld
215 inc_lst = []
216 for path in lst:
217 node = None
218 if os.path.isabs(path):
219 if preproc.go_absolute:
220 node = Build.bld.root.find_dir(path)
221 else:
222 node = self.path.find_dir(path)
223
224 if node:
225 inc_lst.append(node)
226
227 self.env['INC_PATHS'] = self.env['INC_PATHS'] + inc_lst
228
231
232 st = self.env[self.type+'_USELIB']
233 if st: self.uselib = self.uselib + ' ' + st
234
235
236
237 for var in self.p_type_vars:
238 compvar = '_'.join([self.type, var])
239
240 value = self.env[compvar]
241 if value: self.env.append_value(var, value)
242
243 @taskgen
244 @feature('cprogram', 'cshlib', 'cstaticlib')
245 @after('apply_core')
246 -def apply_link(self):
247
248 link = getattr(self, 'link', None)
249 if not link:
250 if 'cstaticlib' in self.features: link = 'ar_link_static'
251 elif 'cxx' in self.features: link = 'cxx_link'
252 else: link = 'cc_link'
253 linktask = self.create_task(link)
254 outputs = [t.outputs[0] for t in self.compiled_tasks]
255 linktask.set_inputs(outputs)
256 linktask.set_outputs(self.path.find_or_declare(get_target_name(self)))
257
258 self.link_task = linktask
259
263 env = self.env
264
265
266
267 uselib = self.to_list(self.uselib)
268 seen = []
269 names = [] + self.to_list(self.uselib_local)
270 while names:
271 x = names.pop(0)
272
273 if x in seen:
274 continue
275
276
277 y = Build.bld.name_to_obj(x)
278 if not y:
279 raise Utils.WafError("object '%s' was not found in uselib_local (required by '%s')" % (x, self.name))
280
281
282 if y.uselib_local:
283 lst = y.to_list(y.uselib_local)
284 for u in lst:
285 if not u in seen:
286 names.append(u)
287
288
289 y.post()
290 seen.append(x)
291
292 if 'cshlib' in y.features:
293 env.append_value('LIB', y.target)
294 elif 'cstaticlib' in y.features:
295 env.append_value('STATICLIB', y.target)
296
297
298 tmp_path = y.path.bldpath(self.env)
299 if not tmp_path in env['LIBPATH']: env.prepend_value('LIBPATH', tmp_path)
300
301
302 if y.link_task is not None:
303 self.link_task.set_run_after(y.link_task)
304 dep_nodes = getattr(self.link_task, 'dep_nodes', [])
305 self.link_task.dep_nodes = dep_nodes + y.link_task.outputs
306
307
308 morelibs = y.to_list(y.uselib)
309 for v in morelibs:
310 if v in uselib: continue
311 uselib = [v]+uselib
312
313
314
315 if getattr(y, 'export_incdirs', None):
316 cpppath_st = self.env['CPPPATH_ST'<