如何在Xcode中正确配置J2Objc外部构建规则并完成链接?
Xcode结合外部构建规则使用J2ObjC的正确配置指南(解决链接失败问题)
已完成操作
- 通过Makefile转译Java源码
- 按照官方指引创建外部构建项目
- 将该构建项目添加至需使用转译源码的目标项目
- 构建项目后,转译后的Java/Objective-C源码可在构建目录中找到
- 在桥接头文件中导入转译后的源码(将使用Swift而非原生Objective-C)
核心问题
转译编译后的Java源码目标文件无法与应用目标文件正常链接,尽管构建目录中存在所需目标文件,但调用相关类/方法时会因链接错误导致构建失败。
补充信息
- 外部构建项目添加方式:通过
Target->General->Frameworks, Libraries and Embedded Content中的“Add Framework”添加,再在Target->Build Phases->Target Dependencies中再次添加。 - 已尝试的临时方案:
- 将编译后的
*.o文件作为资源添加到项目,再加入Target->Build Phases->Link Library with Binary中,但不利于版本控制 - 添加
$(TARGET_TEMP_DIR)到头文件搜索路径无效 - 在用户头文件搜索路径和库搜索路径中添加
$(J2OBJC_DIST)/include - 需添加
$(J2OBJC_DIST)/lib/macosx到库搜索路径(递归添加/lib会因appletvos版本库不兼容报错) - 在其他链接标志中添加
-ljre_emul和-liconv后构建成功,但认为此方式并非正确方案
- 将编译后的
详细分步配置指南
1. 规范外部构建项目的产物输出路径
调整Makefile,将转译后的.m/.h文件以及编译生成的静态库(建议将零散.o打包为静态库,而非单独保留)输出到固定目录,例如:$(PROJECT_DIR)/J2ObjcBuild/Products/$(CONFIGURATION)-$(PLATFORM_NAME)
该目录需确保Xcode能在构建阶段正确识别。
2. 配置外部构建项目的Build Settings
打开外部构建项目的Build Settings面板:
- 在
Header Search Paths中添加$(J2OBJC_DIST)/include,设置为非递归 - 在
Library Search Paths中添加$(J2OBJC_DIST)/lib/$(PLATFORM_NAME),设置为非递归(避免跨平台库版本冲突) - 在
Other Linker Flags中添加-ljre_emul -liconv(注:这是J2ObjC运行的必要依赖,属于官方要求的标准配置,并非临时方案)
3. 完善外部构建项目的Build Phases
- 在
Compile Sources阶段,确保包含所有转译后的.m文件;若通过Makefile自动生成源码,可添加脚本阶段自动将新生成的.m文件加入该列表 - 在
Link Binary With Libraries中,直接从$(J2OBJC_DIST)/lib/$(PLATFORM_NAME)路径下添加libjre_emul.a和libiconv.tbd,替代手动添加链接标志的方式
4. 正确关联外部项目与主应用
- 打开主应用项目的
Target->Build Phases->Target Dependencies,添加外部构建项目的目标(确保主应用构建前先完成外部项目的编译) - 在
Target->General->Frameworks, Libraries and Embedded Content中,添加外部构建项目生成的静态库产物,设置为Do Not Embed
5. 配置主应用项目的Build Settings
- 在
Header Search Paths中添加外部构建项目的头文件输出目录,例如$(PROJECT_DIR)/J2ObjcBuild/Products/$(CONFIGURATION)-$(PLATFORM_NAME)/include,根据实际路径设置是否递归 - 在
Library Search Paths中添加外部构建项目的库输出目录,例如$(PROJECT_DIR)/J2ObjcBuild/Products/$(CONFIGURATION)-$(PLATFORM_NAME)/lib,设置为非递归
6. 验证桥接头文件配置
确保主应用的桥接头文件正确导入转译后的头文件,示例:
#import "com/example/MyJavaClass.h"
同时在主应用的Build Settings->Swift Compiler - General->Objective-C Bridging Header中,确认桥接头文件的路径配置正确。
7. 清理缓存并重新构建
- 执行
Product->Clean Build Folder清理旧构建缓存 - 先单独构建外部构建项目,确认产物生成正常
- 再构建主应用项目,验证链接是否正常、类/方法是否可调用
内容的提问来源于stack exchange,提问作者Thieri
相关产品推荐
相关产品推荐

