本文參考https://blog.csdn.net/sqshining/article/details/70193354
參考上述連接配接進行自己的ARM9開發闆上實作paho.mqtt.embedded-c庫的編譯,實作測試例程在周立功的i-mx287A開發闆上正常運作,在交叉編譯mqtt庫期間遇到一些坑,在此記錄并說明一番,給自己的學習之路添加一些墊腳石,也希望能對後來人一點啟發提示。
一、首先編譯MQTT協定包封裝庫:
項目mqtt源碼包可以在如下連結下載下傳
git clone https://github.com/eclipse/paho.mqtt.embedded-c.git
解壓paho.mqtt.embedded-c-master.zip之後,進入目錄,
修改Makefile:
1、修改第70行CC ?=gcc為:
CC ?=arm-linux-gcc
2、第43行SOURCE_FILES_C = $(srcdir)/*.c改為:
SOURCE_FILES_C = $(wildcard $(srcdir)/*.c )
OBJS = $(addsuffix .o,$(basename $(SOURCE_FILES_C)))
這個是把那個目錄下的所有.c檔案都編譯進去,不然,後面引用這個庫的時候會出錯。
3、第95行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鍵符
4、在121行install: build 下面添加:
-mkdir -p $(DESTDIR)${libdir}
-mkdir -p $(DESTDIR)${includedir}
cp -r $(HEADERS) $(DESTDIR)${includedir}
這是建立安裝目錄、複制頭檔案。
5、
make
編譯好後:
編譯結果你可以看到用的指定的編譯工具并不是arm-linux-gcc,仔細看了Makefile才知道,
有個系統參數需要再make後面添加。
執行如下make指令,編譯出來的庫就是能在arm闆上調用的庫檔案:
make CC=arm-linux-gcc
編譯結果如下圖:
6、下面進行庫在本機的安裝:
make install DESTDIR=/usr/local/arm/paho.mqtt.embedded-c prefix=
這裡指定prefix(字首)為空。,不然安裝的時候,會在我們指定的目錄後加入usr/local這個子路徑。
安裝好後可以在安裝目錄下檢視到安裝的庫的頭檔案和庫檔案
就安裝到了主機的/usr/local/arm/paho.mqtt.embedded-c目錄下了,這個目錄下有兩個子目錄:
1)、include,這個在我們編譯自己的程式的時候需要用到;
2)、lib子目錄:
注意,如果庫檔案夾中的軟連接配接不全,需要手動補齊
這個是我們編譯自己的程式需要連結的動态庫,照例,把它複制到arm闆的檔案系統的/usr/lib中。
二、嘗試編譯client和樣例程式:
1、進入MQTTClient-C/samples目錄,把linux子目錄複制一份命名為mx287
cp -r linux mx287
進入mx287目錄,編輯build.sh
把裡面的内容都删掉,改為:
cp ../../src/MQTTClient.c .
cp ../../src/linux/MQTTLinux.c .
cp ../../src/linux/MQTTLinux.h .
sed '/^#include "MQTTPacket.h"/i\\#include "MQTTLinux.h"' ../../src/MQTTClient.h > MQTTClient.h
make
sed ‘/^#include “MQTTPacket.h”/i\#include “MQTTLinux.h”’ ../../src/MQTTClient.h > MQTTClient.h
這句的意思是讀入../../src/MQTTClient.h 檔案,然後搜#include “MQTTPacket.h”,然後在它的下一行插入#include “MQTTLinux.h”
然後把所有内容寫入MQTTClient.h儲存在目前目錄。
因為要引用後面那個頭檔案,不加入,會出錯。
下面來寫一個Makefile,内容如下:
TOPDIR = ../..
CC=arm-linux-gcc
INCDIR :=-I /usr/local/arm/paho.mqtt.embedded-c/include
COMPILE.c= $(CC) $(CFLAGS) $(INCDIR) -MMD -c
LINK.c= $(CC) $(LDFLAGS) -lpthread -lrt
.PHONY: all
%.o:%.c
$(COMPILE.c) $< -o $@
SRC_FILE := \
MQTTClient.c \
MQTTLinux.c \
stdoutsub.c
OBJS := $(addsuffix .o, $(basename $(SRC_FILE)))
DEPS :=$(OBJS:.o=.d)
all:mqtt
mqtt:$(OBJS)
$(LINK.c) $(OBJS) -lpaho-embed-mqtt3c -L /usr/local/arm/paho.mqtt.embedded-c/lib -o $@
cp $@ /home/nfs/share/src/c_project/embed_mqtt_test
clean:
rm -f $(OBJS) mqtt
distclean:clean
rm -f $(DEPS)
-include $(DEPS)
2、然後修改stdoutsub.c。
第213行 Client c;改為:
MQTTClient c;
第218行NewNetwork(&n);改為:
NetworkInit(&n);
第219行ConnectNetwork(&n, opts.host, opts.port);改為:
NetworkConnect(&n, opts.host, opts.port);
第220行MQTTClient(&c, &n, 1000, buf, 100, readbuf, 100);改為:
MQTTClientInit(&c, &n, 1000, buf, 100, readbuf, 100);
第248行n.disconnect(&n);改為:
NetworkDisconnect(&n);
然後儲存、退出,執行腳本:
./build.sh
這個腳本隻需要執行一次,後面可以使用make來編譯了。
結果如下:
已經編譯好,并拷貝到arm闆的/usr/my目錄中了,可執行檔案名字叫mqtt。
此mqtt運作隻有訂閱功能,mqtt用戶端連接配接mqtt伺服器的client參數在stdoutsub.c檔案中的91行的opts參數中修改你自己的測試伺服器。修改儲存退出後重新運作make,生成的檔案就是可以連接配接到你自己的mqtt伺服器的程式,運作如下:
至此,基于i-mx287a的paho.mqtt.embedded-c庫的編譯移植和測試告一段落,接下來可以結合mqtt例程實作遠端控制硬體接口的一些應用的開發,比如遠端開關闆子上的燈,闆子連接配接傳感器采集某些資料傳輸給遠端伺服器或者管理平台等待,展開你的想象,去實作這些好玩的功能吧,再會。。。。。。