当前位置: 首页 > news >正文

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

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

在这里插入图片描述

【 所有文章汇总】

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

相关文章:

  • TC8:SOMEIPSRV_FORMAT_01-10
  • 软考:信息安全工程师3
  • 接口(续)和Object类
  • 构造接口,免费查询快递物流
  • 被裁后一个offer都没有,测试人的问题在哪里?
  • 图像运算和图像增强一
  • 【C++】unordered map/set
  • 定时任务框架
  • C型9.4MM针脚距电磁阀插头
  • 【算法 | 实验8】分配最小页数(数组划分和最大值最小化问题)
  • rsync远程同步+inotify监控
  • 学会这个Python技能,就可以跟excel说再见了
  • 【漏洞复现-showdoc-文件上传】​vulfocus/showdoc-cnvd_2020_26585
  • 改进YOLOv7系列:首发结合最新Transformer视觉模型MOAT结构:交替移动卷积和注意力带来强大的Transformer视觉模型,超强的提升
  • 【jQuery案例】手风琴
  • 收藏网友的 源程序下载网
  • Angular数据绑定机制
  • Babel配置的不完全指南
  • HomeBrew常规使用教程
  • MD5加密原理解析及OC版原理实现
  • mysql外键的使用
  • node.js
  • 初识MongoDB分片
  • 从重复到重用
  • 第2章 网络文档
  • 使用Gradle第一次构建Java程序
  • 数据可视化之 Sankey 桑基图的实现
  • 微信小程序--------语音识别(前端自己也能玩)
  • 鱼骨图 - 如何绘制?
  • LevelDB 入门 —— 全面了解 LevelDB 的功能特性
  • 国内开源镜像站点
  • ###项目技术发展史
  • #100天计划# 2013年9月29日
  • #NOIP 2014# day.2 T2 寻找道路
  • %3cscript放入php,跟bWAPP学WEB安全(PHP代码)--XSS跨站脚本攻击
  • (10)ATF MMU转换表
  • (4)STL算法之比较
  • (C++)八皇后问题
  • (day 2)JavaScript学习笔记(基础之变量、常量和注释)
  • (三)docker:Dockerfile构建容器运行jar包
  • (转)Linux NTP配置详解 (Network Time Protocol)
  • (转)编辑寄语:因为爱心,所以美丽
  • .bat批处理(十一):替换字符串中包含百分号%的子串
  • .chm格式文件如何阅读
  • .net 按比例显示图片的缩略图
  • .net(C#)中String.Format如何使用
  • .net开源工作流引擎ccflow表单数据返回值Pop分组模式和表格模式对比
  • .NET项目中存在多个web.config文件时的加载顺序
  • /etc/motd and /etc/issue
  • @Data注解的作用
  • @ModelAttribute使用详解
  • [20140403]查询是否产生日志
  • [C++] cout、wcout无法正常输出中文字符问题的深入调查(1):各种编译器测试
  • [C++] 多线程编程-thread::yield()-sleep_for()
  • [echarts] y轴不显示0