diff options
| author | Chelsea Cassanova <chelsea_cassanova@apple.com> | 2025-06-12 13:55:44 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-06-12 13:55:44 -0700 |
| commit | 8a8ea8fec063bd64c17e463e7c3eaae5cdb4a645 (patch) | |
| tree | 33703df3f974022fe5cc657224facdf5ecfe9175 /lldb/scripts | |
| parent | 741ea80446e21b4052d723765011fe3583d3fc7f (diff) | |
Reland "[lldb][headers] Create Python script to fix up framework head… (#143945)
…ers" (#143941)
Reland the script that converts lldb headers to RPC headers. The RPC
test was failing due to the incorrect input filepath being used.
Original commit message:
This commit replaces the shell script that fixes up includes for the
LLDB framework with a Python script. This script will also be used when
fixing up includes for the LLDBRPC.framework.
Diffstat (limited to 'lldb/scripts')
| -rwxr-xr-x | lldb/scripts/framework-header-fix.py | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/lldb/scripts/framework-header-fix.py b/lldb/scripts/framework-header-fix.py new file mode 100755 index 000000000000..9528fdb7e30b --- /dev/null +++ b/lldb/scripts/framework-header-fix.py @@ -0,0 +1,126 @@ +#!/usr/bin/env python3 + +""" +Usage: <path/to/input-directory> <path/to/output-directory> + +This script is used when building LLDB.framework or LLDBRPC.framework. For each framework, local includes are converted to their respective framework includes. + +This script is used in 2 ways: +1. It is used on header files that are copied into LLDB.framework. For these files, local LLDB includes are converted into framework includes, e.g. #include "lldb/API/SBDefines.h" -> #include <LLDB/SBDefines.h>. + +2. It is used on header files for LLDBRPC.framework. For these files, includes of RPC common files will be converted to framework includes, e.g. #include <lldb-rpc/common/RPCCommon.h> -> #include <LLDBRPC/RPCCommon.h>. It will also change local includes to framework includes, e.g. #include "SBAddress.h" -> #include <LLDBRPC/SBAddress.h> +""" + +import argparse +import os +import re +import shutil +import subprocess +import sys + +# Main header regexes +INCLUDE_FILENAME_REGEX = re.compile( + r'#include "lldb/API/(?P<include_filename>.*){0,1}"' +) + +# RPC header regexes +RPC_COMMON_REGEX = re.compile(r"#include <lldb-rpc/common/(?P<include_filename>.*)>") +RPC_INCLUDE_FILENAME_REGEX = re.compile(r'#include "(?P<include_filename>.*)"') + + +def modify_rpc_includes(input_file_path, output_file_path): + with open(input_file_path, "r") as input_file: + lines = input_file.readlines() + file_buffer = "".join(lines) + with open(output_file_path, "w") as output_file: + # Local includes must be changed to RPC framework level includes. + # e.g. #include "SBDefines.h" -> #include <LLDBRPC/SBDefines.h> + # Also, RPC common code includes must change to RPC framework level includes. + # e.g. #include "lldb-rpc/common/RPCPublic.h" -> #include <LLDBRPC/RPCPublic.h> + rpc_common_matches = RPC_COMMON_REGEX.finditer(file_buffer) + rpc_include_filename_matches = RPC_INCLUDE_FILENAME_REGEX.finditer( + file_buffer + ) + for match in rpc_common_matches: + file_buffer = re.sub( + match.group(), + r"#include <LLDBRPC/" + match.group("include_filename") + ">", + file_buffer, + ) + for match in rpc_include_filename_matches: + file_buffer = re.sub( + match.group(), + r"#include <LLDBRPC/" + match.group("include_filename") + ">", + file_buffer, + ) + output_file.write(file_buffer) + + +def modify_main_includes(input_file_path, output_file_path): + with open(input_file_path, "r") as input_file: + lines = input_file.readlines() + file_buffer = "".join(lines) + with open(output_file_path, "w") as output_file: + # Local includes must be changed to framework level includes. + # e.g. #include "lldb/API/SBDefines.h" -> #include <LLDB/SBDefines.h> + regex_matches = INCLUDE_FILENAME_REGEX.finditer(file_buffer) + for match in regex_matches: + file_buffer = re.sub( + match.group(), + r"#include <LLDB/" + match.group("include_filename") + ">", + file_buffer, + ) + output_file.write(file_buffer) + + +def remove_guards(output_file_path, unifdef_path, unifdef_guards): + # The unifdef path should be passed in from CMake. If it wasn't there in CMake or is incorrect, + # find it using shutil. If shutil can't find it, then exit. + if not shutil.which(unifdef_path): + unifdef_path = shutil.which("unifdef") + if not unifdef_path: + print( + "Unable to find unifdef executable. Guards will not be removed from input files. Exiting..." + ) + sys.exit() + + subprocess_command = ( + [unifdef_path, "-o", output_file_path] + unifdef_guards + [output_file_path] + ) + subprocess.run(subprocess_command) + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument("-f", "--framework", choices=["lldb_main", "lldb_rpc"]) + parser.add_argument("-i", "--input_file") + parser.add_argument("-o", "--output_file") + parser.add_argument("-p", "--unifdef_path") + parser.add_argument( + "unifdef_guards", + nargs="+", + type=str, + help="Guards to be removed with unifdef. These must be specified in the same way as they would be when passed directly into unifdef.", + ) + args = parser.parse_args() + input_file_path = str(args.input_file) + output_file_path = str(args.output_file) + framework_version = args.framework + unifdef_path = str(args.unifdef_path) + # Prepend dashes to the list of guards passed in from the command line. + # unifdef takes the guards to remove as arguments in their own right (e.g. -USWIG) + # but passing them in with dashes for this script causes argparse to think that they're + # arguments in and of themself, so they need to passed in without dashes. + unifdef_guards = ["-" + guard for guard in args.unifdef_guards] + + if framework_version == "lldb_main": + modify_main_includes(input_file_path, output_file_path) + if framework_version == "lldb_rpc": + modify_rpc_includes(input_file_path, output_file_path) + # After the incldues have been modified, run unifdef on the headers to remove any guards + # specified at the command line. + remove_guards(output_file_path, unifdef_path, unifdef_guards) + + +if __name__ == "__main__": + main() |
