AP_TECS: Remove duplicate setting of flare pitch upper limit
[ardupilot.git] / wscript
blobb72d2a6eb31d55855e994653ffae90f92f7028d8
1 #!/usr/bin/env python
2 # encoding: utf-8
4 from __future__ import print_function
6 import os.path
7 import os
8 import sys
9 import subprocess
10 import json
11 import fnmatch
12 sys.path.insert(0, 'Tools/ardupilotwaf/')
14 import ardupilotwaf
15 import boards
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
21 try:
22 from subprocess import CompletedProcess
23 except ImportError:
24 # Python 2
25 class CompletedProcess:
27 def __init__(self, args, returncode, stdout=None, stderr=None):
28 self.args = args
29 self.returncode = returncode
30 self.stdout = stdout
31 self.stderr = stderr
33 def check_returncode(self):
34 if self.returncode != 0:
35 err = subprocess.CalledProcessError(self.returncode, self.args, output=self.stdout)
36 raise err
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)
43 if input is not None:
44 if 'stdin' in kwargs:
45 raise ValueError('stdin and input arguments may not both be used.')
46 kwargs['stdin'] = subprocess.PIPE
47 process = subprocess.Popen(*popenargs, **kwargs)
48 try:
49 outs, errs = process.communicate(input)
50 except:
51 process.kill()
52 process.wait()
53 raise
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
68 # as well.
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
72 # be sufficient.
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):
85 continue
86 c.variant = board
88 def init(ctx):
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()
93 try:
94 p = os.path.join(Context.out_dir, Build.CACHE_DIR, Build.CACHE_SUFFIX)
95 env.load(p)
96 except EnvironmentError:
97 return
99 Configure.autoconfig = 'clobber' if env.AUTOCONFIG else False
101 board = ctx.options.board or env.BOARD
103 if not board:
104 return
106 # define the variant build commands according to the board
107 _set_build_context_variant(board)
109 def options(opt):
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',
119 action='store',
120 default=None,
121 help='Target board to build, choices are %s.' % ', '.join(boards_names))
123 g.add_option('--debug',
124 action='store_true',
125 default=False,
126 help='Configure as debug variant.')
128 g.add_option('--disable-watchdog',
129 action='store_true',
130 default=False,
131 help='Build with watchdog disabled.')
133 g.add_option('--coverage',
134 action='store_true',
135 default=False,
136 help='Configure coverage flags.')
138 g.add_option('--Werror',
139 action='store_true',
140 default=False,
141 help='build with -Werror.')
143 g.add_option('--toolchain',
144 action='store',
145 default=None,
146 help='Override default toolchain used for the board. Use "native" for using the host toolchain.')
148 g.add_option('--disable-gccdeps',
149 action='store_true',
150 default=False,
151 help='Disable the use of GCC dependencies output method and use waf default method.')
153 g.add_option('--enable-asserts',
154 action='store_true',
155 default=False,
156 help='enable OS level asserts.')
158 g.add_option('--save-temps',
159 action='store_true',
160 default=False,
161 help='save compiler temporary files.')
163 g.add_option('--enable-malloc-guard',
164 action='store_true',
165 default=False,
166 help='enable malloc guard regions.')
168 g.add_option('--enable-stats',
169 action='store_true',
170 default=False,
171 help='enable OS level thread statistics.')
173 g.add_option('--bootloader',
174 action='store_true',
175 default=False,
176 help='Configure for building a bootloader.')
178 g.add_option('--signed-fw',
179 action='store_true',
180 default=False,
181 help='Configure for signed firmware support.')
183 g.add_option('--private-key',
184 action='store',
185 default=None,
186 help='path to private key for signing firmware.')
188 g.add_option('--no-autoconfig',
189 dest='autoconfig',
190 action='store_false',
191 default=True,
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.
195 ''')
197 g.add_option('--no-submodule-update',
198 dest='submodule_update',
199 action='store_false',
200 default=True,
201 help='''Don't update git submodules. Useful for building with
202 submodules at specific revisions.
203 ''')
205 g.add_option('--enable-header-checks', action='store_true',
206 default=False,
207 help="Enable checking of headers")
209 g.add_option('--default-parameters',
210 default=None,
211 help='set default parameters to embed in the firmware')
213 g.add_option('--enable-math-check-indexes',
214 action='store_true',
215 default=False,
216 help="Enable checking of math indexes")
218 g.add_option('--disable-scripting', action='store_true',
219 default=False,
220 help="Disable onboard scripting engine")
222 g.add_option('--no-gcs', action='store_true',
223 default=False,
224 help="Disable GCS code")
226 g.add_option('--scripting-checks', action='store_true',
227 default=True,
228 help="Enable runtime scripting sanity checks")
230 g.add_option('--enable-onvif', action='store_true',
231 default=False,
232 help="Enables and sets up ONVIF camera control")
234 g.add_option('--scripting-docs', action='store_true',
235 default=False,
236 help="enable generation of scripting documentation")
238 g.add_option('--enable-opendroneid', action='store_true',
239 default=False,
240 help="Enables OpenDroneID")
242 g.add_option('--enable-check-firmware', action='store_true',
243 default=False,
244 help="Enables firmware ID checking on boot")
246 g.add_option('--enable-custom-controller', action='store_true',
247 default=False,
248 help="Enables custom controller")
250 g.add_option('--enable-gps-logging', action='store_true',
251 default=False,
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)
259 if option:
260 opt.parser.remove_option(k)
261 g.add_option(option)
263 g.add_option('--apstatedir',
264 action='store',
265 default='',
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',
271 dest='rsync_dest',
272 action='store',
273 default='',
274 help='''Destination for the rsync Waf command. It can be passed during
275 configuration in order to save typing.
276 ''')
278 g.add_option('--enable-benchmarks',
279 action='store_true',
280 default=False,
281 help='Enable benchmarks.')
283 g.add_option('--enable-lttng', action='store_true',
284 default=False,
285 help="Enable lttng integration")
287 g.add_option('--disable-libiio', action='store_true',
288 default=False,
289 help="Don't use libiio even if supported by board and dependencies available")
291 g.add_option('--disable-tests', action='store_true',
292 default=False,
293 help="Disable compilation and test execution")
295 g.add_option('--enable-sfml', action='store_true',
296 default=False,
297 help="Enable SFML graphics library")
299 g.add_option('--enable-sfml-joystick', action='store_true',
300 default=False,
301 help="Enable SFML joystick input library")
303 g.add_option('--enable-sfml-audio', action='store_true',
304 default=False,
305 help="Enable SFML audio library")
307 g.add_option('--osd', action='store_true',
308 default=False,
309 help="Enable OSD support")
311 g.add_option('--osd-fonts', action='store_true',
312 default=False,
313 help="Enable OSD support with fonts")
315 g.add_option('--sitl-osd', action='store_true',
316 default=False,
317 help="Enable SITL OSD")
319 g.add_option('--sitl-rgbled', action='store_true',
320 default=False,
321 help="Enable SITL RGBLed")
323 g.add_option('--sitl-32bit', action='store_true',
324 default=False,
325 help="Enable SITL 32bit")
327 g.add_option('--build-dates', action='store_true',
328 default=False,
329 help="Include build date in binaries. Appears in AUTOPILOT_VERSION.os_sw_version")
331 g.add_option('--sitl-flash-storage',
332 action='store_true',
333 default=False,
334 help='Use flash storage emulation.')
336 g.add_option('--disable-ekf2',
337 action='store_true',
338 default=False,
339 help='Configure without EKF2.')
341 g.add_option('--disable-ekf3',
342 action='store_true',
343 default=False,
344 help='Configure without EKF3.')
346 g.add_option('--ekf-double',
347 action='store_true',
348 default=False,
349 help='Configure EKF as double precision.')
351 g.add_option('--ekf-single',
352 action='store_true',
353 default=False,
354 help='Configure EKF as single precision.')
356 g.add_option('--static',
357 action='store_true',
358 default=False,
359 help='Force a static build')
361 g.add_option('--postype-single',
362 action='store_true',
363 default=False,
364 help='force single precision postype_t')
366 g.add_option('--extra-hwdef',
367 action='store',
368 default=None,
369 help='Extra hwdef.dat file for custom build.')
371 g.add_option('--assert-cc-version',
372 default=None,
373 help='fail configure if not using the specified gcc version')
375 def _collect_autoconfig_files(cfg):
376 for m in sys.modules.values():
377 paths = []
378 if hasattr(m, '__file__') and m.__file__ is not None:
379 paths.append(m.__file__)
380 elif hasattr(m, '__path__'):
381 for p in m.__path__:
382 if p is not None:
383 paths.append(p)
385 for p in paths:
386 if p in cfg.files or not os.path.isfile(p):
387 continue
389 with open(p, 'rb') as f:
390 cfg.hash = Utils.h_list((cfg.hash, f.read()))
391 cfg.files.append(p)
393 def configure(cfg):
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
403 break
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')
449 cfg.load('mavgen')
450 if cfg.options.board in cfg.ap_periph_boards():
451 cfg.load('dronecangen')
452 else:
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'):
459 cfg.end_msg('yes')
460 else:
461 cfg.end_msg('no')
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')
469 cfg.load('gtest')
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')
476 else:
477 cfg.end_msg('disabled', color='YELLOW')
479 cfg.start_msg('Unit tests')
480 if cfg.env.HAS_GTEST:
481 cfg.end_msg('enabled')
482 else:
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')
488 else:
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')
497 else:
498 cfg.end_msg('disabled', color='YELLOW')
500 cfg.start_msg('Debug build')
501 if cfg.env.DEBUG:
502 cfg.end_msg('enabled')
503 else:
504 cfg.end_msg('disabled', color='YELLOW')
506 cfg.start_msg('Coverage build')
507 if cfg.env.COVERAGE:
508 cfg.end_msg('enabled')
509 else:
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')
515 else:
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
532 else:
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):
552 dirs = []
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))
559 for g in globs:
560 for d in bld.srcnode.ant_glob(g + '/wscript', **kw):
561 dirs.append(d.parent.relpath())
562 return dirs
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())
570 @conf
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()
577 tasks = []
578 with open(os.path.join(Context.top_dir, "tasklist.json"), "w") as tlist:
579 for board in boardlist:
580 task = {}
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']
586 else:
587 task['targets'] = ['AP_Periph']
588 elif 'iofirmware' in board:
589 task['targets'] = ['iofirmware', 'bootloader']
590 else:
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']
595 else:
596 task['targets'] = ['antennatracker', 'copter', 'heli', 'plane', 'rover', 'sub', 'bootloader']
597 task['buildOptions'] = '--upload'
598 tasks.append(task)
599 tlist.write(json.dumps(tasks))
600 if do_print:
601 print(json.dumps(tasks))
603 def board(ctx):
604 env = ConfigSet.ConfigSet()
605 try:
606 p = os.path.join(Context.out_dir, Build.CACHE_DIR, Build.CACHE_SUFFIX)
607 env.load(p)
608 except:
609 print('No board currently configured')
610 return
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
617 bld.cmd = 'check'
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:
626 bld(
627 features='mavgen',
628 source='modules/mavlink/message_definitions/v1.0/all.xml',
629 output_dir='libraries/GCS_MAVLink/include/mavlink/v2.0/',
630 name='mavlink',
631 # this below is not ideal, mavgen tool should set this, but that's not
632 # currently possible
633 export_includes=[
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:
640 bld(
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',
644 name='uavcan',
645 export_includes=[
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:
651 bld(
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/',
655 name='dronecan',
656 export_includes=[
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())
666 bld(
667 name='ap_version',
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.
682 bld.ap_stlib(
683 name='ap',
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:
692 bld.libbenchmark()
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.
699 '*',
700 'Tools/*',
701 'libraries/*/examples/*',
702 'libraries/*/tests',
703 'libraries/*/utility/tests',
704 'libraries/*/benchmarks',
707 common_dirs_excl = [
708 'modules',
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(
720 bld,
721 common_dirs_patterns,
722 excl=common_dirs_excl,
724 if bld.env.IOMCU_FW is not None:
725 if bld.env.IOMCU_FW:
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(
739 bld,
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
745 # recompilation.
746 dirs_to_recurse.sort()
748 for d in dirs_to_recurse:
749 bld.recurse(d)
751 def _build_post_funs(bld):
752 if bld.cmd == 'check':
753 bld.add_post_fun(ardupilotwaf.test_summary)
754 else:
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':
763 return
764 brd = bld.get_board()
765 if getattr(brd, 'pre_build', None):
766 brd.pre_build(bld)
768 def build(bld):
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(
778 use=['mavlink'],
779 cxxflags=['-include', 'ap_config.h'],
782 _load_pre_build(bld)
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"""
830 cmd = 'localinstall'
832 def __init__(self, **kw):
833 super(LocalInstallContext, self).__init__(**kw)
834 self.local_destdir = os.path.join(self.variant_dir, 'install')
836 def execute(self):
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
841 return r
843 class RsyncContext(LocalInstallContext):
844 """runs localinstall and then rsyncs BLD/install with the target system"""
845 cmd = 'rsync'
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')
855 self.add_group()
857 tg = self(
858 name='rsync',
859 rule='${RSYNC} -a ${RSYNC_SRC}/ ${RSYNC_DEST}',
860 always=True,
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.')
870 tg.post()