third_party:waf: update to upstream 2.0.4 release
[nivanova/samba-autobuild/.git] / third_party / waf / waflib / extras / ticgt.py
1 #! /usr/bin/env python
2 # encoding: utf-8
3 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
4
5 #!/usr/bin/env python
6 # encoding: utf-8
7
8 # Texas Instruments code generator support (experimental)
9 # When reporting issues, please directly assign the bug to the maintainer.
10
11 __author__ = __maintainer__ = "Jérôme Carretero <cJ-waf@zougloub.eu>"
12 __copyright__ = "Jérôme Carretero, 2012"
13
14 """
15 TI cgt6x is a compiler suite for TI DSPs.
16
17 The toolchain does pretty weird things, and I'm sure I'm missing some of them.
18 But still, the tool saves time.
19
20 What this tool does is:
21
22 - create a TI compiler environment
23 - create TI compiler features, to handle some specifics about this compiler
24   It has a few idiosyncracies, such as not giving the liberty of the .o file names
25 - automatically activate them when using the TI compiler
26 - handle the tconf tool
27   The tool
28
29 TODO:
30
31 - the set_platform_flags() function is not nice
32 - more tests
33 - broaden tool scope, if needed
34
35 """
36
37 import os, re
38
39 from waflib import Options, Utils, Task, TaskGen
40 from waflib.Tools import c, ccroot, c_preproc
41 from waflib.Configure import conf
42 from waflib.TaskGen import feature, before_method
43 from waflib.Tools.c import cprogram
44
45 opj = os.path.join
46
47 @conf
48 def find_ticc(conf):
49         conf.find_program(['cl6x'], var='CC', path_list=opj(getattr(Options.options, 'ti-cgt-dir', ""), 'bin'))
50         conf.env.CC_NAME = 'ticc'
51
52 @conf
53 def find_tild(conf):
54         conf.find_program(['lnk6x'], var='LINK_CC', path_list=opj(getattr(Options.options, 'ti-cgt-dir', ""), 'bin'))
55         conf.env.LINK_CC_NAME = 'tild'
56
57 @conf
58 def find_tiar(conf):
59         conf.find_program(['ar6x'], var='AR', path_list=opj(getattr(Options.options, 'ti-cgt-dir', ""), 'bin'))
60         conf.env.AR_NAME = 'tiar'
61         conf.env.ARFLAGS = 'qru'
62
63 @conf
64 def ticc_common_flags(conf):
65         v = conf.env
66
67         if not v['LINK_CC']:
68                 v['LINK_CC'] = v['CC']
69         v['CCLNK_SRC_F']         = []
70         v['CCLNK_TGT_F']         = ['-o']
71         v['CPPPATH_ST']   = '-I%s'
72         v['DEFINES_ST']   = '-d%s'
73
74         v['LIB_ST']           = '-l%s' # template for adding libs
75         v['LIBPATH_ST']   = '-i%s' # template for adding libpaths
76         v['STLIB_ST']       = '-l=%s.lib'
77         v['STLIBPATH_ST']       = '-i%s'
78
79         # program
80         v['cprogram_PATTERN']    = '%s.out'
81
82         # static lib
83         #v['LINKFLAGS_cstlib']    = ['-Wl,-Bstatic']
84         v['cstlib_PATTERN']      = '%s.lib'
85
86 def configure(conf):
87         v = conf.env
88         v.TI_CGT_DIR = getattr(Options.options, 'ti-cgt-dir', "")
89         v.TI_DSPLINK_DIR = getattr(Options.options, 'ti-dsplink-dir', "")
90         v.TI_BIOSUTILS_DIR = getattr(Options.options, 'ti-biosutils-dir', "")
91         v.TI_DSPBIOS_DIR = getattr(Options.options, 'ti-dspbios-dir', "")
92         v.TI_XDCTOOLS_DIR = getattr(Options.options, 'ti-xdctools-dir', "")
93         conf.find_ticc()
94         conf.find_tiar()
95         conf.find_tild()
96         conf.ticc_common_flags()
97         conf.cc_load_tools()
98         conf.cc_add_flags()
99         conf.link_add_flags()
100         conf.find_program(['tconf'], var='TCONF', path_list=v.TI_XDCTOOLS_DIR)
101
102         conf.env.TCONF_INCLUDES += [
103          opj(conf.env.TI_DSPBIOS_DIR, 'packages'),
104         ]
105
106         conf.env.INCLUDES += [
107          opj(conf.env.TI_CGT_DIR, 'include'),
108         ]
109
110         conf.env.LIBPATH += [
111          opj(conf.env.TI_CGT_DIR, "lib"),
112         ]
113
114         conf.env.INCLUDES_DSPBIOS += [
115          opj(conf.env.TI_DSPBIOS_DIR, 'packages', 'ti', 'bios', 'include'),
116         ]
117
118         conf.env.LIBPATH_DSPBIOS += [
119          opj(conf.env.TI_DSPBIOS_DIR, 'packages', 'ti', 'bios', 'lib'),
120         ]
121
122         conf.env.INCLUDES_DSPLINK += [
123          opj(conf.env.TI_DSPLINK_DIR, 'dsplink', 'dsp', 'inc'),
124         ]
125
126 @conf
127 def ti_set_debug(cfg, debug=1):
128         """
129         Sets debug flags for the compiler.
130
131         TODO:
132         - for each TI CFLAG/INCLUDES/LINKFLAGS/LIBPATH replace RELEASE by DEBUG
133         - -g --no_compress
134         """
135         if debug:
136                 cfg.env.CFLAGS += "-d_DEBUG -dDEBUG -dDDSP_DEBUG".split()
137
138 @conf
139 def ti_dsplink_set_platform_flags(cfg, splat, dsp, dspbios_ver, board):
140         """
141         Sets the INCLUDES, LINKFLAGS for DSPLINK and TCONF_INCLUDES
142         For the specific hardware.
143
144         Assumes that DSPLINK was built in its own folder.
145
146         :param splat: short platform name (eg. OMAPL138)
147         :param dsp: DSP name (eg. 674X)
148         :param dspbios_ver: string identifying DspBios version (eg. 5.XX)
149         :param board: board name (eg. OMAPL138GEM)
150
151         """
152         d1 = opj(cfg.env.TI_DSPLINK_DIR, 'dsplink', 'dsp', 'inc', 'DspBios', dspbios_ver)
153         d = opj(cfg.env.TI_DSPLINK_DIR, 'dsplink', 'dsp', 'inc', 'DspBios', dspbios_ver, board)
154         cfg.env.TCONF_INCLUDES += [d1, d]
155         cfg.env.INCLUDES_DSPLINK += [
156          opj(cfg.env.TI_DSPLINK_DIR, 'dsplink', 'dsp', 'inc', dsp),
157          d,
158         ]
159
160         cfg.env.LINKFLAGS_DSPLINK += [
161          opj(cfg.env.TI_DSPLINK_DIR, 'dsplink', 'dsp', 'export', 'BIN', 'DspBios', splat, board+'_0', 'RELEASE', 'dsplink%s.lib' % x)
162          for x in ('', 'pool', 'mpcs', 'mplist', 'msg', 'data', 'notify', 'ringio')
163         ]
164
165
166 def options(opt):
167         opt.add_option('--with-ti-cgt', type='string', dest='ti-cgt-dir', help = 'Specify alternate cgt root folder', default="")
168         opt.add_option('--with-ti-biosutils', type='string', dest='ti-biosutils-dir', help = 'Specify alternate biosutils folder', default="")
169         opt.add_option('--with-ti-dspbios', type='string', dest='ti-dspbios-dir', help = 'Specify alternate dspbios folder', default="")
170         opt.add_option('--with-ti-dsplink', type='string', dest='ti-dsplink-dir', help = 'Specify alternate dsplink folder', default="")
171         opt.add_option('--with-ti-xdctools', type='string', dest='ti-xdctools-dir', help = 'Specify alternate xdctools folder', default="")
172
173 class ti_cprogram(cprogram):
174         """
175         Link object files into a c program
176         
177         Changes:
178
179         - the linked executable to have a relative path (because we can)
180         - put the LIBPATH first
181         """
182         run_str = '${LINK_CC} ${LIBPATH_ST:LIBPATH} ${LIB_ST:LIB} ${LINKFLAGS} ${CCLNK_SRC_F}${SRC} ${CCLNK_TGT_F}${TGT[0].bldpath()} ${RPATH_ST:RPATH} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${FRAMEWORK_ST:FRAMEWORK} ${ARCH_ST:ARCH} ${STLIB_MARKER} ${STLIBPATH_ST:STLIBPATH} ${STLIB_ST:STLIB} ${SHLIB_MARKER} '
183
184 @feature("c")
185 @before_method('apply_link')
186 def use_ti_cprogram(self):
187         """
188         Automatically uses ti_cprogram link process
189         """
190         if 'cprogram' in self.features and self.env.CC_NAME == 'ticc':
191                 self.features.insert(0, "ti_cprogram")
192
193 class ti_c(Task.Task):
194         """
195         Compile task for the TI codegen compiler
196
197         This compiler does not allow specifying the output file name, only the output path.
198
199         """
200         "Compile C files into object files"
201         run_str = '${CC} ${ARCH_ST:ARCH} ${CFLAGS} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${SRC} -c ${OUT} ${CPPFLAGS}'
202         vars    = ['CCDEPS'] # unused variable to depend on, just in case
203         ext_in  = ['.h'] # set the build order easily by using ext_out=['.h']
204         scan    = c_preproc.scan
205
206 def create_compiled_task(self, name, node):
207         """
208         Overrides ccroot.create_compiled_task to support ti_c
209         """
210         out = '%s' % (node.change_ext('.obj').name)
211         if self.env.CC_NAME == 'ticc':
212                 name = 'ti_c'
213         task = self.create_task(name, node, node.parent.find_or_declare(out))
214         self.env.OUT = '-fr%s' % (node.parent.get_bld().abspath())
215         try:
216                 self.compiled_tasks.append(task)
217         except AttributeError:
218                 self.compiled_tasks = [task]
219         return task
220
221 @TaskGen.extension('.c')
222 def c_hook(self, node):
223         "Bind the c file extension to the creation of a :py:class:`waflib.Tools.c.c` instance"
224         if self.env.CC_NAME == 'ticc':
225                 return create_compiled_task(self, 'ti_c', node)
226         else:
227                 return self.create_compiled_task('c', node)
228
229
230 @feature("ti-tconf")
231 @before_method('process_source')
232 def apply_tconf(self):
233         sources = [x.get_src() for x in self.to_nodes(self.source, path=self.path.get_src())]
234         node = sources[0]
235         assert(sources[0].name.endswith(".tcf"))
236         if len(sources) > 1:
237                 assert(sources[1].name.endswith(".cmd"))
238
239         target = getattr(self, 'target', self.source)
240         target_node = node.get_bld().parent.find_or_declare(node.name)
241         
242         procid = "%d" % int(getattr(self, 'procid', 0))
243
244         importpaths = []
245         includes = Utils.to_list(getattr(self, 'includes', []))
246         for x in includes + self.env.TCONF_INCLUDES:
247                 if x == os.path.abspath(x):
248                         importpaths.append(x)
249                 else:
250                         relpath = self.path.find_node(x).path_from(target_node.parent)
251                         importpaths.append(relpath)
252
253         task = self.create_task('ti_tconf', sources, target_node.change_ext('.cdb'))
254         task.path = self.path
255         task.includes = includes
256         task.cwd = target_node.parent.abspath()
257         task.env = self.env.derive()
258         task.env["TCONFSRC"] = node.path_from(target_node.parent)
259         task.env["TCONFINC"] = '-Dconfig.importPath=%s' % ";".join(importpaths)
260         task.env['TCONFPROGNAME'] = '-Dconfig.programName=%s' % target
261         task.env['PROCID'] = procid
262         task.outputs = [
263          target_node.change_ext("cfg_c.c"),
264          target_node.change_ext("cfg.s62"),
265          target_node.change_ext("cfg.cmd"),
266         ]
267
268         create_compiled_task(self, 'ti_c', task.outputs[1])
269         ctask = create_compiled_task(self, 'ti_c', task.outputs[0])
270         ctask.env = self.env.derive()
271
272         self.add_those_o_files(target_node.change_ext("cfg.cmd"))
273         if len(sources) > 1:
274                 self.add_those_o_files(sources[1])
275         self.source = []
276
277 re_tconf_include = re.compile(r'(?P<type>utils\.importFile)\("(?P<file>.*)"\)',re.M)
278 class ti_tconf(Task.Task):
279         run_str = '${TCONF} ${TCONFINC} ${TCONFPROGNAME} ${TCONFSRC} ${PROCID}'
280         color   = 'PINK'
281
282         def scan(self):
283                 includes = Utils.to_list(getattr(self, 'includes', []))
284
285                 def deps(node):
286                         nodes, names = [], []
287                         if node:
288                                 code = Utils.readf(node.abspath())
289                                 for match in re_tconf_include.finditer(code):
290                                         path = match.group('file')
291                                         if path:
292                                                 for x in includes:
293                                                         filename = opj(x, path)
294                                                         fi = self.path.find_resource(filename)
295                                                         if fi:
296                                                                 subnodes, subnames = deps(fi)
297                                                                 nodes += subnodes
298                                                                 names += subnames
299                                                                 nodes.append(fi)
300                                                                 names.append(path)
301                                                                 break
302                         return nodes, names
303                 return deps(self.inputs[0])
304