Skip to content

Commit 6a9c874

Browse files
committed
OPTIMIZE: add module.modulemap to libffi.xcframework
1 parent 735cd14 commit 6a9c874

File tree

9 files changed

+280
-8
lines changed

9 files changed

+280
-8
lines changed

OCRunner.podspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ s.license = "MIT"
1010
s.author = { "SilverFruity" => "389185764@qq.com" }
1111
s.ios.deployment_target = "11.0"
1212
s.source = { :git => "https://github.com/SilverFruity/OCRunner.git", :tag => "#{s.version}" }
13-
s.source_files = "OCRunner/*.{h,m,c,mm}", "OCRunner/ORCoreImp/**/*.{h,m,c,mm}", "OCRunner/RunEnv/**/*.{h,m,c,mm}", "OCRunner/Util/**/*.{h,m,c,mm}", "OCRunner/libffi/**/*.{h,m,c,mm}"
13+
s.source_files = "OCRunner/*.{h,m,c,mm}", "OCRunner/ORCoreImp/**/*.{h,m,c,mm}", "OCRunner/RunEnv/**/*.{h,m,c,mm}", "OCRunner/Util/**/*.{h,m,c,mm}"
1414
s.ios.vendored_frameworks = 'OCRunner/libffi/libffi.xcframework'
1515
s.dependency "ORPatchFile", "1.2.3"
1616
end
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module libffi {
2+
umbrella header "ffi.h"
3+
export *
4+
module * { export * }
5+
}
0 Bytes
Binary file not shown.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module libffi {
2+
umbrella header "ffi.h"
3+
export *
4+
module * { export * }
5+
}
Binary file not shown.

build_libffi_scripts/README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,29 @@
77
- `build_libffi_xcframework.sh` - 主构建脚本,用于构建 iOS 和 iOS Simulator 版本的 libffi 并生成 xcframework
88
- `apply-remove-ios-armv7-patch.py` - Python 脚本,用于应用 patch 移除 iOS armv7 支持
99
- `remove-ios-armv7.patch` - Patch 文件,用于移除 generate-darwin-source-and-headers.py 中的 iOS armv7 支持
10+
- `apply-export-tramp-symbols-patch.py` - Python 脚本,用于应用 patch 导出 tramp.c 中的符号(针对 iOS Simulator x86_64)
11+
- `export-tramp-symbols-x86_64.patch` - Patch 文件,用于导出 tramp.c 中的符号
1012

1113
## 使用方法
1214

1315
```bash
1416
cd build_libffi_scripts
17+
./build_libffi_xcframework.sh [选项]
18+
```
19+
20+
### 选项
21+
22+
- `--enable-exec-static-tramp` - 启用 FFI_EXEC_STATIC_TRAMP 宏(默认:禁用)
23+
- `--help``-h` - 显示帮助信息
24+
25+
### 示例
26+
27+
```bash
28+
# 默认构建(禁用 FFI_EXEC_STATIC_TRAMP)
1529
./build_libffi_xcframework.sh
30+
31+
# 启用 FFI_EXEC_STATIC_TRAMP
32+
./build_libffi_xcframework.sh --enable-exec-static-tramp
1633
```
1734

