动态库下(5)

简介: 动态库下(5)

动态库下(5)


XCFramework


XCFramework: 是苹果官方推荐的, 支持的, 可以更方便的表示一个多个平台和架构的分发二进制库的格式.

需要Xcode11以上支持.

是为更好的支持Mac Catalyst和ARM芯片的macOS.专门在2019年提出的framework的另一种先进格式.


平时开发中会设计到的一些架构


  • iOS/iPad: arm64
  • iOS/iPad Simulator: x86_64 arm64
  • Mac Catalyst: x86_64 arm64
  • Mac: x86_64 arm64


和传统的framework相比


  1. 可以用单个.xcframework文件提供多个平台的分发二进制文件.
  2. 与Fat Header相比, 可以按照平台划分, 可以包含相同架构的不同平台文件.
  3. 在使用时, 不需要再通过脚本去剥离不需要的架构体系.


多架构合并


1. SYTimer -> 编译生成几个不同的需要的架构
2. xcodebuild archive -project 'SYTimer.xcodeproj' \ //指定project-scheme 'SYTimer' \ //指定scheme-configuration Release \ //指定编译的环境-destination 'generic/platform=iOS Simulator' //指定分发的架构平台-archivePath '../archives/SYTimer.framework-iphonesimulator.xcarchive' //指定输出路径SIKP_INSTALL=NO //只有指定为NO的时候才会进行拷贝,方便我们查看最终的编译产物
   1. xcodebuild -> 正常开发过程中使用的构建
   2. archive -> 代表打包
3. 进行真机的架构打包
   1. xcodebuild archive -project 'SYTimer.xcodeproj' 
      -scheme 'SYTimer' 
      -configuration Release 
      -destination 'generic/platform=iOS' 
      -archivePath '../archives/SYTimer.framework-iphoneos.xcarchive' 
      SKIP_INSTALL=NO
   2. SYTimer
4. 通过lipo命令合并
   1. 注意库文件的合并,支持放在一起,进行压缩,并不是真正意义上的合并
   2. lipo命令最大的问题就是相同的架构不能合并. 例如:两个库都有同一种架构
   3. lipo
5. xcFramework
   1. xcframework
6. xcFramework的使用
   1. 直接将生产的xcframework拖拽到 ->  targets/general/frameworks
   2. 引入头文件 #import <SYTimer/SYTimer.h>
   3. XCode编译器,会根据你的程序编译对象,自动选择相应的架构

动静态实战


weak_import


  1. 项目链接SYTimer


// 2. -F: frmaework 所在的目录
FRAMEWORK_SEARCH_PATHS = $(inherited) ${SRCROOT}
// 1. -I :头文件
HEADER_SEARCH_PATHS = $(inherited) ${SRCROOT}/SYTimer.framework/Headers
// 路径
// "/Users/ws/Desktop/VIP课程/第五节、动态库与静态库实战/完成代码/动态库与静态库实战/weak_import/LGApp"
LD_RUNPATH_SEARCH_PATHS = $(inherited)
// 3. 名称
// null -》 runtime -〉 nil
// weak_import
// library
OTHER_LDFLAGS = $(inherited) -Xlinker -weak_framework -Xlinker "SYTimer"


静态库冲突


  1. APP 链接 AFNetworking静态库


//-I
HEADER_SEARCH_PATHS = $(inherited) "${SRCROOT}/AFNetworking" "${SRCROOT}/AFNetworking2"
//-L
LIBRARY_SEARCH_PATHS = $(inherited) "${SRCROOT}/AFNetworking" "${SRCROOT}/AFNetworking2"
//-l
// 冲突
// all_load
// -ObjC
// 两个静态库 -》 库
OTHER_LDFLAGS = $(inherited) -l"AFNetworking" -l"AFNetworking2" -Xlinker -force_load -Xlinker "${SRCROOT}/AFNetworking/libAFNetworking.a"


  1. 编译的时候并没有冲突, 是因为专门为静态库设计的 -noall_load


      1.这时使用all_load,以及-ObjC都不行, 都会将冲突暴露出来

      2.使用-force_load 来只链接其中一个

      3.将其中一个链接生成为动态库.也可以解决


SDK建议:


  1. 一个成熟的SDK,没有理由用了一堆其他的SDK
  2. SDK -> 基本上都是动态库


动动


  1. App -> 使用自己的动态库 -> 自己的动态库使用了其他的动态库.例:AFNetworking
  2. 两种解决方案


      1.脚本copy,参考cocoapods的sh脚本

           1.注意,cocoapods提供动态库的时候,支持提供了链接参数,并没有将动态库copy,只不过最后通过脚本进行了copy


      2.cocoapods, 重新引入其他的动态库到APP

微信图片_20220509215149.png

image.png


  1. 反依赖的情况, 动态库 -> APP


