嵌入式linux移植——ptlib、H323plus、oh323tut 交叉编译

发布时间 2023-05-05 09:51:18作者: 阿风小子

前言:上一篇博客主要讲了比较多原理的东西,也是我解决问题时掌握到的一些东西和重要依据,这篇博客接着上一篇博客

嵌入式linux移植——ptlib、H323plus交叉编译 I 继续往下讲~

【补充】开发环境:Ubuntu16.04 、Hi3531a ; 编译工具链:arm-hisiv300-linux ;

 

【一个刷存在感而且想要骗赞的目录】

(1)实现 ptlib的sample里的 hello_world 移植

(2)测试ptlib开源库的移植、实现h323plus的交叉编译,并且移植到开发板上面~

【补充】讲讲如何在交叉编译链接的时候找到需要的库

(3)实现simph323这个demo在开发板上面的移植,并且能够运行和使用

6.ptlib、H323plus交叉编译(编译器arm-hisiv300-linux)
(1).实现 ptlib的sample里的 hello_world 移植
来一波SHELL脚本~

kai $ tar -zxvf ptlib-2_10_9_1.tar.gz
kai $ mv ptlib-2_10_9_1 arm_ptlib
arm_ptlib $ vi configure.sh
****************************************************************
#! /bin/bash
./configure --host=arm-hisiv300-linux \
--enable-minsize \
--disable-openssl \
--disable-sdl \
*********根据需求来选择添加屏蔽相关的功能*********
********刚开始测试的时候就不要加太多依赖库********
****************************************************************
arm_ptlib $ chmod 766 configure.sh
arm_ptlib $ vi arm_ptlib/make/ptlib.mak
****************************************************************
ifndef PTLIBDIR
$(error No PTLIBDIR environment variable defined! \
You need to define PTLIBDIR! \
Try something like: ) *******************
PTLIBDIR=/home/share/armFile/arm_ptlib --根据环境更改路径
*******************
endif
****************************************************************
arm_ptlib $ ./configure.sh
arm_ptlib $ make
arm_ptlib $ cd /samples/hello_world
arm_ptlib/samples/hello_world $ vi Makefile
****************************************************************
ifndef PTLIBDIR *****************
PTLIBDIR=/home/share/armFile/arm_ptlib --根据环境更改路径
endif *****************
****************************************************************
arm_ptlib/samples/hello_world $ make && make bothnoshared

************************交叉编译完成*****************************
ps. arm_ptlib/make/ptlib.mak这个文件建议去了解一下,可以理清楚这个ptlib编译的大概思路

交叉编译ptlib这个东西主要是依赖库的细节和一些莫名其妙的坑比较多,首先ptlib这个源代码是综合了各种编译方式的,如果是一些路径没有设置好,可能编译出来的依赖库虽然是在lib_linux_arm这个文件下,不过不是arm的而且x86环境的,所以需要检查依赖库。

 

 

如果遇到编译出来的共享库是X86的,说明你的编译路径还有环境变量没有设置好~这个时候就把整个ptlib删掉,保留那个configure.sh文件即可,重新tar 一个压缩包重新来一遍,因为如果是 x86生成的一些执行文件会跟 arm 生成的一些中间执行文件(*.o,*.dep...)相互冲突,而make clean是没法clean 干净的,然后在编译执行文件的时候就会报一些 “PSDL”“PFFMPEG”“PTelnet"等等函数未引用的错误

【补充】有些可能需要export PTLIBDIR=YOURPTLIBDIR添加临时环境变量来编译,不建议写进系统的环境变量(移植性不好)

接下来,就把这个可执行文件所在的文件系统挂载到开发板上面,再把对应的共享库放在板子的 /lib 和 /usr/lib , 执行可执行文件应该就会出来你想要的结果了.

【--------------------------------------------------未完待续-2018.8.6晚-------------------------------------------】

问题抛出:用make bothnoshared出来文件大小比较大的可执行文件来测试板子上面的环境~

 

 

答案摸索:

1.猜测是嵌入式linux系统在链接动态库的时候找不到libpthread.so.0,对libpthread.so.0 研究一波,这个共享库这不就是linux的基本库线程吗,我的Ubuntu上面可以找到一大堆,于是我把我的Ubuntu的这个同名文件复制 到嵌入式开发板的 /usr/lib/ 目录下,显然能够成功找到这个库,不过提示说这个库不属于arm这个环境的,所以这个适用于x86的libpthread.so.0并不适用于arm这个环境,不过也就验证了我们的猜测。

