www.2527.com_澳门新葡8455手机版_新京葡娱乐场网址_
做最好的网站

iOS输出静态库和framework须求潜心的事

2019-09-17 02:13 来源:未知

了解更多,请关注我的微信公众号:mellong

今天给app打包时,Xcode报错:Undefined symbols for architecture armv7

一、静态库简介

问题

最近因为项目需要,经常要打包静态库给别人用,同时静态库本身要加入其他同事做好的静态库,在build的时候发现比较多的问题就是提示:

Symbol not found for architecture arm64

图片 1

  • 1.1、:是程序代码的集合,是共享程序代码的一种方式。

  • 1.2、根据源代码的公开情况,库可以分为2种类型

    • <1>、开源库公开源代码,能看到具体实现,比如我们常见的:AFNetworking、SDWebImage、MJRefresh 等等
    • <2>、闭源库不公开源代码,是经过编译后的二进制文件,看不到具体实现主要分为:静态库动态库
  • 1.3、静态库和动态库的存在形式

    • 静态库:.a.framework
    • 动态库:.dylib.framework
  • 1.4、静态库和动态库在使用上的区别

    • 静态库:链接时,静态库会被完整地复制到可执行文件中,被多次使用就有多份冗余拷贝图片 2静态库
    • 动态库:链接时不复制,程序运行时由系统动态加载到内存,供程序调用,系统只加载一次,多个程序共用,节省内存图片 3动态库

      需要注意的是:iOS平台 在 iOS8 之前,苹果不允许第三方框架使用动态方式加载,从 iOS8 开始允许开发者有条件地创建和使用动态框架,这种框架叫做 Cocoa Touch Framework。虽然同样是动态框架,但是和系统 framework 不同,app 中使用 Cocoa Touch Framework 制作的动态库 在打包和提交 app 时会被放到 app main bundle 的根目录 中,运行在沙盒里,而不是系统中。也就是说,不同的 app 就算使用了同样的 framework,但还是会有多份的框架被分别签名,打包和加载。不过 iOS8 上开放了 App Extension 功能,可以为一个应用创建插件,这样主app和插件之间共享动态库还是可行的。苹果系统专属的framework 是共享的, 但是我们自己使用 Cocoa Touch Framework 制作的动态库是放到 app bundle 中,运行在沙盒中的

  • 1.5、 静态库应用场景?

    • 保护自己的核心代码,比如国内的环信,百度地图,高德地图,友盟,个推,他们掌握有核心技术,同时是又希望更多的程序员来使用其技术,因此采用"闭源"的方式开发使用,你只能看到他们的.h文件以及一些不重要的.m文件
    • MRC 的项目,打包成静态库, 可以在ARC下直接使用, 不需要转换
  • 1.6、静态库的特点?

    • .a.h 组成
    • 看不到具体实现的代码

原因

原因是打包静态库时直接用的时debug环境,而在该环境下默认设置Build Active Architecture Only为YES。

WechatIMG19.jpeg.jpeg

二、.a 静态库的制作

解决

解决的方法有两种:

1.修改编译环境为release,再打包。2.修改Build Active Architecture Only中debug的值为NO。

到底选择哪种方法,具体还得看需求而定了。

于是百度了下,直觉告诉我解决方法就在排在第一的 Stack Overflow。

  • 2.1、 创建项目时, 直接选择静态库(.a)

    图片 4创建项目时, 直接选择静态库

  • 2.2、定义一个类方法 jk_test,在.h里面暴露出来jk_test

    图片 5定义一个类方法` jk_test`

  • 2.3、添加暴露的文件

    图片 6添加暴露的文件

  • 2.4、分别在真机与6s下编译,查看生成的.a与暴露文件

    图片 7分别在真机与6s下编译,查看生成的.a与暴露文件图片 8分别在真机与6s下编译,查看生成的.a与暴露文件

  • 2.5、新建一个工程测试 上面我们创建的 .a 文件 与 暴露文件 是否可以使用

    图片 9新建一个工程测试 上面我们创建的 `.a` 文件 与 暴露文件 是否可以使用

    • 测试结果:

      • 1、使用6S模拟器进行测试, 可以使用
      • 2、使用低型号模拟器测试,; 失败
      • 3、使用真机, 编译; 失败

    分析原因:原因是静态库分架构,不同的CPU架构是不一样的 ,如果 .a静态库 不支持架构,运行会报错

    • 静态库所支持的架构
    • 模拟器: 4s~5 : i386;5s ~ XS Max: x86_64
    • 真机: 3gs~4s : armv7;5/5c : armv7s(armv7兼容armv7s);5s~XS Max: arm64: arm64提示:上面的 i386、x86_64、armv7、armv7s、arm64 都是架构的名字
    • 测试 .a静态库 所支持的架构:

      cd 进入 .a静态库所在的文件夹lipo -info 库文件名
      

      我们以上面在模拟器下的 .a静态库 为例,如下图

      图片 10我们以上面在模拟器下的 `.a静态库` 为例

  • 2.6、怎样一次编译支持多个架构的的静态库?

    • 解决方案:在 Build Settings ->Build Active ->NO,这样设置之后,debug真机下支持debug真机下所有的架构,debug模拟器下支持debug模拟器下所有的架构,再重复上面的测试,在iPhone5或者iPhone4下就不会报错了

      图片 11在 `Build Settings` ->` Build Active` ->` NO`

      注意:你的xcode要有上面架构的机型,否则只会包含有的架构,如果没有 i386架构,你可以 下载 4s~5 模拟器,再重复上面的操作

    • 解决方案:xcodebuild 命令行生成静态库参考博客

      • debug版本

        xcodebuild -target 要生成的静态库目名 -configuration Debug -sdk iphoneos -arch armv7 -arch arm64xcodebuild -target 要生成的静态库目名 -configuration Debug -sdk iphonesimulator -arch i386 -arch x86_64
        
      • release版本

        xcodebuild -target 要生成的静态库目名 -configuration Release -sdk iphoneos -arch armv7 -arch arm64xcodebuild -target 要生成的静态库目名 -configuration Release -sdk iphonesimulator -arch i386 -arch x86_64
        
      • 提示:我们只需要生成发布版本的就好,如下步骤

        # 1、cd 进入静态库项目cd 静态库项目# 2、操作上面 release版本 的命令
        

        注意:在使用过 xcodebuild ,再利用 lipo -info 静态库名检测,响应的架构都支持

  • 2.7、通过上面我们可以知道 .a静态库 在debug模式下的真机和模拟器编译各会生成一个 .a静态库,在release模式下的真机和模拟器编译也各会生成一个 .a静态库,那么我们给别人哪些 .a静态库用呢?答案是:给其他人在release模式下的:真机与模拟器下的.a静态库

    提示:.a静态库测试版本发布版本特点

    • Debug:1、调试版本会包含完整的符号信息,以方便调试;2、调试版本不会对代码进行优化
    • Release: 1、发布版本不会包含完整的符号信息;2、发布版本的执行代码是进行过优化的;3、发布版本的大小会比调试版本的略小;4、在执行速度方面,发布版本会更快些,但不意味着会有显著的提升
  • 2.8、我们给用户发布版本的两个.a静态库(真机下的release模式下的.a静态库与模拟器release模式下的.a静态库),如果想要一个静态库, 既可以在模拟器上运行, 也可以在真机上运行怎么做?答案:把发布版本的两个.a静态库合成一个 .a静态库

    TAG标签:
版权声明:本文由澳门新葡8455手机版发布于计算机编程,转载请注明出处:iOS输出静态库和framework须求潜心的事