IOS 之 PJSIP 笔记(一) 编译多平台支持的静态库
好久没有写博客了,这也算是我步入新工作后的第一篇技术博文吧。在进入新公司前,早就有了技术层进入下一个迭代的准备,但很多事情是意想不到的,就像我以 C# 程序员的身份面试入职的,而今却是一个全职的 IOS 开发。从 C# 到 Objective-C 的切换,还是有不少成本的,加上今年又推出了 Swift,以后要学习的路是漫长的,其实,学习的路本身就是漫长的,不应该满足于一个阶段和特定领域。对我而言,语言的切换,已经太常见了,学习一门语言是很容易的事情,但,完全的掌握它,却不是易事,就像去摸清一个陌生人的脾气一样。有点扯远了,还是进入今天的正题吧!
PJSIP,如果你不知道它是什么,那么说明你无需使用它,那也就没必要继续看我的这篇文章了。由于项目中需要使用到 VOIP,而对比下来,使用 SIP 实现的代价是相对小的,在 Android 里,谷歌内置了对 SIP 的支持,IOS 中就没这么好运了,于是乎找到了 PJSIP,这是一个纯 C 的库,实现的相当漂亮。在网络上找了很久,也没有找到适合我这种的入门级教程,在我的摸索和努力下,终于搞出点名堂来了。那么,恭喜你,你不用走我走过的弯路了。
下面正式开始,一步步来:
第一步:下载
首先,去官网下载源代码,这里推荐下载 .tar.bz2 的包,下载完成后,找到对应的目录,用 tar 或者图形化操作来解压,这里我用命令行的方式来操作:
$ tar -jxvf pjproject-2.2.1.tar.bz2
第二步:编译
首先,要在 pjlib/include/pj/ 目录下,建立一个 config_site.h 的文件,切换到该目录下,用 vi 或者 touch 一个文件:
$ cd pjlib/include/pj/
$ vi config_site.h
按照官方的说明文档,我们文件内容定义如下:
#define PJ_CONFIG_IPHONE 1
#include <pj/config_site_sample.h>
OK,保存,切换回主目录下(也就是有pjlib、pjmedia、pjnath等目录的文件夹),这时候我们就可以编译了,还有个前提,你必须安装了 XCode 的 Command Line Tools(XCode –> Preferences –>Downloads)。
i386
首先编译模拟器平台的静态库,依次执行下面这三句:
$ export DEVPATH=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer
$ ARCH="-arch i386" CFLAGS="-O2 -m32 -mios-simulator-version-min=5.0" LDFLAGS="-O2 -m32 -mios-simulator-version-min=5.0" ./configure-iphone
$ make dep && make clean && make
OK,没有什么问题的话,你模拟器版本的静态库就编译完成了,它们存在于:
- pjlib/lib
- pjlib-util/lib
- pjmedia/lib
- pjnath/lib
- pjsip/lib
- third_party/lib
这些,是在以后的 SIP 开发中,必须要使用到的静态库,目前该库只支持模拟器(可使用 lipo –info 命令来查看,只支持 i386),所以,我们将其拷贝出来,当然,我已经为你写好拷贝的脚本了:
#!/bin/bash PJLIB_PATH="./lib/$1/pjlib"
PJLIB_UTIL_PATH="./lib/$1/pjlib-util"
PJMEDIA_PATH="./lib/$1/pjmedia"
PJNATH_PATH="./lib/$1/pjnath"
PJSIP_PATH="./lib/$1/pjsip"
THIRD_PARTY="./lib/$1/third_party" echo "start coping to $1" rm -rf $PJLIB_PATH
rm -rf $PJLIB_UTIL_PATH
rm -rf $PJMEDIA_PATH
rm -rf $PJNATH_PATH
rm -rf $PJSIP_PATH
rm -rf $THIRD_PARTY mkdir -p $PJLIB_PATH
mkdir -p $PJLIB_UTIL_PATH
mkdir -p $PJMEDIA_PATH
mkdir -p $PJNATH_PATH
mkdir -p $PJSIP_PATH
mkdir -p $THIRD_PARTY cp -r ./pjlib/lib/ $PJLIB_PATH
cp -r ./pjlib-util/lib/ $PJLIB_UTIL_PATH
cp -r ./pjmedia/lib/ $PJMEDIA_PATH
cp -r ./pjnath/lib/ $PJNATH_PATH
cp -r ./pjsip/lib/ $PJSIP_PATH
cp -r ./third_party/lib/ $THIRD_PARTY echo "copy done"
将该脚本保存为 copylibs.sh 存放到主目录下(你应该知道主目录在哪吧!),然后执行:
$ ./copylibs.sh i386
如果提示权限不够,那么使用 chmod 777 copylibs.sh 来赋予该文件最大的访问权限,执行完后,所有生成的静态库,都被拷贝到主目录下 lib 目录中的对应位置。
armv7
下面继续编译 armv7 版的库,关闭刚刚的那个控制台,注意,是全部关闭后再进入,然后到主目录依次执行下面的命令:
$ ARCH='-arch armv7' ./configure-iphone
$ make dep && make clean && make
$ ./copylibs.sh armv7
armv7s
现在编译 armv7s 版本的库,这次不用关闭控制台了,直接依次执行下面的命令(有报错误,但都是示例项目编译出错,和静态链接库文件没关系):
$ ARCH='-arch armv7s' ./configure-iphone
$ make dep && make clean && make
$ ./copylibs.sh armv7s
arm64
最后,我们完成 arm64 版本库的编译:
$ ARCH='-arch arm64' ./configure-iphone
$ make dep && make clean && make
$ ./copylibs.sh arm64
第三步:合并静态链接库
好了,现在我们需要的库都已经被拷贝到 lib 目录下了,它目前应该是这样的:
对的,这底下有一个 mix.sh,当然,这也是我为你写好的脚本:
#!/bin/bash OUPUT_PATH="./mixed/"
XLIPO="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/lipo" for dir in armv7/*
do
LIB_NAME=${dir##*/}
LIB_OUTPUT=${OUPUT_PATH}$LIB_NAME rm -rf $LIB_OUTPUT
mkdir -p $LIB_OUTPUT for subdir in ${dir}/*
do
AFILE=${subdir##*/}
ARMV7_FILE="./armv7/$LIB_NAME/$AFILE"
ARMV7S_FILE="./armv7s/$LIB_NAME/$AFILE"
ARM64_FILE="./arm64/$LIB_NAME/$AFILE"
I386_FILE="./i386/$LIB_NAME/$AFILE"
echo "start mixing file: $AFILE" ${XLIPO} -arch armv7 $ARMV7_FILE -arch armv7s $ARMV7S_FILE -arch arm64 $ARM64_FILE -arch i386 $I386_FILE -create -output ${LIB_OUTPUT}/$AFILE done
done echo "all mixed done"
将上面的脚本,保存到 lib 目录下 mix.sh 中,控制台中,cd 切换到 lib 目录下,然后执行:
./mix.sh
OK,现在一切都完成了,在 lib 目录下会多出个 mixed 目录,该目录底下的所有库,都是包含了上诉各种架构版本信息的,可以使用 lipo 来验证下:
注意,无论是合并还是查看,都要使用 Xcode 下的 lipo,mac 自带的那个 lipo 不支持。
如果你觉得,亲自动手太麻烦的话,那么这里有一个已经帮你编译好的版本,直接下载使用即可:
https://github.com/chebur/pjsip
不过,我还是推荐你自己动手来一遍,自己弄出来的,使用起来才更有意思嘛,呵呵~
IOS 之 PJSIP 笔记(一) 编译多平台支持的静态库的更多相关文章
- Qt5.7中使用MySQL Driver(需要把libmysql.dll文件拷贝到Qt的bin目录中。或者自己编译的时候,链接静态库)
Qt5.7中使用MySQL Driver 1.使用环境 Qt5.7的安装安装就已经带了MySQL Driver,只需要在安装的时候选择一下即可.如果没有安装,可以采取自己编译的方式.在Qt的源码包的q ...
- IOS 之 PJSIP 笔记(二) iPJSUA 的简单使用
上一篇在编译完之后,就很不负责的结束了,本篇就对 PJSIP 库中提供的一个示例 iPJSUA 的使用,做一个简单的介绍.也能解除很多人对官方文档的一个困扰,起码我是被困扰过了. 首先,要确保你的 P ...
- Msys2+mingw-w64 编译VS2013使用的ffmpeg静态库注意事项
1.环境准备 第一步:从http://sourceforge.net/projects/msys2/下载msys2的安装程序安装msys2; 第二步:通过msys2的包管理工具pacman安装ming ...
- VS2012中使用编译的Qt-5.1.1静态库开发程序
1. 安装qt-vs-addin-1.2.2-opensource.exe,安装之后,vs2012菜单栏就会出现QT5菜单. 2. 在qt-vs-addin添加Qt5静态库: QT5->Qt O ...
- autotools入门笔记(二)——创建和使用静态库、动态库
带有静态库或者动态库的工程的构建过程与上一节()只包含一个源文件的工程的构建过程是类似的.只是对于复杂的工程,如果包含多个还有源文件的目录时,需要对每个包含源文件的目录执行构建过程,另外创建和使用库文 ...
- GCC 预处理,汇编,编译,链接,连接静态库,动态库
gcc Record gcc -E file1.c > output gcc -E file1.c -o file1.i gcc -S file1.i -o file1.s gcc -S fil ...
- 【iOS】编译静态库
与java和.net一样,objc也由类库的概念,不过在在objc上一般叫库,库表示程序代码集合,可以共享给其他程序使用,库是编译后的二进制文件,因此不能看到源代码,多用于一些开放sdk(如百度地图s ...
- iOS静态库及Framework 创建
本文转自cocoachina,尊重作者的汗水. 讲述的非常透彻,有需要的朋友可以阅读实践.转载请注明出处 //=================以下留着备份==================// 在 ...
- Xcode 之自己编译静态库
今天介绍下,如何利用Xcode,新建一个静态库,以及如何编译成i386.armv7.armv7s 等平台架构. 开发环境:MAC OS X 10.9.4 + Xcode 5.0.2 背景知识:库分两种 ...
随机推荐
- Codeforces Round #382 (Div. 2) D. Taxes 哥德巴赫猜想
D. Taxes 题目链接 http://codeforces.com/contest/735/problem/D 题面 Mr. Funt now lives in a country with a ...
- Android开发(二十四)——数据存储SharePreference、SQLite、File、ContentProvider
Android提供以下四种存储方式: SharePreference SQLite File ContentProvider Android系统中数据基本都是私有的,一般存放在“data/data/程 ...
- 现在看看自己写的博客,怎么感觉好low啊。。。
是不会写还是怎么着? 感觉比较好的东西,难以整理,就没往上放.... 现在猛一看,博客里的东西乱七八糟的...各位看官随便看看就好
- C/C++/Qt 统计运行时间
http://www.cnblogs.com/Romi/archive/2012/04/19/2457175.html 程序中经常需要统计时间,需要统计某项运算的运行时间时,需要计算时间差. 1. C ...
- php 类文件加载 Autoloader
做习惯了编译语言,转到php 使用 php的面向对象开发时候遇见一个挺别扭的问题.在Php中引入对象 后 在调用过程中还需要将对象所在的php文件 require 到当前php文件 目前代码结构 in ...
- 使用Doxygen生成net帮助文档
一. 什么是Doxygen? Doxygen 是一个程序的文件产生工具,可将程序中的特定批注转换成为说明文件.通常我们在写程序时,或多或少都会写上批注,但是对于其它人而言,要直接探索程序里的批注,与打 ...
- failed jobs because of past close date,关工单报错
今天会计反映关不了工单.我们公司关工单的程序是自己开发的,可以整批关.报如下错误.我试着用Standad程序关,可以.看来应该是我们开发的程序有问题.后来发现,是抛到WIP_DJ_CLOSE_TEMP ...
- Devexpress treelist 树形控件 实现带三种状态的CheckBox
树形控件是使用频率很高的一种控件.对于属性控件往往需要下面两个功能 1.TreeList带有CheckBox,并且节点要有三种状态(所有的子节点都选中,所有的子节点都没选择,一部分子节点选中).使用 ...
- Ubuntu下的杀毒
Ubuntu 11.04 杀毒软件ESET NOD32 Linux防病毒,并不代表没有病毒,只是数量过少.因技术精英发现漏洞后即时打补丁,病毒很少. 有兴趣的同学可以尝试下Ubuntu 11. ...
- 审核流(2)流程设计-SNF.WorkFlow功能使用说明--SNF快速开发平台3.1
流程设计 图形化的流程设计,更方便.直观 1.打开“流程设计“程序,如上.点击”新建“如下: 2.红色部分为必填项,审批对象是选择要审批的程序菜单,单据名称是在审核流流转时用于提示的单据名称,还要选择 ...