1835
构建完成后,xcframework 将输出到 `OCRunner/libffi/libffi.xcframework`
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
#!/usr/bin/env python3
2+
"""
3+
应用 patch 导出 tramp.c 中的符号(针对 iOS Simulator x86_64)
4+
"""
5+
6+
import sys
7+
import os
8+
import re
9+
10+
def apply_patch(file_path):
11+
"""应用 patch 导出 tramp.c 中的符号"""
12+
if not os.path.exists(file_path):
13+
print(f"错误:文件 {file_path} 不存在", file=sys.stderr)
14+
return False
15+
16+
# 备份原文件
17+
backup_path = file_path + '.orig'
18+
if not os.path.exists(backup_path):
19+
with open(file_path, 'r') as f:
20+
content = f.read()
21+
with open(backup_path, 'w') as f:
22+
f.write(content)
23+
print(f"已备份原文件到 {backup_path}")
24+
25+
# 读取文件内容
26+
with open(file_path, 'r') as f:
27+
content = f.read()
28+
29+
# 检查是否已经应用过 patch
30+
if 'FFI_TRAMP_EXPORT' in content:
31+
print("Patch 已应用,跳过")
32+
return True
33+
34+
# 找到 "#else /* !FFI_EXEC_STATIC_TRAMP */" 后的块
35+
else_pattern = r'(#else\s*/\*\s*!FFI_EXEC_STATIC_TRAMP\s*\*/)'
36+
match = re.search(else_pattern, content)
37+
38+
if not match:
39+
print("错误:找不到 #else /* !FFI_EXEC_STATIC_TRAMP */ 块", file=sys.stderr)
40+
return False
41+
42+
# 在 #else 后添加导出宏定义
43+
else_pos = match.end()
44+
45+
# 添加导出宏定义
46+
export_macro = '''
47+
48+
#ifdef __APPLE__
49+
#include <TargetConditionals.h>
50+
#if TARGET_OS_SIMULATOR && defined(__x86_64__)
51+
/* 在 iOS Simulator x86_64 上,确保符号被导出 */
52+
#define FFI_TRAMP_EXPORT __attribute__((visibility("default")))
53+
#else
54+
#define FFI_TRAMP_EXPORT
55+
#endif
56+
#else
57+
#define FFI_TRAMP_EXPORT
58+
#endif
59+
60+
'''
61+
62+
# 在 #else 后插入宏定义
63+
content = content[:else_pos] + export_macro + content[else_pos:]
64+
65+
# 修改函数声明,在返回类型前添加 FFI_TRAMP_EXPORT
66+
# 匹配模式:int\nffi_tramp_is_supported(void)
67+
# 需要匹配:返回类型(int/void */void)在单独一行,函数名在下一行
68+
function_patterns = [
69+
(r'^(int)\s*\n\s*(ffi_tramp_is_supported\(void\))', r'FFI_TRAMP_EXPORT int\n\2'),
70+
(r'^(void \*)\s*\n\s*(ffi_tramp_alloc\s*\([^)]*\))', r'FFI_TRAMP_EXPORT void *\n\2'),
71+
(r'^(void)\s*\n\s*(ffi_tramp_set_parms\s*\([^)]*\))', r'FFI_TRAMP_EXPORT void\n\2'),
72+
(r'^(void \*)\s*\n\s*(ffi_tramp_get_addr\s*\([^)]*\))', r'FFI_TRAMP_EXPORT void *\n\2'),
73+
(r'^(void)\s*\n\s*(ffi_tramp_free\s*\([^)]*\))', r'FFI_TRAMP_EXPORT void\n\2'),
74+
]
75+
76+
for pattern, replacement in function_patterns:
77+
content = re.sub(pattern, replacement, content, flags=re.MULTILINE)
78+
79+
# 写回文件
80+
with open(file_path, 'w') as f:
81+
f.write(content)
82+
83+
print("Patch 已成功应用,tramp.c 符号导出已启用(iOS Simulator x86_64)")
84+
return True
85+
86+
if __name__ == '__main__':
87+
script_dir = os.path.dirname(os.path.abspath(__file__))
88+
# 脚本在 build_libffi_scripts 目录,libffi 目录在父目录下
89+
project_root = os.path.dirname(script_dir)
90+
target_file = os.path.join(project_root, 'libffi', 'src', 'tramp.c')
91+
92+
if apply_patch(target_file):
93+
sys.exit(0)
94+
else:
95+
sys.exit(1)

build_libffi_scripts/build_libffi_xcframework.sh

Lines changed: 102 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@
44
# 支持 iOS 设备 (arm64) 和 iOS Simulator (x86_64, arm64)
55
#
66
# 使用方法:
7-
# ./build_libffi_xcframework.sh
7+
# ./build_libffi_xcframework.sh [选项]
8+
#
9+
# 选项:
10+
# --enable-exec-static-tramp 启用 FFI_EXEC_STATIC_TRAMP 宏(默认:禁用)
811
#
912
# 依赖:
1013
# - Xcode Command Line Tools
@@ -16,6 +19,9 @@
1619

1720
set -e # 遇到错误立即退出
1821

