ArduPilot之开源代码waf-configure编译

2023-12-26 14:20

本文主要是介绍ArduPilot之开源代码waf-configure编译,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

ArduPilot之开源代码waf-configure编译

  • 1. 源由
  • 2. `wscript`脚本
  • 3. `wscript`功能
  • 4. `configure`调用关系
  • 5. 总结
  • 6. 参考资料

1. 源由

./waf configure --board Aocoda-RC-H743Dual是配置Ardupilot目标板的命令,该命令将根据硬件配置文件生成相应用于编译的目标板源代码文件。

该部分内容涉及以下几点:

  1. 目标配置:飞控、配件模块等
  2. 系统配置:ESP32/ChibiOS等
  3. 编译、链接命令

2. wscript脚本

#!/usr/bin/env python3
# encoding: utf-8from __future__ import print_functionimport os.path
import os
import sys
import subprocess
import json
import fnmatch
sys.path.insert(0, 'Tools/ardupilotwaf/')import ardupilotwaf
import boards
import shutilfrom waflib import Build, ConfigSet, Configure, Context, Utils
from waflib.Configure import conf# Ref: https://stackoverflow.com/questions/40590192/getting-an-error-attributeerror-module-object-has-no-attribute-run-while
try:from subprocess import CompletedProcess
except ImportError:# Python 2class CompletedProcess:def __init__(self, args, returncode, stdout=None, stderr=None):self.args = argsself.returncode = returncodeself.stdout = stdoutself.stderr = stderrdef check_returncode(self):if self.returncode != 0:err = subprocess.CalledProcessError(self.returncode, self.args, output=self.stdout)raise errreturn self.returncodedef sp_run(*popenargs, **kwargs):input = kwargs.pop("input", None)check = kwargs.pop("handle", False)kwargs.pop("capture_output", True)if input is not None:if 'stdin' in kwargs:raise ValueError('stdin and input arguments may not both be used.')kwargs['stdin'] = subprocess.PIPEprocess = subprocess.Popen(*popenargs, **kwargs)try:outs, errs = process.communicate(input)except:process.kill()process.wait()raisereturncode = process.poll()if check and returncode:raise subprocess.CalledProcessError(returncode, popenargs, output=outs)return CompletedProcess(popenargs, returncode, stdout=outs, stderr=errs)subprocess.run = sp_run# ^ This monkey patch allows it work on Python 2 or 3 the same way# 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 the generated ap_config.h file
# this makes recompilation at least when defines change. which might
# be sufficient.# Default installation prefix for Linux boards
default_prefix = '/usr/'# 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):continuec.variant = boarddef init(ctx):# Generate Task List, so that VS Code extension can keep track# of changes to possible build targetsgenerate_tasklist(ctx, False)env = ConfigSet.ConfigSet()try:p = os.path.join(Context.out_dir, Build.CACHE_DIR, Build.CACHE_SUFFIX)env.load(p)except EnvironmentError:returnConfigure.autoconfig = 'clobber' if env.AUTOCONFIG else Falseboard = ctx.options.board or env.BOARDif not board:return# define the variant build commands according to the board_set_build_context_variant(board)def options(opt):opt.load('compiler_cxx compiler_c waf_unit_test python')opt.load('ardupilotwaf')opt.load('build_summary')g = opt.ap_groups['configure']boards_names = boards.get_boards_names()removed_names = boards.get_removed_boards()g.add_option('--board',action='store',default=None,help='Target board to build, choices are %s.' % ', '.join(boards_names))g.add_option('--debug',action='store_true',default=False,help='Configure as debug variant.')g.add_option('--debug-symbols', '-g',action='store_true',default=False,help='Add debug symbolds to build.')g.add_option('--disable-watchdog',action='store_true',default=False,help='Build with watchdog disabled.')g.add_option('--coverage',action='store_true',default=False,help='Configure coverage flags.')g.add_option('--Werror',action='store_true',default=None,help='build with -Werror.')g.add_option('--disable-Werror',action='store_true',default=None,help='Disable -Werror.')g.add_option('--toolchain',action='store',default=None,help='Override default toolchain used for the board. Use "native" for using the host toolchain.')g.add_option('--disable-gccdeps',action='store_true',default=False,help='Disable the use of GCC dependencies output method and use waf default method.')g.add_option('--enable-asserts',action='store_true',default=False,help='enable OS level asserts.')g.add_option('--save-temps',action='store_true',default=False,help='save compiler temporary files.')g.add_option('--enable-malloc-guard',action='store_true',default=False,help='enable malloc guard regions.')g.add_option('--enable-stats',action='store_true',default=False,help='enable OS level thread statistics.')g.add_option('--bootloader',action='store_true',default=False,help='Configure for building a bootloader.')g.add_option('--signed-fw',action='store_true',default=False,help='Configure for signed firmware support.')g.add_option('--private-key',action='store',default=None,help='path to private key for signing firmware.')g.add_option('--no-autoconfig',dest='autoconfig',action='store_false',default=True,help='''Disable autoconfiguration feature. By default, the build system
triggers a reconfiguration whenever it thinks it's necessary - this
option disables that.
''')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.
''')g.add_option('--enable-header-checks', action='store_true',default=False,help="Enable checking of headers")g.add_option('--default-parameters',default=None,help='set default parameters to embed in the firmware')g.add_option('--enable-math-check-indexes',action='store_true',default=False,help="Enable checking of math indexes")g.add_option('--disable-scripting', action='store_true',default=False,help="Disable onboard scripting engine")g.add_option('--enable-scripting', action='store_true',default=False,help="Enable onboard scripting engine")g.add_option('--no-gcs', action='store_true',default=False,help="Disable GCS code")g.add_option('--scripting-checks', action='store_true',default=True,help="Enable runtime scripting sanity checks")g.add_option('--enable-onvif', action='store_true',default=False,help="Enables and sets up ONVIF camera control")g.add_option('--scripting-docs', action='store_true',default=False,help="enable generation of scripting documentation")g.add_option('--enable-opendroneid', action='store_true',default=False,help="Enables OpenDroneID")g.add_option('--enable-check-firmware', action='store_true',default=False,help="Enables firmware ID checking on boot")g.add_option('--enable-custom-controller', action='store_true',default=False,help="Enables custom controller")g.add_option('--enable-gps-logging', action='store_true',default=False,help="Enables GPS logging")g.add_option('--enable-dds', action='store_true',help="Enable the dds client to connect with ROS2/DDS.")g.add_option('--disable-networking', action='store_true',help="Disable the networking API code")g.add_option('--enable-networking-tests', action='store_true',help="Enable the networking test code. Automatically enables networking.")g.add_option('--enable-dronecan-tests', action='store_true',default=False,help="Enables DroneCAN tests in sitl")g = opt.ap_groups['linux']linux_options = ('--prefix', '--destdir', '--bindir', '--libdir')for k in linux_options:option = opt.parser.get_option(k)if option:opt.parser.remove_option(k)g.add_option(option)g.add_option('--apstatedir',action='store',default='',help='''Where to save data like parameters, log and terrain.
This is the --localstatedir + ArduPilots subdirectory [default:
board-dependent, usually /var/lib/ardupilot]''')g.add_option('--rsync-dest',dest='rsync_dest',action='store',default='',help='''Destination for the rsync Waf command. It can be passed during
configuration in order to save typing.
''')g.add_option('--enable-benchmarks',action='store_true',default=False,help='Enable benchmarks.')g.add_option('--enable-lttng', action='store_true',default=False,help="Enable lttng integration")g.add_option('--disable-libiio', action='store_true',default=False,help="Don't use libiio even if supported by board and dependencies available")g.add_option('--disable-tests', action='store_true',default=False,help="Disable compilation and test execution")g.add_option('--enable-sfml', action='store_true',default=False,help="Enable SFML graphics library")g.add_option('--enable-sfml-joystick', action='store_true',default=False,help="Enable SFML joystick input library")g.add_option('--enable-sfml-audio', action='store_true',default=False,help="Enable SFML audio library")g.add_option('--osd', action='store_true',default=False,help="Enable OSD support")g.add_option('--osd-fonts', action='store_true',default=False,help="Enable OSD support with fonts")g.add_option('--sitl-osd', action='store_true',default=False,help="Enable SITL OSD")g.add_option('--sitl-rgbled', action='store_true',default=False,help="Enable SITL RGBLed")g.add_option('--force-32bit', action='store_true',default=False,help="Force 32bit build")g.add_option('--build-dates', action='store_true',default=False,help="Include build date in binaries.  Appears in AUTOPILOT_VERSION.os_sw_version")g.add_option('--sitl-flash-storage',action='store_true',default=False,help='Use flash storage emulation.')g.add_option('--enable-ekf2',action='store_true',default=False,help='Configure with EKF2.')g.add_option('--disable-ekf3',action='store_true',default=False,help='Configure without EKF3.')g.add_option('--ekf-double',action='store_true',default=False,help='Configure EKF as double precision.')g.add_option('--ekf-single',action='store_true',default=False,help='Configure EKF as single precision.')g.add_option('--static',action='store_true',default=False,help='Force a static build')g.add_option('--postype-single',action='store_true',default=False,help='force single precision postype_t')g.add_option('--consistent-builds',action='store_true',default=False,help='force consistent build outputs for things like __LINE__')g.add_option('--extra-hwdef',action='store',default=None,help='Extra hwdef.dat file for custom build.')g.add_option('--assert-cc-version',default=None,help='fail configure if not using the specified gcc version')g.add_option('--num-aux-imus',type='int',default=0,help='number of auxiliary IMUs')g.add_option('--board-start-time',type='int',default=0,help='zero time on boot in microseconds')def _collect_autoconfig_files(cfg):for m in sys.modules.values():paths = []if hasattr(m, '__file__') and m.__file__ is not None:paths.append(m.__file__)elif hasattr(m, '__path__'):for p in m.__path__:if p is not None:paths.append(p)for p in paths:if p in cfg.files or not os.path.isfile(p):continuewith open(p, 'rb') as f:cfg.hash = Utils.h_list((cfg.hash, f.read()))cfg.files.append(p)def configure(cfg):# we need to enable debug mode when building for gconv, and force it to sitlif cfg.options.board is None:cfg.options.board = 'sitl'boards_names = boards.get_boards_names()if not cfg.options.board in boards_names:for b in boards_names:if b.upper() == cfg.options.board.upper():cfg.options.board = bbreakcfg.env.BOARD = cfg.options.boardcfg.env.DEBUG = cfg.options.debugcfg.env.DEBUG_SYMBOLS = cfg.options.debug_symbolscfg.env.COVERAGE = cfg.options.coveragecfg.env.AUTOCONFIG = cfg.options.autoconfig_set_build_context_variant(cfg.env.BOARD)cfg.setenv(cfg.env.BOARD)if cfg.options.signed_fw:cfg.env.AP_SIGNED_FIRMWARE = Truecfg.options.enable_check_firmware = Truecfg.env.BOARD = cfg.options.boardcfg.env.DEBUG = cfg.options.debugcfg.env.DEBUG_SYMBOLS = cfg.options.debug_symbolscfg.env.COVERAGE = cfg.options.coveragecfg.env.FORCE32BIT = cfg.options.force_32bitcfg.env.ENABLE_ASSERTS = cfg.options.enable_assertscfg.env.BOOTLOADER = cfg.options.bootloadercfg.env.ENABLE_MALLOC_GUARD = cfg.options.enable_malloc_guardcfg.env.ENABLE_STATS = cfg.options.enable_statscfg.env.SAVE_TEMPS = cfg.options.save_tempscfg.env.HWDEF_EXTRA = cfg.options.extra_hwdefif cfg.env.HWDEF_EXTRA:cfg.env.HWDEF_EXTRA = os.path.abspath(cfg.env.HWDEF_EXTRA)cfg.env.OPTIONS = cfg.options.__dict__# Allow to differentiate our build from the make buildcfg.define('WAF_BUILD', 1)cfg.msg('Autoconfiguration', 'enabled' if cfg.options.autoconfig else 'disabled')if cfg.options.static:cfg.msg('Using static linking', 'yes', color='YELLOW')cfg.env.STATIC_LINKING = Trueif cfg.options.num_aux_imus > 0:cfg.define('INS_AUX_INSTANCES', cfg.options.num_aux_imus)if cfg.options.board_start_time != 0:cfg.define('AP_BOARD_START_TIME', cfg.options.board_start_time)# also in env for hrt.ccfg.env.AP_BOARD_START_TIME = cfg.options.board_start_time# require python 3.8.x or latercfg.load('python')cfg.check_python_version(minver=(3,6,9))cfg.load('ap_library')cfg.msg('Setting board to', cfg.options.board)cfg.get_board().configure(cfg)cfg.load('clang_compilation_database')cfg.load('waf_unit_test')cfg.load('mavgen')cfg.load('dronecangen')cfg.env.SUBMODULE_UPDATE = cfg.options.submodule_updatecfg.start_msg('Source is git repository')if cfg.srcnode.find_node('.git'):cfg.end_msg('yes')else:cfg.end_msg('no')cfg.env.SUBMODULE_UPDATE = Falsecfg.msg('Update submodules', 'yes' if cfg.env.SUBMODULE_UPDATE else 'no')cfg.load('git_submodule')if cfg.options.enable_benchmarks:cfg.load('gbenchmark')cfg.load('gtest')cfg.load('static_linking')cfg.load('build_summary')cfg.start_msg('Benchmarks')if cfg.env.HAS_GBENCHMARK:cfg.end_msg('enabled')else:cfg.end_msg('disabled', color='YELLOW')cfg.start_msg('Unit tests')if cfg.env.HAS_GTEST:cfg.end_msg('enabled')else:cfg.end_msg('disabled', color='YELLOW')cfg.start_msg('Scripting')if cfg.options.disable_scripting:cfg.end_msg('disabled', color='YELLOW')elif cfg.options.enable_scripting:cfg.end_msg('enabled')else:cfg.end_msg('maybe')cfg.recurse('libraries/AP_Scripting')cfg.recurse('libraries/AP_GPS')cfg.recurse('libraries/AP_HAL_SITL')cfg.recurse('libraries/SITL')cfg.start_msg('Scripting runtime checks')if cfg.options.scripting_checks:cfg.end_msg('enabled')else:cfg.end_msg('disabled', color='YELLOW')cfg.start_msg('Debug build')if cfg.env.DEBUG:cfg.end_msg('enabled')else:cfg.end_msg('disabled', color='YELLOW')cfg.start_msg('Coverage build')if cfg.env.COVERAGE:cfg.end_msg('enabled')else:cfg.end_msg('disabled', color='YELLOW')cfg.start_msg('Force 32-bit build')if cfg.env.FORCE32BIT:cfg.end_msg('enabled')else:cfg.end_msg('disabled', color='YELLOW')cfg.env.append_value('GIT_SUBMODULES', 'mavlink')cfg.env.prepend_value('INCLUDES', [cfg.srcnode.abspath() + '/libraries/',])cfg.find_program('rsync', mandatory=False)if cfg.options.rsync_dest:cfg.msg('Setting rsync destination to', cfg.options.rsync_dest)cfg.env.RSYNC_DEST = cfg.options.rsync_destif cfg.options.enable_header_checks:cfg.msg('Enabling header checks', cfg.options.enable_header_checks)cfg.env.ENABLE_HEADER_CHECKS = Trueelse:cfg.env.ENABLE_HEADER_CHECKS = False# Always use system extensionscfg.define('_GNU_SOURCE', 1)if cfg.options.Werror:# print(cfg.options.Werror)if cfg.options.disable_Werror:cfg.options.Werror = Falsecfg.write_config_header(os.path.join(cfg.variant, 'ap_config.h'), guard='_AP_CONFIG_H_')# add in generated flagscfg.env.CXXFLAGS += ['-include', 'ap_config.h']_collect_autoconfig_files(cfg)def collect_dirs_to_recurse(bld, globs, **kw):dirs = []globs = Utils.to_list(globs)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))for g in globs:for d in bld.srcnode.ant_glob(g + '/wscript', **kw):dirs.append(d.parent.relpath())return dirsdef list_boards(ctx):print(*boards.get_boards_names())def list_ap_periph_boards(ctx):print(*boards.get_ap_periph_boards())@conf
def ap_periph_boards(ctx):return boards.get_ap_periph_boards()def generate_tasklist(ctx, do_print=True):boardlist = boards.get_boards_names()ap_periph_targets = boards.get_ap_periph_boards()tasks = []with open(os.path.join(Context.top_dir, "tasklist.json"), "w") as tlist:for board in boardlist:task = {}task['configure'] = boardif board in ap_periph_targets:if 'sitl' not in board:# we only support AP_Periph and bootloader buildstask['targets'] = ['AP_Periph', 'bootloader']else:task['targets'] = ['AP_Periph']elif 'iofirmware' in board:task['targets'] = ['iofirmware', 'bootloader']else:if 'sitl' in board or 'SITL' in board:task['targets'] = ['antennatracker', 'copter', 'heli', 'plane', 'rover', 'sub', 'replay']elif 'linux' in board:task['targets'] = ['antennatracker', 'copter', 'heli', 'plane', 'rover', 'sub']else:task['targets'] = ['antennatracker', 'copter', 'heli', 'plane', 'rover', 'sub', 'bootloader']task['buildOptions'] = '--upload'tasks.append(task)tlist.write(json.dumps(tasks))if do_print:print(json.dumps(tasks))def board(ctx):env = ConfigSet.ConfigSet()try:p = os.path.join(Context.out_dir, Build.CACHE_DIR, Build.CACHE_SUFFIX)env.load(p)except:print('No board currently configured')returnprint('Board configured to: {}'.format(env.BOARD))def _build_cmd_tweaks(bld):if bld.cmd == 'check-all':bld.options.all_tests = Truebld.cmd = 'check'if bld.cmd == 'check':if not bld.env.HAS_GTEST:bld.fatal('check: gtest library is required')bld.options.clear_failed_tests = Truedef _build_dynamic_sources(bld):if not bld.env.BOOTLOADER:bld(features='mavgen',source='modules/mavlink/message_definitions/v1.0/all.xml',output_dir='libraries/GCS_MAVLink/include/mavlink/v2.0/',name='mavlink',# this below is not ideal, mavgen tool should set this, but that's not# currently possibleexport_includes=[bld.bldnode.make_node('libraries').abspath(),bld.bldnode.make_node('libraries/GCS_MAVLink').abspath(),],)if (bld.get_board().with_can or bld.env.HAL_NUM_CAN_IFACES) and not bld.env.AP_PERIPH:bld(features='dronecangen',source=bld.srcnode.ant_glob('modules/DroneCAN/DSDL/* libraries/AP_DroneCAN/dsdl/*', dir=True, src=False),output_dir='modules/DroneCAN/libcanard/dsdlc_generated/',name='dronecan',export_includes=[bld.bldnode.make_node('modules/DroneCAN/libcanard/dsdlc_generated/include').abspath(),bld.srcnode.find_dir('modules/DroneCAN/libcanard/').abspath(),bld.srcnode.find_dir('libraries/AP_DroneCAN/canard/').abspath(),])elif bld.env.AP_PERIPH:bld(features='dronecangen',source=bld.srcnode.ant_glob('modules/DroneCAN/DSDL/* libraries/AP_DroneCAN/dsdl/*', dir=True, src=False),output_dir='modules/DroneCAN/libcanard/dsdlc_generated/',name='dronecan',export_includes=[bld.bldnode.make_node('modules/DroneCAN/libcanard/dsdlc_generated/include').abspath(),bld.srcnode.find_dir('modules/DroneCAN/libcanard/').abspath(),])if bld.env.ENABLE_DDS:bld.recurse("libraries/AP_DDS")def write_version_header(tsk):bld = tsk.generator.bldreturn bld.write_version_header(tsk.outputs[0].abspath())bld(name='ap_version',target='ap_version.h',vars=['AP_VERSION_ITEMS'],rule=write_version_header,)bld.env.prepend_value('INCLUDES', [bld.bldnode.abspath(),])def _build_common_taskgens(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.bld.ap_stlib(name='ap',ap_vehicle='UNKNOWN',ap_libraries=bld.ap_get_all_libraries(),)if bld.env.HAS_GTEST:bld.libgtest(cxxflags=['-include', 'ap_config.h'])if bld.env.HAS_GBENCHMARK:bld.libbenchmark()def _build_recursion(bld):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/*','libraries/*/tests','libraries/*/utility/tests','libraries/*/benchmarks',]common_dirs_excl = ['modules','libraries/AP_HAL_*',]hal_dirs_patterns = ['libraries/%s/tests','libraries/%s/*/tests','libraries/%s/*/benchmarks','libraries/%s/examples/*',]dirs_to_recurse = collect_dirs_to_recurse(bld,common_dirs_patterns,excl=common_dirs_excl,)if bld.env.IOMCU_FW is not None:if bld.env.IOMCU_FW:dirs_to_recurse.append('libraries/AP_IOMCU/iofirmware')if bld.env.PERIPH_FW is not None:if bld.env.PERIPH_FW:dirs_to_recurse.append('Tools/AP_Periph')dirs_to_recurse.append('libraries/AP_Scripting')if bld.env.ENABLE_ONVIF:dirs_to_recurse.append('libraries/AP_ONVIF')for p in hal_dirs_patterns:dirs_to_recurse += collect_dirs_to_recurse(bld,[p % l for l in bld.env.AP_LIBRARIES],)# NOTE: we need to sort to ensure the repeated sources get the# same index, and random ordering of the filesystem doesn't cause# recompilation.dirs_to_recurse.sort()for d in dirs_to_recurse:bld.recurse(d)def _build_post_funs(bld):if bld.cmd == 'check':bld.add_post_fun(ardupilotwaf.test_summary)else:bld.build_summary_post_fun()if bld.env.SUBMODULE_UPDATE:bld.git_submodule_post_fun()def _load_pre_build(bld):'''allow for a pre_build() function in build modules'''if bld.cmd == 'clean':returnbrd = bld.get_board()if getattr(brd, 'pre_build', None):brd.pre_build(bld)    def build(bld):config_hash = Utils.h_file(bld.bldnode.make_node('ap_config.h').abspath())bld.env.CCDEPS = config_hashbld.env.CXXDEPS = config_hashbld.post_mode = Build.POST_LAZYbld.load('ardupilotwaf')bld.env.AP_LIBRARIES_OBJECTS_KW.update(use=['mavlink'],cxxflags=['-include', 'ap_config.h'],)_load_pre_build(bld)if bld.get_board().with_can:bld.env.AP_LIBRARIES_OBJECTS_KW['use'] += ['dronecan']_build_cmd_tweaks(bld)if bld.env.SUBMODULE_UPDATE:bld.add_group('git_submodules')for name in bld.env.GIT_SUBMODULES:bld.git_submodule(name)bld.add_group('dynamic_sources')_build_dynamic_sources(bld)bld.add_group('build')bld.get_board().build(bld)_build_common_taskgens(bld)_build_recursion(bld)_build_post_funs(bld)ardupilotwaf.build_command('check',program_group_list='all',doc='builds all programs and run tests',
)
ardupilotwaf.build_command('check-all',program_group_list='all',doc='shortcut for `waf check --alltests`',
)for name in ('antennatracker', 'copter', 'heli', 'plane', 'rover', 'sub', 'blimp', 'bootloader','iofirmware','AP_Periph','replay'):ardupilotwaf.build_command(name,program_group_list=name,doc='builds %s programs' % name,)for program_group in ('all', 'bin', 'tool', 'examples', 'tests', 'benchmarks'):ardupilotwaf.build_command(program_group,program_group_list=program_group,doc='builds all programs of %s group' % program_group,)class LocalInstallContext(Build.InstallContext):"""runs install using BLD/install as destdir, where BLD is the build variant directory"""cmd = 'localinstall'def __init__(self, **kw):super(LocalInstallContext, self).__init__(**kw)self.local_destdir = os.path.join(self.variant_dir, 'install')def execute(self):old_destdir = self.options.destdirself.options.destdir = self.local_destdirr = super(LocalInstallContext, self).execute()self.options.destdir = old_destdirreturn rclass RsyncContext(LocalInstallContext):"""runs localinstall and then rsyncs BLD/install with the target system"""cmd = 'rsync'def __init__(self, **kw):super(RsyncContext, self).__init__(**kw)self.add_pre_fun(RsyncContext.create_rsync_taskgen)def create_rsync_taskgen(self):if 'RSYNC' not in self.env:self.fatal('rsync program seems not to be installed, can\'t continue')self.add_group()tg = self(name='rsync',rule='${RSYNC} -a ${RSYNC_SRC}/ ${RSYNC_DEST}',always=True,)tg.env.RSYNC_SRC = self.local_destdirif self.options.rsync_dest:self.env.RSYNC_DEST = self.options.rsync_destif 'RSYNC_DEST' not in tg.env:self.fatal('Destination for rsync not defined. Either pass --rsync-dest here or during configuration.')tg.post()

