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
|
|
|
|
|
|
|
from waflib import ConfigSet, Utils
|
|
|
|
from waflib.Build import BuildContext, CleanContext, InstallContext, UninstallContext
|
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
|
|
|
|
for c in (BuildContext, CleanContext, InstallContext, UninstallContext, CheckContext):
|
|
|
|
class context(c):
|
|
|
|
variant = env.BOARD
|
|
|
|
|
2015-10-09 11:03:59 -03:00
|
|
|
def options(opt):
|
2015-11-26 10:34:24 -04:00
|
|
|
boards_names = boards.get_boards_names()
|
|
|
|
|
2015-10-30 12:50:44 -03:00
|
|
|
opt.load('compiler_cxx compiler_c waf_unit_test')
|
2015-10-09 11:03:59 -03:00
|
|
|
opt.add_option('--board',
|
|
|
|
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
|
|
|
|
2015-10-30 12:50:44 -03:00
|
|
|
g = opt.add_option_group('Check options')
|
|
|
|
g.add_option('--check-verbose',
|
|
|
|
action='store_true',
|
|
|
|
help='Output all test programs')
|
|
|
|
|
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
|
|
|
|
board_dict = boards.BOARDS[cfg.env.BOARD].get_merged_dict()
|
|
|
|
|
|
|
|
# Always prepend so that arguments passed in the command line get
|
|
|
|
# the priority.
|
|
|
|
for k in board_dict:
|
|
|
|
val = board_dict[k]
|
|
|
|
# Dictionaries (like 'DEFINES') are converted to lists to
|
|
|
|
# conform to waf conventions.
|
|
|
|
if isinstance(val, dict):
|
|
|
|
for item in val.items():
|
|
|
|
cfg.env.prepend_value(k, '%s=%s' % item)
|
|
|
|
else:
|
|
|
|
cfg.env.prepend_value(k, val)
|
|
|
|
|
2015-11-30 17:13:20 -04:00
|
|
|
cfg.load('toolchain')
|
2015-10-09 11:03:59 -03:00
|
|
|
cfg.load('compiler_cxx compiler_c')
|
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')
|
2015-11-12 17:39:30 -04:00
|
|
|
cfg.load('gbenchmark')
|
|
|
|
|
|
|
|
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
|
|
|
|
2015-10-30 13:14:28 -03:00
|
|
|
cfg.env.HAS_GTEST = cfg.check_cxx(
|
|
|
|
lib='gtest',
|
|
|
|
mandatory=False,
|
|
|
|
uselib_store='GTEST',
|
|
|
|
errmsg='not found, unit tests disabled',
|
|
|
|
)
|
|
|
|
|
2015-10-09 11:03:59 -03:00
|
|
|
cfg.env.prepend_value('INCLUDES', [
|
|
|
|
cfg.srcnode.abspath() + '/libraries/'
|
|
|
|
])
|
|
|
|
|
|
|
|
# TODO: Investigate if code could be changed to not depend on the
|
|
|
|
# source absolute path.
|
|
|
|
cfg.env.prepend_value('DEFINES', [
|
|
|
|
'SKETCHBOOK="' + cfg.srcnode.abspath() + '"',
|
|
|
|
])
|
|
|
|
|
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)
|
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
|
|
|
|
2015-10-09 11:03:59 -03:00
|
|
|
def build(bld):
|
|
|
|
# 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.
|
|
|
|
ardupilotwaf.vehicle_stlib(
|
|
|
|
bld,
|
|
|
|
name='ap',
|
|
|
|
vehicle='UNKNOWN',
|
|
|
|
libraries=ardupilotwaf.get_all_libraries(bld),
|
|
|
|
)
|
|
|
|
|
|
|
|
# TODO: Currently each vehicle also generate its own copy of the
|
|
|
|
# libraries. Fix this, or at least reduce the amount of
|
|
|
|
# vehicle-dependent libraries.
|
|
|
|
vehicles = collect_dirs_to_recurse(bld, '*')
|
|
|
|
|
|
|
|
# NOTE: we need to sort to ensure the repeated sources get the
|
|
|
|
# same index, and random ordering of the filesystem doesn't cause
|
|
|
|
# recompilation.
|
|
|
|
vehicles.sort()
|
|
|
|
|
|
|
|
tools = collect_dirs_to_recurse(bld, 'Tools/*')
|
2015-10-30 12:50:44 -03:00
|
|
|
examples = collect_dirs_to_recurse(bld,
|
|
|
|
'libraries/*/examples/*',
|
|
|
|
excl='libraries/AP_HAL_* libraries/SITL')
|
|
|
|
|
|
|
|
tests = collect_dirs_to_recurse(bld,
|
|
|
|
'**/tests',
|
|
|
|
excl='modules Tools libraries/AP_HAL_* libraries/SITL')
|
|
|
|
board_tests = ['libraries/%s/**/tests' % l for l in bld.env.AP_LIBRARIES]
|
|
|
|
tests.extend(collect_dirs_to_recurse(bld, board_tests))
|
2015-10-09 11:03:59 -03:00
|
|
|
|
2015-11-12 17:39:30 -04:00
|
|
|
benchmarks = collect_dirs_to_recurse(bld,
|
|
|
|
'**/benchmarks',
|
|
|
|
excl='modules Tools libraries/AP_HAL_* libraries/SITL')
|
|
|
|
board_benchmarks = ['libraries/%s/**/benchmarks' % l for l in bld.env.AP_LIBRARIES]
|
|
|
|
benchmarks.extend(collect_dirs_to_recurse(bld, board_benchmarks))
|
|
|
|
|
2015-10-09 11:03:59 -03:00
|
|
|
hal_examples = []
|
|
|
|
for l in bld.env.AP_LIBRARIES:
|
|
|
|
hal_examples.extend(collect_dirs_to_recurse(bld, 'libraries/' + l + '/examples/*'))
|
|
|
|
|
2015-11-12 17:39:30 -04:00
|
|
|
for d in vehicles + tools + examples + hal_examples + tests + benchmarks:
|
2015-10-09 11:03:59 -03:00
|
|
|
bld.recurse(d)
|
2015-10-30 12:50:44 -03:00
|
|
|
|
|
|
|
if bld.cmd == 'check':
|
2015-10-30 13:14:28 -03:00
|
|
|
if not bld.env.HAS_GTEST:
|
|
|
|
bld.fatal('check: gtest library is required')
|
2015-10-30 12:50:44 -03:00
|
|
|
bld.add_post_fun(ardupilotwaf.test_summary)
|
|
|
|
|
2015-12-10 14:22:07 -04:00
|
|
|
class CheckContext(BuildContext):
|
2015-10-30 12:50:44 -03:00
|
|
|
'''executes tests after build'''
|
|
|
|
cmd = 'check'
|