• 【iOS】编译静态库


      与java和.net一样,objc也由类库的概念,不过在在objc上一般叫库,库表示程序代码集合,可以共享给其他程序使用,库是编译后的二进制文件,因此不能看到源代码,多用于一些开放sdk(如百度地图sdk),商用库,这两天在研究iOS上编译静态库,这里把编译的过程和中间遇到的一些问题做一下记录,方便以后查阅

      objc上的库一般分为两类

        静态库: .a 和 .framework

          .a文件:纯二进制文件,需要配合.h文件一起使用,通过.h文件引用库里面的内容
          .framework文件:包含二进制文件

          链接时,静态库会被完整地复制到可执行文件中,例如iOS程序打包的时候会包含所有引用的静态库

        动态库: .dylib 和 .framework

          iOS项目不支持动态库,每个APP都是独立运行的,并且不能直接互相访问,APP只能访问系统自带的动态库,动态库系统只加载一次,并可以用于多个程序共享的,一般在用于桌面系统,链接时不会被添加到可执行文件,如果动态链接库不存在,程序可能执行失败

      这里只讨论静态链接库,这里只讨论.a文件的生成,.framework文件先不讨论

     1、下面我们创建一个自己的静态库(Cocoa Touch Static Library

    2、添加自己的类和category

      编译的时候需要将 头文件拷贝到生成的库路径下,这里的头文件是用于给外部使用的,一般是把库里面的文件放在一个头文件中引用,这样外部在使用的时候直接引用该头文件即可

    3、设置支持的最低版本和最高版本

      Base SDK:是当前类库是基于哪个版本的SDK开发的,也就是最高支持的SDK

      Deployment Target:类库支持的最低版本

      

      

    4、配置编译选项

      由于我们编译的是类库,在使用的时候需要支持Debug和Release两种模式下,需要编译所有的architecture版本

      

      4、编译(Cmd + B)

        我们分别切换到模拟器和真机模式进行编译,在真机模式下编译完成后,Products中的文件会变正常(原来为红色)   

        注意,需要设置Build Release 版本

        

        

             

    5、编译完成

      编译完成后我们得到很多个.a文件,每个目录下都对应一个.a文件,从libCalculator.a进入Finder查看

        iphoneos是真机用的

        iphonesimulator是给模拟器用的

        

    6、使用

      我们创建一个iOS项目,吧相关的.a文件和.h文件拖到我们的项目中,拖入后,xcode会自动把静态库添加到工程

        这里需要注意的是

          1、头文件也要引入到工程里面(不然你怎么用)

          2、模拟器和真机对应的.a文件不一样,根据需要引用.a文件

          2、如果静态库内有category分类,那么需要在添加 -ObjC 编译标识,否则可能会报:unrecognized selector sent to instance 

          

          3、其他编译参数        

            -ObjC:加了这个参数后,链接器就会把静态库中所有的Objective-C类和分类都加载到最后的可执行文件中
            -all_load:会让链接器把所有找到的目标文件都加载到可执行文件中,但是千万不要随便使用这个参数!假如你使用了不止一个静态库文件,然后又使用了这个参数,那么你很有可能会遇到ld: duplicate symbol错误,因为不同的库文件里面可能会有相同的目标文件,所以建议在遇到-ObjC失效的情况下使用-force_load参数。
            -force_load:所做的事情跟-all_load其实是一样的,但是-force_load需要指定要进行全部加载的库文件的路径,这样的话,你就只是完全加载了一个库文件,不影响其余库文件的按需加载

            引用自:http://www.cnblogs.com/robinkey/archive/2013/05/27/3101095.html

          4、如果静态库中采用ObjectC++实现,或者静态库使用C/C++写的,在调用的时候可能出错,因此需要您保证您工程中至少有一个.mm后缀的源文件(您可以将任意一个.m后缀的文件改名为.mm)

            或者在工程属性中指定编译方式,即将XCode的Project -> Edit Active Target -> Build -> GCC4.2 - Language -> Compile Sources As设置为"Objective-C++"

            引用自:http://blog.csdn.net/zhangkongzhongyun/article/details/8047500

    7、合并.a文件

      上面看到,编译后的用于模拟器的静态库和用于真机的静态库不一样,每次切换的适合都得重新引用.a文件,这样显得特别麻烦,苹果提供了一个合并多个.a文件的方法,合并后的.a文件真机和模拟器都支持(合并后大小为原来两个文件大小之和)

      在终端通过命令合并

    lipo –create Release-iphoneos/libsqlcipher.a Release-iphonesimulator/libsqlcipher.a –output libsqlcipher.a

      还有一种方法可以动态的引用静态库,就是通过配置工程的库引用路径和编译标示,编译的适合xcode会根据当前的环境自动找到相关的.a库,参见:http://www.cnblogs.com/bomo/p/4760791.html 

    8、Demo  

      http://files.cnblogs.com/files/bomo/CompileStaticLibrary.zip

  • 相关阅读:
    做一个会切图的前端
    居中详解
    《MFC游戏开发》笔记二 建立工程、调整窗口
    [置顶] 《MFC游戏开发》笔记一 系列简介
    SRM 584 第一次玩TopCoder。。。只水题一道。。。
    c语言排序算法总结
    uva10004 Bicoloring 黑白染色问题,DFS
    uva 784 Maze Exploration 染色 搜索水题 DFS
    采用最低松弛度优先调度的实时系统调度程序
    UVA 539 The Settlers of Catan dfs找最长链
  • 原文地址:https://www.cnblogs.com/bomo/p/4760177.html
Copyright © 2020-2023  润新知