1#!/usr/bin/env python
2# encoding: utf-8
3# Thomas Nagy, 2008-2018 (ita)
4
5"""
6Assembly support, used by tools such as gas and nasm
7
8To declare targets using assembly::
9
10	def configure(conf):
11		conf.load('gcc gas')
12
13	def build(bld):
14		bld(
15			features='c cstlib asm',
16			source = 'test.S',
17			target = 'asmtest')
18
19		bld(
20			features='asm asmprogram',
21			source = 'test.S',
22			target = 'asmtest')
23
24Support for pure asm programs and libraries should also work::
25
26	def configure(conf):
27		conf.load('nasm')
28		conf.find_program('ld', 'ASLINK')
29
30	def build(bld):
31		bld(
32			features='asm asmprogram',
33			source = 'test.S',
34			target = 'asmtest')
35"""
36
37import re
38from waflib import Errors, Logs, Task
39from waflib.Tools.ccroot import link_task, stlink_task
40from waflib.TaskGen import extension
41from waflib.Tools import c_preproc
42
43re_lines = re.compile(
44	'^[ \t]*(?:%)[ \t]*(ifdef|ifndef|if|else|elif|endif|include|import|define|undef)[ \t]*(.*)\r*$',
45	re.IGNORECASE | re.MULTILINE)
46
47class asm_parser(c_preproc.c_parser):
48	def filter_comments(self, node):
49		code = node.read()
50		code = c_preproc.re_nl.sub('', code)
51		code = c_preproc.re_cpp.sub(c_preproc.repl, code)
52		return re_lines.findall(code)
53
54class asm(Task.Task):
55	"""
56	Compiles asm files by gas/nasm/yasm/...
57	"""
58	color = 'BLUE'
59	run_str = '${AS} ${ASFLAGS} ${ASMPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${AS_SRC_F}${SRC} ${AS_TGT_F}${TGT}'
60
61	def scan(self):
62		if self.env.ASM_NAME == 'gas':
63			return c_preproc.scan(self)
64			Logs.warn('There is no dependency scanner for Nasm!')
65			return  [[], []]
66		elif self.env.ASM_NAME == 'nasm':
67			Logs.warn('The Nasm dependency scanner is incomplete!')
68
69		try:
70			incn = self.generator.includes_nodes
71		except AttributeError:
72			raise Errors.WafError('%r is missing the "asm" feature' % self.generator)
73
74		if c_preproc.go_absolute:
75			nodepaths = incn
76		else:
77			nodepaths = [x for x in incn if x.is_child_of(x.ctx.srcnode) or x.is_child_of(x.ctx.bldnode)]
78
79		tmp = asm_parser(nodepaths)
80		tmp.start(self.inputs[0], self.env)
81		return (tmp.nodes, tmp.names)
82
83@extension('.s', '.S', '.asm', '.ASM', '.spp', '.SPP')
84def asm_hook(self, node):
85	"""
86	Binds the asm extension to the asm task
87
88	:param node: input file
89	:type node: :py:class:`waflib.Node.Node`
90	"""
91	return self.create_compiled_task('asm', node)
92
93class asmprogram(link_task):
94	"Links object files into a c program"
95	run_str = '${ASLINK} ${ASLINKFLAGS} ${ASLNK_TGT_F}${TGT} ${ASLNK_SRC_F}${SRC}'
96	ext_out = ['.bin']
97	inst_to = '${BINDIR}'
98
99class asmshlib(asmprogram):
100	"Links object files into a c shared library"
101	inst_to = '${LIBDIR}'
102
103class asmstlib(stlink_task):
104	"Links object files into a c static library"
105	pass # do not remove
106
107def configure(conf):
108	conf.env.ASMPATH_ST = '-I%s'
109