3. wscript功能

主要组件和功能概述:

  1. Imports and Setup:

Import necessary modules and libraries.
Set the default installation prefix for Linux boards.

  1. Monkey Patching:

Some modifications are made to the subprocess module to handle compatibility issues between Python 2 and 3.

  1. Configuration Options:

Define various configuration options and command-line arguments for the build process.
Options include the target board, debug mode, debug symbols, coverage, toolchain selection, etc.

  1. Customization of Build Context:

Override methods in the Waf build context to implement custom behavior related to autoconfiguration and variant build commands.

  1. Initialization and Configuration:

Set up the build environment based on configuration options.
Load necessary modules and configurations.

  1. Build Script Commands:

Define command-line options and functionalities for various build commands such as configuring a board, compiling a vehicle, enabling/disabling features, etc.

  1. Autoconfiguration:

Implement autoconfiguration features to trigger reconfiguration when necessary.

  1. Preparation for Board Configuration:

Set the variant build commands according to the selected board.
Define initialization tasks.

  1. Build Script Options:

Define various build options and configurations, such as enabling/disabling features, specifying toolchains, etc.

  1. Collect Autoconfig Files:

Collect autoconfiguration files from modules for hashing.

  1. Configure Method:

Implement the configuration process based on the specified options.

  1. Generate Task List:

