Skip to content

Commit 62d0c96

Browse files
committed
[lldb][headers] Create Python script to fix up framework headers
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.
1 parent 9553514 commit 62d0c96

File tree

7 files changed

+134
-36
lines changed

7 files changed

+134
-36
lines changed

lldb/cmake/modules/LLDBFramework.cmake

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -68,24 +68,16 @@ if(NOT APPLE_EMBEDDED)
6868
)
6969
endif()
7070

71-
# At configuration time, collect headers for the framework bundle and copy them
72-
# into a staging directory. Later we can copy over the entire folder.
73-
file(GLOB public_headers ${LLDB_SOURCE_DIR}/include/lldb/API/*.h)
74-
set(generated_public_headers ${LLDB_OBJ_DIR}/include/lldb/API/SBLanguages.h)
75-
file(GLOB root_public_headers ${LLDB_SOURCE_DIR}/include/lldb/lldb-*.h)
76-
file(GLOB root_private_headers ${LLDB_SOURCE_DIR}/include/lldb/lldb-private*.h)
77-
list(REMOVE_ITEM root_public_headers ${root_private_headers})
78-
7971
find_program(unifdef_EXECUTABLE unifdef)
8072

81-
set(lldb_header_staging ${CMAKE_CURRENT_BINARY_DIR}/FrameworkHeaders)
82-
foreach(header
83-
${public_headers}
84-
${generated_public_headers}
85-
${root_public_headers})
73+
# All necessary header files should be staged in the include directory in the build directory,
74+
# so just copy the files from there into the framework's staging directory.
75+
set(lldb_build_dir_header_staging ${CMAKE_BINARY_DIR}/include/lldb)
76+
set(lldb_framework_header_staging ${CMAKE_CURRENT_BINARY_DIR}/FrameworkHeaders)
77+
foreach(header ${lldb_build_dir_header_staging})
8678

8779
get_filename_component(basename ${header} NAME)
88-
set(staged_header ${lldb_header_staging}/${basename})
80+
set(staged_header ${lldb_framework_header_staging}/${basename})
8981

9082
if(unifdef_EXECUTABLE)
9183
# unifdef returns 0 when the file is unchanged and 1 if something was changed.
@@ -107,14 +99,17 @@ endforeach()
10799
# Wrap output in a target, so lldb-framework can depend on it.
108100
add_custom_target(liblldb-resource-headers DEPENDS lldb-sbapi-dwarf-enums ${lldb_staged_headers})
109101
set_target_properties(liblldb-resource-headers PROPERTIES FOLDER "LLDB/Resources")
102+
103+
# We're taking the header files from where they've been staged in the build directory's include folder,
104+
# so create a dependency on the build step that creates that directory.
105+
add_dependencies(liblldb-resource-headers liblldb-header-staging)
110106
add_dependencies(liblldb liblldb-resource-headers)
111107

112-
# At build time, copy the staged headers into the framework bundle (and do
113-
# some post-processing in-place).
108+
# Take the headers from the staging directory and fix up their includes for the framework.
109+
# Then write them to the output directory.
114110
add_custom_command(TARGET liblldb POST_BUILD
115-
COMMAND ${CMAKE_COMMAND} -E copy_directory ${lldb_header_staging} $<TARGET_FILE_DIR:liblldb>/Headers
116-
COMMAND ${LLDB_SOURCE_DIR}/scripts/framework-header-fix.sh $<TARGET_FILE_DIR:liblldb>/Headers ${LLDB_VERSION}
117-
COMMENT "LLDB.framework: copy framework headers"
111+
COMMAND ${LLDB_SOURCE_DIR}/scripts/framework-header-fix.py lldb ${lldb_framework_header_staging} $<TARGET_FILE_DIR:liblldb>/Headers
112+
COMMENT "LLDB.framework: Fix up and copy framework headers"
118113
)
119114

120115
# Copy vendor-specific headers from clang (without staging).

lldb/scripts/framework-header-fix.py

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
#!/usr/bin/env python3
2+
3+
"""
4+
Usage: <path/to/input-directory> <path/to/output-directory>
5+
6+
This script is used when building LLDB.framework or LLDBRPC.framework. For each framework, local includes are converted to their respective framework includes.
7+
8+
This script is used in 2 ways:
9+
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>.
10+
11+
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>
12+
"""
13+
14+
import argparse
15+
import os
16+
import re
17+
18+
# Main header regexes
19+
INCLUDE_FILENAME_REGEX = re.compile(r'#include "lldb/API/(?P<include_filename>.*){0,1}"')
20+
21+
# RPC header regexes
22+
RPC_COMMON_REGEX = re.compile(r'#include <lldb-rpc/common/(?P<include_filename>.*)>')
23+
RPC_INCLUDE_FILENAME_REGEX = re.compile(r'#include "(?P<include_filename>.*)"')
24+
25+
def modify_rpc_includes(input_directory_path, output_directory_path):
26+
for input_filepath in os.listdir(input_directory_path):
27+
current_input_file = os.path.join(input_directory_path, input_filepath)
28+
output_dest = os.path.join(output_directory_path, input_filepath)
29+
if os.path.isfile(current_input_file):
30+
with open(current_input_file, "r") as input_file:
31+
lines = input_file.readlines()
32+
file_buffer = "".join(lines)
33+
with open(output_dest, "w") as output_file:
34+
# Local includes must be changed to RPC framework level includes.
35+
# e.g. #include "SBDefines.h" -> #include <LLDBRPC/SBDefines.h>
36+
# Also, RPC common code includes must change to RPC framework level includes.
37+
# e.g. #include "lldb-rpc/common/RPCPublic.h" -> #include <LLDBRPC/RPCPublic.h>
38+
rpc_common_matches = RPC_COMMON_REGEX.finditer(file_buffer)
39+
rpc_include_filename_matches = RPC_INCLUDE_FILENAME_REGEX.finditer(file_buffer)
40+
for match in rpc_common_matches:
41+
file_buffer = re.sub(match.group(), r'#include <LLDBRPC/' + match.group('include_filename') + '>', file_buffer)
42+
for match in rpc_include_filename_matches:
43+
file_buffer = re.sub(match.group(), r'#include <LLDBRPC/' + match.group('include_filename') + '>', file_buffer)
44+
output_file.write(file_buffer)
45+
46+
def modify_main_includes(input_directory_path, output_directory_path):
47+
for input_filepath in os.listdir(input_directory_path):
48+
current_input_file = os.path.join(input_directory_path, input_filepath)
49+
output_dest = os.path.join(output_directory_path, input_filepath)
50+
if os.path.isfile(current_input_file):
51+
with open(current_input_file, "r") as input_file:
52+
lines = input_file.readlines()
53+
file_buffer = "".join(lines)
54+
with open(output_dest, "w") as output_file:
55+
# Local includes must be changed to framework level includes.
56+
# e.g. #include "lldb/API/SBDefines.h" -> #include <LLDB/SBDefines.h>
57+
regex_matches = INCLUDE_FILENAME_REGEX.finditer(file_buffer)
58+
for match in regex_matches:
59+
file_buffer = re.sub(match.group(), r'#include <LLDB/' + match.group('include_filename') + '>', file_buffer)
60+
output_file.write(file_buffer)
61+
62+
def main():
63+
parser = argparse.ArgumentParser()
64+
parser.add_argument("framework", choices=["lldb_main", "lldb_rpc"])
65+
parser.add_argument("input_directory")
66+
parser.add_argument("output_directory")
67+
args = parser.parse_args()
68+
input_directory_path = str(args.input_directory)
69+
output_directory_path = str(args.output_directory)
70+
framework_version = args.framework
71+
72+
if framework_version == "lldb_main":
73+
modify_main_includes(input_directory_path, output_directory_path)
74+
if framework_version == "lldb_rpc":
75+
modify_rpc_includes(input_directory_path, output_directory_path)
76+
77+
if __name__ == "__main__":
78+
main()

lldb/scripts/framework-header-fix.sh

Lines changed: 0 additions & 17 deletions
This file was deleted.
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// This is a truncated version of an SB API file
2+
// used to test framework-header-fix.py to make sure the includes are correctly fixed
3+
// up for the LLDB.framework.
4+
5+
// Local includes must be changed to framework level includes.
6+
// e.g. #include "lldb/API/SBDefines.h" -> #include <LLDB/SBDefines.h>
7+
#include "lldb/API/SBDefines.h"
8+
#include "lldb/API/SBModule.h"
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// This is a truncated version of an SB API file generated by lldb-rpc-gen
2+
// used to test framework-header-fix.py to make sure the includes are correctly fixed
3+
// up for the LLDBRPC.framework.
4+
5+
// Local includes must be changed to framework level includes.
6+
// e.g. #include "lldb/API/SBDefines.h" -> #include <LLDB/SBDefines.h>
7+
#include "LLDBRPC.h"
8+
#include "SBDefines.h"
9+
#include <lldb-rpc/common/RPCPublic.h>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Create a temp dir for output and run the framework fix script on the truncated version of SBAddress.h in the inputs dir.
2+
RUN: mkdir -p %t/Outputs
3+
RUN: %python %p/../../../scripts/framework-header-fix.py lldb_main %p/Inputs/ %t/Outputs/
4+
5+
# Check the output
6+
RUN: cat %t/Outputs/SBAddress.h | FileCheck %s
7+
8+
# Local includes must be changed to framework level includes.
9+
# e.g. #include "lldb/API/SBDefines.h" -> #include <LLDB/SBDefines.h>
10+
CHECK: #include <LLDB/SBDefines.h>
11+
CHECK: #include <LLDB/SBModule.h>
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Create a temp dir for output and run the framework fix script on the truncated version of SBAddress.h in the inputs dir.
2+
RUN: mkdir -p %t/Outputs
3+
RUN: %python %p/../../../scripts/framework-header-fix.py lldb_rpc %p/Inputs/ %t/Outputs/
4+
5+
# Check the output
6+
RUN: cat %t/Outputs/RPCSBAddress.h | FileCheck %s
7+
8+
# Local includes must be changed to RPC framework level includes.
9+
# e.g. #include "SBDefines.h" -> #include <LLDBRPC/SBDefines.h>
10+
# Also, RPC common code includes must change to RPC framework level includes.
11+
# e.g. #include "lldb-rpc/common/RPCPublic.h" -> #include <LLDBRPC/RPCPublic.h>
12+
CHECK: #include <LLDBRPC/RPCPublic.h>
13+
CHECK: #include <LLDBRPC/SBDefines.h>
14+
CHECK: #include <LLDBRPC/LLDBRPC.h>

0 commit comments

Comments
 (0)