2015-10-09 11:03:59 -03:00
|
|
|
#!/usr/bin/env python
|
|
|
|
# encoding: utf-8
|
|
|
|
|
2015-11-30 11:41:45 -04:00
|
|
|
from __future__ import print_function
|
|
|
|
|
2015-10-09 11:03:59 -03:00
|
|
|
import os.path
|
|
|
|
import sys
|
|
|
|
sys.path.insert(0, 'Tools/ardupilotwaf/')
|
|
|
|
|
|
|
|
import ardupilotwaf
|
2015-11-26 10:34:24 -04:00
|
|
|
import boards
|
2015-12-10 14:22:07 -04:00
|
|
|
|
2016-02-05 08:21:23 -04:00
|
|
|
from waflib import Build, ConfigSet, Context, Utils
|
2015-10-09 11:03:59 -03:00
|
|
|
|
|
|
|
# TODO: implement a command 'waf help' that shows the basic tasks a
|
|
|
|
# developer might want to do: e.g. how to configure a board, compile a
|
|
|
|
# vehicle, compile all the examples, add a new example. Should fit in
|
|
|
|
# less than a terminal screen, ideally commands should be copy
|
|
|
|
# pastable. Add the 'export waf="$PWD/waf"' trick to be copy-pastable
|
|
|
|
# as well.
|
|
|
|
|
|
|
|
# TODO: replace defines with the use of a generated config.h file
|
|
|
|
# this makes recompilation at least when defines change. which might
|
|
|
|
# be sufficient.
|
|
|
|
|
|
|
|
# TODO: set git version as part of build preparation.
|
|
|
|
|
2015-12-10 14:22:07 -04:00
|
|
|
def init(ctx):
|
|
|
|
env = ConfigSet.ConfigSet()
|
|
|
|
try:
|
|
|
|
env.load('build/c4che/_cache.py')
|
|
|
|
except:
|
|
|
|
return
|
|
|
|
|
|
|
|
# define the variant build commands according to the board
|
2016-02-05 08:21:23 -04:00
|
|
|
for c in Context.classes:
|
|
|
|
if not issubclass(c, Build.BuildContext):
|
2016-01-27 07:48:59 -04:00
|
|
|
continue
|
|
|
|
c.variant = env.BOARD
|
2015-12-10 14:22:07 -04:00
|
|
|
|
2015-10-09 11:03:59 -03:00
|
|
|
def options(opt):
|
2016-01-02 07:22:36 -04:00
|
|
|
opt.load('compiler_cxx compiler_c waf_unit_test python')
|
2016-02-17 08:35:29 -04:00
|
|
|
|
2016-02-17 08:48:08 -04:00
|
|
|
opt.ap_groups = {
|
|
|
|
'configure': opt.add_option_group('Ardupilot configure options'),
|
|
|
|
'build': opt.add_option_group('Ardupilot build options'),
|
|
|
|
'check': opt.add_option_group('Ardupilot check options'),
|
|
|
|
}
|
|
|
|
|
|
|
|
opt.load('ardupilotwaf')
|
|
|
|
|
|
|
|
g = opt.ap_groups['configure']
|
2016-02-17 08:35:29 -04:00
|
|
|
boards_names = boards.get_boards_names()
|
|
|
|
g.add_option('--board',
|
2015-10-09 11:03:59 -03:00
|
|
|
action='store',
|
2015-11-26 10:34:24 -04:00
|
|
|
choices=boards_names,
|
2015-10-09 11:03:59 -03:00
|
|
|
default='sitl',
|
2015-11-26 10:34:24 -04:00
|
|
|
help='Target board to build, choices are %s' % boards_names)
|
2015-10-09 11:03:59 -03:00
|
|
|
|
2016-02-19 12:44:32 -04:00
|
|
|
g.add_option('--no-submodule-update',
|
|
|
|
dest='submodule_update',
|
|
|
|
action='store_false',
|
|
|
|
default=True,
|
|
|
|
help='Don\'t update git submodules. Useful for building ' +
|
|
|
|
'with submodules at specific revisions.')
|
|
|
|
|
2016-02-17 09:13:37 -04:00
|
|
|
g.add_option('--enable-benchmarks',
|
|
|
|
action='store_true',
|
|
|
|
default=False,
|
|
|
|
help='Enable benchmarks')
|
|
|
|
|
2015-10-09 11:03:59 -03:00
|
|
|
def configure(cfg):
|
2015-12-10 14:22:07 -04:00
|
|
|
cfg.env.BOARD = cfg.options.board
|
|
|
|
# use a different variant for each board
|
|
|
|
cfg.setenv(cfg.env.BOARD)
|
|
|
|
|
2015-11-25 11:48:45 -04:00
|
|
|
cfg.msg('Setting board to', cfg.options.board)
|
|
|
|
cfg.env.BOARD = cfg.options.board
|
2016-02-15 17:26:14 -04:00
|
|
|
boards.get_board(cfg.env.BOARD).configure(cfg)
|
2015-11-25 11:48:45 -04:00
|
|
|
|
2015-10-26 23:27:55 -03:00
|
|
|
cfg.load('clang_compilation_database')
|
2015-10-30 12:50:44 -03:00
|
|
|
cfg.load('waf_unit_test')
|
2016-01-02 07:22:36 -04:00
|
|
|
cfg.load('mavgen')
|
2016-02-05 08:28:11 -04:00
|
|
|
cfg.load('git_submodule')
|
2016-02-17 09:13:37 -04:00
|
|
|
if cfg.options.enable_benchmarks:
|
|
|
|
cfg.load('gbenchmark')
|
2016-01-18 12:41:21 -04:00
|
|
|
cfg.load('gtest')
|
2016-01-07 07:16:53 -04:00
|
|
|
cfg.load('static_linking')
|
2015-11-12 17:39:30 -04:00
|
|
|
|
|
|
|
cfg.start_msg('Benchmarks')
|
|
|
|
if cfg.env.HAS_GBENCHMARK:
|
|
|
|
cfg.end_msg('enabled')
|
|
|
|
else:
|
|
|
|
cfg.end_msg('disabled', color='YELLOW')
|
2015-10-09 11:03:59 -03:00
|
|
|
|
2016-01-18 12:41:21 -04:00
|
|
|
cfg.start_msg('Unit tests')
|
|
|
|
if cfg.env.HAS_GTEST:
|
|
|
|
cfg.end_msg('enabled')
|
|
|
|
else:
|
|
|
|
cfg.end_msg('disabled', color='YELLOW')
|
2015-10-30 13:14:28 -03:00
|
|
|
|
2016-02-05 12:09:21 -04:00
|
|
|
cfg.env.append_value('GIT_SUBMODULES', 'mavlink')
|
|
|
|
|
2015-10-09 11:03:59 -03:00
|
|
|
cfg.env.prepend_value('INCLUDES', [
|
2016-01-02 07:22:36 -04:00
|
|
|
cfg.srcnode.abspath() + '/libraries/',
|
2016-01-13 16:52:56 -04:00
|
|
|
])
|
2015-10-09 11:03:59 -03:00
|
|
|
|
|
|
|
# TODO: Investigate if code could be changed to not depend on the
|
|
|
|
# source absolute path.
|
|
|
|
cfg.env.prepend_value('DEFINES', [
|
|
|
|
'SKETCHBOOK="' + cfg.srcnode.abspath() + '"',
|
|
|
|
])
|
|
|
|
|
2016-02-19 12:44:32 -04:00
|
|
|
if cfg.options.submodule_update:
|
2016-03-01 18:30:04 -04:00
|
|
|
cfg.env.SUBMODULE_UPDATE = True
|
2016-02-19 12:44:32 -04:00
|
|
|
|
2016-04-06 00:45:43 -03:00
|
|
|
cfg.write_config_header(os.path.join(cfg.variant, 'ap_config.h'))
|
2016-04-05 17:09:48 -03:00
|
|
|
|
2015-11-04 09:34:11 -04:00
|
|
|
def collect_dirs_to_recurse(bld, globs, **kw):
|
2015-10-09 11:03:59 -03:00
|
|
|
dirs = []
|
2015-12-10 14:22:07 -04:00
|
|
|
globs = Utils.to_list(globs)
|
2016-03-09 18:36:35 -04:00
|
|
|
|
|
|
|
if bld.bldnode.is_child_of(bld.srcnode):
|
|
|
|
kw['excl'] = Utils.to_list(kw.get('excl', []))
|
|
|
|
kw['excl'].append(bld.bldnode.path_from(bld.srcnode))
|
|
|
|
|
2015-11-04 09:34:11 -04:00
|
|
|
for g in globs:
|
|
|
|
for d in bld.srcnode.ant_glob(g + '/wscript', **kw):
|
|
|
|
dirs.append(d.parent.relpath())
|
2015-10-09 11:03:59 -03:00
|
|
|
return dirs
|
|
|
|
|
2015-11-30 11:41:45 -04:00
|
|
|
def list_boards(ctx):
|
2015-11-26 10:34:24 -04:00
|
|
|
print(*boards.get_boards_names())
|
2015-11-30 11:41:45 -04:00
|
|
|
|
2016-02-03 08:53:19 -04:00
|
|
|
def _build_cmd_tweaks(bld):
|
2016-01-27 12:39:40 -04:00
|
|
|
if bld.cmd == 'check-all':
|
|
|
|
bld.options.all_tests = True
|
|
|
|
bld.cmd = 'check'
|
|
|
|
|
2016-02-03 08:53:19 -04:00
|
|
|
if bld.cmd == 'check':
|
|
|
|
bld.options.clear_failed_tests = True
|
|
|
|
if not bld.env.HAS_GTEST:
|
|
|
|
bld.fatal('check: gtest library is required')
|
|
|
|
bld.add_post_fun(ardupilotwaf.test_summary)
|
|
|
|
|
2016-02-05 08:28:11 -04:00
|
|
|
def _build_dynamic_sources(bld):
|
2016-01-13 16:35:37 -04:00
|
|
|
bld(
|
|
|
|
features='mavgen',
|
|
|
|
source='modules/mavlink/message_definitions/v1.0/ardupilotmega.xml',
|
2016-01-14 12:32:26 -04:00
|
|
|
output_dir='libraries/GCS_MAVLink/include/mavlink/v1.0/',
|
2016-01-13 16:35:37 -04:00
|
|
|
name='mavlink',
|
2016-01-13 16:52:56 -04:00
|
|
|
# this below is not ideal, mavgen tool should set this, but that's not
|
|
|
|
# currently possible
|
|
|
|
export_includes=[
|
|
|
|
bld.bldnode.make_node('libraries').abspath(),
|
|
|
|
bld.bldnode.make_node('libraries/GCS_MAVLink').abspath(),
|
|
|
|
],
|
2016-01-13 16:35:37 -04:00
|
|
|
)
|
2016-01-02 07:22:36 -04:00
|
|
|
|
2016-02-05 08:28:11 -04:00
|
|
|
def _build_common_taskgens(bld):
|
2015-10-09 11:03:59 -03:00
|
|
|
# NOTE: Static library with vehicle set to UNKNOWN, shared by all
|
|
|
|
# the tools and examples. This is the first step until the
|
|
|
|
# dependency on the vehicles is reduced. Later we may consider
|
|
|
|
# split into smaller pieces with well defined boundaries.
|
waf: use ardupilotwaf as a Waf tool
That will make it possible to replace calls of the form
`ardupilotwaf.<method>(bld, <keyword-args...>)` with
`bld.<method>(<keyword-args...>)` in the wscripts.
Advantages of that approach:
- there is no need to import ardupilotwaf in every single wscript
- it follows the same standard used by c and cxx tools (like bld.program,
bld.stlib etc)
- semantically, ap_program, ap_stlib, example etc are all build related
methods, so it makes sense to bind them to the build context
- from the wscripts' perspective, the code is cleaner, since ardupilotwaf,
which is not specific to just build contexts, isn't *explictly* used
2016-01-21 09:47:10 -04:00
|
|
|
bld.ap_stlib(
|
2015-10-09 11:03:59 -03:00
|
|
|
name='ap',
|
|
|
|
vehicle='UNKNOWN',
|
2016-01-22 17:00:13 -04:00
|
|
|
libraries=bld.ap_get_all_libraries(),
|
2016-01-13 16:35:37 -04:00
|
|
|
use='mavlink',
|
2015-10-09 11:03:59 -03:00
|
|
|
)
|
2016-02-02 16:38:42 -04:00
|
|
|
|
2016-02-05 08:59:13 -04:00
|
|
|
bld.libgtest()
|
|
|
|
|
2016-02-17 17:34:48 -04:00
|
|
|
if bld.env.HAS_GBENCHMARK:
|
|
|
|
bld.libbenchmark()
|
|
|
|
|
2016-02-03 08:53:19 -04:00
|
|
|
def _build_recursion(bld):
|
2016-02-02 16:38:42 -04:00
|
|
|
common_dirs_patterns = [
|
|
|
|
# TODO: Currently each vehicle also generate its own copy of the
|
|
|
|
# libraries. Fix this, or at least reduce the amount of
|
|
|
|
# vehicle-dependent libraries.
|
|
|
|
'*',
|
|
|
|
'Tools/*',
|
|
|
|
'libraries/*/examples/*',
|
|
|
|
'**/tests',
|
|
|
|
'**/benchmarks',
|
|
|
|
]
|
|
|
|
|
|
|
|
common_dirs_excl = [
|
|
|
|
'modules',
|
|
|
|
'libraries/AP_HAL_*',
|
|
|
|
'libraries/SITL',
|
|
|
|
]
|
|
|
|
|
|
|
|
hal_dirs_patterns = [
|
|
|
|
'libraries/%s/**/tests',
|
|
|
|
'libraries/%s/**/benchmarks',
|
|
|
|
'libraries/%s/examples/*',
|
|
|
|
]
|
|
|
|
|
|
|
|
dirs_to_recurse = collect_dirs_to_recurse(
|
|
|
|
bld,
|
|
|
|
common_dirs_patterns,
|
|
|
|
excl=common_dirs_excl,
|
|
|
|
)
|
|
|
|
|
|
|
|
for p in hal_dirs_patterns:
|
|
|
|
dirs_to_recurse += collect_dirs_to_recurse(
|
|
|
|
bld,
|
|
|
|
[p % l for l in bld.env.AP_LIBRARIES],
|
|
|
|
)
|
2015-10-09 11:03:59 -03:00
|
|
|
|
|
|
|
# NOTE: we need to sort to ensure the repeated sources get the
|
|
|
|
# same index, and random ordering of the filesystem doesn't cause
|
|
|
|
# recompilation.
|
2016-02-02 16:38:42 -04:00
|
|
|
dirs_to_recurse.sort()
|
|
|
|
|
|
|
|
for d in dirs_to_recurse:
|
2015-10-09 11:03:59 -03:00
|
|
|
bld.recurse(d)
|
2015-10-30 12:50:44 -03:00
|
|
|
|
2016-02-03 08:53:19 -04:00
|
|
|
def build(bld):
|
2016-04-06 00:45:43 -03:00
|
|
|
config_header = Utils.h_file(bld.bldnode.make_node('ap_config.h').abspath())
|
2016-04-05 17:09:48 -03:00
|
|
|
|
|
|
|
bld.env.CCDEPS = config_header
|
|
|
|
bld.env.CXXDEPS = config_header
|
|
|
|
|
2016-02-05 08:28:11 -04:00
|
|
|
bld.post_mode = Build.POST_LAZY
|
|
|
|
|
2016-02-03 08:53:19 -04:00
|
|
|
bld.load('ardupilotwaf')
|
|
|
|
|
|
|
|
_build_cmd_tweaks(bld)
|
2016-02-05 08:28:11 -04:00
|
|
|
|
2016-02-19 12:44:32 -04:00
|
|
|
if bld.env.SUBMODULE_UPDATE:
|
|
|
|
bld.add_group('git_submodules')
|
|
|
|
for name in bld.env.GIT_SUBMODULES:
|
|
|
|
bld.git_submodule(name)
|
2016-02-05 08:28:11 -04:00
|
|
|
|
|
|
|
bld.add_group('dynamic_sources')
|
|
|
|
_build_dynamic_sources(bld)
|
|
|
|
|
|
|
|
bld.add_group('build')
|
2016-02-24 15:18:00 -04:00
|
|
|
boards.get_board(bld.env.BOARD).build(bld)
|
2016-02-05 08:28:11 -04:00
|
|
|
_build_common_taskgens(bld)
|
|
|
|
|
2016-02-03 08:53:19 -04:00
|
|
|
_build_recursion(bld)
|
2015-10-30 12:50:44 -03:00
|
|
|
|
2016-01-27 12:16:37 -04:00
|
|
|
ardupilotwaf.build_command('check',
|
2016-01-27 12:07:36 -04:00
|
|
|
program_group_list='all',
|
|
|
|
doc='builds all programs and run tests',
|
|
|
|
)
|
2016-01-27 12:39:40 -04:00
|
|
|
ardupilotwaf.build_command('check-all',
|
|
|
|
program_group_list='all',
|
|
|
|
doc='shortcut for `waf check --alltests`',
|
|
|
|
)
|
2016-01-15 12:14:00 -04:00
|
|
|
|
2016-03-24 17:18:06 -03:00
|
|
|
for name in ('antennatracker', 'copter', 'plane', 'rover'):
|
|
|
|
ardupilotwaf.build_command(name,
|
|
|
|
program_group_list=name,
|
|
|
|
doc='builds %s programs' % name,
|
|
|
|
)
|
2016-01-27 08:57:29 -04:00
|
|
|
|
|
|
|
for program_group in ('all', 'bin', 'tools', 'examples', 'tests', 'benchmarks'):
|
2016-01-27 12:16:37 -04:00
|
|
|
ardupilotwaf.build_command(program_group,
|
2016-01-27 11:58:48 -04:00
|
|
|
program_group_list=program_group,
|
|
|
|
doc='builds all programs of %s group' % program_group,
|
|
|
|
)
|