mirror of
https://github.com/espressif/esp-idf.git
synced 2026-09-22 13:01:16 +03:00
The G1 dependency check fails when an expected extra dependency is no longer present after the real component edge was removed.
173 lines
6.6 KiB
Python
173 lines
6.6 KiB
Python
# SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
|
|
# SPDX-License-Identifier: Unlicense OR CC0-1.0
|
|
import argparse
|
|
import glob
|
|
import logging
|
|
import os
|
|
|
|
# Base G1/G0 components (static list)
|
|
g1_g0_components_base = [
|
|
'hal',
|
|
'cxx',
|
|
'esp_libc',
|
|
'freertos',
|
|
'esp_hw_support',
|
|
'heap',
|
|
'log',
|
|
'soc',
|
|
'esp_rom',
|
|
'esp_common',
|
|
'esp_system',
|
|
'xtensa',
|
|
'riscv',
|
|
'esp_mm',
|
|
'esp_mspi',
|
|
]
|
|
|
|
|
|
def get_all_esp_hal_components() -> list[str]:
|
|
"""Dynamically discover all esp_hal_* components"""
|
|
esp_hal_components = []
|
|
|
|
# Try to get IDF_PATH from environment
|
|
idf_path = os.environ.get('IDF_PATH')
|
|
if idf_path is None:
|
|
# Fallback: assume script is in IDF_PATH/tools/test_apps/system/g1_components/
|
|
script_dir = os.path.dirname(os.path.abspath(__file__))
|
|
idf_path = os.path.join(script_dir, '../../../../..')
|
|
|
|
components_dir = os.path.join(idf_path, 'components')
|
|
if os.path.exists(components_dir):
|
|
# Find all esp_hal_* directories
|
|
esp_hal_dirs = glob.glob(os.path.join(components_dir, 'esp_hal_*'))
|
|
for hal_dir in esp_hal_dirs:
|
|
if os.path.isdir(hal_dir):
|
|
component_name = os.path.basename(hal_dir)
|
|
esp_hal_components.append(component_name)
|
|
|
|
return sorted(esp_hal_components)
|
|
|
|
|
|
# Build complete G1/G0 components list (base + dynamic esp_hal_* components)
|
|
g1_g0_components = g1_g0_components_base + get_all_esp_hal_components()
|
|
|
|
# Global expected dependency violations that apply to all targets
|
|
expected_dep_violations = {
|
|
'esp_system': ['esp_timer', 'bootloader_support', 'esp_pm'],
|
|
'esp_hw_support': ['efuse', 'bootloader_support', 'esp_driver_gpio', 'esp_timer'],
|
|
# efuse: esp_mspi_align queries the flash encryption state to derive MSPI buffer alignment
|
|
'esp_mspi': ['bootloader_support', 'efuse'],
|
|
'cxx': ['pthread'],
|
|
}
|
|
|
|
if os.environ.get('IDF_BUILD_V2'):
|
|
expected_dep_violations['esp_system'].append('esp_app_format')
|
|
else:
|
|
# Requirements are resolved before Kconfig under build system v1, so esp_system
|
|
# depends on the ROM CDC console unconditionally. Under v2 the dependency is
|
|
# only added when the console is set to USB CDC.
|
|
expected_dep_violations['esp_system'].append('esp_usb_cdc_rom_console')
|
|
|
|
# Target-specific expected dependency violations
|
|
target_specific_expected_dep_violations: dict[str, dict[str, list[str]]] = {
|
|
# 'target': {
|
|
# Add target-specific violations for target here
|
|
# 'component_name': ['dependency1', 'dependency2'],
|
|
# },
|
|
}
|
|
|
|
|
|
def merge_expected_violations(target: str | None = None) -> dict[str, list[str]]:
|
|
"""
|
|
Merge global and target-specific expected dependency violations.
|
|
|
|
Args:
|
|
target: The target target name (e.g., 'esp32', 'esp32s3', etc.)
|
|
|
|
Returns:
|
|
Merged dictionary of expected dependency violations
|
|
"""
|
|
# Start with a deep copy of global violations
|
|
merged_violations = {}
|
|
for component, deps in expected_dep_violations.items():
|
|
merged_violations[component] = deps.copy()
|
|
|
|
# Add target-specific violations if target is specified
|
|
if target and target in target_specific_expected_dep_violations:
|
|
target_violations = target_specific_expected_dep_violations[target]
|
|
for component, deps in target_violations.items():
|
|
if component in merged_violations:
|
|
# Extend existing list with target-specific dependencies
|
|
merged_violations[component].extend(deps)
|
|
else:
|
|
# Add new component with its dependencies
|
|
merged_violations[component] = deps.copy()
|
|
|
|
return merged_violations
|
|
|
|
|
|
def parse_dependencies(file_path: str, target: str | None = None) -> tuple[dict[str, list[str]], list[str]]:
|
|
new_dependency_errors = []
|
|
|
|
# Get merged expected violations for the specified target
|
|
merged_expected_violations = merge_expected_violations(target)
|
|
|
|
with open(file_path) as file:
|
|
for line in file:
|
|
line = line.strip(' ;')
|
|
|
|
if line:
|
|
parts = line.split(' -> ')
|
|
|
|
if len(parts) >= 2:
|
|
source_component = parts[0].strip('"')
|
|
target_component = parts[1].split()[0].strip('"') # Extracting the target component
|
|
print(f'{source_component} -> {target_component}')
|
|
logging.debug(f'Parsed dependency: {source_component} -> {target_component}')
|
|
|
|
# Check that g1/g0 dependencies are either on the list of expected violations
|
|
# or dependencies to other g1/g0 components
|
|
if source_component in g1_g0_components and target_component not in g1_g0_components:
|
|
if (
|
|
source_component in merged_expected_violations
|
|
and target_component in merged_expected_violations[source_component]
|
|
):
|
|
logging.debug(
|
|
f'Removing dependency {target_component} from {source_component} '
|
|
f'in list of expected violations'
|
|
)
|
|
merged_expected_violations[source_component].remove(target_component)
|
|
else:
|
|
new_dependency_errors.append(f'{source_component} -> {target_component}')
|
|
|
|
# Any leftover dependencies in the merged_expected_violations are no longer true dependencies and
|
|
# can be removed from the list
|
|
false_dependencies = {k: v for k, v in merged_expected_violations.items() if len(v) > 0}
|
|
|
|
return (false_dependencies, new_dependency_errors)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
parser = argparse.ArgumentParser(description='Check G1 dependencies')
|
|
parser.add_argument(
|
|
'--component_deps_file', required=True, type=str, help='The path to the component_deps.dot file'
|
|
)
|
|
parser.add_argument('--target', type=str, help='The target name (e.g., esp32, esp32s3, esp32c6, etc.)')
|
|
|
|
args = parser.parse_args()
|
|
|
|
(false_dependencies, new_dependency_errors) = parse_dependencies(args.component_deps_file, args.target)
|
|
|
|
if new_dependency_errors:
|
|
print('Found the following new dependency violations:')
|
|
print(new_dependency_errors)
|
|
exit(1)
|
|
|
|
if false_dependencies:
|
|
print('The following dependencies are list as violations, but were not found in the component_deps.dot file:')
|
|
print(false_dependencies)
|
|
print('Please remove them from the violation list')
|
|
exit(1)
|
|
|
|
print('No new dependency violations found')
|