4 from __future__
import print_function
12 sys
.path
.insert(0, 'Tools/ardupilotwaf/')
17 from waflib
import Build
, ConfigSet
, Configure
, Context
, Utils
18 from waflib
.Configure
import conf
20 # Ref: https://stackoverflow.com/questions/40590192/getting-an-error-attributeerror-module-object-has-no-attribute-run-while
22 from subprocess
import CompletedProcess
25 class CompletedProcess
:
27 def __init__(self
, args
, returncode
, stdout
=None, stderr
=None):
29 self
.returncode
= returncode
33 def check_returncode(self
):
34 if self
.returncode
!= 0:
35 err
= subprocess
.CalledProcessError(self
.returncode
, self
.args
, output
=self
.stdout
)
37 return self
.returncode
39 def sp_run(*popenargs
, **kwargs
):
40 input = kwargs
.pop("input", None)
41 check
= kwargs
.pop("handle", False)
42 kwargs
.pop("capture_output", True)
45 raise ValueError('stdin and input arguments may not both be used.')
46 kwargs
['stdin'] = subprocess
.PIPE
47 process
= subprocess
.Popen(*popenargs
, **kwargs
)
49 outs
, errs
= process
.communicate(input)
54 returncode
= process
.poll()
55 if check
and returncode
:
56 raise subprocess
.CalledProcessError(returncode
, popenargs
, output
=outs
)
57 return CompletedProcess(popenargs
, returncode
, stdout
=outs
, stderr
=errs
)
59 subprocess
.run
= sp_run
60 # ^ This monkey patch allows it work on Python 2 or 3 the same way
63 # TODO: implement a command 'waf help' that shows the basic tasks a
64 # developer might want to do: e.g. how to configure a board, compile a
65 # vehicle, compile all the examples, add a new example. Should fit in
66 # less than a terminal screen, ideally commands should be copy
67 # pastable. Add the 'export waf="$PWD/waf"' trick to be copy-pastable
70 # TODO: replace defines with the use of the generated ap_config.h file
71 # this makes recompilation at least when defines change. which might
74 # Default installation prefix for Linux boards
75 default_prefix
= '/usr/'
77 # Override Build execute and Configure post_recurse methods for autoconfigure purposes
78 Build
.BuildContext
.execute
= ardupilotwaf
.ap_autoconfigure(Build
.BuildContext
.execute
)
79 Configure
.ConfigurationContext
.post_recurse
= ardupilotwaf
.ap_configure_post_recurse()
82 def _set_build_context_variant(board
):
83 for c
in Context
.classes
:
84 if not issubclass(c
, Build
.BuildContext
):
89 # Generate Task List, so that VS Code extension can keep track
90 # of changes to possible build targets
91 generate_tasklist(ctx
, False)
92 env
= ConfigSet
.ConfigSet()
94 p
= os
.path
.join(Context
.out_dir
, Build
.CACHE_DIR
, Build
.CACHE_SUFFIX
)
96 except EnvironmentError:
99 Configure
.autoconfig
= 'clobber' if env
.AUTOCONFIG
else False
101 board
= ctx
.options
.board
or env
.BOARD
106 # define the variant build commands according to the board
107 _set_build_context_variant(board
)
110 opt
.load('compiler_cxx compiler_c waf_unit_test python')
111 opt
.load('ardupilotwaf')
112 opt
.load('build_summary')
114 g
= opt
.ap_groups
['configure']
116 boards_names
= boards
.get_boards_names()
117 removed_names
= boards
.get_removed_boards()
118 g
.add_option('--board',
121 help='Target board to build, choices are %s.' % ', '.join(boards_names
))
123 g
.add_option('--debug',
126 help='Configure as debug variant.')
128 g
.add_option('--disable-watchdog',
131 help='Build with watchdog disabled.')
133 g
.add_option('--coverage',
136 help='Configure coverage flags.')
138 g
.add_option('--Werror',
141 help='build with -Werror.')
143 g
.add_option('--toolchain',
146 help='Override default toolchain used for the board. Use "native" for using the host toolchain.')
148 g
.add_option('--disable-gccdeps',
151 help='Disable the use of GCC dependencies output method and use waf default method.')
153 g
.add_option('--enable-asserts',
156 help='enable OS level asserts.')
158 g
.add_option('--save-temps',
161 help='save compiler temporary files.')
163 g
.add_option('--enable-malloc-guard',
166 help='enable malloc guard regions.')
168 g
.add_option('--enable-stats',
171 help='enable OS level thread statistics.')
173 g
.add_option('--bootloader',
176 help='Configure for building a bootloader.')
178 g
.add_option('--signed-fw',
181 help='Configure for signed firmware support.')
183 g
.add_option('--private-key',
186 help='path to private key for signing firmware.')
188 g
.add_option('--no-autoconfig',
190 action
='store_false',
192 help='''Disable autoconfiguration feature. By default, the build system
193 triggers a reconfiguration whenever it thinks it's necessary - this
194 option disables that.
197 g
.add_option('--no-submodule-update',
198 dest
='submodule_update',
199 action
='store_false',
201 help='''Don't update git submodules. Useful for building with
202 submodules at specific revisions.
205 g
.add_option('--enable-header-checks', action
='store_true',
207 help="Enable checking of headers")
209 g
.add_option('--default-parameters',
211 help='set default parameters to embed in the firmware')
213 g
.add_option('--enable-math-check-indexes',
216 help="Enable checking of math indexes")
218 g
.add_option('--disable-scripting', action
='store_true',
220 help="Disable onboard scripting engine")
222 g
.add_option('--no-gcs', action
='store_true',
224 help="Disable GCS code")
226 g
.add_option('--scripting-checks', action
='store_true',
228 help="Enable runtime scripting sanity checks")
230 g
.add_option('--enable-onvif', action
='store_true',
232 help="Enables and sets up ONVIF camera control")
234 g
.add_option('--scripting-docs', action
='store_true',
236 help="enable generation of scripting documentation")
238 g
.add_option('--enable-opendroneid', action
='store_true',
240 help="Enables OpenDroneID")
242 g
.add_option('--enable-check-firmware', action
='store_true',
244 help="Enables firmware ID checking on boot")
246 g
.add_option('--enable-custom-controller', action
='store_true',
248 help="Enables custom controller")
250 g
.add_option('--enable-gps-logging', action
='store_true',
252 help="Enables GPS logging")
254 g
= opt
.ap_groups
['linux']
256 linux_options
= ('--prefix', '--destdir', '--bindir', '--libdir')
257 for k
in linux_options
:
258 option
= opt
.parser
.get_option(k
)
260 opt
.parser
.remove_option(k
)
263 g
.add_option('--apstatedir',
266 help='''Where to save data like parameters, log and terrain.
267 This is the --localstatedir + ArduPilots subdirectory [default:
268 board-dependent, usually /var/lib/ardupilot]''')
270 g
.add_option('--rsync-dest',
274 help='''Destination for the rsync Waf command. It can be passed during
275 configuration in order to save typing.
278 g
.add_option('--enable-benchmarks',
281 help='Enable benchmarks.')
283 g
.add_option('--enable-lttng', action
='store_true',
285 help="Enable lttng integration")
287 g
.add_option('--disable-libiio', action
='store_true',
289 help="Don't use libiio even if supported by board and dependencies available")
291 g
.add_option('--disable-tests', action
='store_true',
293 help="Disable compilation and test execution")
295 g
.add_option('--enable-sfml', action
='store_true',
297 help="Enable SFML graphics library")
299 g
.add_option('--enable-sfml-joystick', action
='store_true',
301 help="Enable SFML joystick input library")
303 g
.add_option('--enable-sfml-audio', action
='store_true',
305 help="Enable SFML audio library")
307 g
.add_option('--osd', action
='store_true',
309 help="Enable OSD support")
311 g
.add_option('--osd-fonts', action
='store_true',
313 help="Enable OSD support with fonts")
315 g
.add_option('--sitl-osd', action
='store_true',
317 help="Enable SITL OSD")
319 g
.add_option('--sitl-rgbled', action
='store_true',
321 help="Enable SITL RGBLed")
323 g
.add_option('--sitl-32bit', action
='store_true',
325 help="Enable SITL 32bit")
327 g
.add_option('--build-dates', action
='store_true',
329 help="Include build date in binaries. Appears in AUTOPILOT_VERSION.os_sw_version")
331 g
.add_option('--sitl-flash-storage',
334 help='Use flash storage emulation.')
336 g
.add_option('--disable-ekf2',
339 help='Configure without EKF2.')
341 g
.add_option('--disable-ekf3',
344 help='Configure without EKF3.')
346 g
.add_option('--ekf-double',
349 help='Configure EKF as double precision.')
351 g
.add_option('--ekf-single',
354 help='Configure EKF as single precision.')
356 g
.add_option('--static',
359 help='Force a static build')
361 g
.add_option('--postype-single',
364 help='force single precision postype_t')
366 g
.add_option('--extra-hwdef',
369 help='Extra hwdef.dat file for custom build.')
371 g
.add_option('--assert-cc-version',
373 help='fail configure if not using the specified gcc version')
375 def _collect_autoconfig_files(cfg
):
376 for m
in sys
.modules
.values():
378 if hasattr(m
, '__file__') and m
.__file
__ is not None:
379 paths
.append(m
.__file
__)
380 elif hasattr(m
, '__path__'):
386 if p
in cfg
.files
or not os
.path
.isfile(p
):
389 with
open(p
, 'rb') as f
:
390 cfg
.hash = Utils
.h_list((cfg
.hash, f
.read()))
394 # we need to enable debug mode when building for gconv, and force it to sitl
395 if cfg
.options
.board
is None:
396 cfg
.options
.board
= 'sitl'
398 boards_names
= boards
.get_boards_names()
399 if not cfg
.options
.board
in boards_names
:
400 for b
in boards_names
:
401 if b
.upper() == cfg
.options
.board
.upper():
402 cfg
.options
.board
= b
405 cfg
.env
.BOARD
= cfg
.options
.board
406 cfg
.env
.DEBUG
= cfg
.options
.debug
407 cfg
.env
.COVERAGE
= cfg
.options
.coverage
408 cfg
.env
.AUTOCONFIG
= cfg
.options
.autoconfig
410 _set_build_context_variant(cfg
.env
.BOARD
)
411 cfg
.setenv(cfg
.env
.BOARD
)
413 if cfg
.options
.signed_fw
:
414 cfg
.env
.AP_SIGNED_FIRMWARE
= True
415 cfg
.options
.enable_check_firmware
= True
417 cfg
.env
.BOARD
= cfg
.options
.board
418 cfg
.env
.DEBUG
= cfg
.options
.debug
419 cfg
.env
.COVERAGE
= cfg
.options
.coverage
420 cfg
.env
.SITL32BIT
= cfg
.options
.sitl_32bit
421 cfg
.env
.ENABLE_ASSERTS
= cfg
.options
.enable_asserts
422 cfg
.env
.BOOTLOADER
= cfg
.options
.bootloader
423 cfg
.env
.ENABLE_MALLOC_GUARD
= cfg
.options
.enable_malloc_guard
424 cfg
.env
.ENABLE_STATS
= cfg
.options
.enable_stats
425 cfg
.env
.SAVE_TEMPS
= cfg
.options
.save_temps
427 cfg
.env
.HWDEF_EXTRA
= cfg
.options
.extra_hwdef
428 if cfg
.env
.HWDEF_EXTRA
:
429 cfg
.env
.HWDEF_EXTRA
= os
.path
.abspath(cfg
.env
.HWDEF_EXTRA
)
431 cfg
.env
.OPTIONS
= cfg
.options
.__dict
__
433 # Allow to differentiate our build from the make build
434 cfg
.define('WAF_BUILD', 1)
436 cfg
.msg('Autoconfiguration', 'enabled' if cfg
.options
.autoconfig
else 'disabled')
438 if cfg
.options
.static
:
439 cfg
.msg('Using static linking', 'yes', color
='YELLOW')
440 cfg
.env
.STATIC_LINKING
= True
442 cfg
.load('ap_library')
444 cfg
.msg('Setting board to', cfg
.options
.board
)
445 cfg
.get_board().configure(cfg
)
447 cfg
.load('clang_compilation_database')
448 cfg
.load('waf_unit_test')
450 if cfg
.options
.board
in cfg
.ap_periph_boards():
451 cfg
.load('dronecangen')
453 cfg
.load('uavcangen')
455 cfg
.env
.SUBMODULE_UPDATE
= cfg
.options
.submodule_update
457 cfg
.start_msg('Source is git repository')
458 if cfg
.srcnode
.find_node('.git'):
462 cfg
.env
.SUBMODULE_UPDATE
= False
464 cfg
.msg('Update submodules', 'yes' if cfg
.env
.SUBMODULE_UPDATE
else 'no')
465 cfg
.load('git_submodule')
467 if cfg
.options
.enable_benchmarks
:
468 cfg
.load('gbenchmark')
470 cfg
.load('static_linking')
471 cfg
.load('build_summary')
473 cfg
.start_msg('Benchmarks')
474 if cfg
.env
.HAS_GBENCHMARK
:
475 cfg
.end_msg('enabled')
477 cfg
.end_msg('disabled', color
='YELLOW')
479 cfg
.start_msg('Unit tests')
480 if cfg
.env
.HAS_GTEST
:
481 cfg
.end_msg('enabled')
483 cfg
.end_msg('disabled', color
='YELLOW')
485 cfg
.start_msg('Scripting')
486 if cfg
.options
.disable_scripting
:
487 cfg
.end_msg('disabled', color
='YELLOW')
489 cfg
.end_msg('enabled')
490 cfg
.recurse('libraries/AP_Scripting')
492 cfg
.recurse('libraries/AP_GPS')
494 cfg
.start_msg('Scripting runtime checks')
495 if cfg
.options
.scripting_checks
:
496 cfg
.end_msg('enabled')
498 cfg
.end_msg('disabled', color
='YELLOW')
500 cfg
.start_msg('Debug build')
502 cfg
.end_msg('enabled')
504 cfg
.end_msg('disabled', color
='YELLOW')
506 cfg
.start_msg('Coverage build')
508 cfg
.end_msg('enabled')
510 cfg
.end_msg('disabled', color
='YELLOW')
512 cfg
.start_msg('SITL 32-bit build')
513 if cfg
.env
.SITL32BIT
:
514 cfg
.end_msg('enabled')
516 cfg
.end_msg('disabled', color
='YELLOW')
518 cfg
.env
.append_value('GIT_SUBMODULES', 'mavlink')
520 cfg
.env
.prepend_value('INCLUDES', [
521 cfg
.srcnode
.abspath() + '/libraries/',
524 cfg
.find_program('rsync', mandatory
=False)
525 if cfg
.options
.rsync_dest
:
526 cfg
.msg('Setting rsync destination to', cfg
.options
.rsync_dest
)
527 cfg
.env
.RSYNC_DEST
= cfg
.options
.rsync_dest
529 if cfg
.options
.enable_header_checks
:
530 cfg
.msg('Enabling header checks', cfg
.options
.enable_header_checks
)
531 cfg
.env
.ENABLE_HEADER_CHECKS
= True
533 cfg
.env
.ENABLE_HEADER_CHECKS
= False
535 # TODO: Investigate if code could be changed to not depend on the
536 # source absolute path.
537 cfg
.env
.prepend_value('DEFINES', [
538 'SKETCHBOOK="' + cfg
.srcnode
.abspath() + '"',
541 # Always use system extensions
542 cfg
.define('_GNU_SOURCE', 1)
544 cfg
.write_config_header(os
.path
.join(cfg
.variant
, 'ap_config.h'), guard
='_AP_CONFIG_H_')
546 # add in generated flags
547 cfg
.env
.CXXFLAGS
+= ['-include', 'ap_config.h']
549 _collect_autoconfig_files(cfg
)
551 def collect_dirs_to_recurse(bld
, globs
, **kw
):
553 globs
= Utils
.to_list(globs
)
555 if bld
.bldnode
.is_child_of(bld
.srcnode
):
556 kw
['excl'] = Utils
.to_list(kw
.get('excl', []))
557 kw
['excl'].append(bld
.bldnode
.path_from(bld
.srcnode
))
560 for d
in bld
.srcnode
.ant_glob(g
+ '/wscript', **kw
):
561 dirs
.append(d
.parent
.relpath())
564 def list_boards(ctx
):
565 print(*boards
.get_boards_names())
567 def list_ap_periph_boards(ctx
):
568 print(*boards
.get_ap_periph_boards())
571 def ap_periph_boards(ctx
):
572 return boards
.get_ap_periph_boards()
574 def generate_tasklist(ctx
, do_print
=True):
575 boardlist
= boards
.get_boards_names()
576 ap_periph_targets
= boards
.get_ap_periph_boards()
578 with
open(os
.path
.join(Context
.top_dir
, "tasklist.json"), "w") as tlist
:
579 for board
in boardlist
:
581 task
['configure'] = board
582 if board
in ap_periph_targets
:
583 if 'sitl' not in board
:
584 # we only support AP_Periph and bootloader builds
585 task
['targets'] = ['AP_Periph', 'bootloader']
587 task
['targets'] = ['AP_Periph']
588 elif 'iofirmware' in board
:
589 task
['targets'] = ['iofirmware', 'bootloader']
591 if 'sitl' in board
or 'SITL' in board
:
592 task
['targets'] = ['antennatracker', 'copter', 'heli', 'plane', 'rover', 'sub', 'replay']
593 elif 'linux' in board
:
594 task
['targets'] = ['antennatracker', 'copter', 'heli', 'plane', 'rover', 'sub']
596 task
['targets'] = ['antennatracker', 'copter', 'heli', 'plane', 'rover', 'sub', 'bootloader']
597 task
['buildOptions'] = '--upload'
599 tlist
.write(json
.dumps(tasks
))
601 print(json
.dumps(tasks
))
604 env
= ConfigSet
.ConfigSet()
606 p
= os
.path
.join(Context
.out_dir
, Build
.CACHE_DIR
, Build
.CACHE_SUFFIX
)
609 print('No board currently configured')
612 print('Board configured to: {}'.format(env
.BOARD
))
614 def _build_cmd_tweaks(bld
):
615 if bld
.cmd
== 'check-all':
616 bld
.options
.all_tests
= True
619 if bld
.cmd
== 'check':
620 if not bld
.env
.HAS_GTEST
:
621 bld
.fatal('check: gtest library is required')
622 bld
.options
.clear_failed_tests
= True
624 def _build_dynamic_sources(bld
):
625 if not bld
.env
.BOOTLOADER
:
628 source
='modules/mavlink/message_definitions/v1.0/all.xml',
629 output_dir
='libraries/GCS_MAVLink/include/mavlink/v2.0/',
631 # this below is not ideal, mavgen tool should set this, but that's not
634 bld
.bldnode
.make_node('libraries').abspath(),
635 bld
.bldnode
.make_node('libraries/GCS_MAVLink').abspath(),
639 if (bld
.get_board().with_can
or bld
.env
.HAL_NUM_CAN_IFACES
) and not bld
.env
.AP_PERIPH
:
641 features
='uavcangen',
642 source
=bld
.srcnode
.ant_glob('modules/DroneCAN/DSDL/* libraries/AP_UAVCAN/dsdl/*', dir=True, src
=False),
643 output_dir
='modules/uavcan/libuavcan/include/dsdlc_generated',
646 bld
.bldnode
.make_node('modules/uavcan/libuavcan/include/dsdlc_generated').abspath(),
647 bld
.srcnode
.find_dir('modules/uavcan/libuavcan/include').abspath()
650 elif bld
.env
.AP_PERIPH
:
652 features
='dronecangen',
653 source
=bld
.srcnode
.ant_glob('modules/DroneCAN/DSDL/* libraries/AP_UAVCAN/dsdl/*', dir=True, src
=False),
654 output_dir
='modules/DroneCAN/libcanard/dsdlc_generated/',
657 bld
.bldnode
.make_node('modules/DroneCAN/libcanard/dsdlc_generated/include').abspath(),
658 bld
.srcnode
.find_dir('modules/DroneCAN/libcanard/').abspath(),
662 def write_version_header(tsk
):
663 bld
= tsk
.generator
.bld
664 return bld
.write_version_header(tsk
.outputs
[0].abspath())
668 target
='ap_version.h',
669 vars=['AP_VERSION_ITEMS'],
670 rule
=write_version_header
,
673 bld
.env
.prepend_value('INCLUDES', [
674 bld
.bldnode
.abspath(),
677 def _build_common_taskgens(bld
):
678 # NOTE: Static library with vehicle set to UNKNOWN, shared by all
679 # the tools and examples. This is the first step until the
680 # dependency on the vehicles is reduced. Later we may consider
681 # split into smaller pieces with well defined boundaries.
684 ap_vehicle
='UNKNOWN',
685 ap_libraries
=bld
.ap_get_all_libraries(),
688 if bld
.env
.HAS_GTEST
:
689 bld
.libgtest(cxxflags
=['-include', 'ap_config.h'])
691 if bld
.env
.HAS_GBENCHMARK
:
694 def _build_recursion(bld
):
695 common_dirs_patterns
= [
696 # TODO: Currently each vehicle also generate its own copy of the
697 # libraries. Fix this, or at least reduce the amount of
698 # vehicle-dependent libraries.
701 'libraries/*/examples/*',
703 'libraries/*/utility/tests',
704 'libraries/*/benchmarks',
709 'libraries/AP_HAL_*',
712 hal_dirs_patterns
= [
713 'libraries/%s/tests',
714 'libraries/%s/*/tests',
715 'libraries/%s/*/benchmarks',
716 'libraries/%s/examples/*',
719 dirs_to_recurse
= collect_dirs_to_recurse(
721 common_dirs_patterns
,
722 excl
=common_dirs_excl
,
724 if bld
.env
.IOMCU_FW
is not None:
726 dirs_to_recurse
.append('libraries/AP_IOMCU/iofirmware')
728 if bld
.env
.PERIPH_FW
is not None:
729 if bld
.env
.PERIPH_FW
:
730 dirs_to_recurse
.append('Tools/AP_Periph')
732 dirs_to_recurse
.append('libraries/AP_Scripting')
734 if bld
.env
.ENABLE_ONVIF
:
735 dirs_to_recurse
.append('libraries/AP_ONVIF')
737 for p
in hal_dirs_patterns
:
738 dirs_to_recurse
+= collect_dirs_to_recurse(
740 [p
% l
for l
in bld
.env
.AP_LIBRARIES
],
743 # NOTE: we need to sort to ensure the repeated sources get the
744 # same index, and random ordering of the filesystem doesn't cause
746 dirs_to_recurse
.sort()
748 for d
in dirs_to_recurse
:
751 def _build_post_funs(bld
):
752 if bld
.cmd
== 'check':
753 bld
.add_post_fun(ardupilotwaf
.test_summary
)
755 bld
.build_summary_post_fun()
757 if bld
.env
.SUBMODULE_UPDATE
:
758 bld
.git_submodule_post_fun()
760 def _load_pre_build(bld
):
761 '''allow for a pre_build() function in build modules'''
762 if bld
.cmd
== 'clean':
764 brd
= bld
.get_board()
765 if getattr(brd
, 'pre_build', None):
769 config_hash
= Utils
.h_file(bld
.bldnode
.make_node('ap_config.h').abspath())
770 bld
.env
.CCDEPS
= config_hash
771 bld
.env
.CXXDEPS
= config_hash
773 bld
.post_mode
= Build
.POST_LAZY
775 bld
.load('ardupilotwaf')
777 bld
.env
.AP_LIBRARIES_OBJECTS_KW
.update(
779 cxxflags
=['-include', 'ap_config.h'],
784 if bld
.get_board().with_can
:
785 bld
.env
.AP_LIBRARIES_OBJECTS_KW
['use'] += ['uavcan']
786 if bld
.env
.AP_PERIPH
:
787 bld
.env
.AP_LIBRARIES_OBJECTS_KW
['use'] += ['dronecan']
789 _build_cmd_tweaks(bld
)
791 if bld
.env
.SUBMODULE_UPDATE
:
792 bld
.add_group('git_submodules')
793 for name
in bld
.env
.GIT_SUBMODULES
:
794 bld
.git_submodule(name
)
796 bld
.add_group('dynamic_sources')
797 _build_dynamic_sources(bld
)
799 bld
.add_group('build')
800 bld
.get_board().build(bld
)
801 _build_common_taskgens(bld
)
803 _build_recursion(bld
)
805 _build_post_funs(bld
)
807 ardupilotwaf
.build_command('check',
808 program_group_list
='all',
809 doc
='builds all programs and run tests',
811 ardupilotwaf
.build_command('check-all',
812 program_group_list
='all',
813 doc
='shortcut for `waf check --alltests`',
816 for name
in ('antennatracker', 'copter', 'heli', 'plane', 'rover', 'sub', 'blimp', 'bootloader','iofirmware','AP_Periph','replay'):
817 ardupilotwaf
.build_command(name
,
818 program_group_list
=name
,
819 doc
='builds %s programs' % name
,
822 for program_group
in ('all', 'bin', 'tool', 'examples', 'tests', 'benchmarks'):
823 ardupilotwaf
.build_command(program_group
,
824 program_group_list
=program_group
,
825 doc
='builds all programs of %s group' % program_group
,
828 class LocalInstallContext(Build
.InstallContext
):
829 """runs install using BLD/install as destdir, where BLD is the build variant directory"""
832 def __init__(self
, **kw
):
833 super(LocalInstallContext
, self
).__init
__(**kw
)
834 self
.local_destdir
= os
.path
.join(self
.variant_dir
, 'install')
837 old_destdir
= self
.options
.destdir
838 self
.options
.destdir
= self
.local_destdir
839 r
= super(LocalInstallContext
, self
).execute()
840 self
.options
.destdir
= old_destdir
843 class RsyncContext(LocalInstallContext
):
844 """runs localinstall and then rsyncs BLD/install with the target system"""
847 def __init__(self
, **kw
):
848 super(RsyncContext
, self
).__init
__(**kw
)
849 self
.add_pre_fun(RsyncContext
.create_rsync_taskgen
)
851 def create_rsync_taskgen(self
):
852 if 'RSYNC' not in self
.env
:
853 self
.fatal('rsync program seems not to be installed, can\'t continue')
859 rule
='${RSYNC} -a ${RSYNC_SRC}/ ${RSYNC_DEST}',
863 tg
.env
.RSYNC_SRC
= self
.local_destdir
864 if self
.options
.rsync_dest
:
865 self
.env
.RSYNC_DEST
= self
.options
.rsync_dest
867 if 'RSYNC_DEST' not in tg
.env
:
868 self
.fatal('Destination for rsync not defined. Either pass --rsync-dest here or during configuration.')