CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
Ardupilot

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.

GitHub Repository: Ardupilot/ardupilot
Path: blob/master/Tools/ardupilotwaf/dronecangen.py
Views: 1798
1
# encoding: utf-8
2
3
"""
4
generate DSDLC headers for uavcan
5
"""
6
7
from waflib import Logs, Task, Utils, Node
8
from waflib.TaskGen import feature, before_method, extension
9
import os
10
import os.path
11
from xml.etree import ElementTree as et
12
import subprocess
13
14
class dronecangen(Task.Task):
15
"""generate uavcan header files"""
16
color = 'BLUE'
17
before = 'cxx c'
18
19
def run(self):
20
python = self.env.get_flat('PYTHON')
21
out = self.env.get_flat('OUTPUT_DIR')
22
src = self.env.get_flat('SRC')
23
dsdlc = self.env.get_flat("DC_DSDL_COMPILER_DIR")
24
25
cmd = ['{}'.format(python),
26
'{}/dronecan_dsdlc.py'.format(dsdlc),
27
'-O{}'.format(out)] + [x.abspath() for x in self.inputs]
28
ret = self.exec_command(cmd)
29
if ret != 0:
30
# ignore if there was a signal to the interpreter rather
31
# than a real error in the script. Some environments use a
32
# signed and some an unsigned return for this
33
if ret > 128 or ret < 0:
34
Logs.warn('dronecangen crashed with code: {}'.format(ret))
35
ret = 0
36
else:
37
Logs.warn('dronecangen: cmd=%s ' % str(cmd))
38
# re-run command with stdout visible to see errors
39
subprocess.call(cmd)
40
Logs.error('dronecangen returned {} error code'.format(ret))
41
return ret
42
43
def post_run(self):
44
super(dronecangen, self).post_run()
45
for header in self.generator.output_dir.ant_glob("*.h **/*.h", remove=False):
46
header.sig = header.cache_sig = self.cache_sig
47
48
def options(opt):
49
opt.load('python')
50
51
@feature('dronecangen')
52
@before_method('process_rule')
53
def process_dronecangen(self):
54
if not hasattr(self, 'output_dir'):
55
self.bld.fatal('dronecangen: missing option output_dir')
56
57
inputs = self.to_nodes(self.source)
58
# depend on each message file in the source so rebuilds will occur properly
59
deps = []
60
for inp in inputs:
61
deps.extend(inp.ant_glob("**/*.uavcan"))
62
# also depend on the generator source itself
63
dsdlc_dir = self.env.get_flat("DC_DSDL_COMPILER_DIR")
64
dsdlc = self.bld.root.find_node(dsdlc_dir) # expected to be absolute
65
if dsdlc is None:
66
self.bld.fatal("dronecangen: waf couldn't find dsdlc at abspath {}".format(dsdlc_dir))
67
deps.extend(dsdlc.ant_glob("**/*.py **/*.em"))
68
outputs = []
69
70
self.source = []
71
72
if not isinstance(self.output_dir, Node.Node):
73
self.output_dir = self.bld.bldnode.find_or_declare(self.output_dir)
74
75
task = self.create_task('dronecangen', inputs, outputs)
76
task.dep_nodes = deps
77
task.env['OUTPUT_DIR'] = self.output_dir.abspath()
78
79
task.env.env = dict(os.environ)
80
81
def configure(cfg):
82
"""
83
setup environment for uavcan header generator
84
"""
85
env = cfg.env
86
env.DC_DSDL_COMPILER_DIR = cfg.srcnode.make_node('modules/DroneCAN/dronecan_dsdlc/').abspath()
87
cfg.msg('DC_DSDL compiler in', env.DC_DSDL_COMPILER_DIR)
88
89