4 # Texas Instruments code generator support (experimental)
5 # When reporting issues, please directly assign the bug to the maintainer.
7 __author__
= __maintainer__
= "Jérôme Carretero <cJ-waf@zougloub.eu>"
8 __copyright__
= "Jérôme Carretero, 2012"
11 TI cgt6x is a compiler suite for TI DSPs.
13 The toolchain does pretty weird things, and I'm sure I'm missing some of them.
14 But still, the tool saves time.
16 What this tool does is:
18 - create a TI compiler environment
19 - create TI compiler features, to handle some specifics about this compiler
20 It has a few idiosyncracies, such as not giving the liberty of the .o file names
21 - automatically activate them when using the TI compiler
22 - handle the tconf tool
27 - the set_platform_flags() function is not nice
29 - broaden tool scope, if needed
35 from waflib
import Options
, Utils
, Task
, TaskGen
36 from waflib
.Tools
import c
, ccroot
, c_preproc
37 from waflib
.Configure
import conf
38 from waflib
.TaskGen
import feature
, before_method
39 from waflib
.Tools
.c
import cprogram
45 conf
.find_program(['cl6x'], var
='CC', path_list
=opj(getattr(Options
.options
, 'ti-cgt-dir', ""), 'bin'))
46 conf
.env
.CC_NAME
= 'ticc'
50 conf
.find_program(['lnk6x'], var
='LINK_CC', path_list
=opj(getattr(Options
.options
, 'ti-cgt-dir', ""), 'bin'))
51 conf
.env
.LINK_CC_NAME
= 'tild'
55 conf
.find_program(['ar6x'], var
='AR', path_list
=opj(getattr(Options
.options
, 'ti-cgt-dir', ""), 'bin'))
56 conf
.env
.AR_NAME
= 'tiar'
57 conf
.env
.ARFLAGS
= 'qru'
60 def ticc_common_flags(conf
):
64 v
['LINK_CC'] = v
['CC']
66 v
['CCLNK_TGT_F'] = ['-o']
67 v
['CPPPATH_ST'] = '-I%s'
68 v
['DEFINES_ST'] = '-d%s'
70 v
['LIB_ST'] = '-l%s' # template for adding libs
71 v
['LIBPATH_ST'] = '-i%s' # template for adding libpaths
72 v
['STLIB_ST'] = '-l=%s.lib'
73 v
['STLIBPATH_ST'] = '-i%s'
76 v
['cprogram_PATTERN'] = '%s.out'
79 #v['LINKFLAGS_cstlib'] = ['-Wl,-Bstatic']
80 v
['cstlib_PATTERN'] = '%s.lib'
84 v
.TI_CGT_DIR
= getattr(Options
.options
, 'ti-cgt-dir', "")
85 v
.TI_DSPLINK_DIR
= getattr(Options
.options
, 'ti-dsplink-dir', "")
86 v
.TI_BIOSUTILS_DIR
= getattr(Options
.options
, 'ti-biosutils-dir', "")
87 v
.TI_DSPBIOS_DIR
= getattr(Options
.options
, 'ti-dspbios-dir', "")
88 v
.TI_XDCTOOLS_DIR
= getattr(Options
.options
, 'ti-xdctools-dir', "")
92 conf
.ticc_common_flags()
96 conf
.find_program(['tconf'], var
='TCONF', path_list
=v
.TI_XDCTOOLS_DIR
)
98 conf
.env
.TCONF_INCLUDES
+= [
99 opj(conf
.env
.TI_DSPBIOS_DIR
, 'packages'),
102 conf
.env
.INCLUDES
+= [
103 opj(conf
.env
.TI_CGT_DIR
, 'include'),
106 conf
.env
.LIBPATH
+= [
107 opj(conf
.env
.TI_CGT_DIR
, "lib"),
110 conf
.env
.INCLUDES_DSPBIOS
+= [
111 opj(conf
.env
.TI_DSPBIOS_DIR
, 'packages', 'ti', 'bios', 'include'),
114 conf
.env
.LIBPATH_DSPBIOS
+= [
115 opj(conf
.env
.TI_DSPBIOS_DIR
, 'packages', 'ti', 'bios', 'lib'),
118 conf
.env
.INCLUDES_DSPLINK
+= [
119 opj(conf
.env
.TI_DSPLINK_DIR
, 'dsplink', 'dsp', 'inc'),
123 def ti_set_debug(cfg
, debug
=1):
125 Sets debug flags for the compiler.
128 - for each TI CFLAG/INCLUDES/LINKFLAGS/LIBPATH replace RELEASE by DEBUG
132 cfg
.env
.CFLAGS
+= "-d_DEBUG -dDEBUG -dDDSP_DEBUG".split()
135 def ti_dsplink_set_platform_flags(cfg
, splat
, dsp
, dspbios_ver
, board
):
137 Sets the INCLUDES, LINKFLAGS for DSPLINK and TCONF_INCLUDES
138 For the specific hardware.
140 Assumes that DSPLINK was built in its own folder.
142 :param splat: short platform name (eg. OMAPL138)
143 :param dsp: DSP name (eg. 674X)
144 :param dspbios_ver: string identifying DspBios version (eg. 5.XX)
145 :param board: board name (eg. OMAPL138GEM)
148 d1
= opj(cfg
.env
.TI_DSPLINK_DIR
, 'dsplink', 'dsp', 'inc', 'DspBios', dspbios_ver
)
149 d
= opj(cfg
.env
.TI_DSPLINK_DIR
, 'dsplink', 'dsp', 'inc', 'DspBios', dspbios_ver
, board
)
150 cfg
.env
.TCONF_INCLUDES
+= [d1
, d
]
151 cfg
.env
.INCLUDES_DSPLINK
+= [
152 opj(cfg
.env
.TI_DSPLINK_DIR
, 'dsplink', 'dsp', 'inc', dsp
),
156 cfg
.env
.LINKFLAGS_DSPLINK
+= [
157 opj(cfg
.env
.TI_DSPLINK_DIR
, 'dsplink', 'dsp', 'export', 'BIN', 'DspBios', splat
, board
+'_0', 'RELEASE', 'dsplink%s.lib' % x
)
158 for x
in ('', 'pool', 'mpcs', 'mplist', 'msg', 'data', 'notify', 'ringio')
163 opt
.add_option('--with-ti-cgt', type='string', dest
='ti-cgt-dir', help = 'Specify alternate cgt root folder', default
="")
164 opt
.add_option('--with-ti-biosutils', type='string', dest
='ti-biosutils-dir', help = 'Specify alternate biosutils folder', default
="")
165 opt
.add_option('--with-ti-dspbios', type='string', dest
='ti-dspbios-dir', help = 'Specify alternate dspbios folder', default
="")
166 opt
.add_option('--with-ti-dsplink', type='string', dest
='ti-dsplink-dir', help = 'Specify alternate dsplink folder', default
="")
167 opt
.add_option('--with-ti-xdctools', type='string', dest
='ti-xdctools-dir', help = 'Specify alternate xdctools folder', default
="")
169 class ti_cprogram(cprogram
):
171 Link object files into a c program
175 - the linked executable to have a relative path (because we can)
176 - put the LIBPATH first
178 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} '
181 @before_method('apply_link')
182 def use_ti_cprogram(self
):
184 Automatically uses ti_cprogram link process
186 if 'cprogram' in self
.features
and self
.env
.CC_NAME
== 'ticc':
187 self
.features
.insert(0, "ti_cprogram")
189 class ti_c(Task
.Task
):
191 Compile task for the TI codegen compiler
193 This compiler does not allow specifying the output file name, only the output path.
196 "Compile C files into object files"
197 run_str
= '${CC} ${ARCH_ST:ARCH} ${CFLAGS} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${SRC} -c ${OUT} ${CPPFLAGS}'
198 vars = ['CCDEPS'] # unused variable to depend on, just in case
199 ext_in
= ['.h'] # set the build order easily by using ext_out=['.h']
200 scan
= c_preproc
.scan
202 def create_compiled_task(self
, name
, node
):
204 Overrides ccroot.create_compiled_task to support ti_c
206 out
= '%s' % (node
.change_ext('.obj').name
)
207 if self
.env
.CC_NAME
== 'ticc':
209 task
= self
.create_task(name
, node
, node
.parent
.find_or_declare(out
))
210 self
.env
.OUT
= '-fr%s' % (node
.parent
.get_bld().abspath())
212 self
.compiled_tasks
.append(task
)
213 except AttributeError:
214 self
.compiled_tasks
= [task
]
217 @TaskGen.extension('.c')
218 def c_hook(self
, node
):
219 "Bind the c file extension to the creation of a :py:class:`waflib.Tools.c.c` instance"
220 if self
.env
.CC_NAME
== 'ticc':
221 return create_compiled_task(self
, 'ti_c', node
)
223 return self
.create_compiled_task('c', node
)
227 @before_method('process_source')
228 def apply_tconf(self
):
229 sources
= [x
.get_src() for x
in self
.to_nodes(self
.source
, path
=self
.path
.get_src())]
231 assert(sources
[0].name
.endswith(".tcf"))
233 assert(sources
[1].name
.endswith(".cmd"))
235 target
= getattr(self
, 'target', self
.source
)
236 target_node
= node
.get_bld().parent
.find_or_declare(node
.name
)
238 procid
= "%d" % int(getattr(self
, 'procid', 0))
241 includes
= Utils
.to_list(getattr(self
, 'includes', []))
242 for x
in includes
+ self
.env
.TCONF_INCLUDES
:
243 if x
== os
.path
.abspath(x
):
244 importpaths
.append(x
)
246 relpath
= self
.path
.find_node(x
).path_from(target_node
.parent
)
247 importpaths
.append(relpath
)
249 task
= self
.create_task('ti_tconf', sources
, target_node
.change_ext('.cdb'))
250 task
.path
= self
.path
251 task
.includes
= includes
252 task
.cwd
= target_node
.parent
.abspath()
253 task
.env
= self
.env
.derive()
254 task
.env
["TCONFSRC"] = node
.path_from(target_node
.parent
)
255 task
.env
["TCONFINC"] = '-Dconfig.importPath=%s' % ";".join(importpaths
)
256 task
.env
['TCONFPROGNAME'] = '-Dconfig.programName=%s' % target
257 task
.env
['PROCID'] = procid
259 target_node
.change_ext("cfg_c.c"),
260 target_node
.change_ext("cfg.s62"),
261 target_node
.change_ext("cfg.cmd"),
264 create_compiled_task(self
, 'ti_c', task
.outputs
[1])
265 ctask
= create_compiled_task(self
, 'ti_c', task
.outputs
[0])
266 ctask
.env
= self
.env
.derive()
268 self
.add_those_o_files(target_node
.change_ext("cfg.cmd"))
270 self
.add_those_o_files(sources
[1])
273 re_tconf_include
= re
.compile(r
'(?P<type>utils\.importFile)\("(?P<file>.*)"\)',re
.M
)
274 class ti_tconf(Task
.Task
):
275 run_str
= '${TCONF} ${TCONFINC} ${TCONFPROGNAME} ${TCONFSRC} ${PROCID}'
279 includes
= Utils
.to_list(getattr(self
, 'includes', []))
282 nodes
, names
= [], []
284 code
= Utils
.readf(node
.abspath())
285 for match
in re_tconf_include
.finditer(code
):
286 path
= match
.group('file')
289 filename
= opj(x
, path
)
290 fi
= self
.path
.find_resource(filename
)
292 subnodes
, subnames
= deps(fi
)
299 return deps(self
.inputs
[0])