Generate a task list for different build targets and configurations.

  1. Build Board Configuration:

Configure the build based on the selected board.

  1. Configure Method for Specific Build Options:

Implement specific configuration options, e.g., enabling/disabling features, setting default parameters, etc.

  1. Collecting Directories to Recurse:

Determine directories to recurse during the build process.

  1. Build Dynamic Sources:

Build dynamic sources such as MAVLink and DroneCAN.

  1. Build Common Task Generators:

Build common task generators shared by all programs and examples.

  1. Recursion for Subdirectories:

Recurse into subdirectories for building programs, tests, benchmarks, etc.

  1. Load Pre-Build Function:

Allow for a pre_build() function in build modules.

  1. Build Post Functions:

Execute post functions after the build, such as test summaries or submodule updates.

  1. Build Command Definitions:

Define custom build commands such as ‘check’, ‘check-all’, and specific board builds.

  1. Local Install and Rsync Contexts:

Implement custom build contexts for local installation and rsync.

4. configure调用关系

$ ./waf configure --board Aocoda-RC-H743Dual

注:选择chibios相关重点进行研读,对于一些不太理解,暂时不需要考虑的(直接略过),有兴趣的朋友请留言讨论。

./waf└──> ./modules/waf/waf-light└──> ./wscript├──> configure  //wscript│   └──> board.configure //boards.py│       └──> board.configure_env //boards.py│           └──> chibios.configure_env //boards.py└──> ardupilotwaf.ap_autoconfigure  //ardupilotwaf.py└──> chibios.configure  //chibios.py└──> chibios.generate_hwdef_h  //chibios.py└──> ./libraries/AP_HAL_ChibiOS/hwdef/scripts/chibios_hwdef.py  //chibios.py

