paho.mqtt.embedded-c移植QT工程

发布时间:2023年12月22日

参考文章:http://velep.com/archives/1438.html

一.下载地址

https://github.com/eclipse/paho.mqtt.embedded-c

二.修改Makefile

1、第70行CC ?=gcc修改为自己的交叉编译器,使用echo $CC查看,
可以不做修改,make时自动会替换
在这里插入图片描述

CC := 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}
	${CC} ${CCFLAGS_SO} -o $@ ${SOURCE_FILES_C} ${LDFLAGS_C}

改为

.c.o:
	$(CC) $(CCFLAGS_SO) -o $@ -c $<
${EMBED_MQTTLIB_C_TARGET}: $(OBJS) ${HEADERS_C}
	${CC} ${CCFLAGS_SO} -o $@ $(OBJS) ${LDFLAGS_C}

这是把所有的.o文件都链接到动态库中。不然,后面引用动态库的时候会报错误说缺少相关引用,注意前面都有个tab键符

5、在121行install: build 下面添加:

install: build 
	$(INSTALL_DATA) ${INSTALL_OPTS} ${EMBED_MQTTLIB_C_TARGET} $(DESTDIR)${libdir}


	/sbin/ldconfig $(DESTDIR)${libdir}
	ln -s lib$(MQTT_EMBED_LIB_C).so.${MAJOR_VERSION} $(DESTDIR)${libdir}/lib$(MQTT_EMBED_LIB_C).so

改为

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}

6.第32行编译路径修改

prefix = /usr/local

改为

prefix = build/install/usr/local

最后修改好的Makefile如下:

#*******************************************************************************
#  Copyright (c) 2009, 2014 IBM Corp.
# 
#  All rights reserved. This program and the accompanying materials
#  are made available under the terms of the Eclipse Public License v1.0
#  and Eclipse Distribution License v1.0 which accompany this distribution. 
# 
#  The Eclipse Public License is available at 
#     http://www.eclipse.org/legal/epl-v10.html
#  and the Eclipse Distribution License is available at 
#    http://www.eclipse.org/org/documents/edl-v10.php.
# 
#  Contributors:
#     Xiang Rong - 442039 Add makefile to Embedded C client
#*******************************************************************************/

# Note: on OS X you should install XCode and the associated command-line tools

SHELL = /bin/sh
.PHONY: clean, mkdir, install, uninstall, html 

# assume this is normally run in the main Paho directory
ifndef srcdir
  srcdir = MQTTPacket/src
endif

ifndef blddir
  blddir = build/output
endif

ifndef prefix
	# prefix = /usr/local
	prefix = build/install/usr/local
endif

ifndef exec_prefix
	exec_prefix = ${prefix}
endif

