【Bluetooth|蓝牙开发】十一、一文秒懂 | 超详细的Bluez交叉编译

img
个人主页:董哥聊技术
我是董哥,嵌入式领域新星创作者
创作理念:专注分享高质量嵌入式文章,让大家读有所得!
img

【Bluetooth|蓝牙开发】十一、一文秒懂 | 超详细的Bluez交叉编译_第1张图片

【 所有文章汇总】

1、 前言

前面几篇文章,主要讲解了蓝牙协议栈层面的内容,本篇来从源码层面来分析!

蓝牙协议栈,如何在代码层面将其落地?用的最多的就是开源的Bluez所实现的蓝牙协议栈了!

Bluez官网:http://www.bluez.org/

Bluez的交叉编译较为复杂,其依赖的文件之多,不失为一个练习交叉编译的好机会!

本文我们旨在研究交叉编译的手法,以一敌百,了解交叉编译的底层方法。

最后,文末也描述一种简单的编译方法,仅供了解。

 

2、安装包下载

前往Bluez官网,下载Bluez源码包

目前最新的是Bluez5.6.5版本,以该版本为案例进行分析。

wget http://www.kernel.org/pub/linux/bluetooth/bluez-5.65.tar.xz		# 下载Bluez
tar -xvf bluez-5.65.tar.xz			# 解压bluez
cd bluez-5.64/						# 进入目录	

 

3、Bluez安装概览

首先,我们进入到bluez-5.65后,查看README文件,我们可以看到其依赖项:

In order to compile Bluetooth utilities you need following software packages:

  • GCC compiler
  • GLib library
  • D-Bus library
  • udev library (optional)
  • readline (command line clients)

由上可知,欲安装Bluez,需要对其依赖项进行逐一安装,下面我们依次进行安装!

 

4、安装步骤

mkdir bluez_output
cd bluez_output
export bluez_output=/home/dong/WorkSpace/Program/BlueZ/bluez_output		#设置环境变量

GCC交叉编译器,我们就直接忽略了哈……

 

4.1 GLib

GLib 是一个通用的、可移植的实用程序库,它提供了许多有用的数据类型、宏、类型转换、字符串实用程序、文件实用程序、主循环抽象等。

GLib官网:https://docs.gtk.org/glib

GLib下载地址:Gitlab下载、站点下载

我们下载的是glib-2.46.2.tar.gz

新版本的GLib需要Meson工具编译,因此我们这里使用2.46.2版本的,可以通过cmake编译

wget https://download.gnome.org/sources/glib/2.46/glib-2.46.2.tar.xz	#下载GLib
tar -xvf glib-2.46.2.tar.xz 			# 解压
cd glib-2.46.2/							# 进入目录

 

然后手动创建arm-linux.cache文件,手动写入下面内容:

touch arm-linux.cache		# 创建文件, 添加下面内容

glib_cv_long_long_format=ll

glib_cv_stack_grows=no

glib_cv_working_bcopy=no

glib_cv_sane_realloc=yes

glib_cv_have_strlcpy=no

glib_cv_va_val_copy=yes

glib_cv_rtldglobal_broken=no

glib_cv_uscore=no

ac_cv_func_posix_getpwuid_r=yes

ac_cv_func_nonposix_getpwuid_r=no

ac_cv_func_posix_getgrgid_r=no

glib_cv_use_pid_surrogate=no

ac_cv_func_printf_unix98=no

ac_cv_func_vsnprintf_c99=no

ac_cv_path_GLIB_COMPILE_SCHEMAS=yes

 

然后接着执行下面命令

./configure --prefix=$bluez_output CC="arm-linux-gnueabihf-gcc -I$bluez_output/include -L$bluez_output/lib" --host=arm-linux-gnueabihf --cache-file=arm-linux.cache
make -j8
make install

 

如果报错:error: format not a string literal, format string not checked

可以看下面两篇文章,有解决方案

https://www.cnblogs.com/yuandaozhe/p/14365389.html

https://blog.csdn.net/wwwyue1985/article/details/113359706

如果报错:fatal error: ffi.h: No such file or directory

表明了GLib仍需要依赖libffi库,我们需要提前安装Libffi

 

4.1.1 libffi

