From e6fa2d54e89db4c648e7d2c7825e70e8b3a1e127 Mon Sep 17 00:00:00 2001 From: Gustavo Jose de Sousa Date: Thu, 3 Mar 2016 17:01:04 -0300 Subject: [PATCH] waf: px4: build firmware Copy the program library to the place where PX4Firmware CMake build will look for and trigger the firmware build. There isn't really a real output defined for px4_copy_lib because Waf would complain about multiple tasks having same output when building multiple programs. After the firmware build, copy it to the correct place (from program group and name perspective) and add git hashes. Since the place where the library is placed is shared by different target programs, we need to synchronize the firmware build, that's why the use of _firmware_semaphorish_tasks. That variable is set as a list because of the upcoming upload task. --- Tools/ardupilotwaf/px4.py | 96 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 93 insertions(+), 3 deletions(-) diff --git a/Tools/ardupilotwaf/px4.py b/Tools/ardupilotwaf/px4.py index 3655888ded..c698d132a7 100644 --- a/Tools/ardupilotwaf/px4.py +++ b/Tools/ardupilotwaf/px4.py @@ -64,6 +64,40 @@ def px4_import_objects_from_use(self): queue.extend(Utils.to_list(getattr(tg, 'use', []))) +class px4_copy_lib(Task.Task): + run_str = '${CP} ${SRC} ${PX4_AP_PROGRAM_LIB}' + color = 'CYAN' + + def runnable_status(self): + status = super(px4_copy_lib, self).runnable_status() + if status != Task.SKIP_ME: + return status + + pseudo_target = self.get_pseudo_target() + try: + if pseudo_target.sig != self.inputs[0].sig: + status = Task.RUN_ME + except AttributeError: + status = Task.RUN_ME + + return status + + def get_pseudo_target(self): + if hasattr(self, 'pseudo_target'): + return self.pseudo_target + + bldnode = self.generator.bld.bldnode + self.pseudo_target = bldnode.make_node(self.env.PX4_AP_PROGRAM_LIB) + return self.pseudo_target + + def keyword(self): + return 'PX4: Copying program library' + + def post_run(self): + super(px4_copy_lib, self).post_run() + pseudo_target = self.get_pseudo_target() + pseudo_target.sig = pseudo_target.cache_sig = self.inputs[0].sig + class px4_copy(Task.Task): run_str = '${CP} ${SRC} ${TGT}' color = 'CYAN' @@ -71,12 +105,30 @@ class px4_copy(Task.Task): def keyword(self): return "PX4: Copying %s to" % self.inputs[0].name +class px4_add_git_hashes(Task.Task): + run_str = '${PYTHON} ${PX4_ADD_GIT_HASHES} --ardupilot ${PX4_APM_ROOT} --px4 ${PX4_ROOT} --nuttx ${PX4_NUTTX_ROOT} --uavcan ${PX4_UAVCAN_ROOT} ${SRC} ${TGT}' + color = 'CYAN' + + def keyword(self): + return "PX4: Copying firmware and adding git hashes" + + def __str__(self): + return self.outputs[0].path_from(self.outputs[0].ctx.launch_node()) + +def _update_firmware_sig(fw_task, firmware): + original_post_run = fw_task.post_run + def post_run(): + original_post_run() + firmware.sig = firmware.cache_sig = Utils.h_file(firmware.abspath()) + fw_task.post_run = post_run + _cp_px4io = None +_firmware_semaphorish_tasks = [] @feature('px4_ap_program') @after_method('process_source') def px4_firmware(self): - global _cp_px4io + global _cp_px4io, _firmware_semaphorish_tasks version = self.env.get_flat('PX4_VERSION') if self.env.PX4_USE_PX4IO and not _cp_px4io: @@ -92,6 +144,34 @@ def px4_firmware(self): _cp_px4io = self.create_task('px4_copy', px4io, romfs_px4io) _cp_px4io.keyword = lambda: 'PX4: Copying PX4IO to ROMFS' + cp_lib = self.create_task('px4_copy_lib', self.link_task.outputs) + # we need to synchronize because the path PX4_AP_PROGRAM_LIB is used by all + # ap_programs + if _firmware_semaphorish_tasks: + for t in _firmware_semaphorish_tasks: + cp_lib.set_run_after(t) + _firmware_semaphorish_tasks = [] + + fw_task = self.create_cmake_build_task( + 'px4', + 'build_firmware_px4fmu-v%s' % version, + ) + fw_task.set_run_after(cp_lib) + if self.env.PX4_USE_PX4IO and _cp_px4io.generator is self: + fw_task.set_run_after(_cp_px4io) + + firmware = fw_task.config_taskgen.cmake_bld.make_node( + 'src/firmware/nuttx/nuttx-px4fmu-v%s-apm.px4' % version, + ) + _update_firmware_sig(fw_task, firmware) + + fw_dest = self.bld.bldnode.make_node( + os.path.join(self.program_group, '%s.px4' % self.program_name) + ) + git_hashes = self.create_task('px4_add_git_hashes', firmware, fw_dest) + git_hashes.set_run_after(fw_task) + _firmware_semaphorish_tasks.append(git_hashes) + def _px4_taskgen(bld, **kw): if 'cls_keyword' in kw and not callable(kw['cls_keyword']): cls_keyword = str(kw['cls_keyword']) @@ -132,12 +212,22 @@ def configure(cfg): env.PX4_ROMFS_BLD = 'px4-extra-files/ROMFS' env.PX4_BOOTLOADER = 'mk/PX4/bootloader/%s' % bootloader_name + program_lib_name = cfg.env.cxxstlib_PATTERN % 'ap_program' + env.PX4_AP_PROGRAM_LIB = os.path.join('px4-extra-files', program_lib_name) + + env.PX4_ADD_GIT_HASHES = srcpath('Tools/scripts/add_git_hashes.py') + env.PX4_APM_ROOT = srcpath('') + env.PX4_ROOT = srcpath('modules/PX4Firmware') + env.PX4_NUTTX_ROOT = srcpath('modules/PX4NuttX') + env.PX4_UAVCAN_ROOT = srcpath('modules/uavcan') + env.PX4_CMAKE_VARS = dict( CONFIG='nuttx_px4fmu-v%s_apm' % env.get_flat('PX4_VERSION'), CMAKE_MODULE_PATH=srcpath('Tools/ardupilotwaf/px4/cmake'), - UAVCAN_LIBUAVCAN_PATH=srcpath('modules/uavcan'), - NUTTX_SRC=srcpath('modules/PX4NuttX'), + UAVCAN_LIBUAVCAN_PATH=env.PX4_UAVCAN_ROOT, + NUTTX_SRC=env.PX4_NUTTX_ROOT, PX4_NUTTX_ROMFS=bldpath(env.PX4_ROMFS_BLD), + APM_PROGRAM_LIB=bldpath(env.PX4_AP_PROGRAM_LIB), EXTRA_CXX_FLAGS=' '.join(( # NOTE: these "-Wno-error=*" flags should be removed as we update # the submodule