动态库--动态库
场景:App --> 动态库A --> 动态库 B
存在问题:动态库B应该的路径 = 动态库A的rpath + 动态库B的install_name。但是这种场景下,动态库B并不在这个路径下
解决方案:修改动态库 A的 rpath 或者 copy 动态库 B到指定路径中。
方式一:修改A的 rpath为动态库B的install_name之前的绝对路径。(在xcconfig中配置 LD_RUNPATH_SEARCH_PATHS)
方式二:Cocoapods向app导入动态库B,在导入过程中Cocopods会自动将动态库B拷贝到app的framework目录下
方式三:写脚本,通过脚本copy动态库B到app的framework目录下
反向依赖问题
反向依赖即动态库使用app符号的问题。动态库在运行时能找到app的符号,但是在编译时可能会报找不到符号的错误
可以通过 -U <符号 >,来指定⼀个符号的是动态查找符号。
app跨库使用符号
APP想要使用动态库B的符号,可行的方案有:
1、让app直接链接动态库B
2、通过 reexport_framework 或者 -reexport_l 重新将动态库B 通过动态库A导出给app
OTHER_LDFLAGS = -Xlinker -reexport_framework -Xlinker AFNetworking $(inherited)
动态库--静态库
场景:App --> 动态库A --> 静态库 B
动态库A⽣成的过程中在链接静态库B 时,会把静态库 B 所有代码都链接进去。所以编译链接都不会报错
如果不想把静态库B的导出符号(全局符号)暴露出去,可以通过 -hidden-l
隐藏静态库的全局符号。
OTHER_LDFLAGS = -Xlinker -hidden-l"AFNetworking" $(inherited)
同时需要在app的xcconfig文件中设置 HEADER_SEARCH_PATHS
HEADER_SEARCH_PATHS = "${SRCROOT}/../AFramework/Pods/Headers/Public/AFNetworking" $(inherited)
静态库--静态库
场景:App --> 静态库A --> 静态库 B
问题:静态库A ⽣成时,只保存了静态库B 的头⽂件信息或者静态库B 的名称( Auto-Link )。App链接静态库A时,会把静态库A 所有代码都链接进去。但是并不知道静态库B 的位置和名称。
解决方案1:通过cocoapods将静态库 B 引入到app中
workspace '../MulitProject.xcworkspace'
target 'AFramework' do
# use_frameworks!
pod 'AFNetworking'
end
target 'App' do
project '../App/App.xcodeproj'
# use_frameworks!
pod 'AFNetworking'
end
解决方案2:
⼿动配置静态库B 的位置和名称:
LIBRARY_SEARCH_PATHS = $(inherited) "${BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/AFNetworking"
OTHER_LDFLAGS = $(inherited) -ObjC -l"AFNetworking"
静态库 -- 动态库
场景:App --> 静态库A --> 动态库 B
静态库A⽣成时,只保存了动态库B 的名称( BAuto-Link)。app链接静态库A 后,会把静态库A所有代码都链接进去。但是 App 并不知道动态库B的位置,也没有提供 rpath 。保存的 @rpath 与动态库B 的 install_name 组合的路径下:
动态库B的路径 = App的rpath + 动态库B的install_name
解决方案1:通过Cocoapods将动态库B 引⼊到App内:
workspace '../MulitProject.xcworkspace'
target 'Framework' do
# use_frameworks!
pod 'AFNetworking'
end
target 'App' do
project '../App/App.xcodeproj'
use_frameworks!
pod 'AFNetworking'
end
解决方案2:配置app的rpath,并通过脚本将动态库B引入到app内
HEADER_SEARCH_PATHS = $(inherited) "${BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/AFNetworking/AFNetworking.framework/Headers"
FRAMEWORK_SEARCH_PATHS = $(inherited) "${BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/AFNetworking"
LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' '@executable_path/../../Frameworks'