#4. chibios_hwdef.py脚本

$  python chibios_hwdef.py -h
usage: chibios_pins.py [-h] [-D OUTDIR] [--bootloader] [--signed-fw][--params PARAMS]hwdef [hwdef ...]positional arguments:hwdef                 hardware definition fileoptional arguments:-h, --help            show this help message and exit-D OUTDIR, --outdir OUTDIROutput directory--bootloader          configure for bootloader--signed-fw           configure for signed FW--params PARAMS       user default params path

该脚本生成以下相关硬件配置文件:

  1. hw.dat //for ROMFS
  2. hwdef.h //for hardware definition
  3. ldscript.ld //for link script

调用关系:

chibios_hwdef.py├──> └──> run└──> process_file└──> process_line├──> get_config├──> build_peripheral_list├──> write_all_lines├──> write_hwdef_header├──> write_ldscript├──> romfs_add_dir├──> romfs_add_dir├──> write_ROMFS├──> copy_common_linkerscript├──> <not args.bootloader> write_processed_defaults_file└──> write_env_py

重要且唯一类ChibiOSHWDef,重点函数方法:

  • process_file
  • process_line
  • get_config
  • build_peripheral_list
  • write_all_lines
  • write_hwdef_header
  • write_ldscript
  • romfs_add_dir
  • romfs_add_dir
  • write_ROMFS
  • copy_common_linkerscript
  • write_processed_defaults_file

