mirror of
https://github.com/PX4/PX4-Autopilot.git
synced 2026-05-22 14:24:21 +08:00
8b58c01cd7
Build all targets / Scan for Board Targets (push) Has been cancelled
Build all targets / Build Group [${{ matrix.group }}][${{ matrix.arch == 'nuttx' && 'x86' || 'arm64' }}] (push) Has been cancelled
Build all targets / Upload Artifacts to S3 (push) Has been cancelled
Build all targets / Create Release and Upload Artifacts (push) Has been cancelled
Checks / build (NO_NINJA_BUILD=1 px4_fmu-v5_default) (push) Has been cancelled
Checks / build (NO_NINJA_BUILD=1 px4_sitl_default) (push) Has been cancelled
Checks / build (check_format) (push) Has been cancelled
Checks / build (check_newlines) (push) Has been cancelled
Checks / build (module_documentation) (push) Has been cancelled
Checks / build (px4_fmu-v2_default stack_check) (push) Has been cancelled
Checks / build (px4_sitl_allyes) (push) Has been cancelled
Checks / build (shellcheck_all) (push) Has been cancelled
Checks / build (tests) (push) Has been cancelled
Checks / build (tests_coverage) (push) Has been cancelled
Checks / build (validate_module_configs) (push) Has been cancelled
Clang Tidy / build (push) Has been cancelled
MacOS build / build (px4_fmu-v5_default) (push) Has been cancelled
MacOS build / build (px4_sitl) (push) Has been cancelled
Ubuntu environment build / Build and Test (ubuntu:22.04) (push) Has been cancelled
Ubuntu environment build / Build and Test (ubuntu:24.04) (push) Has been cancelled
Container build / Set Tags and Variables (push) Has been cancelled
Container build / Build Container (amd64) (push) Has been cancelled
Container build / Build Container (arm64) (push) Has been cancelled
Container build / Deploy To Registry (push) Has been cancelled
EKF Update Change Indicator / unit_tests (push) Has been cancelled
Failsafe Simulator Build / build (failsafe_web) (push) Has been cancelled
FLASH usage analysis / Analyzing px4_fmu-v5x (push) Has been cancelled
FLASH usage analysis / Analyzing px4_fmu-v6x (push) Has been cancelled
FLASH usage analysis / Publish Results (push) Has been cancelled
ITCM check / Checking nxp_tropic-community (push) Has been cancelled
ITCM check / Checking px4_fmu-v5x (push) Has been cancelled
ITCM check / Checking px4_fmu-v6xrt (push) Has been cancelled
MAVROS Mission Tests / build (map[mission:MC_mission_box vehicle:iris]) (push) Has been cancelled
MAVROS Offboard Tests / build (map[test_file:mavros_posix_tests_offboard_posctl.test vehicle:iris]) (push) Has been cancelled
Nuttx Target with extra env config / build (px4_fmu-v5_default) (push) Has been cancelled
Python CI Checks / build (push) Has been cancelled
ROS Integration Tests / build (push) Has been cancelled
ROS Translation Node Tests / Build and test (map[ros_version:humble ubuntu:jammy]) (push) Has been cancelled
ROS Translation Node Tests / Build and test (map[ros_version:jazzy ubuntu:noble]) (push) Has been cancelled
SITL Tests / Testing PX4 tailsitter (push) Has been cancelled
SITL Tests / Testing PX4 iris (push) Has been cancelled
SITL Tests / Testing PX4 standard_vtol (push) Has been cancelled
Handle stale issues and PRs / stale (push) Has been cancelled
Fuzzing / Fuzzing (push) Has been cancelled
nsh console running on USB param module running working with i2c and common drivers provided implementation for drv_pwm_output.h i2cdetect working as expected with no device mavlink started succesfully mounts sd card and logger runs logger to file succesfully pwm_servo implemented without using Nuttx lib pwm_out outputs expected waveforms - however currently if the frequency is higher than what the pwm_out driver runs, there will be aliasing, based on how the registers gets resets wifi softap working - Seeing wifi hotspot - cant connect due to wrong password - problems with adjusting ssid and password wifi ssid and password being set accordinglu connected to wifi hotspot with dhpcd - made some changes to nuttx to only build for SoftAP mode, however this was effectivelyy removing the ifdef for STATION mode. Should investigate the coexist option again added ifdef to not use timer 0 when wifi enabled - reverted esp32 rt_timer to make use of timer 0 by default fix setting incorrect bit in hrt timer register - hrt running as expected, but on startup the pwm_out driver starts up at about 200Hz and then rises over a minute or so 250Hz. Not sure if this was present previously, and could be due to Wifi running at time priority on timer 0 pull xtensa compilers in setup.ubuntu.sh revert logger stacksize and cmake argument esp32 chip revision and PX4 UUID implemented spi board reset implemented, formatting checked devkit acts on startup as a wifi bridge for comms - the most usefull setting for the general developer when buying a esp32 devkit - testing Mavlink shell using ./Tools/mavlink_shell.py - todo: Test mavlink messages being forward improve wifi telemetry by increasing prio - Remove power save mode on wifi - increased daemon thread schedule priority to 50 compiles without Nuttx changes - updated compiler settings to match those of nuttx on px4 side add espressif_esp32 to excluded boards ci: allow docker to find xtensa compilers
300 lines
11 KiB
Python
Executable File
300 lines
11 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
""" Script to generate a JSON config with all build targets (for CI) """
|
|
|
|
import argparse
|
|
import os
|
|
import sys
|
|
import json
|
|
import re
|
|
from kconfiglib import Kconfig
|
|
|
|
kconf = Kconfig()
|
|
|
|
# Supress warning output
|
|
kconf.warn_assign_undef = False
|
|
kconf.warn_assign_override = False
|
|
kconf.warn_assign_redun = False
|
|
|
|
source_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..')
|
|
|
|
parser = argparse.ArgumentParser(description='Generate build targets')
|
|
|
|
parser.add_argument('-v', '--verbose', dest='verbose', action='store_true',
|
|
help='Verbose Output')
|
|
parser.add_argument('-p', '--pretty', dest='pretty', action='store_true',
|
|
help='Pretty output instead of a single line')
|
|
parser.add_argument('-g', '--groups', dest='group', action='store_true',
|
|
help='Groups targets')
|
|
parser.add_argument('-f', '--filter', dest='filter', help='comma separated list of board names to use instead of all')
|
|
|
|
args = parser.parse_args()
|
|
verbose = args.verbose
|
|
|
|
board_filter = []
|
|
if args.filter:
|
|
for board in args.filter.split(','):
|
|
board_filter.append(board)
|
|
|
|
default_container = 'ghcr.io/px4/px4-dev:v1.16.0-rc1-258-g0369abd556'
|
|
build_configs = []
|
|
grouped_targets = {}
|
|
excluded_boards = ['modalai_voxl2', 'px4_ros2', 'espressif_esp32'] # TODO: fix and enable
|
|
excluded_manufacturers = ['atlflight']
|
|
excluded_platforms = ['qurt']
|
|
excluded_labels = [
|
|
'stackcheck',
|
|
'nolockstep', 'replay', 'test',
|
|
'uavcanv1', # TODO: fix and enable
|
|
]
|
|
|
|
github_action_config = { 'include': build_configs }
|
|
extra_args = {}
|
|
if args.pretty:
|
|
extra_args['indent'] = 2
|
|
|
|
def chunks(arr, size):
|
|
# splits array into parts
|
|
for i in range(0, len(arr), size):
|
|
yield arr[i:i + size]
|
|
|
|
def comma_targets(targets):
|
|
# turns array of targets into a comma split string
|
|
return ",".join(targets)
|
|
|
|
def process_target(px4board_file, target_name):
|
|
# reads through the board file and grabs
|
|
# useful information for building
|
|
ret = None
|
|
platform = None
|
|
toolchain = None
|
|
group = None
|
|
|
|
if px4board_file.endswith("default.px4board") or \
|
|
px4board_file.endswith("performance-test.px4board") or \
|
|
px4board_file.endswith("bootloader.px4board"):
|
|
kconf.load_config(px4board_file, replace=True)
|
|
else: # Merge config with default.px4board
|
|
default_kconfig = re.sub(r'[a-zA-Z\d_-]+\.px4board', 'default.px4board', px4board_file)
|
|
kconf.load_config(default_kconfig, replace=True)
|
|
kconf.load_config(px4board_file, replace=False)
|
|
|
|
if "BOARD_TOOLCHAIN" in kconf.syms:
|
|
toolchain = kconf.syms["BOARD_TOOLCHAIN"].str_value
|
|
|
|
if "BOARD_PLATFORM" in kconf.syms:
|
|
platform = kconf.syms["BOARD_PLATFORM"].str_value
|
|
|
|
assert platform, f"PLATFORM not found in {px4board_file}"
|
|
|
|
if platform not in excluded_platforms:
|
|
container = default_container
|
|
if platform == 'posix':
|
|
group = 'base'
|
|
if toolchain:
|
|
if toolchain.startswith('aarch64'):
|
|
group = 'aarch64'
|
|
elif toolchain == 'arm-linux-gnueabihf':
|
|
group = 'armhf'
|
|
else:
|
|
if verbose: print(f'unmatched toolchain: {toolchain}')
|
|
elif platform == 'nuttx':
|
|
group = 'nuttx'
|
|
else:
|
|
if verbose: print(f'unmatched platform: {platform}')
|
|
|
|
ret = {'target': target_name, 'container': container}
|
|
if(args.group):
|
|
ret['arch'] = group
|
|
|
|
return ret
|
|
|
|
# Look for board targets in the ./boards directory
|
|
if(verbose):
|
|
print("=======================")
|
|
print("= scanning for boards =")
|
|
print("=======================")
|
|
|
|
# We also need to build metadata
|
|
# includes:
|
|
# - Airframe
|
|
# - Parameters
|
|
# - Events
|
|
metadata_targets = ['airframe_metadata', 'parameters_metadata', 'extract_events']
|
|
grouped_targets['base'] = {}
|
|
grouped_targets['base']['container'] = default_container
|
|
grouped_targets['base']['manufacturers'] = {}
|
|
grouped_targets['base']['manufacturers']['px4'] = []
|
|
grouped_targets['base']['manufacturers']['px4'] += metadata_targets
|
|
|
|
for manufacturer in os.scandir(os.path.join(source_dir, '../boards')):
|
|
if not manufacturer.is_dir():
|
|
continue
|
|
if manufacturer.name in excluded_manufacturers:
|
|
if verbose: print(f'excluding manufacturer {manufacturer.name}')
|
|
continue
|
|
|
|
for board in os.scandir(manufacturer.path):
|
|
if not board.is_dir():
|
|
continue
|
|
|
|
for files in os.scandir(board.path):
|
|
if files.is_file() and files.name.endswith('.px4board'):
|
|
|
|
board_name = manufacturer.name + '_' + board.name
|
|
label = files.name[:-9]
|
|
target_name = manufacturer.name + '_' + board.name + '_' + label
|
|
|
|
if board_filter and not board_name in board_filter:
|
|
if verbose: print(f'excluding board {board_name} ({target_name})')
|
|
continue
|
|
|
|
if board_name in excluded_boards:
|
|
if verbose: print(f'excluding board {board_name} ({target_name})')
|
|
continue
|
|
|
|
if label in excluded_labels:
|
|
if verbose: print(f'excluding label {label} ({target_name})')
|
|
continue
|
|
target = process_target(files.path, target_name)
|
|
if (args.group and target is not None):
|
|
if (target['arch'] not in grouped_targets):
|
|
grouped_targets[target['arch']] = {}
|
|
grouped_targets[target['arch']]['container'] = target['container']
|
|
grouped_targets[target['arch']]['manufacturers'] = {}
|
|
if(manufacturer.name not in grouped_targets[target['arch']]['manufacturers']):
|
|
grouped_targets[target['arch']]['manufacturers'][manufacturer.name] = []
|
|
grouped_targets[target['arch']]['manufacturers'][manufacturer.name].append(target_name)
|
|
if target is not None:
|
|
build_configs.append(target)
|
|
|
|
if(verbose):
|
|
import pprint
|
|
print("============================")
|
|
print("= Boards found in ./boards =")
|
|
print("============================")
|
|
pprint.pp(grouped_targets)
|
|
|
|
if(verbose):
|
|
print("===================")
|
|
print("= Generating JSON =")
|
|
print("===================")
|
|
|
|
if (args.group):
|
|
# if we are using this script for grouping builds
|
|
# we loop trough the manufacturers list and split their targets
|
|
# if a manufacturer has more than a LIMIT of boards then we split that
|
|
# into sub groups such as "arch-manufacturer name-index"
|
|
# example:
|
|
# nuttx-px4-0
|
|
# nuttx-px4-1
|
|
# nuttx-px4-2
|
|
# nuttx-ark-0
|
|
# nuttx-ark-1
|
|
# if the manufacturer doesn't have more targets than LIMIT then we add
|
|
# them to a generic group with the following structure "arch-index"
|
|
# example:
|
|
# nuttx-0
|
|
# nuttx-1
|
|
final_groups = []
|
|
last_man = ''
|
|
last_arch = ''
|
|
SPLIT_LIMIT = 10
|
|
LOWER_LIMIT = 5
|
|
if(verbose):
|
|
print(f'=:Architectures: [{grouped_targets.keys()}]')
|
|
for arch in grouped_targets:
|
|
runner = 'x64' if arch == 'nuttx' else 'arm64'
|
|
if(verbose):
|
|
print(f'=:Processing: [{arch}]')
|
|
temp_group = []
|
|
for man in grouped_targets[arch]['manufacturers']:
|
|
if(verbose):
|
|
print(f'=:Processing: [{arch}][{man}]')
|
|
man_len = len(grouped_targets[arch]['manufacturers'][man])
|
|
if(man_len > LOWER_LIMIT and man_len < (SPLIT_LIMIT + 1)):
|
|
# Manufacturers can have their own group
|
|
if(verbose):
|
|
print(f'=:Processing: [{arch}][{man}][{man_len}]==Manufacturers can have their own group')
|
|
group_name = arch + "-" + man
|
|
targets = comma_targets(grouped_targets[arch]['manufacturers'][man])
|
|
final_groups.append({
|
|
"container": grouped_targets[arch]['container'],
|
|
"targets": targets,
|
|
"arch": arch,
|
|
"runner": runner,
|
|
"group": group_name,
|
|
"len": len(grouped_targets[arch]['manufacturers'][man])
|
|
})
|
|
elif(man_len >= (SPLIT_LIMIT + 1)):
|
|
# Split big man groups into subgroups
|
|
# example: Pixhawk
|
|
if(verbose):
|
|
print(f'=:Processing: [{arch}][{man}][{man_len}]==Manufacturers has multiple own groups')
|
|
chunk_limit = SPLIT_LIMIT
|
|
chunk_counter = 0
|
|
for chunk in chunks(grouped_targets[arch]['manufacturers'][man], chunk_limit):
|
|
group_name = arch + "-" + man + "-" + str(chunk_counter)
|
|
targets = comma_targets(chunk)
|
|
final_groups.append({
|
|
"container": grouped_targets[arch]['container'],
|
|
"targets": targets,
|
|
"arch": arch,
|
|
"runner": runner,
|
|
"group": group_name,
|
|
"len": len(chunk),
|
|
})
|
|
chunk_counter += 1
|
|
else:
|
|
if(verbose):
|
|
print(f'=:Processing: [{arch}][{man}][{man_len}]==Manufacturers too small group with others')
|
|
temp_group.extend(grouped_targets[arch]['manufacturers'][man])
|
|
|
|
temp_len = len(temp_group)
|
|
chunk_counter = 0
|
|
if(temp_len > 0 and temp_len < (SPLIT_LIMIT + 1)):
|
|
if(verbose):
|
|
print(f'=:Processing: [{arch}][orphan][{temp_len}]==Leftover arch can have their own group')
|
|
group_name = arch + "-" + str(chunk_counter)
|
|
targets = comma_targets(temp_group)
|
|
final_groups.append({
|
|
"container": grouped_targets[arch]['container'],
|
|
"targets": targets,
|
|
"arch": arch,
|
|
"runner": runner,
|
|
"group": group_name,
|
|
"len": temp_len
|
|
})
|
|
elif(temp_len >= (SPLIT_LIMIT + 1)):
|
|
# Split big man groups into subgroups
|
|
# example: Pixhawk
|
|
if(verbose):
|
|
print(f'=:Processing: [{arch}][orphan][{temp_len}]==Leftover arch can has multpile group')
|
|
chunk_limit = SPLIT_LIMIT
|
|
chunk_counter = 0
|
|
for chunk in chunks(temp_group, chunk_limit):
|
|
group_name = arch + "-" + str(chunk_counter)
|
|
targets = comma_targets(chunk)
|
|
final_groups.append({
|
|
"container": grouped_targets[arch]['container'],
|
|
"targets": targets,
|
|
"arch": arch,
|
|
"runner": runner,
|
|
"group": group_name,
|
|
"len": len(chunk),
|
|
})
|
|
chunk_counter += 1
|
|
if(verbose):
|
|
import pprint
|
|
print("================")
|
|
print("= final_groups =")
|
|
print("================")
|
|
pprint.pp(final_groups)
|
|
|
|
print("===============")
|
|
print("= JSON output =")
|
|
print("===============")
|
|
|
|
print(json.dumps({ "include": final_groups }, **extra_args))
|
|
else:
|
|
print(json.dumps(github_action_config, **extra_args))
|