2.这里就有两个方法了:

一个是交叉编译libpthread.so.0这个共享库,libpthread.so.0的官网:https://pkgs.org/download/libpthread.so.0

不过我还没能够编译出来,因为我的嵌入式板子的linux是海思diy出来,没有专门适用的arm版本号(uname -a查看CPU内核信息),所以这个方法对我来说不是很可行~

另外一个是把这个libthread 给./confgure的时候静态编译好,目前还在尝试中~

我的方法是修改我的configure.sh文件

#! /bin/bash
./configure --host=arm-hisiv300-linux \
--enable-minsize \
--disable-openssl \
--disable-sdl \
LDFLAGS=-lpthread \
添加了这个参数 : LDFLAGS=-lpthread \ ,也有可能需要更改makefile ,添加 -lpthread这个参数

然后一通编译,编译出sample的hello_world的执行文件正常,不过实验室停电了还没检验~

【--------------------------------------------------未完待续-2018.8.7早-------------------------------------------】

事实证明我的 ptlib 在configure执行的时候加上 LDFLAGS=-lpthread,生成的可执行文件可以说没有变化(根据文件的大小变化,因为静态编译出来的可执行文件会明显变大的多)

于是我尝试在Makefile中寻找方法,发现ptlib的makeFile有个这样的关系:

Makefile <-----arm_ptlib/make/ptlib.mak <------common.mak + unix.mak <----- (略)

然后我就在common.mak里面加上一句:

LDFLAGS += -static
结果这个可执行文件重新编译出来的大小就明显变大了(我们无法查找可执行文件的依赖库关系时,可以根据大小来判断)

对比如下:

(前)

 

 

开发板的执行结果为

 

 

(后)

 

 

开发板的执行结果为

 

 

这里就已经代表着你的程序编译通过了,但是运行的时候抛出异常。

【刨根究底】

关于这个问题:

terminate called after throwing an instance of '__gnu_cxx::__concurrence_broadcast_error'
what(): __gnu_cxx::__concurrence_broadcast_error
Aborted

参照博客:https://blog.csdn.net/skyflying2012/article/details/22855179

可以发现这个是需要静态编译pthread这个共享库,

后来找了一些嵌入式开发论坛,这种把系统依赖库静态编译进可执行文件的方法很少用于开发的场景,所以这种方法就暂且搁置掉,如有兴趣可以看上面那一篇博客。

接下来,“版本回退”到没有更改common.mak之前(也就是把common.mak那条LDFLAGS += -static去掉,虽然这也是一种编译可执行文件的方法)

问题重新定位到“./hello can't load share library 'libpthead.so.0' ”这个问题,

所以有可能是开发板裁剪的时候没有把libpthread这个动态可执行文件加进来,于是我找到开发板的官方压缩包,找到libpthread.so.0这个文件,从文件名和大小就可以察觉到它只是一个软链接而已,所以也要把lipthread-0.9.33.3.so这个共享库复制进来(这种方式也就是为了开发的移植性),然后在板子的 /usr/lib/ 建立一个软链接去使得这个可执行文件放在可以找得到这些共享库。

 

 

【问题解决】

 

 

----------------------------------2018.8.8早 交叉编译ptlib移植解决、未完待续----------------------------------------------------

【补充】在这里大家可能会想,这里有obj-linux-arm-d-s和obj-linux-arm-s,说一下他们的异同:

两个文件里面都是可移植性强的可执行文件,可以不需要ptlib.so.0,这里的s指:no-shared的意思,而d指debug,也就是携带调试信息,可以调试,因此就会文件大小会大得多~

(2)测试ptlib开源库的移植、实现h323plus的交叉编译,并且移植到开发板上面~
使用ptlib中sample例子来作为测试,会发现有些是可以正常运行,而有些不行,原因就是我的configure.sh文件设置的参数,有些依赖库没有加进去,故而缺少某些功能,然后h323plus的功能是需要依靠ptlib才能实现,因此我在编译h323的simple时,出现如下的错误:

“对PFactoryLoader::PWAVFileFormatPCM_link()’未定义的引用

对‘PTelnetSocket::PTelnetSocket()’未定义的引用 。。。”

