移植MQTT到ubuntu和ARM开发板
1.ARM开发板的移植
安装openssl
<1>下载openssl:
首先需要移植openssl,因为编译mqtt时会用到openssl的lib库
官方下载网站:https://www.openssl.org/source/
<2>解压下载的安装包,进入解压后的文件夹:
tar -zxvf openssl-1.0.2l.tar.gz
cd openssl-1.0.2l/
<3>执行配置:
./config no-asm shared --prefix=$(pwd)/__install
no-asm:是在交叉编译过程中不使用汇编代码代码加速编译过程,因为它的汇编代码是对arm格式不支持的
shared :生成动态连接库
--prefix :指定make install后生成目录的路径,$(pwd)为当前文件夹
<4>修改Makefile文件:
CC=/(你的交叉编译工具链的路径)/arm-2009q3/bin/arm-none-linux-gnueabi-gcc
AR=/(你的交叉编译工具链的路径)/arm-2009q3/bin/arm-none-linux-gnueabi-ar $(ARFLAGS) r
ARFLAGS=
RANLIB=/(你的交叉编译工具链的路径)/arm-2009q3/bin/arm-none-linux-gnueabi-ranlib
(即将编译工具链更换成ARM开发板的交叉编译工具链)
CNF_CFLAGS=-pthread
CNF_CXXFLAGS=-std=c++11 -pthread
(即把标志位中的-m64去掉)
<5>编译安装:
make
make install
成功后,在<3>中prefix配置的的文件夹下会有_install的文件夹,其中include为头文件,lib为程序运行中用到的库
交叉编译mqtt
<1>下载mqtt:
源码下载:http://mosquitto.org/download/
<2>解压,进入文件夹:
tar -zxvf mosquitto-1.6.3.tar.gz
cd mosquitto-1.6.3/
<3>修改config.mk文件:
WITH_SRV:=no
WITH_WEBSOCKETS:=no
WITH_DOCS:=no
WITH_UUID:=no
CFLAGS += -l/(前边openssl安装的路径)/openssl-1.1.1c/__install/include/openssl
LDFLAGS += -L/(前边openssl安装的路径)/openssl-1.1.1c/__install/lib -lssl -lcrypto
STRIP?=/(你的交叉编译工具链的路径)/arm-2009q3/bin/arm-none-linux-gnueabi-strip
(CFLAGS和LDFLAGS分别为前边安装openssl中最后一步提到的,include中的头文件路径和lib库的路径)
<4>编译,安装
make CC=/(你的交叉编译工具链的路径)/arm-2009q3/bin/arm-none-linux-gnueabi-gcc CXX=/(你的交叉编译工具链的路径)/arm-2009q3/bin/arm-none-linux-gnueabi-g++
make install
执行成功后,就可以在/usr/local/lib中发现编译好的文件:libmosquitto.so.1,或在client文件夹中有mqtt发布订阅的例程程序,src文件夹中有mqtt的代理broker的例程程序,lib中有库文件libmosquitto.so.1
在make编译时,有报错:../config.h:45: fatal error: openssl/opensslconf.h: No such file or directory,但是到openssl安装好的openssl-1.1.1c/__install/include/openssl中,发现是有这个文件的,原因是由于头文件和此处执行的程序不在一个文件夹内,导致程序中找不到头文件。所以将安装openssl的include中的头文件以及lib库文件,复制到当前文件夹下,就可以正常编译了。
2.ubuntu的安装:
<1>按上述步骤灵活的将openssl和mqtt安装好,同样使用上述的安装包:
在安装openssl时,不需要对Makefile文件做任何修改;
安装mqtt时,只需要对config.mk文件中的CFLAGS和LDFLAGS做修改,其他都不需要修改;
最后再编译的时候,直接make即可,不需要指定编译工具链。
执行成功后,在client文件夹中有mqtt发布订阅的例程程序,src文件夹中有mqtt的代理broker的例程程序,lib中有库文件libmosquitto.so.1
<2>在ubuntu上测试mqtt的例程:
在一个终端中启动mosquitto服务器(在mosquitto-1.6.3/src文件夹中):
./mosquitto -v
在另一个终端中订阅消息(如topic)(在client文件夹中,192.168.10.222为服务器IP地址):
./mosquitto_sub -h 192.168.10.222 -v -t topic
在第三个终端中发布消息,主题为topic,内容为good(在client文件夹中,192.168.10.222为服务器IP地址):
./mosquitto_pub -h 192.168.10.222 -p 1883 -t topic -m good
或者
mosquitto_pub -d -h "192.168.10.222" -t "v1/devices/me/telemetry" -u "ACCESS_TOKEN" -f "data.json"
-t:发布或者定义的主题
-m:要发布的消息
-f:要发布的文件
-h:服务器IP地址
-p:服务器端口号
就可以在订阅消息的终端中,看到发布的消息:主题为topic,内容为good或者文件data.json中的内容
<3>若上述过程出现错误,如下:
./mosquitto_sub: error while loading shared libraries: libmosquitto.so.1: cannot open shared object file: No such file or directory
./mosquitto_sub: error while loading shared libraries: libssl.so.1.1: cannot open shared object file: No such file or directory
./mosquitto_sub: error while loading shared libraries: libcrypto.so.1.1: cannot open shared object file: No such file or directory
这是因为程序找不到库文件的位置,可以参考下一个步骤中的做法,或者修改环境变量,在~/.bashrc文件中添加下句,然后执行
source ~/.bashrc:
export LD_LIBRARY_PATH=~/MQTT_ubuntu/mosquitto-1.6.3/lib:~/MQTT_ubuntu/mosquitto-1.6.3/openssl/lib
冒号前为libmosquitto.so.1库所在的位置,冒号后为libssl.so.1.1和libcrypto.so.1.1库所在的位置
3.在ARM开发板中测试mqtt的例程:
将第1步中,交叉编译 之后的openssl安装的文件夹_install下的include文件夹以及lib文件夹,mqtt交叉编译 之后mosquitto安装的文件夹中的client、lib、src文件夹拷贝到ARM开发板中。
首先要保证ubuntu和arm开发板之间能够ping通。
在ubuntu中执行2.2中启动mosquitto服务器,以及mosquitto_sub订阅消息的程序命令,在ARM开发板中执行mosquitto_pub发布消息的程序,就可以看到2.2中一样的效果
可能也会出现上述2.3的错误,这种情况下需要将libmosquitto.so.1、libssl.so.1.1、libcrypto.so.1.1拷贝到开发板中/usr/lib文件夹下,因为程序执行会先默认到环境变量的文件路径中寻找,而/usr/lib即为环境变量中的一个文件路径。