最近在作Apple的IOS开发,有开发静态库的需求,自己IOS的开发,只容许静态库或者Framework。在Xcode上没有找到容许编译,如同Android上的*.so和Win32上的dll这样的说法。不过Framework这样的框架,估计也是相似动态库的实现,不过没有具体研究过,后续继续深刻研究。 ios
我这个文档的静态库的开发是基于Xcode4.2和iOS SDK5.0编写的。Xcode4跟以前的Xcode3仍是有很多的差异的。
下面就简单写一个静态库和一个调用静态库的例子。
静态库的编写:
1.静态库工程的创建: app
Xcode New一个新的project,选择IOS下面的Framework&Library,下面有一个Cocoa Touch Static Library。直接next去创建一个Print这样的工程。 框架
2.工程创建 iphone
咱们添加很简单的"- (void)printA;"和"+ (void)printB;"的方法,这个方法的实现也是很简单的,在*.m文件中的实现就是一个"NSLog(@“”);"这样咱们编译出来的libstaticlib就能够被其余的IOS工程进行调用了。这块注意一下,目前咱们的Print->iOS Device 函数
3.编译前准备 ui
这里分release与debug版本,须要设置一下 spa
4.OK,编译 debug
咱们能够在Products下面找到咱们编译生成的libstaticlib.a这个文件。 code
注意未编译前为红色:左 编译后为黑色: 右 orm
5.ok
在右边 这个文件上右键Open In Finder。这时候咱们打开了一个文件夹,里面有一个libPrint.a。后面咱们继续编写一个调用这个libPrint.a的App。可是这个App在编译时候会出错,经过这个错误的解决,说明Xcode的一些编译相关的东西。这里,咱们在command下面根据路径找到这个文件,用这个很是重要的命令查看一下这个lib的信息!
打开终端写入以下命令:这是什么?这就是所在的路径
如下均是在本身的mac上的路径。你须要将/Users/pjk1129/Library/Developer/Xcode/DerivedData/Print-dgfkluumuexoxhcapzidtsmdgqcj/Build/Products/ 替换成你的路径。
cd /Users/pjk1129/Library/Developer/Xcode/DerivedData/Print-dgfkluumuexoxhcapzidtsmdgqcj/Build/Products/
咱们手动打开这个路径:能够看到以下信息:Release-iphoneos
这个是给真机用的,那咱们要给模拟器和真机封装的静态库应该都能用才好。这个下面介绍!!!!!
而后再在终端 打开这个文件:cd /Users/user/Library/Developer/Xcode/DerivedData/UItab-dbvoszbzpavyglaboxgflvrnzfce/Build/Products/Debug-iphoneos
命令是:lipo -info libPrint.a,能够看到显示的结果是:Arch是 Arm7。下面我会具体介绍一下。
6.创建一个调用这个libPrint.a的应用
应用就很简单了,咱们添加刚才libPrint.a的*.h文件。 而后在这个工程的Build Phases的Link Binary With Library里面添加咱们刚才拷贝出来的那个libPrint.a。
7.插入了h和a文件后
咱们就能够在control里面调用这个libPrint.a 函数了。
#import "AstroDiskAppDelegate.h"
#import "Print.h"
@implementation AstroDiskAppDelegate
@synthesize window = _window;
- (void)dealloc
{
[_window release];
[_viewController release];
[super dealloc];
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//调用libPrint.a
[Print printB];
Print *print = [[[Print alloc] init] autorelease];
[print printA];
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
[self.window makeKeyAndVisible];
return YES;
}
8.OK,编译运行这个应用程序。
编译出现错误了。这个就是这篇文档的关键了。主要就是为了介绍编译静态库相关的东西。
9.能够看到undefine symbols for architecture i386这样的错误。
其实这个错误缘由很简单,就是由于,咱们用错了编译出来的libUITab.a lib,在模拟器里面,咱们须要的是基于i386构架编译的static lib,可是这个a文件,你们还记得前面说的arm6 arm7构架的么。这个a实际上是在iphone这个arm构架上运行的代码。其实show in finder指向的是一个ios device的库,并非i386模拟器下的库。那如何编译i386的库呢?看见第二张图片的Print>IOS Device了么?咱们将这个iOS Device修改为iPhone5.0 Simulator。在进行编译,这样就能够编译出i386下面的库。这个时候咱们show in finder打开的文件夹仍是ios device下的库。咱们最好本身去那个目录下看一下。这里咱们用command去查看了一下目录状况,以下:能够看到一个iphoneos的目录和一个simulator的目录。
而后咱们再看看这个目录与第4条所示的目录有什么不一样! 一样也有一个libPrint.a文件。
10.错误缘由分析
Release-iphoneos里面的是基于arm6 arm7编译出来的库文件。Release-iphonesimulator文件夹下面的是基于i386编译出来的文件。
11.合并.a文件,制做通用静态库
这二个库一个是用于真机运行的一个是用于模拟器运行的.其实咱们能够利用lipo将这二个文件打包成一个通用的a文件。命令以下:
将/Users/user/Library/Developer/Xcode/DerivedData/UITab-dgfkluumuexoxhcapzidtsmdgqcj/Build/Products替换成你的路径。
将/Users/user/Desktop/libPrint.a替换成合并后的路径。
lipo -create /Users/pjk1129/Library/Developer/Xcode/DerivedData/Print-dgfkluumuexoxhcapzidtsmdgqcj/Build/Products/Release-iphonesimulator/libPrint.a /Users/pjk1129/Library/Developer/Xcode/DerivedData/Print-dgfkluumuexoxhcapzidtsmdgqcj/Build/Products/Release-iphoneos/libPrint.a -output /Users/pjk1129/Desktop/libPrint.a
12.打包之后的库文件,咱们查看信息
而后打入以下命令:lipo -info /Users/pjk1129/Desktop/libPrint.a
能够看到以下信息:
如上,你已经看到了,它具有了i386和arm7的条件。 如今咱们这个静态库,支持的构架已是armv7 i386了。
这个通用库生成后,咱们将原来,调用这个库进行替换一下,在进行编译,成功编译,运行结果以下所示: