Files
qt6-migration-pipeline/fix_export_headers_proper.py
T
torstenandCopilot 342ffd3e5c Update submodule to latest BUILD_RTI fixes
- HandlerMinelayerData: BUILD_RTI Guards für RTI-Abhängigkeiten
- svcTabCommon: Export-Header-Fix via Fallback-Target
- TrainingAreaBase: Stub-Header für BUILD_RTI=OFF
- ddsfts: Include-Pfad und Dependency-Fixes
- BUILD_RTI=OFF Compilation vollständig unterstützt

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Entire-Checkpoint: 01M0JNZA586SACX1PRZ2DJAE5S
2026-08-21 19:30:20 +02:00

190 lines
6.3 KiB
Python
Executable File

#!/usr/bin/env python3
"""
Fix wrong export header includes by finding correct target names from CMakeLists.txt
"""
import os
import re
import subprocess
from pathlib import Path
# Mapping von bekannten falschen Includes zu korrekten Target-Namen basierend auf CMakeLists.txt Analyse
KNOWN_MAPPINGS = {
# Lts/Common/LtsWidgets
'Lts/Common/LtsWidgets': 'ltswidgets',
# Lts/Common/LtsSession
'Lts/Common/LtsSession': 'ltssessiondata',
# Lts/Common/LtsUtils/LtsUtilsSettings
'Lts/Common/LtsUtils/LtsUtilsSettings': 'ltsutilssettings',
# Lts/Common/LtsCoordTrans
'Lts/Common/LtsCoordTrans': 'ltscoordtrans',
# Lts/DDS/QosProfile
'Lts/DDS/QosProfile': 'qosprofile',
# Lts/DDS/FTS
'Lts/DDS/FTS': 'ddsfts',
# Lts/Services/AreaEffectSimulation
'Lts/Services/AreaEffectSimulation': 'svcaessimulation',
# Lts/Services/CentralEffectSimulation
'Lts/Services/CentralEffectSimulation': 'aescore',
# Lts/Proxies/Buildings/BuildingControlUnit
'Lts/Proxies/Buildings/BuildingControlUnit': 'buildingcontrolunit',
# Lts/Plugins/SituationMapPlugin
'Lts/Plugins/SituationMapPlugin': 'situationmapplugin',
# Z/src/WMS_Interface
'Z/src/WMS_Interface': 'wmsinterface',
}
def find_target_in_cmake(file_path, base_dir):
"""Search CMakeLists.txt files to find the target name for a given source file"""
file_dir = Path(file_path).parent
rel_path = Path(file_path).relative_to(base_dir)
rel_dir = str(rel_path.parent)
# Try to match directory to known mappings
for dir_pattern, target_name in KNOWN_MAPPINGS.items():
if rel_dir.startswith(dir_pattern) or dir_pattern in rel_dir:
return target_name
# Search for CMakeLists.txt in the file's directory or parents
cmake_file = file_dir / "CMakeLists.txt"
if cmake_file.exists():
with open(cmake_file, 'r') as f:
content = f.read()
# Look for NGL_ADD_LIBRARY or NGL_ADD_LIBRARY2
matches = re.findall(r'NGL_ADD_LIBRARY[2]?\s*\([^)]+\s+(\w+)\s+(?:SHARED|MODULE|STATIC)', content)
if matches:
return matches[0].lower()
matches = re.findall(r'NGL_ADD_LIBRARY\s*\(\w+\s+\w+\s+\w+\s+(\w+)\s+SHARED', content)
if matches:
return matches[0].lower()
# Search parent directories
for parent in file_dir.parents:
if parent == base_dir.parent:
break
cmake_file = parent / "CMakeLists.txt"
if cmake_file.exists():
with open(cmake_file, 'r') as f:
content = f.read()
matches = re.findall(r'NGL_ADD_LIBRARY[2]?\s*\([^)]+\s+(\w+)\s+(?:SHARED|MODULE|STATIC)', content)
if matches:
return matches[0].lower()
return None
def file_uses_export_macros(file_path):
"""Check if file uses any export macros"""
with open(file_path, 'r') as f:
content = f.read()
patterns = [
r'\b\w+_EXPORT\b',
r'\b\w+_EXPORTS\b',
]
for pattern in patterns:
if re.search(pattern, content):
return True
return False
def fix_file(file_path, correct_export_header):
"""Fix the export header include in a file"""
with open(file_path, 'r') as f:
content = f.read()
# Remove wrong includes
wrong_patterns = [
r'#include\s+"s_export\.h"[ \t]*\n',
r'#include\s+"n_export\.h"[ \t]*\n',
r'#include\s+"a_export\.h"[ \t]*\n',
r'#include\s+"z_export\.h"[ \t]*\n',
r'#include\s+"ws_export\.h"[ \t]*\n',
r'#include\s+"aar_export\.h"[ \t]*\n',
]
for pattern in wrong_patterns:
content = re.sub(pattern, '', content)
# Add correct include if needed
if correct_export_header:
if '#pragma once' in content:
content = re.sub(
r'(#pragma once\s*\n)',
f'\\1#include "{correct_export_header}"\n',
content,
count=1
)
else:
match = re.match(r'(/\*.*?\*/\s*\n)?(#.*\n)*', content, re.DOTALL)
if match:
insert_pos = match.end()
content = content[:insert_pos] + f'#include "{correct_export_header}"\n' + content[insert_pos:]
with open(file_path, 'w') as f:
f.write(content)
def main():
base_dir = Path("/home/torsten/swy/sandbox/qt-migration-legatus/qt6-after/qt6-migrated-legatus").resolve()
os.chdir(base_dir)
wrong_includes = ['s_export.h', 'n_export.h', 'a_export.h', 'z_export.h']
files_to_fix = []
for wrong_include in wrong_includes:
result = subprocess.run(
['grep', '-rl', f'"{wrong_include}"', '.'],
capture_output=True,
text=True
)
for line in result.stdout.strip().split('\n'):
if line and 'external/' not in line:
files_to_fix.append(base_dir / line.lstrip('./'))
print(f"Found {len(files_to_fix)} files with wrong export header includes\n")
fixed_count = 0
removed_count = 0
skipped_count = 0
for file_path in files_to_fix:
if not file_path.exists():
continue
rel_path = file_path.relative_to(base_dir)
print(f"Processing: {rel_path}")
target = find_target_in_cmake(file_path, base_dir)
if target:
correct_header = f"{target}_export.h"
uses_macros = file_uses_export_macros(file_path)
if uses_macros:
fix_file(file_path, correct_header)
print(f" ✓ Fixed to {correct_header}")
fixed_count += 1
else:
fix_file(file_path, None)
print(f" ✓ Removed include (no macros)")
removed_count += 1
else:
uses_macros = file_uses_export_macros(file_path)
if uses_macros:
print(f" ⚠ Skipped: Cannot determine target, but file uses export macros")
skipped_count += 1
else:
fix_file(file_path, None)
print(f" ✓ Removed include (no macros, no target)")
removed_count += 1
print(f"\n=== Summary ===")
print(f"Fixed: {fixed_count}")
print(f"Removed: {removed_count}")
print(f"Skipped: {skipped_count}")
if __name__ == '__main__':
main()