说的就是我们的静态库或者动态库没有这个功能,这个库都是指向ptlib的,所以我们还需要继续更改ptlib的configure.sh(后我改名为configurePtlib.sh,以便与configureH323Plus.sh区分)

对比之前在电脑虚拟机Ubuntu系统的H323Plus,这几个函数应该是跟alsa库有关系,所以来到ptlib的plugin编译了一下alsa文件,果然出错了~

 

 

找不到头文件!!wtf~我不用交叉编译就能找得到,一用交叉编译就给我找不到?

先稳住心态再慢慢搞定它~

【究其原因】交叉编译工具的头文件查找路径跟系统的不一样,系统一般就是在 /usr/include 、/usr/local/include 这地方,放着这些 .h文件;然而对应的库就放着那些 .so .a ,放在/usr/lib 、/usr/local/lib 这里面,交叉编译是在交叉编译工具的安装路径下找的这些头文件和依赖库,可以用下面的命令查找(我是检测我的arm-hisiv300-linux-gcc)

$ echo 'main(){}'|arm-hisiv300-linux-gcc -E -v -
然后会出来一大串的路径啥的,稍作分析即可明白,比如下面的四条路径就是arm-hisiv300-linux交叉编译工具的头文件搜索路径,我习惯就会把这个我额外于要加的复制一份到第四条路径里面。

 

 

**********************************************************************************

【补充】讲讲如何在交叉编译链接的时候找到需要的库?
(1)交叉编译时候直接使用-L和-I参数指定搜索非标准的库文档和头文档的路径。(交叉编译跨平台常用)例如:

arm-hisiv300-linux-gcc test.c -L/usr/local/arm/2.95.3/arm-linux/lib -I/usr/local/arm/2.95.3/arm-linux/include

(2)使用ld.so.conf文档,将用到的库所在文档目录添加到此文档中,然后使用ldconfig命令刷新缓存。

(3)使用类似如下命令:export LD_LIBRARY_PATH=/opt/openmcu/:$LD_LIBRARY_PATH

************************************************************************************

当我把alsa的头文件目录找到放在交叉编译的目录下面,重新make的时候就会发现已经不会显示说找不到头文件了,不过

 

出现一个新的错误,也就是说依赖库对不上的原因,噢噢~我这个alsa的是之前直接apt-get下载的,直接下载对应的可执行动态库,肯定是对应我的x86版本的linux,交叉编译肯定也用不了,所以关于alsa的问题也就是需要下载源码自行交叉编译,才能够使用~nice~虽然没解决问题,不过知道了为什么失败还是有收获的,然后百度参照一些交叉编译移植的博客:

alsa-lib 交叉编译以及声卡驱动测试、还有上一篇关于 交叉编译openssl 的两个参考链接,这一块我就不赘述了(逃~

------------------------------------------2018.8.9 晚 20:00---------------------------------------------

(3)实现simph323这个demo在开发板上面的移植,并且能够运行和使用
【补充】对于h323plus这个开源库在改用交叉编译工具的时候会有有个脚本错误,

附上我的h323的configure脚本,

#!/bin/bash
./configure --prefix=/home/share/armFile/arm_h323plus \
host=arm-hisiv300-linux
运行该脚本会显示一个existence的错误,改正如下:

(修改前)

 

(修改后)

 

对于步骤二里面的“未定义的引用”这种问题跟alsa没有直接的关系(alsa这些只是插件而已,需要附加功能给ptlib才需要编译这些插件),因为查看ptlib的configure -h时候发现有个--enadle-wavfile 、和--enable-telnet的参数选项,这两个选项是不是跟我们的两个错误有着相似的地方呢,所以加上去之后就会自动编译出对应的库了~也就有相对应的函数引用了

我的configurePtlib.sh更改如下:

#! /bin/bash
./configure --host=arm-hisiv300-linux \
--enable-minsize \
--enable-wavfile \
--enable-telnet
(注意:这里的sh脚本命令行的的前后顺序不一样,编出来的效果也有可能不一样的!!)

直接就是一波 ./configurePtlib.sh 、make 、./configureH323.sh 、make 、 cd simph323DIR 、make bothnpshared的操作,然后移植到嵌入式环境,并且找个小伙伴来试一下~

 

nice~双方通信成功~如果你跟我一样,顺利到达了这一步,恭喜你成功地在嵌入式系统移植这一领域迈上了这小小的一步~