#!/bin/python3 import argparse import multiprocessing import os from pathlib import Path import signal import subprocess import sys # Relative to Userland directory PATHS_TO_SEARCH = [ 'Applications/Assistant', 'Applications/Browser', 'Applications/Spreadsheet', 'Applications/TextEditor', 'DevTools/HackStudio', 'Libraries/LibJS', 'Libraries/LibMarkdown', 'Libraries/LibWeb', 'Services/WebContent', ] parser = argparse.ArgumentParser('LibJSGCVerifier', description='A Clang tool to validate usage of the LibJS GC') parser.add_argument('-b', '--build-path', required=True, help='Path to the project Build folder') args = parser.parse_args() build_path = Path(args.build_path).resolve() userland_path = build_path / '..' / 'Userland' include_path = build_path / 'x86_64clang' / 'Root' / 'usr' / 'include' compile_commands_path = build_path / 'x86_64clang' / 'compile_commands.json' if not compile_commands_path.exists(): print(f'Could not find compile_commands.json in {compile_commands_path.parent}') exit(1) paths = [] for containing_path in PATHS_TO_SEARCH: for root, dirs, files in os.walk(userland_path / containing_path): for file in files: # FIXME: The dollar sign in $262Object.cpp gets corrupted in compile_commands.json somehow, and # ends up as "\\$$262Object.cpp". This results in a clang error, so we just ignore the # file here if file.endswith('.cpp') and not file.endswith('262Object.cpp'): paths.append(Path(root) / file) def thread_init(): signal.signal(signal.SIGINT, signal.SIG_IGN) def thread_execute(file_path): clang_args = [ './build/LibJSGCVerifier', '--extra-arg', '-DUSING_AK_GLOBALLY=1', # To avoid errors about USING_AK_GLOBALLY not being defined at all '-p', compile_commands_path, file_path ] proc = subprocess.Popen(clang_args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) sys.stdout.buffer.write(proc.communicate()[0]) sys.stdout.buffer.flush() with multiprocessing.Pool(processes=multiprocessing.cpu_count() - 2, initializer=thread_init) as pool: try: pool.map(thread_execute, paths) except KeyboardInterrupt: pool.terminate() pool.join()