diff --git a/Tools/ardupilotwaf/boards.py b/Tools/ardupilotwaf/boards.py new file mode 100644 index 0000000000..6fa3008eb3 --- /dev/null +++ b/Tools/ardupilotwaf/boards.py @@ -0,0 +1,133 @@ +#!/usr/bin/env python +# encoding: utf-8 + +import sys + +import waflib + +BOARDS = {} + +PROJECT_ENV = waflib.ConfigSet.ConfigSet() + +def define_board(func, name, parent_name=None): + if parent_name is None: + parent = PROJECT_ENV + elif parent_name not in BOARDS: + print("Undefined parent board '%s' for '%s'" % (parent_name, name)) + sys.exit(1) + else: + parent = BOARDS[parent_name] + + env = parent.derive().detach() + if name in BOARDS: + print("Multiple definitions of " + name) + sys.exit(1) + BOARDS[name] = env + func(env) + +# Use a dictionary instead of the convetional list for definitions to +# make easy to override them. Convert back to list before consumption. +PROJECT_ENV.DEFINES = {} + +PROJECT_ENV.CFLAGS += [ + '-ffunction-sections', + '-fdata-sections', + '-fsigned-char', + + '-Wformat', + '-Wall', + '-Wshadow', + '-Wpointer-arith', + '-Wcast-align', + '-Wno-unused-parameter', + '-Wno-missing-field-initializers', +] + +PROJECT_ENV.CXXFLAGS += [ + '-std=gnu++11', + + '-fdata-sections', + '-ffunction-sections', + '-fno-exceptions', + '-fsigned-char', + + '-Wformat', + '-Wall', + '-Wshadow', + '-Wpointer-arith', + '-Wcast-align', + '-Wno-unused-parameter', + '-Wno-missing-field-initializers', + '-Wno-reorder', + '-Werror=format-security', + '-Werror=array-bounds', + '-Wfatal-errors', + '-Werror=unused-but-set-variable', + '-Werror=uninitialized', + '-Werror=init-self', + '-Wno-missing-field-initializers', +] + +PROJECT_ENV.LINKFLAGS += [ + '-Wl,--gc-sections', +] + +# NOTE: Keeping all the board definitions together so we can easily +# identify opportunities to simplify common flags. In the future might +# be worthy to keep board definitions in files of their own. + +def sitl(env): + env.DEFINES.update( + CONFIG_HAL_BOARD = 'HAL_BOARD_SITL', + CONFIG_HAL_BOARD_SUBTYPE = 'HAL_BOARD_SUBTYPE_NONE', + ) + + env.CXXFLAGS += [ + '-O3', + ] + + env.LIB += [ + 'm', + 'pthread', + ] + + env.AP_LIBRARIES += [ + 'AP_HAL_SITL', + 'SITL', + ] + +define_board(sitl, 'sitl') + + +def linux(env): + env.DEFINES.update( + CONFIG_HAL_BOARD = 'HAL_BOARD_LINUX', + CONFIG_HAL_BOARD_SUBTYPE = 'HAL_BOARD_SUBTYPE_LINUX_NONE', + ) + + env.CXXFLAGS += [ + '-O3', + ] + + env.LIB += [ + 'm', + 'pthread', + 'rt', + ] + + env.AP_LIBRARIES = [ + 'AP_HAL_Linux', + ] + +define_board(linux, 'linux') + + +def minlure(env): + env.DEFINES.update( + CONFIG_HAL_BOARD_SUBTYPE = 'HAL_BOARD_SUBTYPE_LINUX_MINLURE', + ) + +define_board(minlure, 'minlure', 'linux') + +def get_boards_names(): + return sorted(list(BOARDS.keys())) diff --git a/wscript b/wscript index fe8adca026..93b623f3a3 100644 --- a/wscript +++ b/wscript @@ -8,6 +8,7 @@ import sys sys.path.insert(0, 'Tools/ardupilotwaf/') import ardupilotwaf +import boards import waflib # TODO: implement a command 'waf help' that shows the basic tasks a @@ -33,128 +34,15 @@ import waflib # contain the board extension so make it less convenient, maybe hook # to support automatic filling this extension? -PROJECT_CONFIG = dict( - CFLAGS=[ - '-ffunction-sections', - '-fdata-sections', - '-fsigned-char', - - '-Wformat', - '-Wall', - '-Wshadow', - '-Wpointer-arith', - '-Wcast-align', - '-Wno-unused-parameter', - '-Wno-missing-field-initializers', - ], - - CXXFLAGS=[ - '-std=gnu++11', - - '-fdata-sections', - '-ffunction-sections', - '-fno-exceptions', - '-fsigned-char', - - '-Wformat', - '-Wall', - '-Wshadow', - '-Wpointer-arith', - '-Wcast-align', - '-Wno-unused-parameter', - '-Wno-missing-field-initializers', - '-Wno-reorder', - '-Werror=format-security', - '-Werror=array-bounds', - '-Wfatal-errors', - '-Werror=unused-but-set-variable', - '-Werror=uninitialized', - '-Werror=init-self', - '-Wno-missing-field-initializers', - ], - - LINKFLAGS=[ - '-Wl,--gc-sections', - ], -) - -# NOTE: Keeping all the board definitions together so we can easily -# identify opportunities to simplify how it works. In the future might -# be worthy to keep board definitions in files of their own. -BOARDS = { - 'sitl': dict( - DEFINES=[ - 'CONFIG_HAL_BOARD=HAL_BOARD_SITL', - 'CONFIG_HAL_BOARD_SUBTYPE=HAL_BOARD_SUBTYPE_NONE', - ], - - CXXFLAGS=[ - '-O3' - ], - - LIB=[ - 'm', - 'pthread', - ], - - AP_LIBRARIES=[ - 'AP_HAL_SITL', - 'SITL', - ], - ), - - 'linux': dict( - DEFINES=[ - 'CONFIG_HAL_BOARD=HAL_BOARD_LINUX', - 'CONFIG_HAL_BOARD_SUBTYPE=HAL_BOARD_SUBTYPE_LINUX_NONE', - ], - - CXXFLAGS=[ - '-O3' - ], - - LIB=[ - 'm', - 'pthread', - 'rt', - ], - - AP_LIBRARIES=[ - 'AP_HAL_Linux', - ], - ), - - 'minlure': dict( - DEFINES=[ - 'CONFIG_HAL_BOARD=HAL_BOARD_LINUX', - 'CONFIG_HAL_BOARD_SUBTYPE=HAL_BOARD_SUBTYPE_LINUX_MINLURE', - ], - - CXXFLAGS=[ - '-O3' - ], - - LIB=[ - 'm', - 'pthread', - 'rt', - ], - - AP_LIBRARIES=[ - 'AP_HAL_Linux', - ], - ), -} - -BOARDS_NAMES = sorted(list(BOARDS.keys())) - def options(opt): + boards_names = boards.get_boards_names() + opt.load('compiler_cxx compiler_c waf_unit_test') opt.add_option('--board', action='store', - choices=BOARDS_NAMES, + choices=boards_names, default='sitl', - help='Target board to build, choices are %s' % BOARDS_NAMES) + help='Target board to build, choices are %s' % boards_names) g = opt.add_option_group('Check options') g.add_option('--check-verbose', @@ -182,15 +70,19 @@ def configure(cfg): cfg.msg('Setting board to', cfg.options.board) cfg.env.BOARD = cfg.options.board - board = BOARDS[cfg.env.BOARD] + board_dict = boards.BOARDS[cfg.env.BOARD].get_merged_dict() - # Always prepend so that arguments passed in the command line get the - # priority. Board configuration gets priority over the project - # configuration. - for k in board.keys(): - cfg.env.prepend_value(k, board[k]) - for k in PROJECT_CONFIG.keys(): - cfg.env.prepend_value(k, PROJECT_CONFIG[k]) + # 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) cfg.env.prepend_value('INCLUDES', [ cfg.srcnode.abspath() + '/libraries/' @@ -211,7 +103,7 @@ def collect_dirs_to_recurse(bld, globs, **kw): return dirs def list_boards(ctx): - print(*BOARDS_NAMES) + print(*boards.get_boards_names()) def build(bld): # NOTE: Static library with vehicle set to UNKNOWN, shared by all