5. 总结

到这里,重点看下chibios相关脚本文件,这些与MCU规格息息相关。

$ pwd
[略...]/ardupilot/libraries/AP_HAL_ChibiOS/hwdef/scripts
$ ls
addfunc_parse.py    CKS32F407xx.py                 defaults_periph.h  STM32F103xB.py  STM32F412Rx.py  STM32F767xx.py  STM32G491xx.py  STM32H757xx.py
af_parse_cubemx.py  convert_betaflight_unified.py  dma_parse.py       STM32F105xC.py  STM32F427xx.py  STM32F777xx.py  STM32H730xx.py  STM32L431xx.py
af_parse.py         defaults_bootloader.h          dma_resolver.py    STM32F303xC.py  STM32F469xx.py  STM32G431xx.py  STM32H743xx.py  STM32L476xx.py
bdshot_encoder.py   defaults_iofirmware.h          dma_resolver.pyc   STM32F405xx.py  STM32F732xx.py  STM32G441xx.py  STM32H750xx.py  STM32L496xx.py
chibios_hwdef.py    defaults_normal.h              STM32F100xB.py     STM32F407xx.py  STM32F745xx.py  STM32G474xx.py  STM32H755xx.py  STM32L4R5xx.py

如果我们回顾下之前Andrew Tridgell在ArduPilot UnConference 2018会议上的PPT文件和视频。

