diff --git a/Tools/AP_Periph/wscript b/Tools/AP_Periph/wscript index 6d298b73b7..cce626760f 100644 --- a/Tools/AP_Periph/wscript +++ b/Tools/AP_Periph/wscript @@ -72,6 +72,7 @@ def build(bld): name= 'AP_Periph_libs', ap_vehicle='AP_Periph', ap_libraries= libraries, + use='dronecan', exclude_src=[ 'libraries/AP_HAL_ChibiOS/Storage.cpp' ] @@ -80,14 +81,11 @@ def build(bld): # build external libcanard library bld.stlib(source=['../../modules/DroneCAN/libcanard/canard.c'] + bld.bldnode.ant_glob('modules/DroneCAN/libcanard/dsdlc_generated/src/**.c'), - includes=[bld.env.SRCROOT + '/modules/DroneCAN/libcanard', - bld.env.BUILDROOT + '/modules/DroneCAN/libcanard/dsdlc_generated/include'], + use='dronecan', target='libcanard') bld.ap_program( program_name='AP_Periph', - use=['AP_Periph_libs', 'libcanard'], + use=['AP_Periph_libs', 'libcanard', 'dronecan'], program_groups=['bin','AP_Periph'], - includes=[bld.env.SRCROOT + '/modules/DroneCAN/libcanard', - bld.env.BUILDROOT + '/modules/DroneCAN/libcanard/dsdlc_generated/include'] ) diff --git a/Tools/ardupilotwaf/boards.py b/Tools/ardupilotwaf/boards.py index ee0b0f9e66..4164a820b7 100644 --- a/Tools/ardupilotwaf/boards.py +++ b/Tools/ardupilotwaf/boards.py @@ -423,9 +423,6 @@ class Board: UAVCAN_NULLPTR = 'nullptr' ) - env.INCLUDES += [ - cfg.srcnode.find_dir('modules/uavcan/libuavcan/include').abspath() - ] if cfg.options.build_dates: env.build_dates = True diff --git a/Tools/ardupilotwaf/chibios.py b/Tools/ardupilotwaf/chibios.py index 1518025a53..89e2c9df86 100644 --- a/Tools/ardupilotwaf/chibios.py +++ b/Tools/ardupilotwaf/chibios.py @@ -459,10 +459,6 @@ def setup_canmgr_build(cfg): else: env.DEFINES += ['UAVCAN_SUPPORT_CANFD=0'] - - env.INCLUDES += [ - cfg.srcnode.find_dir('modules/uavcan/libuavcan/include').abspath(), - ] cfg.get_board().with_can = True def load_env_vars(env): diff --git a/Tools/ardupilotwaf/dronecangen.py b/Tools/ardupilotwaf/dronecangen.py new file mode 100644 index 0000000000..dd1d4fcd65 --- /dev/null +++ b/Tools/ardupilotwaf/dronecangen.py @@ -0,0 +1,75 @@ +# 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 + +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') + dsdlc = self.env.get_flat("DSDL_COMPILER") + + ret = self.exec_command(['{}'.format(python), + '{}'.format(dsdlc), + '-O{}'.format(out)] + [x.abspath() for x in self.inputs]) + 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: + 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) + 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) + task.env['OUTPUT_DIR'] = self.output_dir.abspath() + + task.env.env = dict(os.environ) + +def configure(cfg): + """ + setup environment for uavcan header generator + """ + cfg.load('python') + cfg.check_python_version(minver=(2,7,0)) + + env = cfg.env + env.DSDL_COMPILER_DIR = cfg.srcnode.make_node('modules/DroneCAN/dronecan_dsdlc/').abspath() + env.DSDL_COMPILER = env.DSDL_COMPILER_DIR + '/dronecan_dsdlc.py' + cfg.msg('DSDL compiler', env.DSDL_COMPILER) diff --git a/Tools/ardupilotwaf/uavcangen.py b/Tools/ardupilotwaf/uavcangen.py index 1ec550a025..0ca74c947b 100644 --- a/Tools/ardupilotwaf/uavcangen.py +++ b/Tools/ardupilotwaf/uavcangen.py @@ -73,3 +73,4 @@ def configure(cfg): env = cfg.env env.DSDL_COMPILER_DIR = cfg.srcnode.make_node('modules/uavcan/libuavcan/dsdl_compiler').abspath() env.DSDL_COMPILER = env.DSDL_COMPILER_DIR + '/libuavcan_dsdlc' + cfg.msg('DSDL compiler', env.DSDL_COMPILER) diff --git a/wscript b/wscript index dd027602d0..5243bf7569 100644 --- a/wscript +++ b/wscript @@ -447,7 +447,10 @@ def configure(cfg): cfg.load('clang_compilation_database') cfg.load('waf_unit_test') cfg.load('mavgen') - cfg.load('uavcangen') + if cfg.options.board in cfg.ap_periph_boards(): + cfg.load('dronecangen') + else: + cfg.load('uavcangen') cfg.env.SUBMODULE_UPDATE = cfg.options.submodule_update @@ -545,26 +548,6 @@ def configure(cfg): _collect_autoconfig_files(cfg) -def generate_dronecan_dsdlc(cfg): - dsdlc_gen_path = cfg.bldnode.make_node('modules/DroneCAN/libcanard/dsdlc_generated').abspath() - src = cfg.srcnode.ant_glob('modules/DroneCAN/DSDL/* libraries/AP_UAVCAN/dsdl/*', dir=True, src=False) - dsdlc_path = cfg.srcnode.make_node('modules/DroneCAN/dronecan_dsdlc/dronecan_dsdlc.py').abspath() - if not os.path.exists(dsdlc_path): - print("Please update submodules with: git submodule update --recursive --init") - sys.exit(1) - src = ' '.join([s.abspath() for s in src]) - cmd = '{} {} -O {} {}'.format(cfg.env.get_flat('PYTHON'), - dsdlc_path, - dsdlc_gen_path, - src) - print("Generating DSDLC for CANARD: " + cmd) - ret = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - if ret.returncode != 0: - print('Failed to run: ', cmd) - print(ret.stdout.decode('utf-8')) - print(ret.stderr.decode('utf-8')) - raise RuntimeError('Failed to generate DSDL C bindings') - def collect_dirs_to_recurse(bld, globs, **kw): dirs = [] globs = Utils.to_list(globs) @@ -661,9 +644,20 @@ def _build_dynamic_sources(bld): name='uavcan', export_includes=[ bld.bldnode.make_node('modules/uavcan/libuavcan/include/dsdlc_generated').abspath(), + bld.srcnode.find_dir('modules/uavcan/libuavcan/include').abspath() + ] + ) + elif bld.env.AP_PERIPH: + bld( + features='dronecangen', + source=bld.srcnode.ant_glob('modules/DroneCAN/DSDL/* libraries/AP_UAVCAN/dsdl/*', dir=True, src=False), + output_dir='modules/DroneCAN/libcanard/dsdlc_generated/', + name='dronecan', + export_includes=[ + bld.bldnode.make_node('modules/DroneCAN/libcanard/dsdlc_generated/include').abspath(), + bld.srcnode.find_dir('modules/DroneCAN/libcanard/').abspath(), ] ) - def write_version_header(tsk): bld = tsk.generator.bld @@ -768,12 +762,6 @@ def _load_pre_build(bld): if bld.cmd == 'clean': return brd = bld.get_board() - if bld.env.AP_PERIPH: - dsdlc_gen_path = bld.bldnode.make_node('modules/DroneCAN/libcanard/dsdlc_generated/include').abspath() - #check if canard dsdlc directory empty - # check if directory exists - if not os.path.exists(dsdlc_gen_path) or not os.listdir(dsdlc_gen_path): - generate_dronecan_dsdlc(bld) if getattr(brd, 'pre_build', None): brd.pre_build(bld)