内容


LDAP 与 iPhone,第 1 部分

使用 UNIX 库进行 iOS 开发

Comments

系列内容:

此内容是该系列 # 部分中的第 # 部分: LDAP 与 iPhone,第 1 部分

敬请期待该系列的后续内容。

此内容是该系列的一部分:LDAP 与 iPhone,第 1 部分

敬请期待该系列的后续内容。

简介

iPhone 在手机市场上的出现导致 iTunes 中移动应用程序的数量急剧增加。由于大量应用程序的核心功能是相同的,新的应用程序很难在竞争者中脱颖而出。为了让应用程序能够吸引消费者,越来越有必要添加同类应用程序不支持的特性;但是,从头编写新功能的开发时间很长,工作量很大。迁移原来为 UNIX® 系统编写的库能够帮助开发人员降低成本,让应用程序更快地投入市场。

iPhone 使用的操作系统 iOS 是在 UNIX 核心之上构建的,iOS 应用程序是使用 GCC 编译的,而 GCC 也是大多数 UNIX 系统使用的编译器。这意味着,只需花些时间和精力,就可以把为 UNIX 系统编写的大多数库迁移到 iPhone 上。

本文带领您把一个库迁移到 iPhone 上,这个库一般情况下是在包含 Autoconf 和 Make 的环境中构建的。尽管本文并不详细解释如何迁移用 GNU 工具构建的包,但是了解 GNU 工具的开发人员应该能够根据这里提供的信息把包导入 Xcode 并迁移到 iOS 平台上。

开始

本文中使用的示例已经用 Mac OS X 10.6.4 上的 iOS SDK 4.1 和 OpenLDAP 2.4.22 测试过。尽管示例使用 iOS SDK 4.1,但是应该也适用于以后的 iOS SDK 版本(可能需要稍加修改)。可以在 “下载” 部分中的 zip 文件中找到示例的源代码文件和项目文件。

iPhone SDK 用于编译针对 iPhone OS 平台的移动应用程序。SDK 提供文档、IDE 和用于测试移动应用程序的模拟器(下载信息见 参考资料)。

OpenLDAP 是 Lightweight Directory Access Protocol 的一种免费开放源码实现。这个实现包含的库可以使用 LDAP over TCP 访问 X.500 目录服务(下载信息见 参考资料)。

准备 OpenLDAP 源代码

Xcode 是 iPhone SDK 包含的 IDE。它包含用于为 iOS 平台构建应用程序和库的模板和文档。为了更方便地在 OpenLDAP 源代码树中移动,我们先把源代码导入到一个 Xcode 项目中。为 iOS 平台创建新的 Xcode 项目的方法是,打开 Xcode 并从菜单栏上的 File 菜单中选择 New Project。这应该会打开一个新的对话框,其中有三个面板(见 图 1)。因为将使用这个项目编译 OpenLDAP 客户端库,所以应该用静态库模板创建它。在左面板上,在标题 iPhone OS 下面选择 Library。在右上方的面板中,选择 Cocoa Touch Static Library。单击 Choose 继续。

图 1. Xcode 中的 New Project 对话框
Xcode 中的 New Project 对话框
Xcode 中的 New Project 对话框

图 2 中的对话框用于设置 Xcode 项目的名称。

图 2. 用于在 Xcode 项目中添加现有文件的对话框
用于在 Xcode 项目中添加现有文件的对话框
用于在 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 面板中双击项目名称。这应该会打开项目信息窗口(见 图 3)。在 "Search in Build Settings" 搜索框中单击并输入 Header Search Paths。在 Value 框中双击,添加新的搜索路径 openldap-2.4.22/include

图 3. 项目信息对话框
项目信息对话框
项目信息对话框

准备头文件

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 头文件处理。打开文件,寻找 清单 1 所示的代码行。

清单 1. lber_types.h
27 /* LBER boolean, enum, integers (32 bits or larger) */
28 #undef LBER_INT_T
29 
30 /* LBER tags (32 bits or larger) */
31 #undef LBER_TAG_T
32
33 /* LBER socket descriptor */
34 #undef LBER_SOCKET_T
35 
36 /* LBER lengths (32 bits or larger) */
37 #undef LBER_LEN_T

这些行声明库使用的变量类型。因为 iPhone 是 32 位平台,类型 int 是合适的值。把 #undef 宏改为 #define,把变量类型设置为 int(见 清单 2)。

清单 2. 针对 32 位平台进行调整
27 /* LBER boolean, enum, integers (32 bits or larger) */
28 #define LBER_INT_T int
29 
30 /* LBER tags (32 bits or larger) */
31 #define LBER_TAG_T int
32
33 /* LBER socket descriptor */
34 #define LBER_SOCKET_T int
35 
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 并寻找 清单 3 所示的代码行。

清单 3. ldap_features.h
23 /* OpenLDAP API version macros */
24 #undef LDAP_VENDOR_VERSION
24 #undef LDAP_VENDOR_VERSION_MAJOR
24 #undef LDAP_VENDOR_VERSION_MINOR
24 #undef LDAP_VENDOR_VERSION_PATCH