如果需要移植ChibiOS到新的MCU上,必须考虑这部分内容的配套修改,通过tabula建立相应的MCU规格数据库。

Anyway, it’s a small step from porting chibios to ardupilot AT32.

6. 参考资料

【1】ArduPilot开源飞控系统之简单介绍
【2】ArduPilot之开源代码框架
【3】Ardupilot开源飞控之ChibiOS简介

这篇关于ArduPilot之开源代码waf-configure编译的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/539749

相关文章

SWAP作物生长模型安装教程、数据制备、敏感性分析、气候变化影响、R模型敏感性分析与贝叶斯优化、Fortran源代码分析、气候数据降尺度与变化影响分析

查看原文>>>全流程SWAP农业模型数据制备、敏感性分析及气候变化影响实践技术应用 SWAP模型是由荷兰瓦赫宁根大学开发的先进农作物模型,它综合考虑了土壤-水分-大气以及植被间的相互作用;是一种描述作物生长过程的一种机理性作物生长模型。它不但运用Richard方程,使其能够精确的模拟土壤中水分的运动,而且耦合了WOFOST作物模型使作物的生长描述更为科学。 本文让更多的科研人员和农业工作者

maven 编译构建可以执行的jar包

💝💝💝欢迎莅临我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」👈,「stormsha的知识库」👈持续学习,不断总结,共同进步,为了踏实,做好当下事儿~ 专栏导航 Python系列: Python面试题合集,剑指大厂Git系列: Git操作技巧GO