22+
# 默认配置
23+
ENABLE_EXEC_STATIC_TRAMP=0
24+
1925
# 颜色输出
2026
RED='\033[0;31m'
2127
GREEN='\033[0;32m'
@@ -54,6 +60,31 @@ print_warning() {
5460
echo -e "${YELLOW}[WARNING]${NC} $1"
5561
}
5662

63+
# 解析命令行参数
64+
parse_args() {
65+
while [[ $# -gt 0 ]]; do
66+
case $1 in
67+
--enable-exec-static-tramp)
68+
ENABLE_EXEC_STATIC_TRAMP=1
69+
shift
70+
;;
71+
--help|-h)
72+
echo "使用方法: $0 [选项]"
73+
echo ""
74+
echo "选项:"
75+
echo " --enable-exec-static-tramp 启用 FFI_EXEC_STATIC_TRAMP 宏(默认:禁用)"
76+
echo " --help, -h 显示此帮助信息"
77+
exit 0
78+
;;
79+
*)
80+
print_error "未知选项: $1"
81+
echo "使用 --help 查看帮助信息"
82+
exit 1
83+
;;
84+
esac
85+
done
86+
}
87+
5788
# 检查依赖
5889
check_dependencies() {
5990
print_info "检查依赖..."
@@ -104,6 +135,19 @@ prepare_build_env() {
104135
print_warning "Patch 脚本不存在,尝试直接运行 generate-darwin-source-and-headers.py(可能包含 armv7 构建)"
105136
fi
106137

138+
# 应用 patch 导出 tramp.c 符号(针对 iOS Simulator x86_64)
139+
TRAMP_PATCH_SCRIPT="${SCRIPT_DIR}/apply-export-tramp-symbols-patch.py"
140+
TRAMP_FILE="${LIBFFI_DIR}/src/tramp.c"
141+
142+
if [ -f "${TRAMP_PATCH_SCRIPT}" ] && [ -f "${TRAMP_FILE}" ]; then
143+
print_info "应用 patch 导出 tramp.c 符号(iOS Simulator x86_64)..."
144+
${PYTHON_CMD} "${TRAMP_PATCH_SCRIPT}"
145+
if [ $? -ne 0 ]; then
146+
print_error "应用 tramp.c patch 失败"
147+
exit 1
148+
fi
149+
fi
150+
107151
# 生成 iOS 源文件和头文件
108152
# 注意:这个脚本主要用于 Xcode 项目构建,对于 autotools 构建不是必须的
109153
# 但如果失败,我们仍然继续构建(因为我们使用 autotools 直接构建)
@@ -155,13 +199,25 @@ build_arch() {
155199
export LDFLAGS
156200
export SDKROOT
157201

158-
../configure \
159-
--host=${TARGET} \
160-
--enable-static \
161-
--disable-shared \
162-
--disable-multi-os-directory \
163-
--disable-docs \
202+
# 构建 configure 参数
203+
CONFIGURE_ARGS=(
204+
--host=${TARGET}
205+
--enable-static
206+
--disable-shared
207+
--disable-multi-os-directory
208+
--disable-docs
164209
--prefix=$(pwd)/install
210+
)
211+
212+
# 根据选项决定是否启用 exec-static-tramp
213+
if [ ${ENABLE_EXEC_STATIC_TRAMP} -eq 1 ]; then
214+
CONFIGURE_ARGS+=(--enable-exec-static-tramp)
215+
print_info "启用 FFI_EXEC_STATIC_TRAMP 宏"
216+
else
217+
CONFIGURE_ARGS+=(--disable-exec-static-tramp)
218+
fi
219+
220+
../configure "${CONFIGURE_ARGS[@]}"
165221

166222
# 编译
167223
print_info "编译 ${SDK} ${ARCH}..."
@@ -253,6 +309,30 @@ create_universal_lib() {
253309
}
254310
}
255311

312+
# 创建 module.modulemap 文件
313+
create_module_map() {
314+
local HEADERS_DIR=$1
315+
316+
if [ ! -d "${HEADERS_DIR}" ]; then
317+
print_warning "Headers 目录不存在: ${HEADERS_DIR},跳过创建 module.modulemap"
318+
return 1
319+
fi
320+
321+
print_info "创建 module.modulemap: ${HEADERS_DIR}/module.modulemap"
322+
323+
# 创建 module.modulemap 文件
324+
# 使用 umbrella header 方式,ffi.h 是 libffi 的主头文件
325+
cat > "${HEADERS_DIR}/module.modulemap" <<EOF
326+
module libffi {
327+
umbrella header "ffi.h"
328+
export *
329+
module * { export * }
330+
}
331+
EOF
332+
333+
print_info "module.modulemap 创建完成"
334+
}
335+
256336
# 创建 xcframework
257337
create_xcframework() {
258338
print_info "创建 xcframework..."
@@ -301,6 +381,9 @@ create_xcframework() {
301381
print_warning "未能复制头文件,请检查构建结果"
302382
fi
303383

384+
# 创建 module.modulemap
385+
create_module_map "${IOS_DEVICE_DIR}/Headers"
386+
304387
# iOS Simulator 版本(合并 x86_64 和 arm64)
305388
IOS_SIMULATOR_DIR="${XCFRAMEWORK_PATH}/ios-arm64_x86_64-simulator"
306389
mkdir -p "${IOS_SIMULATOR_DIR}/Headers"
@@ -345,6 +428,9 @@ create_xcframework() {
345428
print_warning "未能复制头文件,请检查构建结果"
346429
fi
347430

431+
# 创建 module.modulemap
432+
create_module_map "${IOS_SIMULATOR_DIR}/Headers"
433+
348434
# 创建 Info.plist
349435
cat > "${XCFRAMEWORK_PATH}/Info.plist" <<EOF
350436
<?xml version="1.0" encoding="UTF-8"?>
@@ -408,6 +494,12 @@ main() {
408494
print_info "开始构建 libffi.xcframework"
409495
print_info "工作目录: ${LIBFFI_DIR}"
410496

497+
if [ ${ENABLE_EXEC_STATIC_TRAMP} -eq 1 ]; then
498+
print_info "配置: FFI_EXEC_STATIC_TRAMP 已启用"
499+
else
500+
print_info "配置: FFI_EXEC_STATIC_TRAMP 已禁用(默认)"
501+
fi
502+
411503
# 检查依赖
412504
check_dependencies
413505

@@ -426,6 +518,9 @@ main() {
426518
print_info "xcframework 位置: ${XCFRAMEWORK_PATH}"
427519
}
428520

521+
# 解析命令行参数
522+
parse_args "$@"
523+
429524
# 运行主函数
430525
main
431526

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
--- a/libffi/src/tramp.c
2+
+++ b/libffi/src/tramp.c
3+
@@ -689,6 +689,29 @@
4+
5+
#else /* !FFI_EXEC_STATIC_TRAMP */
6+
7+
+#ifdef __APPLE__
8+
+#include <TargetConditionals.h>
9+
+#if TARGET_OS_SIMULATOR && defined(__x86_64__)
10+
+/* 在 iOS Simulator x86_64 上,确保符号被导出 */
11+
+#define FFI_TRAMP_EXPORT __attribute__((visibility("default")))
12+
+#else
13+
+#define FFI_TRAMP_EXPORT
14+
+#endif
15+
+#else
16+
+#define FFI_TRAMP_EXPORT
17+
+#endif
18+
+
19+
#include <stddef.h>
20+
21+
-int
22+
+FFI_TRAMP_EXPORT int
23+
ffi_tramp_is_supported(void)
24+
{
25+
return 0;
26+
}
27+
28+
-void *
29+
+FFI_TRAMP_EXPORT void *
30+
ffi_tramp_alloc (int flags)
31+
{
32+
return NULL;
33+
}
34+
35+
-void
36+
+FFI_TRAMP_EXPORT void
37+
ffi_tramp_set_parms (void *arg, void *target, void *data)
38+
{
39+
}
40+
41+
-void *
42+
+FFI_TRAMP_EXPORT void *
43+
ffi_tramp_get_addr (void *arg)
44+
{
45+
return NULL;
46+
}
47+
48+
-void
49+
+FFI_TRAMP_EXPORT void
50+
ffi_tramp_free (void *arg)
51+
{
52+
}
53+
54+
#endif /* FFI_EXEC_STATIC_TRAMP */
55+

0 commit comments

Comments
 (0)