OpenLDAP 的每个版本使用分三部分的版本号。用 X.Y.Z 格式表示版本,其中的 X 是主厂商版本号,Y 是次厂商版本号,Z 是厂商补丁修订号。按公式 ((X*10,000)+(Y*100)+(Z)) 计算出 LDAP_VENDOR_VERSION 的值。例如,使用 清单 4 所示的值计算 OpenLDAP 2.4.22 的 LDAP_VENDOR_VERSION

清单 4. 计算 LDAP_VENDOR_VERSION
LDAP_VENDOR_VERSION_MAJOR = X = 2
LDAP_VENDOR_VERSION_MINOR = Y = 4
LDAP_VENDOR_VERSION_PATCH = Z = 22

LDAP_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,应该做 清单 5 所示的修改。

清单 5. 针对 OpenLDAP 2.4.22 的修改
23 /* OpenLDAP API version macros */
24 #define LDAP_VENDOR_VERSION  20422
24 #define LDAP_VENDOR_VERSION_MAJOR 2
24 #define LDAP_VENDOR_VERSION_MINOR 4
24 #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 源代码树的文件夹拖到终端窗口中(见 图 4)。

图 4. 把 Xcode 组拖到 Terminal.app 中以获得文件夹路径的过程
把 Xcode 组拖到 Terminal.app 中以获得文件夹路径的过程
把 Xcode 组拖到 Terminal.app 中以获得文件夹路径的过程

按回车,把 Terminal.app 中的目录改为 OpenLDAP 源代码树的位置。用 清单 6 所示的标志运行配置脚本。

清单 6. 运行配置脚本
./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 和头文件。输出应该与 图 5 相似。

图 5. 运行配置脚本的前几行输出
运行配置脚本的前几行输出
运行配置脚本的前几行输出

运行以下命令,让 autoconf 根据模板文件 portable.hin 生成 portable.h:./config.status --header=include/portable.h:include/portable.hin

创建 libldap.a

既然源代码和配置文件已经准备好了,现在应该告诉 Xcode LDAP 库将使用哪些源代码文件。在 Xcode 界面中,找到 OpenLDAP 源代码树中的 libldap 目录(见 图 6)。

图 6. libldap 源代码文件在 Xcode 的 Groups & Files 面板中的位置
libldap 源代码文件在 Xcode 的 Groups & Files 面板中的位置
libldap 源代码文件在 Xcode 的 Groups & Files 面板中的位置

在 libldap 目录中,有一个名为 Makefile.in 的文件,其中包含用来构建 libldap.a 的文件列表。打开 Makefile.in,找到 清单 7 所示的代码行。

清单 7. 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,找到 清单 8 所示的代码行。

清单 8. Makefile.in 中的代码行
21 UNIX_SRCS = stdio.c

26 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 客户端。


下载资源


相关主题

  • Android 和 iPhone 浏览器之战,第 1 部分:WebKit 成援兵(Frank Ableson,developerWorks,2009 年 12 月):通过这篇 developerWorks 文章了解如何使用移动浏览器的特性。
  • Introduction to LDAP: Part 1, Installation and simple Java LDAP programming(Jeng Yoong Tan,developerWorks,2010 年 6 月):了解 LDAP (Lightweight Directory Access Protocol) 的概况。
  • 让 UNIX 和 Linux 一起工作(Martin Brown,developerWorks,2006 年 4 月)讲解如何让传统的 UNIX 发行版和 Linux® 一起工作。
  • 获取 iPhone SDK。注册的 ADC 成员可以下载它。
  • 了解 GitHub project for iOS ports。它自动地构建 OpenSSL、Cyrus-SASL 和 OpenLDAP,已经用 SASL Auth、LDAPS 和 LDAP TLS 测试过。
  • 项目网站 下载 OpenLDAP。
  • 访问 Xcode Port of OpenLDAP
  • 获取 OpenLDAP 的 Xcode Port
  • AIX and UNIX 专区:developerWorks 的“AIX and UNIX 专区”提供了大量与 AIX 系统管理的所有方面相关的信息,您可以利用它们来扩展自己的 UNIX 技能。
  • AIX and UNIX 专题汇总:AIX and UNIX 专区已经为您推出了很多的技术专题,为您总结了很多热门的知识点。我们在后面还会继续推出很多相关的热门专题给您,为了方便您的访问,我们在这里为您把本专区的所有专题进行汇总,让您更方便的找到您需要的内容。
  • AIX and UNIX 下载中心:在这里你可以下载到可以运行在 AIX 或者是 UNIX 系统上的 IBM 服务器软件以及工具,让您可以提前免费试用他们的强大功能。
  • IBM Systems Magazine for AIX 中文版:本杂志的内容更加关注于趋势和企业级架构应用方面的内容,同时对于新兴的技术、产品、应用方式等也有很深入的探讨。IBM Systems Magazine 的内容都是由十分资深的业内人士撰写的,包括 IBM 的合作伙伴、IBM 的主机工程师以及高级管理人员。所以,从这些内容中,您可以了解到更高层次的应用理念,让您在选择和应用 IBM 系统时有一个更好的认识。
  • 要收听面向软件开发人员的有趣访谈和讨论,请查看 developerWorks 播客

评论

添加或订阅评论,请先登录注册

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=AIX and UNIX, Open source
ArticleID=659404
ArticleTitle=LDAP 与 iPhone,第 1 部分: 使用 UNIX 库进行 iOS 开发
publish-date=05172011