2022-10-23 22:59:44 -03:00
|
|
|
# encoding: utf-8
|
|
|
|
|
|
|
|
"""
|
|
|
|
generate DSDLC headers for uavcan
|
|
|
|
"""
|
|
|
|
|
|
|
|
from waflib import Logs, Task, Utils, Node
|
|
|
|
from waflib.TaskGen import feature, before_method, extension
|
|
|
|
import os
|
|
|
|
import os.path
|
|
|
|
from xml.etree import ElementTree as et
|
2024-02-10 20:11:40 -04:00
|
|
|
import subprocess
|
2022-10-23 22:59:44 -03:00
|
|
|
|
|
|
|
class dronecangen(Task.Task):
|
|
|
|
"""generate uavcan header files"""
|
|
|
|
color = 'BLUE'
|
|
|
|
before = 'cxx c'
|
|
|
|
|
|
|
|
def run(self):
|
|
|
|
python = self.env.get_flat('PYTHON')
|
|
|
|
out = self.env.get_flat('OUTPUT_DIR')
|
|
|
|
src = self.env.get_flat('SRC')
|
2024-09-14 15:19:34 -03:00
|
|
|
dsdlc = self.env.get_flat("DC_DSDL_COMPILER_DIR")
|
2022-10-23 22:59:44 -03:00
|
|
|
|
2024-02-10 20:11:40 -04:00
|
|
|
cmd = ['{}'.format(python),
|
2024-09-14 15:19:34 -03:00
|
|
|
'{}/dronecan_dsdlc.py'.format(dsdlc),
|
2024-02-10 20:11:40 -04:00
|
|
|
'-O{}'.format(out)] + [x.abspath() for x in self.inputs]
|
|
|
|
ret = self.exec_command(cmd)
|
2022-10-23 22:59:44 -03:00
|
|
|
if ret != 0:
|
|
|
|
# ignore if there was a signal to the interpreter rather
|
|
|
|
# than a real error in the script. Some environments use a
|
|
|
|
# signed and some an unsigned return for this
|
|
|
|
if ret > 128 or ret < 0:
|
|
|
|
Logs.warn('dronecangen crashed with code: {}'.format(ret))
|
|
|
|
ret = 0
|
|
|
|
else:
|
2024-02-10 20:11:40 -04:00
|
|
|
Logs.warn('dronecangen: cmd=%s ' % str(cmd))
|
|
|
|
# re-run command with stdout visible to see errors
|
|
|
|
subprocess.call(cmd)
|
2022-10-23 22:59:44 -03:00
|
|
|
Logs.error('dronecangen returned {} error code'.format(ret))
|
|
|
|
return ret
|
|
|
|
|
|
|
|
def post_run(self):
|
|
|
|
super(dronecangen, self).post_run()
|
|
|
|
for header in self.generator.output_dir.ant_glob("*.h **/*.h", remove=False):
|
|
|
|
header.sig = header.cache_sig = self.cache_sig
|
|
|
|
|
|
|
|
def options(opt):
|
|
|
|
opt.load('python')
|
|
|
|
|
|
|
|
@feature('dronecangen')
|
|
|
|
@before_method('process_rule')
|
|
|
|
def process_dronecangen(self):
|
|
|
|
if not hasattr(self, 'output_dir'):
|
|
|
|
self.bld.fatal('dronecangen: missing option output_dir')
|
|
|
|
|
|
|
|
inputs = self.to_nodes(self.source)
|
2024-09-14 15:19:34 -03:00
|
|
|
# depend on each message file in the source so rebuilds will occur properly
|
|
|
|
deps = []
|
|
|
|
for inp in inputs:
|
|
|
|
deps.extend(inp.ant_glob("**/*.uavcan"))
|
|
|
|
# also depend on the generator source itself
|
|
|
|
dsdlc_dir = self.env.get_flat("DC_DSDL_COMPILER_DIR")
|
|
|
|
dsdlc = self.bld.root.find_node(dsdlc_dir) # expected to be absolute
|
|
|
|
if dsdlc is None:
|
|
|
|
self.bld.fatal("dronecangen: waf couldn't find dsdlc at abspath {}".format(dsdlc_dir))
|
|
|
|
deps.extend(dsdlc.ant_glob("**/*.py **/*.em"))
|
2022-10-23 22:59:44 -03:00
|
|
|
outputs = []
|
|
|
|
|
|
|
|
self.source = []
|
|
|
|
|
|
|
|
if not isinstance(self.output_dir, Node.Node):
|
|
|
|
self.output_dir = self.bld.bldnode.find_or_declare(self.output_dir)
|
|
|
|
|
|
|
|
task = self.create_task('dronecangen', inputs, outputs)
|
2024-09-14 15:19:34 -03:00
|
|
|
task.dep_nodes = deps
|
2022-10-23 22:59:44 -03:00
|
|
|
task.env['OUTPUT_DIR'] = self.output_dir.abspath()
|
|
|
|
|
|
|
|
task.env.env = dict(os.environ)
|
|
|
|
|
|
|
|
def configure(cfg):
|
|
|
|
"""
|
|
|
|
setup environment for uavcan header generator
|
|
|
|
"""
|
|
|
|
env = cfg.env
|
2023-01-05 09:07:00 -04:00
|
|
|
env.DC_DSDL_COMPILER_DIR = cfg.srcnode.make_node('modules/DroneCAN/dronecan_dsdlc/').abspath()
|
2024-09-14 15:19:34 -03:00
|
|
|
cfg.msg('DC_DSDL compiler in', env.DC_DSDL_COMPILER_DIR)
|