waf: support changing board to build without re-configure

This allows to use the board option when building as long as it has been configured before

As we don't want to force configuration of all boards each single time, auto-configuration support now has to be done per-board
This commit is contained in:
Francisco Ferreira 2018-09-02 01:30:36 +01:00 committed by Andrew Tridgell
parent 2e3b4df47e
commit ff77000d93
2 changed files with 105 additions and 15 deletions

View File

@ -2,8 +2,9 @@
# encoding: utf-8
from __future__ import print_function
from waflib import Build, Logs, Options, Utils
from waflib import Build, ConfigSet, Configure, Context, Errors, Logs, Options, Utils
from waflib.Configure import conf
from waflib.Scripting import run_command
from waflib.TaskGen import before_method, feature
import os.path, os
from collections import OrderedDict
@ -92,6 +93,86 @@ IGNORED_AP_LIBRARIES = [
'AP_Scripting', # this gets explicitly included when it is needed and should otherwise never be globbed in
]
def ap_autoconfigure(execute_method):
"""
Decorator that enables context commands to run *configure* as needed.
"""
def execute(self):
"""
Wraps :py:func:`waflib.Context.Context.execute` on the context class
"""
if not Configure.autoconfig:
return execute_method(self)
# Disable autoconfig so waf's version doesn't run (and don't end up on loop of bad configure)
Configure.autoconfig = False
if self.variant == '':
raise Errors.WafError('The project is badly configured: run "waf configure" again!')
env = ConfigSet.ConfigSet()
do_config = False
try:
p = os.path.join(Context.out_dir, Build.CACHE_DIR, self.variant + Build.CACHE_SUFFIX)
env.load(p)
except EnvironmentError:
raise Errors.WafError('The project is not configured for board {0}: run "waf configure --board {0} [...]" first!'.format(self.variant))
lock_env = ConfigSet.ConfigSet()
try:
lock_env.load(os.path.join(Context.top_dir, Options.lockfile))
except EnvironmentError:
Logs.warn('Configuring the project')
do_config = True
else:
if lock_env.run_dir != Context.run_dir:
do_config = True
else:
h = 0
for f in env.CONFIGURE_FILES:
try:
h = Utils.h_list((h, Utils.readf(f, 'rb')))
except EnvironmentError:
do_config = True
break
else:
do_config = h != env.CONFIGURE_HASH
if do_config:
cmd = lock_env.config_cmd or 'configure'
tmp = Options.options.__dict__
if env.OPTIONS and sorted(env.OPTIONS.keys()) == sorted(tmp.keys()):
Options.options.__dict__ = env.OPTIONS
else:
raise Errors.WafError('The project configure options have changed: run "waf configure" again!')
try:
run_command(cmd)
finally:
Options.options.__dict__ = tmp
run_command(self.cmd)
else:
return execute_method(self)
return execute
def ap_configure_post_recurse():
post_recurse_orig = Configure.ConfigurationContext.post_recurse
def post_recurse(self, node):
post_recurse_orig(self, node)
self.all_envs[self.variant].CONFIGURE_FILES = self.files
self.all_envs[self.variant].CONFIGURE_HASH = self.hash
return post_recurse
@conf
def ap_get_all_libraries(bld):
if bld.env.BOOTLOADER:

37
wscript
View File

@ -26,27 +26,34 @@ from waflib import Build, ConfigSet, Configure, Context, Utils
# Default installation prefix for Linux boards
default_prefix = '/usr/'
def _set_build_context_variant(variant):
# Override Build execute and Configure post_recurse methods for autoconfigure purposes
Build.BuildContext.execute = ardupilotwaf.ap_autoconfigure(Build.BuildContext.execute)
Configure.ConfigurationContext.post_recurse = ardupilotwaf.ap_configure_post_recurse()
def _set_build_context_variant(board):
for c in Context.classes:
if not issubclass(c, Build.BuildContext):
continue
c.variant = variant
c.variant = board
def init(ctx):
env = ConfigSet.ConfigSet()
try:
p = os.path.join(Context.out_dir, Build.CACHE_DIR, Build.CACHE_SUFFIX)
env.load(p)
except:
except EnvironmentError:
return
Configure.autoconfig = 'clobber' if env.AUTOCONFIG else False
if 'VARIANT' not in env:
board = ctx.options.board or env.BOARD
if not board:
return
# define the variant build commands according to the board
_set_build_context_variant(env.VARIANT)
_set_build_context_variant(board)
def options(opt):
opt.load('compiler_cxx compiler_c waf_unit_test python')
@ -59,8 +66,8 @@ def options(opt):
g.add_option('--board',
action='store',
choices=boards_names,
default='sitl',
help='Target board to build, choices are %s.' % boards_names)
default=None,
help='Target board to build, choices are %s.' % ', '.join(boards_names))
g.add_option('--debug',
action='store_true',
@ -81,7 +88,7 @@ def options(opt):
action='store_true',
default=False,
help='use old NuttX IO firmware for IOMCU')
g.add_option('--bootloader',
action='store_true',
default=False,
@ -190,14 +197,14 @@ def _collect_autoconfig_files(cfg):
cfg.files.append(p)
def configure(cfg):
if cfg.options.board is None:
cfg.options.board = 'sitl'
cfg.env.BOARD = cfg.options.board
cfg.env.DEBUG = cfg.options.debug
cfg.env.AUTOCONFIG = cfg.options.autoconfig
cfg.env.VARIANT = cfg.env.BOARD
_set_build_context_variant(cfg.env.VARIANT)
cfg.setenv(cfg.env.VARIANT)
_set_build_context_variant(cfg.env.BOARD)
cfg.setenv(cfg.env.BOARD)
cfg.env.BOARD = cfg.options.board
cfg.env.DEBUG = cfg.options.debug
@ -205,6 +212,8 @@ def configure(cfg):
cfg.env.BOOTLOADER = cfg.options.bootloader
cfg.env.USE_NUTTX_IOFW = cfg.options.use_nuttx_iofw
cfg.env.OPTIONS = cfg.options.__dict__
# Allow to differentiate our build from the make build
cfg.define('WAF_BUILD', 1)
@ -315,7 +324,7 @@ def board(ctx):
print('No board currently configured')
return
print('Board configured to: {}'.format(env.VARIANT))
print('Board configured to: {}'.format(env.BOARD))
def _build_cmd_tweaks(bld):
if bld.cmd == 'check-all':