mirror of
https://github.com/espressif/esp-idf.git
synced 2025-09-01 06:27:29 +00:00

- Also adds support to whitelist target specific expected dependency violations in check_dependencies.py
141 lines
5.1 KiB
Python
141 lines
5.1 KiB
Python
# SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
|
# SPDX-License-Identifier: Unlicense OR CC0-1.0
|
|
import argparse
|
|
import logging
|
|
from typing import Dict
|
|
from typing import List
|
|
from typing import Optional
|
|
from typing import Tuple
|
|
|
|
g1_g0_components = [
|
|
'hal',
|
|
'cxx',
|
|
'newlib',
|
|
'freertos',
|
|
'esp_hw_support',
|
|
'heap',
|
|
'log',
|
|
'soc',
|
|
'esp_rom',
|
|
'esp_common',
|
|
'esp_system',
|
|
'xtensa',
|
|
'riscv',
|
|
'spi_flash',
|
|
'esp_mm',
|
|
]
|
|
|
|
# Global expected dependency violations that apply to all targets
|
|
expected_dep_violations = {
|
|
'esp_system': ['esp_timer', 'bootloader_support', 'esp_pm'],
|
|
'spi_flash': ['bootloader_support'],
|
|
'esp_hw_support': ['efuse', 'bootloader_support', 'esp_driver_gpio', 'esp_timer', 'esp_pm'],
|
|
'cxx': ['pthread'],
|
|
}
|
|
|
|
# Target-specific expected dependency violations
|
|
target_specific_expected_dep_violations = {
|
|
# 'target': {
|
|
# Add target-specific violations for target here
|
|
# 'component_name': ['dependency1', 'dependency2'],
|
|
# },
|
|
'esp32s2': {
|
|
# ESP32-S2 uses the crypto DMA lock for encrypted writes, thus, spi_flash needs to depend on esp_security
|
|
'spi_flash': ['esp_security'],
|
|
},
|
|
}
|
|
|
|
|
|
def merge_expected_violations(target: Optional[str] = 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: Optional[str] = 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, 'r') as file:
|
|
for line in file:
|
|
line = line.strip(' ;')
|
|
|
|
if line:
|
|
parts = line.split(' -> ')
|
|
|
|
if len(parts) >= 2:
|
|
source_component = parts[0]
|
|
target_component = parts[1].split()[0] # Extracting the 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')
|