V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
junho
V2EX  ›  iOS

如何把多个私有的 Pod 打包成一个静态 Framework?

  •  
  •   junho · 2019-09-04 18:25:52 +08:00 · 4604 次点击
    这是一个创建于 1890 天前的主题,其中的信息可能已经有所发展或是发生改变。

    项目工程里已经使用 pod 进行了一部分内容的组件化,但是现在有个需求,需要把若干个组件打包成静态 framework 给别人用,请问如何实现? 我目前新建一个 framework 的工程并 Pod 需要的组件,但是生成的静态 framework 是不包含所依赖的 pod 的内容,如何才能包含所依赖的 pod 组件内容。

    PS: 因为是给别人用的静态 Framework,希望达到放到别人工程里就能直接运行。

    14 条回复    2022-12-07 17:45:46 +08:00
    junho
        1
    junho  
    OP
       2019-09-04 18:41:08 +08:00
    有 SDK 开发经验的 V 友来回答下吗。。。
    junho
        2
    junho  
    OP
       2019-09-04 21:42:38 +08:00
    自己想了下:
    1.可以用动态库
    2.把这若干个组件打包成 framework 再手动把 .o 文件合并?(未试过)
    3.源码放在一起打包?(这个感觉违反了组件化思路,而且还要处理主项目 import framework,sdk 不需要问题
    ldp940622
        3
    ldp940622  
       2019-09-05 01:49:21 +08:00
    我使用过一些国产的 SDK 里面有包含了一些类似于 AFN、FMDB 这种第三方组件,他们都是通过直接拖源码 + 修改类名的方式集成的。。
    kingcos
        4
    kingcos  
       2019-09-05 09:07:27 +08:00 via iPhone
    还要带依赖?那就合并了,在一块也有可能有重复符号的问题……
    junho
        5
    junho  
    OP
       2019-09-05 09:43:27 +08:00
    @kingcos 怎么理解这个合并的意思?
    troyl
        6
    troyl  
       2019-09-05 16:09:30 +08:00 via iPhone
    Dynamic Framework 参数会使 Mach-O 文件产生 @rpath 依赖,你需要在编译私有 framework 干预中间 link 过程,这样才可以保证编译出来的 SDK 仍然是 dynamic 的,但所有私有的 object 全部都 statically linked 进你 SDK 的 binary 里。但这只是第一步,你仍然需要保证 SDK 的所有 public interface 全都不会使用私有 framework 中的 public type (return type, parameter type, etc.)。然而这仍然不够,因为,swift 的 interface 文件仍然会产生私有 framework 的 import dependency,而且,这个 interface 文件 (.swiftmodule) 是 binary,不可编辑,所以你需要一个 dummy interface generator 来暴露你希望暴露给第三方用户的接口,这样的好处是你可以控制暴露给第三方和 internal use only 的公有接口。
    这个方法对 Swift 1 以后的 project 都适用。当然,如果你的 project 是 Swift 4 以后的,你可以直接使用 Static Library。但仍需要消除 .swiftmodule 中对私有 framework 的 dependency。

    这是我在全部重写我司 SDK 成 Swift 2 的时候研究出来的,因为 pipeline 的需要,ship 给 3rd party 和 internal team 的 SDK 是一样的,但是 internal team 可以用我们的 private framework,而 3rd party 只会拿到一个包含所有 symbols,但是混淆过的 binary。

    思路就是这样,但是公司原因不能详谈实现。

    祝顺利。
    junho
        7
    junho  
    OP
       2019-09-05 16:34:07 +08:00
    @troyl 感谢回复
    junho
        8
    junho  
    OP
       2019-09-05 16:42:47 +08:00
    @troyl

    "Dynamic Framework 参数会使 Mach-O 文件产生 @rpath 依赖,你需要在编译私有 framework 干预中间 link 过程,这样才可以保证编译出来的 SDK 仍然是 dynamic " ===> 这个是怎么理解?因为是我的话会建立一个暴露接口的动态 framework 壳工程,然后 Pod 自己的私有组件(都是源码),这个过程中需要怎样额外处理 @rpath 和 link?
    troyl
        9
    troyl  
       2019-09-05 20:09:38 +08:00 via iPhone
    你可以用 `otool -l 壳工程的 binary` 来看到所有的 rpath dependency,那里就会暴露你的私有库,而且会让你的壳工程无法脱离私有库来使用,你 #2 楼的想法的第二条我觉得是可行的,你可以试试。
    troyl
        10
    troyl  
       2019-09-05 20:14:08 +08:00 via iPhone
    @junho #8 其实你倒不必纠结干预 link 这一点,那是因为当时 Swift 还不支持 Static Library,我们只好自己想办法来兼容 CocoaPods。现在支持了,就直接用吧。
    troyl
        11
    troyl  
       2019-09-05 21:59:37 +08:00 via iPhone
    @kingcos #4 这是个伪命题…… Swift 是支持 namespace 的,所以不同 module 里如果有相同的 symbol,这个是会加上 module 的前缀的,所以不会重复。如果是 Objective-C,那么它只有一层 namespace (实际上是两层,但对开发者来说只有一层),那么如果你的 project 或者你依赖的 library/framework 有相同的 symbol,那么在 link 的时候就会报错,编译是不会通过的。我唯一遇见的一次 duplicate symbol 是有一个 framework 静态链接了一个我们也依赖的第三方库,但是既然是第三方开源库,它就不应该静态链接,它应该声明这个 dependency,让开发者或者包管理软件来负责链接。
    junho
        12
    junho  
    OP
       2019-09-25 16:44:30 +08:00
    @troyl 谢谢回复哈,今天才发现后面的几条回复居然没有收到提醒
    junho
        13
    junho  
    OP
       2019-09-26 14:44:28 +08:00
    @troyl 再次请教下,请问如何做到 “需要消除 .swiftmodule 中对私有 framework 的 dependency”

    举个例子,新建了一个动态 Framework 的工程,使用 pod 安装 Snapkit,然后 build 出 framework 后放到空白 App 工程里编译,App 工程就会报错 Cannot load underlying module for 'SnapKit'。就算我把 Framework 改成静态,然后把 libSnapKit 拉到 Link Binray with LIbraries 去,最后 App 工程还是会报一样的错
    xiely
        14
    xiely  
       2022-12-07 17:45:46 +08:00
    @junho 我也遇到和你相同的问题,想把自己的代码和 pod 引用的第三方库代码一起打成 Framework 以供其它地方使用。这条问答有点年代了,不过还是想了解下在那之后你有没有实现这个功能。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1342 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 17:41 · PVG 01:41 · LAX 09:41 · JFK 12:41
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.