bindir = $(exec_prefix)/bin
includedir = $(prefix)/include
libdir = $(exec_prefix)/lib
#原文件路径以及编译obj
# SOURCE_FILES_C = $(srcdir)/*.c
SOURCE_FILES_C = $(wildcard $(srcdir)/*.c )
OBJS = $(addsuffix .o,$(basename $(SOURCE_FILES_C)))


HEADERS = $(srcdir)/*.h


SAMPLE_FILES_C = pub0sub1 qos0pub
SYNC_SAMPLES = ${addprefix ${blddir}/samples/,${SAMPLE_FILES_C}}


TEST_FILES_C = test1
SYNC_TESTS = ${addprefix ${blddir}/test/,${TEST_FILES_C}}


# The names of libraries to be built
MQTT_EMBED_LIB_C = paho-embed-mqtt3c


# determine current platform
ifeq ($(OS),Windows_NT)
	OSTYPE = $(OS)
else
	OSTYPE = $(shell uname -s)
	MACHINETYPE = $(shell uname -m)
endif

ifeq ($(OSTYPE),Linux)

# 交叉编译器 使用 echo $CC 查看
CC ?= gcc

ifndef INSTALL
INSTALL = install
endif
INSTALL_PROGRAM = $(INSTALL)
INSTALL_DATA =  $(INSTALL) -m 644

MAJOR_VERSION = 1
MINOR_VERSION = 0
VERSION = ${MAJOR_VERSION}.${MINOR_VERSION}

EMBED_MQTTLIB_C_TARGET = ${blddir}/lib${MQTT_EMBED_LIB_C}.so.${VERSION}


CCFLAGS_SO = -g -fPIC -Os -Wall -fvisibility=hidden -DLINUX_SO
FLAGS_EXE = -I ${srcdir}  -L ${blddir}

LDFLAGS_C = -shared -Wl,-soname,lib$(MQTT_EMBED_LIB_C).so.${MAJOR_VERSION}

all: build
	
build: | mkdir ${EMBED_MQTTLIB_C_TARGET} ${SYNC_SAMPLES} ${SYNC_TESTS}
# 删除中间文件
clean:
	# rm -rf ${blddir}/*
	rm -rf ${blddir}/* $(OBJS) ${srcdir}/../samples/transport.o

mkdir:
	-mkdir -p ${blddir}/samples
	-mkdir -p ${blddir}/test

${SYNC_TESTS}: ${blddir}/test/%: ${srcdir}/../test/%.c
	${CC} -g -o ${blddir}/test/${basename ${+F}} $< -l${MQTT_EMBED_LIB_C} ${FLAGS_EXE}


${SYNC_SAMPLES}: ${blddir}/samples/%: ${srcdir}/../samples/%.c ${srcdir}/../samples/transport.o
	${CC} -o $@ $^ -l${MQTT_EMBED_LIB_C} ${FLAGS_EXE}

# 编译.c.o
# ${EMBED_MQTTLIB_C_TARGET}: ${SOURCE_FILES_C} ${HEADERS_C}
#	${CC} ${CCFLAGS_SO} -o $@ ${SOURCE_FILES_C} ${LDFLAGS_C}
.c.o:
	$(CC) $(CCFLAGS_SO) -o $@ -c $<

${EMBED_MQTTLIB_C_TARGET}: $(OBJS) ${HEADERS_C}
	${CC} ${CCFLAGS_SO} -o $@ $(OBJS) ${LDFLAGS_C}
	-ln -s lib$(MQTT_EMBED_LIB_C).so.${VERSION}  ${blddir}/lib$(MQTT_EMBED_LIB_C).so.${MAJOR_VERSION}
	-ln -s lib$(MQTT_EMBED_LIB_C).so.${MAJOR_VERSION} ${blddir}/lib$(MQTT_EMBED_LIB_C).so


strip_options:
	$(eval INSTALL_OPTS := -s)

install-strip: build strip_options install

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}
#	/sbin/ldconfig $(DESTDIR)${libdir}
#	ln -s lib$(MQTT_EMBED_LIB_C).so.${MAJOR_VERSION} $(DESTDIR)${libdir}/lib$(MQTT_EMBED_LIB_C).so


uninstall:
	rm $(DESTDIR)${libdir}/lib$(MQTT_EMBED_LIB_C).so.${VERSION}

	/sbin/ldconfig $(DESTDIR)${libdir}
	rm $(DESTDIR)${libdir}/lib$(MQTT_EMBED_LIB_C).so


html:

ARDUINO_LIB_FILES = MQTTClient/src/*.h MQTTClient/src/arduino/*.h $(srcdir)/*
ARDUINO_SAMPLES = MQTTClient/samples/arduino/*
LEGAL_FILES = edl-v10 epl-v10 notice.html about.html CONTRIBUTING.md README.md library.properties

arduino: mkdir
	-mkdir -p ${blddir}/arduino/MQTTClient/examples
	-mkdir -p ${blddir}/arduino/MQTTClient/src
	cp $(ARDUINO_LIB_FILES) ${blddir}/arduino/MQTTClient/src
	cp $(LEGAL_FILES) ${blddir}/arduino/MQTTClient
	cp -R $(ARDUINO_SAMPLES) ${blddir}/arduino/MQTTClient/examples
	cd ${blddir}/arduino && zip -r arduino MQTTClient

endif



ifeq ($(OSTYPE),Darwin)

CC ?= gcc

ifndef INSTALL
INSTALL = install
endif
INSTALL_PROGRAM = $(INSTALL)
INSTALL_DATA =  $(INSTALL) -m 644

MAJOR_VERSION = 1
MINOR_VERSION = 0
VERSION = ${MAJOR_VERSION}.${MINOR_VERSION}

EMBED_MQTTLIB_C_TARGET = ${blddir}/lib${MQTT_EMBED_LIB_C}.so.${VERSION}


CCFLAGS_SO = -g -fPIC -Os -Wall -fvisibility=hidden -Wno-deprecated-declarations -DUSE_NAMED_SEMAPHORES
FLAGS_EXE = -I ${srcdir}  -L ${blddir}

LDFLAGS_C = -shared -Wl,-install_name,lib$(MQTT_EMBED_LIB_C).so.${MAJOR_VERSION}

all: build
	
build: | mkdir ${EMBED_MQTTLIB_C_TARGET} ${SYNC_SAMPLES} ${SYNC_TESTS}

clean:
	rm -rf ${blddir}/*
	
mkdir:
	-mkdir -p ${blddir}/samples
	-mkdir -p ${blddir}/test

${SYNC_TESTS}: ${blddir}/test/%: ${srcdir}/../test/%.c
	${CC} -g -o ${blddir}/test/${basename ${+F}} $< -l${MQTT_EMBED_LIB_C} ${FLAGS_EXE}

${SYNC_SAMPLES}: ${blddir}/samples/%: ${srcdir}/../samples/%.c
	${CC} -o ${blddir}/samples/${basename ${+F}} $< ${FLAGS_EXE} -l${MQTT_EMBED_LIB_C} 

${EMBED_MQTTLIB_C_TARGET}: ${SOURCE_FILES_C} ${HEADERS_C}
	${CC} ${CCFLAGS_SO} -o $@ ${SOURCE_FILES_C} ${LDFLAGS_C}
	-ln -s lib$(MQTT_EMBED_LIB_C).so.${VERSION}  ${blddir}/lib$(MQTT_EMBED_LIB_C).so.${MAJOR_VERSION}
	-ln -s lib$(MQTT_EMBED_LIB_C).so.${MAJOR_VERSION} ${blddir}/lib$(MQTT_EMBED_LIB_C).so


strip_options:
	$(eval INSTALL_OPTS := -s)

install-strip: build strip_options install

install: build 
	$(INSTALL_DATA) ${INSTALL_OPTS} ${EMBED_MQTTLIB_C_TARGET} $(DESTDIR)${libdir}

	/sbin/ldconfig $(DESTDIR)${libdir}
	ln -s lib$(MQTT_EMBED_LIB_C).so.${MAJOR_VERSION} $(DESTDIR)${libdir}/lib$(MQTT_EMBED_LIB_C).so


uninstall:
	rm $(DESTDIR)${libdir}/lib$(MQTT_EMBED_LIB_C).so.${VERSION}
	/sbin/ldconfig $(DESTDIR)${libdir}
	rm $(DESTDIR)${libdir}/lib$(MQTT_EMBED_LIB_C).so


html:


endif

7.修改paho.mqtt.embedded-c-master/MQTTPacket/test/test.c里面ftime函数过期了,报错如下:
在这里插入图片描述
改为

#define LOGA_DEBUG 0
#define LOGA_INFO 1
#include <stdarg.h>
#include <time.h>
#include <sys/timeb.h>

void MyLog(int LOGA_level, char* format, ...)
{
	static char msg_buf[256];
	va_list args;
	struct timeb ts;

	struct tm *timeinfo;

	if (LOGA_level == LOGA_DEBUG && options.verbose == 0)
	  return;

//	ftime(&ts);
//	timeinfo = localtime(&ts.time);

	time_t current_time = time(NULL);  // 获取当前的 Unix 时间戳
	timeinfo = localtime(&current_time);

	strftime(msg_buf, 80, "%Y%m%d %H%M%S", timeinfo);

	sprintf(&msg_buf[strlen(msg_buf)], ".%.3hu ", ts.millitm);

	va_start(args, format);
	vsnprintf(&msg_buf[strlen(msg_buf)], sizeof(msg_buf) - strlen(msg_buf), format, args);
	va_end(args);

	printf("%s\n", msg_buf);
	fflush(stdout);
}

三.编译

1.先make clean清理一下,再make,没有问题再make install得到的库在build/output下
在这里插入图片描述
在这里插入图片描述

四.源码移植

1.在工程下的建立MQTTPacket文件夹,用于存放mqtt的源文件和库文件
2.将MQTTPacket\src里面的*.c和*.h全部拷贝到自己工程下MQTTPacket文件夹里面
3.将MQTTClient-C\src\linux的MQTTLinux.c MQTTLinux.h 复制到MQTTPacket文件夹中
4.MQTTClient-C\src的MQTTClient.c MQTTClient.h 复制到MQTTPacket文件夹中
5.将build/output生成的*.so 复制到MQTTPacket文件夹中
6.在MQTTClient.h添加#include “MQTTLinux.h”
在这里插入图片描述
在这里插入图片描述

五.测试

1.下载MQTT的服务端emqxMQTT客户端
2.启动服务端emqx,进入emqx-5.3.0-windows-amd64\bin,输入emqx start
在这里插入图片描述
3.编写客户端测试代码

 #include "mqtt_client_app.h"
#include <stdio.h>
#include <memory.h>
#include "MQTTClient.h"
#include <stdio.h>
#include <signal.h>
#include <sys/time.h>

struct opts_struct
{
    char* clientid;
    int nodelimiter;
    char* delimiter;
    enum QoS qos;
    char* username;
    char* password;
    char* host;
    int port;
    int showtopics;
} opts =
{  
    (char*)"mqtt_id", 0, (char*)"", QOS0, "michale", "1111", (char*)"192.168.1.100", 1883, 0
};


void messageArrived(MessageData* md)
{
    MQTTMessage* message = md->message;

    printf("%.*s\t", md->topicName->lenstring.len, md->topicName->lenstring.data);
    printf("%.*s\n", (int)message->payloadlen, (char*)message->payload);
    fflush(stdout);
}

u8 bsp_mqtt_client_init()
{
    int rc = 0;
    const int buflen = 1024;
    unsigned char buf[buflen];
    unsigned char readbuf[buflen];

    char* topic = "mqtt_topic1";
    char* pubtopic = "mqtt_topic1";

    Network n;
    MQTTClient c;

    NetworkInit(&n);
    NetworkConnect(&n, opts.host, opts.port);

    MQTTClientInit(&c, &n, 1000, buf, buflen, readbuf, buflen);

    MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
    data.willFlag = 0;

    data.MQTTVersion = 3;
    data.clientID.cstring = opts.clientid;
    data.username.cstring = opts.username;
    data.password.cstring = opts.password;

    data.keepAliveInterval = 60;
    data.cleansession = 1;

    rc = MQTTConnect(&c, &data);
    printf("Status :%d Connecting to %s %d\n", rc, opts.host, opts.port);
    if(rc != 0)
        return FALSE;
    printf("Connected %d \n", rc);
    rc = MQTTSubscribe(&c, topic, opts.qos, messageArrived);
    if(rc != 0)
    {
        return FALSE;
    }
    printf("Subscribing to %s\n", topic);

    int cnt = 0, msgid = 0;
    while (1)
    {

        MQTTMessage msg = {
            QOS0,
            0,
            0,
            0,
            message,
            strlen(message),
        };

        msg.id = ++msgid;
        rc = MQTTPublish(&c, pubtopic, &msg);
        printf("MQTTPublish %d, msgid %d\n", rc, msgid);

        MQTTYield(&c, 1000);
    }

    printf("Stopping\n");

    MQTTDisconnect(&c);
    NetworkDisconnect(&n);

    return TRUE;
}


4.使用再建一个客户端
在这里插入图片描述

文章来源:https://blog.csdn.net/u011171361/article/details/134271166
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。