Windows环境利用VS2022编译 libvpx 源码教程

libvpx libvpx 是一个开源的视频编码库,由 WebM 项目开发和维护,专门用于 VP8 和 VP9 视频编码格式的编解码处理。它支持高质量的视频压缩,广泛应用于视频会议、在线教育、视频直播服务等多种场景中。libvpx 的特点包括跨平台兼容性、硬件加速支持以及灵活的接口设计,使其可以轻松集成到各种应用程序中。 libvpx 的安装和配置过程相对简单,用户可以从官方网站下载源代码

Golang test编译使用

创建文件my_test.go package testsimport "testing"func TestMy(t *testing.T) {t.Log("TestMy")} 通常用法: $ go test -v -run TestMy my_test.go=== RUN TestMyTestMy: my_test.go:6: TestMy--- PASS: TestMy (0.

C++/《C/C++程序编译流程》

程序的基本流程如图:   1.预处理        预处理相当于根据预处理指令组装新的C/C++程序。经过预处理,会产生一个没有宏定义,没有条件编译指令,没有特殊符号的输出文件,这个文件的含义同原本的文件无异,只是内容上有所不同。 读取C/C++源程序,对其中的伪指令(以#开头的指令)进行处理将所有的“#define”删除,并且展开所有的宏定义处理所有的条件编译指令,如:“#if”、“

编译linux内核出现 arm-eabi-gcc: error: : No such file or directory

external/e2fsprogs/lib/ext2fs/tdb.c:673:29: warning: comparison between : In function 'max2165_set_params': -。。。。。。。。。。。。。。。。。。 。。。。。。。。。。。。。 。。。。。。。。 host asm: libdvm <= dalvik/vm/mterp/out/Inte

QT 编译报错:C3861: ‘tr‘ identifier not found

问题: QT 编译报错:C3861: ‘tr’ identifier not found 原因 使用tr的地方所在的类没有继承自 QObject 类 或者在不在某一类中, 解决方案 就直接用类名引用 :QObject::tr( )

hector_quadrotor编译总结 | ubuntu 16.04 ros-kinetic版本

hector_quadrotor编译总结 | ubuntu 16.04 ros-kinetic版本 基于Ubuntu 16.04 LTS系统所用ROS版本为 Kinetic hector_quadrotor ROS包主要用于四旋翼无人机的建模、控制和仿真。 1.安装依赖库 所需系统及依赖库 Ubuntu 16.04|ros-kinetic|Gazebo|gazebo_ros_pkgs|ge

hector_quadrotor编译总结 | ubuntu 14.04 ros-indigo版本

hector_quadrotor编译总结 | ubuntu 14.04 ros-indigo版本 基于Ubuntu 14.04 LTS系统所用ROS版本为 Indigo hector_quadrotor ROS包主要用于四旋翼无人机的建模、控制和仿真。 备注:两种安装方式可选:install the binary packages | install the source files

运营版开源代码 多语言跨境商城 跨境电商平台

默认中英双语 后台带翻译接口 支持133种语言自动翻译 支持多商户联盟 一键部署版本 伪静态+后台登陆后缀 源码下载:https://download.csdn.net/download/m0_66047725/89722389 更多资源下载:关注我。