# sipclient-v2 **Repository Path**: tangm421/sipclient-v2 ## Basic Information - **Project Name**: sipclient-v2 - **Description**: 新版sipclient - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 3 - **Forks**: 2 - **Created**: 2021-08-16 - **Last Updated**: 2025-01-22 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 1. sipclient-v2 新版sipclient,将依赖库设计为git子模块,不再提供特定平台预编译好的库。 依赖的基础设施库rutil从resiprocate中剥离并用cmake重写构建脚本,也一并加入到sipclient构建系统中。 和exosip相关的库有三个:exosip,osip,c-ares exosip和osip版本都是5.2.1,c-ares则采用cares-1_16_1,其中osip本身又分为osip和osipparser两个库 ## 1.1. 编译 ### 1.1.1. 拉取完整git仓库代码 ``` git clone --recursive http://10.0.2.235/luanhui/sipclient-v2.git ``` 这一句相当于先执行 `git clone http://10.0.2.235/luanhui/sipclient-v2.git`, 然后再执行 `git submodule update --init --recursive`。 如果是服务端后续有更新的话,本地的同步步骤也要包括可能的子模块的commit指向更新,通过以下git命令更新服务端的最新更新: ``` git pull --recurse-submodules ``` ### 1.1.2. windows #### 1.1.2.1. exosip的编译 windwos平台下利用MSVC编译开源库一直是个麻烦事,特别是涉及到一些依赖时,exosip也不例外。 虽然可以通过MINGW或者MYSYS这种类GNU的工具来构建,但是显然便利程度和兼容性远没有VS来得干脆。 exosip在windows下编译使用的是源码包中自带的vc解决方案(.\platform\vsnet\eXosip.sln),这个解决方案是VC 11.0(Visual Studio 2012),虽然这个库在2021-05-25提交的5.2.1版本,但是显然作者也没有闲心雅致去更新VS相关的构建工程。此解决方案把exosip依赖的osip库的两个VS工程以及自己编写的libcares库的工程也包含在内了,还是很贴心的。 osip库的两个工程是直接引用的osip源码包中的VS工程,而且路径在exosip的工程配置中指定了,所以osip源码包要和exosip源码包同目录存放。 libcares库的工程文件是exosip中自带的,其中参加libcares编译的所有文件以及引用cares的头文件路径也在exosip的工程配置中指定好了,所以c-ares源码包的路径也要和exosip源码包同目录存放。 exosip也可以指定不依赖libcares,在VS工程文件中有两个预编译宏:CARES_STATICLIB,HAVE_CARES_H指定了exosip默认是要依赖libcares的,如果去掉这两个宏,同时删除exosip中对libcares库的引用,则可以解除对libcares的依赖。 exosip中还有个预编译宏:HAVE_OPENSSL_SSL_H,默认是要链接OpenSSL相关的库,所以如果出现编译时找不到openssl相关的头文件的错误,只需要手动加入windows下已经安装好的OpenSSL开发包的头文件路径即可,或者干脆就去掉这个宏,不过基于TLS和DTLS协议的sip就没办法支持。 在编译exosip的过程中,按照上述流程来的话,首先就会遇到报错说找不到ares_build.h之类的问题,这是因为cares-1_16_1中的有些头文件是要通过构建脚本生成的,所以在编译exosip之前,先去c-ares源码包中去执行下 `cmake .` 以生成一些特定平台下的头文件。 紧接着回到VS中编译exosip,貌似一帆风顺,四个库都生成了。 这里要说一下的是,在编译前,先将四个工程的平台工具集都改成最新的工具集,因为exosip编译后生成的库路径是和这个平台工具集相关的,后续编译sipclient时查找exosip相关库的时候要用到! #### 1.1.2.2. 编译sipclient 因为windows下的exosip编译方案未提供安装工程,所以cmake脚本是针对exosip源码包的根路径来寻找exosip头文件和链接库。在编译sipclient时指定exosip源码包的路径: ```bash mkdir build;cd build cmake -DEXOSIP_ROOT= ../ ``` 生成VS解决方案之后,可以直接打开sln文件编译或者调用cmake编译 ``` cmake --build . ``` 编译时会遇到链接错误,类似找不到 _ares__getplatform等等符号的问题。但是libcares确实是在上一步生成了,后来分析了一番,发现原罪还是在exosip附带的libcares工程(.\platform\vsnet\libcares.vcxproj)。 将c-ares目录中的ares_create_query.c,ares_platform.c,ares_strsplit.cz和三个源文件添加到libcares工程中并重新编译exosip。 返回编译sipclient。 #### 1.1.2.3. 关于链接openssl 使用cmake模块自带的FindOpenSSL查找当前系统中安装的openssl,我本机安装的是openssl-1.1.0h,然后查找并链接openssl静态库到sipclient编译的时候出现一些奇怪的链接错误,诸如: ``` 1>libcrypto32MDd.lib(cryptlib.obj) : warning LNK4217: 本地定义的符号 _sscanf 在函数 _OPENSSL_cpuid_setup 中导入 1>libcrypto32MDd.lib(cryptlib.obj) : error LNK2019: 无法解析的外部符号 __imp___vsnwprintf,该符号在函数 _OPENSSL_showfatal 中被引用 1>libcrypto32MDd.lib(pem_lib.obj) : error LNK2019: 无法解析的外部符号 __imp____iob_func,该符号在函数 _PEM_def_callback 中被引用 ``` 原来是因为cmake找到的这个版本的openssl静态库是使用较老的VS编译器版本编译的,关于printf、scanf之类的链接错误可以通过引入legacy_stdio_definitions.lib解决,而另外关于__iob_func的链接错误则需要自己定义 extern "C" { FILE __iob_func[3] = { *stdin,*stdout,*stderr }; } 具体可以参考:[无法解析外部符号__imp__fprintf和__imp____iob_func](https://www.cnblogs.com/lyggqm/p/6214000.html) ### 1.1.3. UNIX 因为有包管理器的存在,unix平台下的编译相对简单得多。 #### 1.1.3.1. 编译exosip 依次进入./libs/c-ares、.libs/osip、.libs/exosip,在每个目录中执行构建的标准流程, `./configure、make、make install`,当然c-ares也可以不用编译,使用系统包管理器安装的 `libc-ares-dev`,后续的cmake构建系统也能定位到系统包安装的路径。 对于osip和exosip,都提供了autogen.sh以及configure.ac,前者可以直接执行以生成configure,后者可以通过 `autoreconf --install` 来生成configure。 configure时带上 `--enable-shared=no` 为后续sipclient的链接静态库提供唯一性。 安装之后,编译sipclient的cmake会在系统安装目录中查找exosip相关的头文件和库。 如果编译之后不想安装,也可以在下面编译sipclient时提供 `-DEXOSIP_ROOT=` 给cmake用于在源码包中寻找编译好的exosip库。 #### 1.1.3.2. 编译sipclient ```bash mkdir build cd build cmake ../ make ``` #### 1.1.3.3. 关于链接openssl cmake在linux下编译时链接的库有先后顺序要求,依赖越深的库就越要放在最后,像openssl的链接库本身需要pthread和dl库的依赖,所以openssl也必须位于这两个库的前面,同时exosip依赖openssl,所以exosip要在openssl库的前面,否则编译sipclient会报已读openssl相关接口未定义的错误。这些事情在sipclient的cmake文件中处理。 ### 1.1.4. 交叉编译 #### 1.1.4.1. 编译exosip 对libs中三个子模块分别进行编译,注意在configure时指定 `--host` 以进行交叉编译,指定 `--enable-shared=no` 以在后续链接静态库。 在编译exosip时,由于要依赖c-ares和osip,所以在configure时手动给出头文件和库的路径,例如 ```bash ./configure --prefix=/opt/hisi-linux/x86-arm/ --host=arm-hisiv400-linux --enable-shared=no --enable-openssl=no --enable-tools=no CFLAGS=-I/root/luanhui/sipclient-v2/libs/osip/include LDFLAGS="-L/root/luanhui/sipclient-v2/libs/osip/src/osipparser2/.libs/ -L/root/luanhui/sipclient-v2/libs/osip/src/osip2/.libs/" ``` 当然如果exosip的依赖库都已经安装到标准系统安装目录的话,就不需要特别指定文件头和库的路径。 #### 1.1.4.2. 编译spdlog spdlog版本 >= 1.9.2 比如,在海思平台上编译时,交叉编译工具arm-hisiv400-linux-g++需要增加编译选项`-mcpu=cortex-a9`,否则运行时会报错:pure virtual method called。 #### 1.1.4.3. 编译sipclient 如果上述库都已经安装到标准系统安装目录的话,只需要执行以下命令 ``` makedir build;cd build cmake ../ -DCMAKE_TOOLCHAIN_FILE=../cmake/Toolchain-arm-hisiv400-linux.cmake ``` 否则,需要指定exosip的源码包根目录 ``` cmake ../ -DCMAKE_TOOLCHAIN_FILE=../cmake/Toolchain-arm-hisiv400-linux.cmake -DEXOSIP_ROOT=../libs/exosip/ ``` 这里的../cmake/Toolchain-arm-hisiv400-linux.cmake是用来设置cmake的交叉编译环境,其中默认指定交叉编译工具链为arm-hisiv400-linux ## 1.2. 思考 因为exosip在windows下编译时的VS工程默认都是编译的静态链接库,而对于像exosip这种本身依赖其他库的情况,这里就会出现很常见的一个问题: ### 1.2.1. 静态库的多重依赖问题 比如上述说到的sipclient依赖exosip的静态链接库,而exosip又依赖osip、c-ares、openssl。 而在编译exosip静态链接库时,并没有指定osip、c-ares、openssl这些依赖库,只是设置了这些依赖的头文件路径,反而是编译sipclient时才真正需要去链接这些依赖库。 因为sipclient是通过调用exosip的某些接口,这些接口内部会去调用有关依赖库的接口,而sipclient中并没有直接调用c-ares、openssl这些库的接口,所以sipclient中不需要包括这些依赖库的头文件,而只需要将这些依赖链上的库全部打包进编译的可执行文件就可以。 ## 1.3. 关于cmake构建 限于对cmake构建体系的了解程度,并没有对sipclient链接的依赖库做更精细化的处理,所有依赖库只要在exosip构建体系中找到,就会应用于sipclient所有VS平台和配置,没有区分debug还是release平台,也没有区分win32还是x64配置。也没有针对不同配置的生成规则制定差异化的编译选项。