上一篇描述了移植了MQTT服务程序mosquitto到ARM linux的过程。本篇主要说明移植MQTT客户端程序paho.mqtt.embedded-c到ARM linux的过程。
eclipse paho是eclipse技术项目组针物联网应用开发的一个MQTT客户端开源项目,它包含多个语言版本,如java、C、C++、.Net、JavaScript等,paho.mqtt.embedded-c是针嵌入式产品特点而提供的开源库。
eclipse paho介绍
官方网站:http://www.eclipse.org/paho/
各版本提供的属性,如下图所示。
paho.mqtt.embedded-c移植参考文档
paho.mqtt.embedded-c移植步骤
一. 下载源码
下载链接:https://github.com/eclipse/paho.mqtt.embedded-c。本人选择的不是主线版本,而是release版本:paho.mqtt.embedded-c Version 1.1.0 (Paho 1.3)
二. 修改makefile
1、修改第70行CC ?=gcc为:
CC := arm-linux-gnueabihf-gcc
2、第43行SOURCE_FILES_C = $(srcdir)/*.c改为:
#SOURCE_FILES_C = $(srcdir)/*.c SOURCE_FILES_C = $(wildcard $(srcdir)/*.c ) OBJS = $(addsuffix .o,$(basename $(SOURCE_FILES_C)))
这个是把那个目录下的所有.c文件都编译进去,不然,后面引用这个库的时候会出错。
3、第95行rm -rf ${blddir}/* 改为:
clean: # rm -rf ${blddir}/* rm -rf ${blddir}/* $(OBJS) ${srcdir}/../samples/transport.o
4、第110行
${EMBED_MQTTLIB_C_TARGET}: ${SOURCE_FILES_C} ${HEADERS_C}
改为
${EMBED_MQTTLIB_C_TARGET}: $(OBJS) ${HEADERS_C}
第111行
${CC} ${CCFLAGS_SO} -o $@ ${SOURCE_FILES_C} ${LDFLAGS_C}
改为
${CC} ${CCFLAGS_SO} -o $@ $(OBJS) ${LDFLAGS_C}
这是把所有的.o文件都链接到动态库中。
不然,后面引用动态库的时候会报错误说缺少相关引用。
注意前面都有个tab键符
5、在121行install: build 下面添加:
-mkdir -p $(DESTDIR)${libdir} -mkdir -p $(DESTDIR)${includedir} cp -r $(HEADERS) $(DESTDIR)${includedir}
这是创建安装目录、复制头文件。
6、make
make会出错:
vmuser@ubuntu:~/armlinux/3_middleware/1_mqtt/client/paho.mqtt.embedded-c/paho.mqtt.embedded-c-1.1.0$ make CC=arm-linux-gnueabihf-gcc
mkdir -p build/output/samples
mkdir -p build/output/test
arm-linux-gnueabihf-gcc -c -o MQTTPacket/src/MQTTPacket.o MQTTPacket/src/MQTTPacket.c
arm-linux-gnueabihf-gcc -c -o MQTTPacket/src/MQTTUnsubscribeServer.o MQTTPacket/src/MQTTUnsubscribeServer.c
arm-linux-gnueabihf-gcc -c -o MQTTPacket/src/MQTTSerializePublish.o MQTTPacket/src/MQTTSerializePublish.c
arm-linux-gnueabihf-gcc -c -o MQTTPacket/src/MQTTFormat.o MQTTPacket/src/MQTTFormat.c
arm-linux-gnueabihf-gcc -c -o MQTTPacket/src/MQTTConnectServer.o MQTTPacket/src/MQTTConnectServer.c
arm-linux-gnueabihf-gcc -c -o MQTTPacket/src/MQTTSubscribeClient.o MQTTPacket/src/MQTTSubscribeClient.c
arm-linux-gnueabihf-gcc -c -o MQTTPacket/src/MQTTDeserializePublish.o MQTTPacket/src/MQTTDeserializePublish.c
arm-linux-gnueabihf-gcc -c -o MQTTPacket/src/MQTTUnsubscribeClient.o MQTTPacket/src/MQTTUnsubscribeClient.c
arm-linux-gnueabihf-gcc -c -o MQTTPacket/src/MQTTSubscribeServer.o MQTTPacket/src/MQTTSubscribeServer.c
arm-linux-gnueabihf-gcc -c -o MQTTPacket/src/MQTTConnectClient.o MQTTPacket/src/MQTTConnectClient.c
arm-linux-gnueabihf-gcc -fPIC -Os -Wall -fvisibility=hidden -DLINUX_SO -o build/output/libpaho-embed-mqtt3c.so.1.0 MQTTPacket/src/MQTTPacket.o MQTTPacket/src/MQTTUnsubscribeServer.o MQTTPacket/src/MQTTSerializePublish.o MQTTPacket/src/MQTTFormat.o MQTTPacket/src/MQTTConnectServer.o MQTTPacket/src/MQTTSubscribeClient.o MQTTPacket/src/MQTTDeserializePublish.o MQTTPacket/src/MQTTUnsubscribeClient.o MQTTPacket/src/MQTTSubscribeServer.o MQTTPacket/src/MQTTConnectClient.o -shared -Wl,-soname,libpaho-embed-mqtt3c.so.1
/home/vmuser/armlinux/1_tool/gcc-linaro-arm-linux-gnueabihf-4.9-2014.09_linux/bin/../lib/gcc/arm-linux-gnueabihf/4.9.2/../../../../arm-linux-gnueabihf/bin/ld: MQTTPacket/src/MQTTPacket.o: relocation R_ARM_THM_MOVW_ABS_NC against `a local symbol’ can not be used when making a shared object; recompile with -fPIC
MQTTPacket/src/MQTTPacket.o: error adding symbols: Bad value
collect2: error: ld returned 1 exit status
Makefile:118: recipe for target ‘build/output/libpaho-embed-mqtt3c.so.1.0’ failed
make: *** [build/output/libpaho-embed-mqtt3c.so.1.0] Error 1
vmuser@ubuntu:~/armlinux/3_middleware/1_mqtt/client/paho.mqtt.embedded-c/paho.mqtt.embedded-c-1.1.0$
这个错误是因为编译源文件时,未加入-fPIC编译选项导致的。
7、在${EMBED_MQTTLIB_C_TARGET}: $(OBJS) ${HEADERS_C} 上面添加编译目标:
# added by gyr 2019.03.14 # 此处必须添加,否则编译总是报错:relocation R_ARM_THM_MOVW_ABS_NC against `a local symbol' can not be used when making a shared object; recompile with -fPIC # 即:编译源文件时,需带 -fPIC # 参考文章:https://blog.csdn.net/test1280/article/details/81157767 .c.o: $(CC) $(CCFLAGS_SO) -o $@ -c $<
8、make clean后,重新make
vmuser@ubuntu:~/armlinux/3_middleware/1_mqtt/client/paho.mqtt.embedded-c/paho.mqtt.embedded-c-1.1.0$ make clean; make
rm -rf build/output/* MQTTPacket/src/MQTTPacket.o MQTTPacket/src/MQTTUnsubscribeServer.o MQTTPacket/src/MQTTSerializePublish.o MQTTPacket/src/MQTTFormat.o MQTTPacket/src/MQTTConnectServer.o MQTTPacket/src/MQTTSubscribeClient.o MQTTPacket/src/MQTTDeserializePublish.o MQTTPacket/src/MQTTUnsubscribeClient.o MQTTPacket/src/MQTTSubscribeServer.o MQTTPacket/src/MQTTConnectClient.o MQTTPacket/src/../samples/transport.o
mkdir -p build/output/samples
mkdir -p build/output/test
arm-linux-gnueabihf-gcc -g -fPIC -Os -Wall -fvisibility=hidden -DLINUX_SO -o MQTTPacket/src/MQTTPacket.o -c MQTTPacket/src/MQTTPacket.c
arm-linux-gnueabihf-gcc -g -fPIC -Os -Wall -fvisibility=hidden -DLINUX_SO -o MQTTPacket/src/MQTTUnsubscribeServer.o -c MQTTPacket/src/MQTTUnsubscribeServer.c
arm-linux-gnueabihf-gcc -g -fPIC -Os -Wall -fvisibility=hidden -DLINUX_SO -o MQTTPacket/src/MQTTSerializePublish.o -c MQTTPacket/src/MQTTSerializePublish.c
arm-linux-gnueabihf-gcc -g -fPIC -Os -Wall -fvisibility=hidden -DLINUX_SO -o MQTTPacket/src/MQTTFormat.o -c MQTTPacket/src/MQTTFormat.c
arm-linux-gnueabihf-gcc -g -fPIC -Os -Wall -fvisibility=hidden -DLINUX_SO -o MQTTPacket/src/MQTTConnectServer.o -c MQTTPacket/src/MQTTConnectServer.c
arm-linux-gnueabihf-gcc -g -fPIC -Os -Wall -fvisibility=hidden -DLINUX_SO -o MQTTPacket/src/MQTTSubscribeClient.o -c MQTTPacket/src/MQTTSubscribeClient.c
arm-linux-gnueabihf-gcc -g -fPIC -Os -Wall -fvisibility=hidden -DLINUX_SO -o MQTTPacket/src/MQTTDeserializePublish.o -c MQTTPacket/src/MQTTDeserializePublish.c
arm-linux-gnueabihf-gcc -g -fPIC -Os -Wall -fvisibility=hidden -DLINUX_SO -o MQTTPacket/src/MQTTUnsubscribeClient.o -c MQTTPacket/src/MQTTUnsubscribeClient.c
arm-linux-gnueabihf-gcc -g -fPIC -Os -Wall -fvisibility=hidden -DLINUX_SO -o MQTTPacket/src/MQTTSubscribeServer.o -c MQTTPacket/src/MQTTSubscribeServer.c
arm-linux-gnueabihf-gcc -g -fPIC -Os -Wall -fvisibility=hidden -DLINUX_SO -o MQTTPacket/src/MQTTConnectClient.o -c MQTTPacket/src/MQTTConnectClient.c
arm-linux-gnueabihf-gcc -g -fPIC -Os -Wall -fvisibility=hidden -DLINUX_SO -o build/output/libpaho-embed-mqtt3c.so.1.0 MQTTPacket/src/MQTTPacket.o MQTTPacket/src/MQTTUnsubscribeServer.o MQTTPacket/src/MQTTSerializePublish.o MQTTPacket/src/MQTTFormat.o MQTTPacket/src/MQTTConnectServer.o MQTTPacket/src/MQTTSubscribeClient.o MQTTPacket/src/MQTTDeserializePublish.o MQTTPacket/src/MQTTUnsubscribeClient.o MQTTPacket/src/MQTTSubscribeServer.o MQTTPacket/src/MQTTConnectClient.o -shared -Wl,-soname,libpaho-embed-mqtt3c.so.1
ln -s libpaho-embed-mqtt3c.so.1.0 build/output/libpaho-embed-mqtt3c.so.1
ln -s libpaho-embed-mqtt3c.so.1 build/output/libpaho-embed-mqtt3c.so
arm-linux-gnueabihf-gcc -g -fPIC -Os -Wall -fvisibility=hidden -DLINUX_SO -o MQTTPacket/src/../samples/transport.o -c MQTTPacket/src/../samples/transport.c
arm-linux-gnueabihf-gcc -o build/output/samples/pub0sub1 MQTTPacket/src/../samples/pub0sub1.c MQTTPacket/src/../samples/transport.o -lpaho-embed-mqtt3c -I MQTTPacket/src -L build/output
arm-linux-gnueabihf-gcc -o build/output/samples/qos0pub MQTTPacket/src/../samples/qos0pub.c MQTTPacket/src/../samples/transport.o -lpaho-embed-mqtt3c -I MQTTPacket/src -L build/output
arm-linux-gnueabihf-gcc -g -o build/output/test/test1 MQTTPacket/src/../test/test1.c -lpaho-embed-mqtt3c -I MQTTPacket/src -L build/output
vmuser@ubuntu:~/armlinux/3_middleware/1_mqtt/client/paho.mqtt.embedded-c/paho.mqtt.embedded-c-1.1.0$
9、make install
这里的make install,主要是提取可直接使用的库头文件和库文件,并不是把它安装到宿主机中。
a. 修改prefix为:
prefix = build/install/usr/local
b. 修改install: build,如下:
install: build -mkdir -p $(DESTDIR)${libdir} -mkdir -p $(DESTDIR)${includedir} cp -r $(HEADERS) $(DESTDIR)${includedir} $(INSTALL_DATA) ${INSTALL_OPTS} ${EMBED_MQTTLIB_C_TARGET} $(DESTDIR)${libdir}
c. 执行make install
可以直接使用的库位于:build/install/usr/local/,把其中include和lib拷贝到应用程序相应目录即可。
上图是库链接关系。
[…] 创建于 2015-01-31*/ var cpro_id = "u1932930"; » 上一篇: 移植paho.mqtt.embedded-c到嵌入式linux平台 » […]