1. 需要APP将需要的头文件暴露出来
   1. Build Phases -> Headers -> project -> 添加需要暴露的头文件 -> 移动到Public
   2. xcconfig -> HEADER_SEARCH_PATH 的头文件暴露
   3. 导入头文件
   4. 编译报错 -> 让APP运行起来,dyld就能找到 -> -undefined
      1. OTHER_LDFLAGS = ... -Xlinker -undefined -Xlinker dynamic_lookup -> 这种写法风险比较大,不建议
      2. OTHER_LDFLAGS = ... -Xlinker -U -Xlinker OBJC_CLASS_LGAppObject为动态库查找的符号
      3. 此时已经反依赖成功.

动静


  1. 关闭cocoapods的user_frameworks! -> 表明引入的是静态库



微信图片_20220509215155.png
image.png


  1. 动态库会将所引用的静态库代码链接
  2. 静态库所有的导出符号相对于动态库来说,还全是导出符号


       1.问题: 给别人提供动态库的时候,不想暴露静态库

       2.

OTHER_LDFLAGS = $(inherited) -ObjC -Xlinker -hidden-l "AFNetworking" -> 可以达到符号的可见性

静静


1. 关闭 use_framerworks -> 表明拉取的是静态库
2. app + 静态库 没问题
   1. 组件静态库 + 组件链接的静态库 -> 有问题,组件链接的静态库相对于APP没有告诉APP链接的三要素
   2. 手动配置三要素,头文件不用了, 需要配置静态库路径,以及静态库名称

静动

1. APP = APP + 静态库 -> 相当于APP直接使用动态库
   1. 静态库 -> 动态库
2. 配置framework路径
3. 进行一个跟上面一样的动动配置.脚本直接使用cocoapods提供的动态库的脚本就可以
    1. APP -> Build Phases -> Run Script -> 执行脚本就可以
    2. 执行脚本的作用就是,进行framework的拷贝

cocoapods即导入静态库又导入动态库


  1. use_frameworks! -> 来控制动静态库
  2. 以下代码达成的效果, 数组里面的都是静态库,不包含的还是默认动态库


target :'LGNetworkManager' do
  use_frameworks!
  # 静态库、动态库
  # 指定需要被编译成static_framework的库
  $static_framework = ['AFNetworking']
  pre_install do |installer|
  installer.pod_targets.each do |pod|
        if $static_framework.include?(pod.name)
            def pod.build_type;
              Pod::Target::BuildType.static_framework
            end
        end
    end
  end
  pod 'SDWebImage'
end


cocoapod 往不同的workspace以及target里面导入动态库的写法


platform :ios, '9.0'
#workspace '../MulitProject.xcworkspace'
target 'LGFramework' do
  use_frameworks!
  pod 'AFNetworking'
end
#target 'LGApp' do
#  project '../LGApp/LGApp.xcodeproj'
#
#  use_frameworks!
#
#  pod 'AFNetworking'
#
#end


总结


  1. XCFramerwork的优点

       1.解决头文件问题

       2.解决调试符号问题

       3.解决相同架构的处理


  1. 实战


1. weak_import: 动态库 运行时不知道这个动态库是否存在 -> 可以使用weak_import来声明一下
2. 静态库冲突 -> APP -> 不存在二级命名空间,并且all_load/-ObjC
3. APP -> 动 动2 -> pod/脚本复制(比较推荐)
   1. reexport重新暴露动2的符号
   2. APP反向依赖
4. APP -> 动 静 -> 静态库不想暴露 -> hidden-l
5. APP -> 静 静2 -> 不知道静2的所在位置
6. APP -> 静 动 ->  编辑就会报错 -> 不知道动态库的位置
   1. 运行时也会报错 ->  动rpath -> pod/脚本复制(比较推荐)


  1. 组件/库 -> 依赖不要太多,最好一个都没有 -> AFN做个封装


实战配置参考


实战配置




目录
相关文章
|
2月前
|
Linux Windows
静态库和动态库
本文详细介绍了静态库和动态库的概念及使用方法。在 Linux 系统中,静态库以 `libxxx.a` 形式存在,而动态库则为 `libxxx.so`。文章分别讲解了如何创建和使用这两种库,并提供了具体的命令示例。此外,还介绍了将库文件添加到系统目录的方法,包括直接复制到默认库路径、修改环境变量以及编辑系统配置文件等方案。适合初学者了解库文件的基本操作。
|
6月前
|
Linux 编译器 开发者
C/C++动态库与静态库 的详细解析
C/C++动态库与静态库 的详细解析
669 0
|
6月前
|
消息中间件 NoSQL Linux
静态库与动态库
静态库与动态库
静态库与动态库
vs2019使用静态库
vs2019使用静态库
307 0
|
存储 Cloud Native Linux
C++ 动态库与静态库的区别?
C++ 动态库与静态库的区别?
|
存储 Linux 编译器
什么是链接库 | 动态库与静态库
什么是链接库 | 动态库与静态库
169 0
|
Shell 开发工具 C语言
动态库与静态库
本文目标:⭐认识动态静态库,学会结合gcc选项,制作动静态库⭐⭐了解动态库加载过程⭐。
动态库与静态库
|
vr&ar C语言 索引
静态链接和静态库
静态链接和静态库
173 0
|
开发者
动态链接和动态库
动态链接和动态库
115 0
vs2019使用动态库
vs2019使用动态库
213 0