动态库与静态库相互连接

动态库--动态库

场景: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'

你可能感兴趣的:(动态库与静态库相互连接)