libffi是可移植外部函数接口库,是构建GLib的先决条件。它是一个接口,允许用一种语言编写的代码调用用另一种语言编写的代码。

libffi下载路径:https://github.com/libffi/libffi/releases/

libffi下载版本:libffi-3.4.2.tar.gz

 

手动下载后,执行下面命令

tar -zxvf libffi-3.4.3.tar.gz		# 解压
cd libffi-3.4.3/					# 切换目录
./configure --prefix=$bluez_output CC="arm-linux-gnueabihf-gcc -I$bluez_output/include -L$bluez_output/lib" --host=arm-linux-gnueabihf
make -j8
make install

安装完libffi后,再次回到GLib进行安装,可见报错:fatal error: zlib.h: No such file or directory

说明GLib仍然依赖zlib库,需要安装zlib

4.1.2 zlib

zlib是一个压缩库,是构建GLib的先决条件。

zlib下载地址:http://zlib.net/zlib-1.2.12.tar.gz

zlib下载版本:zlib-1.2.12.tar.gz

 

手动下载后,执行下面命令

tar -zxvf zlib-1.2.12.tar.gz
cd zlib-1.2.12/
./configure --prefix=$bluez_output --includedir=$bluez_output/include --libdir=$bluez_output/lib

#vim Makefile 将CC变量改为自己的交叉编译器arm-linux-gnueabihf-gcc
CC=arm-linux-gnueabihf-gcc
LDSHARED=arm-linux-gnueabihf-gcc -shared -Wl,-soname,libz.so.1,--version-script,zlib.map
CPP=arm-linux-gnueabihf-gcc -E
AR=arm-linux-gnueabihf-ar
RANLIB=arm-linux-gnueabihf-ranlib

make -j8
make install

安装完zlib后,再回头安装Glib,即可完毕!

 

4.2 D-Bus

D-Bus是一个用于进程间通信和协调的简单系统。

D-Bus下载目录:https://dbus.freedesktop.org/releases/dbus/

D-Bus下载版本:dbus-1.15.0.tar.xz

 

wget https://dbus.freedesktop.org/releases/dbus/dbus-1.15.0.tar.xz	# 下载
tar -xvf dbus-1.15.0.tar.xz				# 解压
cd dbus-1.15.0/							# 切换目录

_____________________________________________________________	# 先看下文

./configure --prefix=$bluez_output CC="arm-linux-gnueabihf-gcc -I$bluez_output/include -L$bluez_output/lib" --host=arm-linux-gnueabihf --enable-selinux=no --without-x	# 生成Makefile
make -j8								# 编译
make install							# 安装到对应目录

我们先不着急安装,查看一下READMEINSTALL文件,发现D-bus的安装,必须依赖Expat库!

当然如果你直接安装,它也肯定会报错的,因为缺少所依赖的库!

Requisite:

  • Gettext
  • expat

Optional:

  • libselinux (for SELinux integration)
  • doxygen (for API documentation)
  • xmlto or meinproc4 (for Spec & other XML documentation)

下面我们来安装Expat库!

 

4.2.1 Expat

Expat是一个用C编写的XML解析器库,是D-Bus守护进程所需的惟一依赖项。

Expat下载路径:https://libexpat.github.io/,https://github.com/libexpat/libexpat/releases

Expat下载版本:expat-2.4.9.tar.xz

 

tar -zvf expat-2.4.9.tar.gz
cd expat-2.4.9/
./configure --prefix=$bluez_output CC="arm-linux-gnueabihf-gcc -I$bluez_output/include -L$bluez_output/lib" --host=arm-linux-gnueabihf 
make -j8
make install

此时,会在$bluez_output目录下,看到安装后所生成的libinclude的一些文件

--enable-selinux=no --without-x 是一些配置信息,不适用selinuxx11支持,否则可能会报错!

安装完expat库后,我们回头安装D-bus

 

4.3 readline

Readline库提供了一组供应用程序使用的函数,并且允许用户在输入命令行时编辑它们。

下载地址:http://git.savannah.gnu.org/cgit/readline.git?h=devel

下载版本readline-8.2.tar.gz

