waf

FORK: waf with some random patches
git clone https://git.neptards.moe/neptards/waf.git
Log | Files | Refs | README

ticgt.py (9474B)


      1 #!/usr/bin/env python
      2 # encoding: utf-8
      3 
      4 # Texas Instruments code generator support (experimental)
      5 # When reporting issues, please directly assign the bug to the maintainer.
      6 
      7 __author__ = __maintainer__ = "Jérôme Carretero <cJ-waf@zougloub.eu>"
      8 __copyright__ = "Jérôme Carretero, 2012"
      9 
     10 """
     11 TI cgt6x is a compiler suite for TI DSPs.
     12 
     13 The toolchain does pretty weird things, and I'm sure I'm missing some of them.
     14 But still, the tool saves time.
     15 
     16 What this tool does is:
     17 
     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
     23   The tool
     24 
     25 TODO:
     26 
     27 - the set_platform_flags() function is not nice
     28 - more tests
     29 - broaden tool scope, if needed
     30 
     31 """
     32 
     33 import os, re
     34 
     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
     40 
     41 opj = os.path.join
     42 
     43 @conf
     44 def find_ticc(conf):
     45 	conf.find_program(['cl6x'], var='CC', path_list=opj(getattr(Options.options, 'ti-cgt-dir', ""), 'bin'))
     46 	conf.env.CC_NAME = 'ticc'
     47 
     48 @conf
     49 def find_tild(conf):
     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'
     52 
     53 @conf
     54 def find_tiar(conf):
     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'
     58 
     59 @conf
     60 def ticc_common_flags(conf):
     61 	v = conf.env
     62 
     63 	if not v['LINK_CC']:
     64 		v['LINK_CC'] = v['CC']
     65 	v['CCLNK_SRC_F']	 = []
     66 	v['CCLNK_TGT_F']	 = ['-o']
     67 	v['CPPPATH_ST']	  = '-I%s'
     68 	v['DEFINES_ST']	  = '-d%s'
     69 
     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'
     74 
     75 	# program
     76 	v['cprogram_PATTERN']    = '%s.out'
     77 
     78 	# static lib
     79 	#v['LINKFLAGS_cstlib']    = ['-Wl,-Bstatic']
     80 	v['cstlib_PATTERN']      = '%s.lib'
     81 
     82 def configure(conf):
     83 	v = conf.env
     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', "")
     89 	conf.find_ticc()
     90 	conf.find_tiar()
     91 	conf.find_tild()
     92 	conf.ticc_common_flags()
     93 	conf.cc_load_tools()
     94 	conf.cc_add_flags()
     95 	conf.link_add_flags()
     96 	conf.find_program(['tconf'], var='TCONF', path_list=v.TI_XDCTOOLS_DIR)
     97 
     98 	conf.env.TCONF_INCLUDES += [
     99 	 opj(conf.env.TI_DSPBIOS_DIR, 'packages'),
    100 	]
    101 
    102 	conf.env.INCLUDES += [
    103 	 opj(conf.env.TI_CGT_DIR, 'include'),
    104 	]
    105 
    106 	conf.env.LIBPATH += [
    107 	 opj(conf.env.TI_CGT_DIR, "lib"),
    108 	]
    109 
    110 	conf.env.INCLUDES_DSPBIOS += [
    111 	 opj(conf.env.TI_DSPBIOS_DIR, 'packages', 'ti', 'bios', 'include'),
    112 	]
    113 
    114 	conf.env.LIBPATH_DSPBIOS += [
    115 	 opj(conf.env.TI_DSPBIOS_DIR, 'packages', 'ti', 'bios', 'lib'),
    116 	]
    117 
    118 	conf.env.INCLUDES_DSPLINK += [
    119 	 opj(conf.env.TI_DSPLINK_DIR, 'dsplink', 'dsp', 'inc'),
    120 	]
    121 
    122 @conf
    123 def ti_set_debug(cfg, debug=1):
    124 	"""
    125 	Sets debug flags for the compiler.
    126 
    127 	TODO:
    128 	- for each TI CFLAG/INCLUDES/LINKFLAGS/LIBPATH replace RELEASE by DEBUG
    129 	- -g --no_compress
    130 	"""
    131 	if debug:
    132 		cfg.env.CFLAGS += "-d_DEBUG -dDEBUG -dDDSP_DEBUG".split()
    133 
    134 @conf
    135 def ti_dsplink_set_platform_flags(cfg, splat, dsp, dspbios_ver, board):
    136 	"""
    137 	Sets the INCLUDES, LINKFLAGS for DSPLINK and TCONF_INCLUDES
    138 	For the specific hardware.
    139 
    140 	Assumes that DSPLINK was built in its own folder.
    141 
    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)
    146 
    147 	"""
    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),
    153 	 d,
    154 	]
    155 
    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')
    159 	]
    160 
    161 
    162 def options(opt):
    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="")
    168 
    169 class ti_cprogram(cprogram):
    170 	"""
    171 	Link object files into a c program
    172 	
    173 	Changes:
    174 
    175 	- the linked executable to have a relative path (because we can)
    176 	- put the LIBPATH first
    177 	"""
    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} '
    179 
    180 @feature("c")
    181 @before_method('apply_link')
    182 def use_ti_cprogram(self):
    183 	"""
    184 	Automatically uses ti_cprogram link process
    185 	"""
    186 	if 'cprogram' in self.features and self.env.CC_NAME == 'ticc':
    187 		self.features.insert(0, "ti_cprogram")
    188 
    189 class ti_c(Task.Task):
    190 	"""
    191 	Compile task for the TI codegen compiler
    192 
    193 	This compiler does not allow specifying the output file name, only the output path.
    194 
    195 	"""
    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
    201 
    202 def create_compiled_task(self, name, node):
    203 	"""
    204 	Overrides ccroot.create_compiled_task to support ti_c
    205 	"""
    206 	out = '%s' % (node.change_ext('.obj').name)
    207 	if self.env.CC_NAME == 'ticc':
    208 		name = 'ti_c'
    209 	task = self.create_task(name, node, node.parent.find_or_declare(out))
    210 	self.env.OUT = '-fr%s' % (node.parent.get_bld().abspath())
    211 	try:
    212 		self.compiled_tasks.append(task)
    213 	except AttributeError:
    214 		self.compiled_tasks = [task]
    215 	return task
    216 
    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)
    222 	else:
    223 		return self.create_compiled_task('c', node)
    224 
    225 
    226 @feature("ti-tconf")
    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())]
    230 	node = sources[0]
    231 	assert(sources[0].name.endswith(".tcf"))
    232 	if len(sources) > 1:
    233 		assert(sources[1].name.endswith(".cmd"))
    234 
    235 	target = getattr(self, 'target', self.source)
    236 	target_node = node.get_bld().parent.find_or_declare(node.name)
    237 	
    238 	procid = "%d" % int(getattr(self, 'procid', 0))
    239 
    240 	importpaths = []
    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)
    245 		else:
    246 			relpath = self.path.find_node(x).path_from(target_node.parent)
    247 			importpaths.append(relpath)
    248 
    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
    258 	task.outputs = [
    259 	 target_node.change_ext("cfg_c.c"),
    260 	 target_node.change_ext("cfg.s62"),
    261 	 target_node.change_ext("cfg.cmd"),
    262 	]
    263 
    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()
    267 
    268 	self.add_those_o_files(target_node.change_ext("cfg.cmd"))
    269 	if len(sources) > 1:
    270 		self.add_those_o_files(sources[1])
    271 	self.source = []
    272 
    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}'
    276 	color   = 'PINK'
    277 
    278 	def scan(self):
    279 		includes = Utils.to_list(getattr(self, 'includes', []))
    280 
    281 		def deps(node):
    282 			nodes, names = [], []
    283 			if node:
    284 				code = Utils.readf(node.abspath())
    285 				for match in re_tconf_include.finditer(code):
    286 					path = match.group('file')
    287 					if path:
    288 						for x in includes:
    289 							filename = opj(x, path)
    290 							fi = self.path.find_resource(filename)
    291 							if fi:
    292 								subnodes, subnames = deps(fi)
    293 								nodes += subnodes
    294 								names += subnames
    295 								nodes.append(fi)
    296 								names.append(path)
    297 								break
    298 			return nodes, names
    299 		return deps(self.inputs[0])
    300