我的工作环境
- 主机平台:Ubuntu 16.04 LTS(x64)
- 目标平台:ARM40-A5
- D-Bus版本:1.0.2
- ARM-GCC编译工具链:gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabi.tar.xz
D-Bus是什么
D-Bus是一种高级的进程间通信机制,D-Bus最主要的用途是在Linux桌面环境为进程提供通信,同时能将Linux桌面环境和Linux内核事件作为消息传递到进程。
D-Bus进程间通信主要有三层架构:
- 底层接口层:主要是通过libdbus这个函数库,给予系统使用D-Bus的能力。
- 总线层:主要Message bus daemon这个总线守护进程提供的,在Linux系统启动时运行,负责进程间的消息路由和传递,其中包括Linux内核和Linux桌面环境的消息传递。总线守护进程可同时与多个应用程序相连,并能把来自一个应用程序的消息路由到0或者多个其他程序。
- 应用封装层:通过一系列基于特定应用程序框架将D-Bus的底层接口封装成友好的Wrapper库,供不同开发人员使用。D-Bus官方网站:https://www.freedesktop.org/wiki/Software/dbus/
编译D-Bus
- 配置编译工具链
$ sudo xz -d gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabi.tar.xz
$ ls
$ sudo tar xvf gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabi.tar -C /opt/
$ cd ~
$ vim .bashrc
在.bashrc的末尾添加文本
export PATH=$PATH:/opt/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabi/bin/
$ arm-linux-gnueabi-gcc -v #查看ARM-GCC版本
Thread model: posix
gcc version 4.9.4 (Linaro GCC 4.9-2017.01)
- 获取源代码
D-Bus依赖于expat,下载dbus-1.0.2和expat2.1.0源码包,并将他们分别释放到指定目录下,为后续编译作准备。为什么选择dbus-1.0.2呢?主要是这个版本能编译过去,其他高版本的各种依赖,懒得去尝试。
$ sudo mkdir -p /opt/expat
$ sudo mkdir -p /opt/dbus #在/opt目录下创建expat,dbus目录备用
$ mkdir dbus-arm #在当前目录下创建dbus-arm编译目录
$ cd dbus-arm
$ git clone https://github.com/libexpat/libexpat.git #克隆源代码
$ wget -c https://dbus.freedesktop.org/releases/dbus/dbus-1.0.2.tar.gz #下载dbus源码包
$ tar xzvf dbus-1.0.2.tar.gz #解压
$ ls
>>>>libexpat dbus-1.0.2.tar.gz dbus-1.0.2
- 编译安装expat
$ sudo apt-get install automake libtool
$ cd dbus-arm/libexpat/expat
$ ./buildconf.sh
$ ./configure --prefix=/opt/expat \
--host=arm-linux-gnueabi \
CC=/opt/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabi/bin/arm-linux-gnueabi-gcc \
CXX=/opt/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabi/bin/arm-linux-gnueabi-g++
$ sudo su #切换到root用户
root# make -j4
root# make install
- 编译安装D-Bus
$ cd dbus-arm/dbus-1.0.2
$ ./configure --prefix=/opt/dbus \
--host=arm-linux-gnueabi \
CC=/opt/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabi/bin/arm-linux-gnueabi-gcc \
CXX=/opt/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabi/bin/arm-linux-gnueabi-g++ \
CFLAGS=-I/opt/expat/include \
LDFLAGS=-L/opt/expat/lib \
--cache-file=arm-linux.cache --without-x
$ sudo su #切换到root用户
root# make -j4
root# make install
- 报错
1、checking abstract socket namespace… configure: error: cannot run test program while cross compiling See `config.log’ for more details.
在当前终端环境下,执行下面这两条命令,可以解决问题。
$ export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/opt/expat/lib/pkgconfig
$ echo ac_cv_have_abstract_sockets=yes>arm-linux.cache
2、Makefile:632: recipe for target ‘dbus-sysdeps-unix.lo’ failed
make3: *** [dbus-sysdeps-unix.lo] Error 1
dbus-sysdeps-unix.c 中找不到struct ucred,新内核的这个结构体被改掉了,所以要加入新kernel结构体。
dbus-1.0.2/dbus/dbus-sysdeps-unix.c
struct ucred
{
pid_t pid; /* 发送进程的进程标识 */
uid_t uid; /* 发送进程的用户标识 */
gid_t gid; /* 发送进程的组标识 */
};
把它放在dbus-sysdeps-unix.c文件中的位置如下:
#ifndef HAVE_SOCKLEN_T
#define socklen_t int
#endif
/*********/
struct ucred
{
pid_t pid; /* PID of sending process. */
uid_t uid; /* UID of sending process. */
gid_t gid; /* GID of sending process. */
};
/*********/
static dbus_bool_t
_dbus_open_socket (int *fd,
int domain,
移植D-Bus到arm40-a5
- 打包dbus文件
$ cd /opt
$ ls dbus
>>>>bin etc include lib man share var
$ ls expat
>>>>bin include lib share
$ tar cvf dbus-expat.tar dbus/ expat/ #将编译好的文件打包
$ls
>>>>dbus-expat.tar dbus expat #将dbus-expat.tar复制到目标板上
- 配置dbus到目标板
root@ARM40:# tar xvf dbus-expat.tar -C /opt #解压
root@ARM40:# ls /opt/
>>>>dbus expat
root@ARM40:# export PATH=$PATH:/opt/dbus/bin #创建环境变量
root@ARM40:# dbus-launch
>>>>DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-THBrzs3cqA,guid=df23c5155f3cbe9ce478b100000000fd
DBUS_SESSION_BUS_PID=1240
可以使用了,这里不再演示例程了,有点麻烦哦。
建议去看D-Bus的绑定,不要直接使用它。
引用网友"ty3219"的“dbus介绍与例子”里的话:
网上很多关于dbus的帖子都是基于dbus-glib或者QT D-bus的,直接使用dbus的教程比较少。也难怪,因为连D-bus的官网都说:“If you use this low-level API directly, you’re signing up for some pain.”