wget http://git.savannah.gnu.org/cgit/readline.git/snapshot/readline-8.2.tar.gz
tar -xvf readline-8.2.tar.gz
cd readline-8.2/
./configure --prefix=$bluez_output CC="arm-linux-gnueabihf-gcc -I$bluez_output/include -L$bluez_output/lib" --host=arm-linux-gnueabihf bash_cv_wcwidth_broken=yes
make -j8
make install

 

4.4 Bluez

安装完之后,我们就来安装最后的大Boss——``Bulez`

cd bluez-5.65/
mkdir output
./configure --prefix=$bluez_output CC="arm-linux-gnueabihf-gcc -I$bluez_output/include -L$bluez_output/lib" PKG_CONFIG_PATH=$bluez_output/lib/pkgconfig --host=arm-linux-gnueabihf --disable-systemd --disable-udev --disable-cups --disable-obex --enable-library 
make SHLIB_LIBS=-lncurses -j8
make install

 

如果报类似以下错误

collect2: error: ld returned 1 exit status
make[1]: *** [Makefile:5503: monitor/btmon] Error 1
/home/dong/WorkSpace/Program/BlueZ/bluez_output/lib/libreadline.so: undefined reference to `tputs'
/home/dong/WorkSpace/Program/BlueZ/bluez_output/lib/libreadline.so: undefined reference to `tgoto'
/home/dong/WorkSpace/Program/BlueZ/bluez_output/lib/libreadline.so: undefined reference to `tgetflag'
/home/dong/WorkSpace/Program/BlueZ/bluez_output/lib/libreadline.so: undefined reference to `UP'
/home/dong/WorkSpace/Program/BlueZ/bluez_output/lib/libreadline.so: undefined reference to `tgetent'
/home/dong/WorkSpace/Program/BlueZ/bluez_output/lib/libreadline.so: undefined reference to `tgetnum'
/home/dong/WorkSpace/Program/BlueZ/bluez_output/lib/libreadline.so: undefined reference to `PC'
/home/dong/WorkSpace/Program/BlueZ/bluez_output/lib/libreadline.so: undefined reference to `tgetstr'
/home/dong/WorkSpace/Program/BlueZ/bluez_output/lib/libreadline.so: undefined reference to `BC'

单看Log,肯定是readline库中缺少一些东西,这些东西就是缺少了ncurses库所导致的!

 

4.4.1 ncurses

ncursesreadline所依赖的一个库

下载地址:http://ftp.gnu.org/pub/gnu/ncurses

下载版本:ncurses-6.3.tar.gz

wget https://ftp.gnu.org/pub/gnu/ncurses/ncurses-6.3.tar.gz
tar -zxvf ncurses-6.3.tar.gz 
cd ncurses-6.3/
./configure --prefix=$bluez_output CC="arm-linux-gnueabihf-gcc -I$bluez_output/include -L$bluez_output/lib"  CXX="arm-linux-gnueabihf-g++" --host=arm-linux-gnueabihf --without-cxx --without-cxx-binding --without-ada --without-manpages --enable-overwrite --without-debug --without-tests --with-shared --without-tests --without-progs
make -j8
make install

安装完ncurse后,我们再次安装readline,需要包含ncurse库!

 

4.4.2 readline

cd readline-8.2/
./configure --prefix=$bluez_output CC="arm-linux-gnueabihf-gcc -I$bluez_output/include -L$bluez_output/lib" --host=arm-linux-gnueabihf bash_cv_wcwidth_broken=yes
make SHLIB_LIBS=-lncurses -j8
make install

 

4.4.3 bluez

ncurses安装后,再次回到bluez,执行安装步骤,并且引入ncurses库!

cd bluez-5.65/
mkdir output
./configure --prefix=$bluez_output CC="arm-linux-gnueabihf-gcc -I$bluez_output/include -L$bluez_output/lib -lncurses" PKG_CONFIG_PATH=$bluez_output/lib/pkgconfig --host=arm-linux-gnueabihf --disable-systemd --disable-udev --disable-cups --disable-obex --enable-library
make -j8
make install

至此,Bluez交叉编译结束!

 


简单一点的方法是什么?

就是通过构建工具来编译,直接通过类似于buildroot等类似的构建工具,直接选中bluez的外部包,直接编译也可以的:)

img
img

你可能感兴趣的:(匠心之作,蓝牙开发详解,linux,嵌入式硬件,iot,bluetooth,物联网)