2014年(11)
分类: iOS平台
2014-11-21 08:21:54
准备 OpenLDAP 源代码
Xcode 是 iPhone SDK 包含的 IDE。它包含用于为 iOS 平台构建应用程序和库的模板和文档。为了更方便地在 OpenLDAP 源代码树中移动,我们先把源代码导入到一个 Xcode 项目中。为 iOS 平台创建新的 Xcode 项目的方法是,打开 Xcode 并从菜单栏上的 File 菜单中选择 New Project。这应该会打开一个新的对话框,其中有三个面板。因为将使用这个项目编译 OpenLDAP 客户端库,所以应该用静态库模板创建它。在左面板上,在标题 iPhone OS 下面选择 Library。在右上方的面板中,选择 Cocoa Touch Static Library。单击 Choose 继续。
中的对话框用于设置 Xcode 项目的名称。
Xcode 通过在项目名称前面加上 lib 并在后面加上 .a 构成库名称。因此,要想创建名为 libldap.a 的库,项目名称必须设置为 ldap。在 Save As 框中输入名称并单击 Save。这会创建一个目录,其中包含项目最初的文件。
既然已经创建了项目,就可以导入 OpenLDAP 的源代码了。从 OpenLDAP 项目页面下载源代码并在 Xcode 项目文件夹中展开 tar 文件。从菜单栏上的 Project 菜单中选择 Add to Project。在打开的文件选择对话框中,选择 Xcode 项目中的文件夹(其中包含 OpenLDAP 的源代码)并单击 Add 按钮。应该会出现另一个对话框。一定要选择 "Recursively create groups for any added folders" 选项并从目标列表中取消 ldap。单击 Add 按钮完成把源代码添加到项目中的步骤。现在,在 Xcode 主项目窗口的 Groups & Files 面板中应该会出现一个名为 OpenLDAP directory 的新组。
OpenLDAP 源代码树包含的一个目录中有头文件,库使用的源代码文件要包含这些头文件。需要通过配置 Xcode 让预处理器在处理 #include 指令时搜索这个目录。在 Xcode 主项目窗口的 Groups & Files 面板中双击项目名称。这应该会打开项目信息窗口。在 "Search in Build Settings" 搜索框中单击并输入 Header Search Paths。在 Value 框中双击,添加新的搜索路径 openldap-2.4.22/include。
准备头文件
OpenLDAP 已经迁移到了许多平台上。OpenLDAP 开发人员使用 C 头文件在编译时定义系统信息。一般情况下,通过用 AutoConf 生成的脚本修改模板文件来创建这些头文件。因为 Xcode 不使用 Autoconf,所以必须手工修改这些文件。必须修改的文件是 lber_types.hin、ldap_config.hin、ldap_features.hin 和 portable.hin。这些文件在 OpenLDAP 源代码树中的 include 目录中。
lber_types.hin
lber_types.hin 文件包含用于定义变量类型的模板。这个模板文件需要改名为 lber_types.h。改名的方法是在 Xcode 中右键单击文件名并从菜单中选择 rename。这会更新文件的 Xcode 元数据,把它作为 C 头文件处理。打开文件,寻找所示的代码行。
27 /* LBER boolean, enum, integers (32 bits or larger) */28 #undef LBER_INT_T29 30 /* LBER tags (32 bits or larger) */31 #undef LBER_TAG_T3233 /* LBER socket descriptor */34 #undef LBER_SOCKET_T35 36 /* LBER lengths (32 bits or larger) */37 #undef LBER_LEN_T |
这些行声明库使用的变量类型。因为 iPhone 是 32 位平台,类型 int 是合适的值。把 #undef 宏改为 #define,把变量类型设置为 int。
27 /* LBER boolean, enum, integers (32 bits or larger) */28 #define LBER_INT_T int29 30 /* LBER tags (32 bits or larger) */31 #define LBER_TAG_T int3233 /* LBER socket descriptor */34 #define LBER_SOCKET_T int35 36 /* LBER lengths (32 bits or larger) */37 #define LBER_LEN_T int |
文件的其他部分声明库使用的定制变量类型,不需要修改。
ldap_config.hin
ldap_config.hin 文件包含的模板定义库应该在哪里搜索 LDAP 客户端配置文件。因为 iOS 不允许用户在设备的文件系统中创建任意文件,所以不需要修改这个文件的内容。需要把这个文件改名为 ldap_config.h,从而避免在编译源代码文件时由于 include 指令失败而生成错误。按照把 lber_types.hin 改名为 lber_types.h 的方法在 Xcode 界面中修改这个文件名。
ldap_features.hin
ldap_features.hin 包含 iOS 平台必需的特性和当前 OpenLDAP 版本的相关信息。把 ldap_features.hin 改名为 ldap_features.h 并寻找所示的代码行。
23 /* OpenLDAP API version macros */24 #undef LDAP_VENDOR_VERSION24 #undef LDAP_VENDOR_VERSION_MAJOR24 #undef LDAP_VENDOR_VERSION_MINOR24 #undef LDAP_VENDOR_VERSION_PATCH |
OpenLDAP 的每个版本使用分三部分的版本号。用 X.Y.Z 格式表示版本,其中的 X 是主厂商版本号,Y 是次厂商版本号,Z 是厂商补丁修订号。按公式 ((X*10,000)+(Y*100)+(Z)) 计算出 LDAP_VENDOR_VERSION 的值。例如,使用所示的值计算 OpenLDAP 2.4.22 的 LDAP_VENDOR_VERSION。
LDAP_VENDOR_VERSION_MAJOR = X = 2LDAP_VENDOR_VERSION_MINOR = Y = 4LDAP_VENDOR_VERSION_PATCH = Z = 22LDAP_VENDOR_VERSION = ((X*10000)+(Y*100)+(Z))LDAP_VENDOR_VERSION = ((2*10000)+(4*100)+(22))LDAP_VENDOR_VERSION = (20000+400+22)LDAP_VENDOR_VERSION = (20422) |
需要更新 ldap_features.h 以反映 OpenLDAP 源代码的版本。把 #undef 宏替换为 #define 并插入版本信息。例如,对于 OpenLDAP 2.4.22,应该做所示的修改。
23 /* OpenLDAP API version macros */24 #define LDAP_VENDOR_VERSION 2042224 #define LDAP_VENDOR_VERSION_MAJOR 224 #define LDAP_VENDOR_VERSION_MINOR 424 #define LDAP_VENDOR_VERSION_PATCH 22 |
不需要修改文件的其他部分。
portable.hin
需 要在 portable.hin 文件中设置在 iPhone SDK 中可用的库函数和头文件的相关信息。但是,这个文件的内容非常多,需要很小心地设置。幸运的是,OpenLDAP 使用 autoconf 执行多个平台必需的测试。可以使用 autoconf 脚本为 portable.hin 生成值。
为了使用 OpenLDAP autoconf 脚本,打开在 /Applications/Utilities/Terminal.app 中找到的 Terminal.app。输入命令 cd 和一个空格。然后,在 Xcode 中把包含 OpenLDAP 源代码树的文件夹拖到终端窗口中。
按回车,把 Terminal.app 中的目录改为 OpenLDAP 源代码树的位置。用所示的标志运行配置脚本。
./configure CC=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/gcc \ LD=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/ld \ --host=arm-apple-darwin --disable-slapd --without-cyrus-sasl \ --without-tls --no-create |
标志 CC=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/gcc 指定 iPhone SDK 使用的编译器的位置,LD=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/ld 指定链接器的位置。标志 --host=arm-apple-darwin 告诉 autoconf 将在哪种平台上使用编译后的代码。标志 --disable-slapd 禁用构建 LDAP 服务器所需的检查(OpenLDAP 附带这些检查)。iPhone SDK 不包含 Cyrus SASL 库、OpenSSL 库或 GNU SSL/TLS 库,所以标志 --without-cyrus-sasl 和 --without-tls禁用对这些库包含的函数的检查。最后,标志 --no-create 禁止 autoconf 创建 Makefile 和头文件。输出应该与相似。
运行以下命令,让 autoconf 根据模板文件 portable.hin 生成 portable.h:./config.status --header=include/portable.h:include/portable.hin。
创建 libldap.a
既然源代码和配置文件已经准备好了,现在应该告诉 Xcode LDAP 库将使用哪些源代码文件。在 Xcode 界面中,找到 OpenLDAP 源代码树中的 libldap 目录。
在 libldap 目录中,有一个名为 Makefile.in 的文件,其中包含用来构建 libldap.a 的文件列表。打开 Makefile.in,找到所示的代码行。
20 SRCS = bind.c open.c result.c error.c compare.c search.c \21 controls.c messages.c references.c extended.c cyrus.c \22 modify.c add.c modrdn.c delete.c abandon.c \23 sasl.c gssapi.c sbind.c unbind.c cancel.c \24 filter.c free.c sort.c passwd.c whoami.c \25 getdn.c getentry.c getattr.c getvalues.c addentry.c \26 request.c os-ip.c url.c pagectrl.c sortctrl.c vlvctrl.c \27 init.c options.c print.c string.c util-int.c schema.c \28 charray.c os-local.c dnssrv.c utf-8.c utf-8-conv.c \29 tls2.c tls_o.c tls_g.c tls_m.c \30 turn.c ppolicy.c dds.c txn.c ldap_sync.c stctrl.c \31 assertion.c deref.c |
需要更新这个列表中的文件,从而把它们包含在 ldap 目标中。为此,右键单击列表中的一个文件并从菜单中选择 Get Info。在新窗口中,选择 Targets 选项卡并单击 Target Memberships 面板中的 ldap 目标。对于列表中的所有文件,重复这个步骤。
创建 liblber.a
liblber.a 是在编译应用程序时 libldap.a 需要的库。OpenLDAP 发行版包含这个库。为了构建它,首先必须为这个库创建一个 Xcode 目标。右键单击 Xcode 的 Groups & Files 面板中的项目图标。从菜单中选择 Add,然后从子菜单中选择 New Target。应该会出现 New Target 向导。在左面板中选择 Cocoa Touch,然后在右面板中选择 Static Library。单击 Next 继续。在 Target Name: 文本框中,输入 lber 并单击 Finish。这应该会创建新的库目标。
liblber.a 依赖于 Foundation 框架。为了配置 Foundation 框架,在 Xcode 的 Groups & Files 面板中滚动到 Targets 部分。展开 Targets 部分并双击目标 lber。这应该会打开 lber 的目标信息窗口。单击 General 选项卡,然后单击 Linked Libraries 面板下面的 + 按钮。在弹出窗口中,从 Device - iPhone OS 4.1 SDK 部分中选择 Foundation.framework。单击 Add 按钮把这个框架添加到库中。
最 后,需要给 Xcode 配置在构建 liblber.a 时要编译的源代码文件。在 Xcode 界面中,找到 OpenLDAP 源代码树中的 liblber 目录。在 liblber 目录中,有一个名为 Makefile.in 的文件,其中包含用来构建 liblber.a 的文件列表。
打开 Makefile.in,找到所示的代码行。
21 UNIX_SRCS = stdio.c26 SRCS= assert.c decode.c encode.c io.c bprint.c debug.c \27 memory.c options.c sockbuf.c $(@PLAT@_SRCS) |
需要更新这个列表中的文件,从而把它们包含在 lber 目标中。为此,右键单击列表中的一个文件并从菜单中选择 Get Info。在新窗口中,选择 Targets 选项卡并单击 Target Memberships 面板中的 lber 目标。对于列表中的所有文件,重复这个步骤。
单击 Xcode 工具栏中的 Build 按钮构建这个库。要想在针对模拟器或设备的构建之间切换,应该从标签为 Overview 的下拉框中选择想要的 SDK。
结束语
与大多数软件开发方法一样,还有编译迁移到 iOS 的库的其他方法。本文使用 Xcode 执行编译,这样就可以利用 Xcode 的依赖项跟踪把库轻松地集成到其他软件包中,还可以用未来的 iPhone SDK 版本轻松地更新库。
本系列的第 2 部分将讲解如何创建第二个 Xcode 项目、作为依赖项添加本文中创建的 Xcode 项目以及使用静态库为 iPhone 创建 LDAP 客户端。
关于作者
David
M. Syzdek 在为电信公司开发 UNIX 软件方面有 10 年经验。当 iPhone SDK 于 2007
年发布时,他开始为移动设备开发应用程序,是最早在 iTunes App Store 上发布应用程序的开发人员之一。David
当前是独立的开发人员,发布属于 Bindle Binaries 的应用程序。