#!/usr/bin/env python3 """ Fix RTI links in CMakeLists.txt files by wrapping them in IF(BUILD_RTI) blocks. This script finds NGL_TARGET_LINK_LIBRARIES blocks that contain RTI:: references and wraps them in IF(BUILD_RTI) conditionals if not already wrapped. """ import os import re import sys def process_cmake_file(filepath): """Process a single CMakeLists.txt file and wrap RTI links in IF(BUILD_RTI).""" with open(filepath, 'r') as f: content = f.read() original_content = content lines = content.split('\n') # Track if we're inside an IF(BUILD_RTI) block build_rti_depth = 0 i = 0 while i < len(lines): line = lines[i] # Check for IF(BUILD_RTI) - increment depth if re.match(r'^\s*IF\s*\(\s*BUILD_RTI\s*\)\s*$', line, re.IGNORECASE): build_rti_depth += 1 i += 1 continue # Check for ENDIF(BUILD_RTI) - decrement depth if re.match(r'^\s*ENDIF\s*\(\s*BUILD_RTI\s*\)\s*$', line, re.IGNORECASE): build_rti_depth = max(0, build_rti_depth - 1) i += 1 continue # Check for NGL_TARGET_LINK_LIBRARIES with RTI reference if re.match(r'^\s*NGL_TARGET_LINK_LIBRARIES\s*\(', line, re.IGNORECASE): # Find the complete block (matching parentheses) block_start = i paren_depth = 0 block_end = i for j in range(i, len(lines)): paren_depth += lines[j].count('(') - lines[j].count(')') if paren_depth == 0: block_end = j break # Check if this block contains RTI:: reference block_content = '\n'.join(lines[block_start:block_end+1]) has_rti = bool(re.search(r'RTI::', block_content)) # Check if already inside IF(BUILD_RTI) already_wrapped = build_rti_depth > 0 if has_rti and not already_wrapped: print(f" Wrapping RTI link block at line {block_start+1}") # Insert IF(BUILD_RTI) before the block indent = '' if block_start > 0: # Try to match indentation of the NGL_TARGET_LINK_LIBRARIES line match = re.match(r'^(\s*)', lines[block_start]) if match: indent = match.group(1) lines.insert(block_start, f'{indent}IF(BUILD_RTI)') # Insert ENDIF(BUILD_RTI) after the block # Adjust block_end because we inserted a line block_end += 1 lines.insert(block_end + 1, f'{indent}ENDIF(BUILD_RTI)') # Skip past the block we just processed i = block_end + 2 continue i += 1 new_content = '\n'.join(lines) if new_content != original_content: with open(filepath, 'w') as f: f.write(new_content) return True return False def find_cmake_files(root_dir): """Find all CMakeLists.txt files recursively.""" cmake_files = [] for dirpath, dirnames, filenames in os.walk(root_dir): # Skip .git directories if '.git' in dirpath: continue if 'CMakeLists.txt' in filenames: cmake_files.append(os.path.join(dirpath, 'CMakeLists.txt')) return cmake_files def main(): if len(sys.argv) < 2: print("Usage: fix_rti_links.py ") sys.exit(1) root_dir = sys.argv[1] if not os.path.isdir(root_dir): print(f"Error: {root_dir} is not a directory") sys.exit(1) cmake_files = find_cmake_files(root_dir) print(f"Found {len(cmake_files)} CMakeLists.txt files") modified_count = 0 for filepath in cmake_files: rel_path = os.path.relpath(filepath, root_dir) # Check if file contains RTI references before processing with open(filepath, 'r') as f: content = f.read() if 'RTI::' not in content: continue print(f"Processing: {rel_path}") if process_cmake_file(filepath): modified_count += 1 print(f"\nModified {modified_count} files") if __name__ == '__main__': main()