交叉编译paho.mqtt.c和paho.mqtt.cpp(MQTT客户端)

一、参考资料

【MQTT】paho.mqtt.cpp 库的 介绍、下载、交叉编译、MQTT客户端例子源码-CSDN博客

【MQTT】paho.mqtt.c 库的“介绍、下载、交叉编译” 详解,以及编写MQTT客户端例子源码-CSDN博客

二、准备工作

1. 重要说明

  • paho.mqtt.cpppaho.mqtt.c,务必版本对齐,否则导致编译失败。

在这里插入图片描述

  • 根据paho.mqtt.cpp版本来确定paho.mqtt.c的版本,先交叉编译paho.mqtt.cpp,然后交叉编译paho.mqtt.c

2. 编译环境

  • 宿主机:Ubuntu 20.04.6 LTS
  • Host:ARM32位。
  • 交叉编译器:arm-linux-gnueabihf-gcc-11.1.0

3. 设置交叉编译工具链

在交叉编译之前,需要设置交叉编译工具链的环境变量。

export PATH=/path/to/toolchains/arm-linux-gnueabihf/bin:$PATH

三、交叉编译paho.mqtt.cpp

1. 下载源码

下载源码:GitHub - eclipse-paho/paho.mqtt.cpp

下载并解压源码:

tar -xvzf paho.mqtt.cpp-1.5.2.tar.gz

2. 编译安装

cd paho.mqtt.cpp-1.5.2 && mkdir build

# 编译带有 openssl 的库
cmake .. \
  -DCMAKE_INSTALL_PREFIX=/path/to/paho.mqtt.cpp/arm_install \
  -DCMAKE_C_COMPILER=arm-linux-gnueabihf-gcc \
  -DCMAKE_CXX_COMPILER=arm-linux-gnueabihf-g++ \
  -DPAHO_WITH_MQTT_C=ON \
  -DPAHO_WITH_SSL=ON \  # 启用 SSL 支持
  -DOPENSSL_ROOT_DIR=/path/to/openssl/arm_install \ # OpenSSL 的交叉编译后路径
  -DPAHO_BUILD_STATIC=OFF \
  -DPAHO_BUILD_SAMPLES=OFF \  # 关闭示例编译
  -DPAHO_BUILD_TESTS=OFF \  # 关闭测试样例编译
  -DCMAKE_CXX_FLAGS="-std=c++11"

make -j8
make install

安装后的文件目录:

yoyo@yoyo:~/360Downloads/paho.mqtt.cpp-1.5.2$ tree -L 4 arm_install/
arm_install/
├── bin
│   └── MQTTVersion
├── include
│   ├── mqtt
│   │   ├── async_client.h
│   │   ├── buffer_ref.h
│   │   ├── buffer_view.h
│   │   ├── callback.h
│   │   ├── client.h
│   │   ├── connect_options.h
│   │   ├── create_options.h
│   │   ├── delivery_token.h
│   │   ├── disconnect_options.h
│   │   ├── event.h
│   │   ├── exception.h
│   │   ├── export.h
│   │   ├── iaction_listener.h
│   │   ├── iasync_client.h
│   │   ├── iclient_persistence.h
│   │   ├── message.h
│   │   ├── platform.h
│   │   ├── properties.h
│   │   ├── reason_code.h
│   │   ├── response_options.h
│   │   ├── server_response.h
│   │   ├── ssl_options.h
│   │   ├── string_collection.h
│   │   ├── subscribe_options.h
│   │   ├── thread_queue.h
│   │   ├── token.h
│   │   ├── topic.h
│   │   ├── topic_matcher.h
│   │   ├── types.h
│   │   └── will_options.h
│   ├── MQTTAsync.h
│   ├── MQTTClient.h
│   ├── MQTTClientPersistence.h
│   ├── MQTTExportDeclarations.h
│   ├── MQTTProperties.h
│   ├── MQTTReasonCodes.h
│   └── MQTTSubscribeOpts.h
├── lib
│   ├── cmake
│   │   ├── eclipse-paho-mqtt-c
│   │   │   ├── eclipse-paho-mqtt-cConfig.cmake
│   │   │   ├── eclipse-paho-mqtt-cConfig-noconfig.cmake
│   │   │   └── eclipse-paho-mqtt-cConfigVersion.cmake
│   │   └── PahoMqttCpp
│   │       ├── PahoMqttCppConfig.cmake
│   │       ├── PahoMqttCppConfigVersion.cmake
│   │       ├── PahoMqttCppTargets.cmake
│   │       └── PahoMqttCppTargets-noconfig.cmake
│   ├── libpaho-mqtt3a.so -> libpaho-mqtt3a.so.1
│   ├── libpaho-mqtt3a.so.1 -> libpaho-mqtt3a.so.1.3.14
│   ├── libpaho-mqtt3a.so.1.3.14
│   ├── libpaho-mqtt3as.so -> libpaho-mqtt3as.so.1
│   ├── libpaho-mqtt3as.so.1 -> libpaho-mqtt3as.so.1.3.14
│   ├── libpaho-mqtt3as.so.1.3.14
│   ├── libpaho-mqtt3c.so -> libpaho-mqtt3c.so.1
│   ├── libpaho-mqtt3c.so.1 -> libpaho-mqtt3c.so.1.3.14
│   ├── libpaho-mqtt3c.so.1.3.14
│   ├── libpaho-mqtt3cs.so -> libpaho-mqtt3cs.so.1
│   ├── libpaho-mqtt3cs.so.1 -> libpaho-mqtt3cs.so.1.3.14
│   ├── libpaho-mqtt3cs.so.1.3.14
│   ├── libpaho-mqttpp3.so -> libpaho-mqttpp3.so.1
│   ├── libpaho-mqttpp3.so.1 -> libpaho-mqttpp3.so.1.5.1
│   └── libpaho-mqttpp3.so.1.5.1
└── share
    └── doc
        └── Eclipse Paho C
            ├── CONTRIBUTING.md
            ├── edl-v10
            ├── epl-v20
            ├── notice.html
            ├── README.md
            └── samples

cmake 编译:

yoyo@yoyo:~/360Downloads/paho.mqtt.cpp-1.5.2/build$ cmake .. \
>   -DCMAKE_INSTALL_PREFIX=/path/to/paho.mqtt.cpp-1.5.2/arm_install \
>   -DCMAKE_C_COMPILER=arm-linux-gnueabihf-gcc \
>   -DCMAKE_CXX_COMPILER=arm-linux-gnueabihf-g++ \
>   -DPAHO_WITH_MQTT_C=ON \
>   -DPAHO_WITH_SSL=ON \
>   -DOPENSSL_ROOT_DIR=/path/to/openssl-openssl-3.5.0/arm_install \
>   -DPAHO_BUILD_STATIC=OFF \
>   -DPAHO_BUILD_SAMPLES=OFF \
>   -DPAHO_BUILD_TESTS=OFF \
>   -DCMAKE_CXX_FLAGS="-std=c++11"
-- The C compiler identification is GNU 11.1.0
-- The CXX compiler identification is GNU 11.1.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /path/to/toolchains/arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /path/to/toolchains/arm-linux-gnueabihf/bin/arm-linux-gnueabihf-g++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found OpenSSL: /path/to/openssl-openssl-3.5.0/arm_install/lib/libcrypto.so (found version "3.5.0")
-- Paho C: Bundled
CMake Deprecation Warning at externals/paho-mqtt-c/CMakeLists.txt:18 (cmake_minimum_required):
  Compatibility with CMake < 3.10 will be removed from a future version of
  CMake.

  Update the VERSION argument <min> value.  Or, use the <min>...<max> syntax
  to tell CMake that the project requires at least <min> but has been updated
  to work with policies introduced by <max> or earlier.


-- CMake version: 3.31.3
-- CMake system name: Linux
-- Timestamp is 2025-04-14T06:10:16Z
-- Using OpenSSL with headers at /path/to/openssl-openssl-3.5.0/arm_install/include
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Failed
-- Check if compiler accepts -pthread
-- Check if compiler accepts -pthread - yes
-- Found Threads: TRUE
-- Creating shared library
-- Performing Test COMPILER_HAS_HIDDEN_VISIBILITY
-- Performing Test COMPILER_HAS_HIDDEN_VISIBILITY - Success
-- Performing Test COMPILER_HAS_HIDDEN_INLINE_VISIBILITY
-- Performing Test COMPILER_HAS_HIDDEN_INLINE_VISIBILITY - Success
-- Performing Test COMPILER_HAS_DEPRECATED_ATTR
-- Performing Test COMPILER_HAS_DEPRECATED_ATTR - Success
-- Configuring done (0.8s)
-- Generating done (0.0s)
-- Build files have been written to: /path/to/paho.mqtt.cpp-1.5.2/build

make 编译:

yoyo@yoyo:~/360Downloads/paho.mqtt.cpp-1.5.2/build$ make -j8
[  1%] Building C object externals/paho-mqtt-c/src/CMakeFiles/common_obj.dir/MQTTProtocolClient.c.o
[  2%] Building C object externals/paho-mqtt-c/src/CMakeFiles/common_ssl_obj.dir/MQTTProtocolClient.c.o
[  5%] Building C object externals/paho-mqtt-c/src/CMakeFiles/common_ssl_obj.dir/Clients.c.o
[  5%] Building C object externals/paho-mqtt-c/src/CMakeFiles/common_ssl_obj.dir/MQTTTime.c.o
[  8%] Building C object externals/paho-mqtt-c/src/CMakeFiles/common_obj.dir/Clients.c.o
[  8%] Building C object externals/paho-mqtt-c/src/CMakeFiles/common_obj.dir/MQTTTime.c.o
[  9%] Building C object externals/paho-mqtt-c/src/CMakeFiles/common_obj.dir/utf-8.c.o
[ 10%] Building C object externals/paho-mqtt-c/src/CMakeFiles/common_obj.dir/MQTTPacket.c.o
[ 12%] Building C object externals/paho-mqtt-c/src/CMakeFiles/common_ssl_obj.dir/utf-8.c.o
[ 13%] Building C object externals/paho-mqtt-c/src/CMakeFiles/common_obj.dir/MQTTPacketOut.c.o
[ 14%] Building C object externals/paho-mqtt-c/src/CMakeFiles/common_obj.dir/Messages.c.o
[ 16%] Building C object externals/paho-mqtt-c/src/CMakeFiles/common_obj.dir/Tree.c.o
[ 17%] Building C object externals/paho-mqtt-c/src/CMakeFiles/common_obj.dir/Socket.c.o
[ 18%] Building C object externals/paho-mqtt-c/src/CMakeFiles/common_ssl_obj.dir/MQTTPacket.c.o
[ 20%] Building C object externals/paho-mqtt-c/src/CMakeFiles/common_obj.dir/Log.c.o
[ 21%] Building C object externals/paho-mqtt-c/src/CMakeFiles/common_obj.dir/MQTTPersistence.c.o
[ 22%] Building C object externals/paho-mqtt-c/src/CMakeFiles/common_obj.dir/Thread.c.o
[ 24%] Building C object externals/paho-mqtt-c/src/CMakeFiles/common_obj.dir/MQTTProtocolOut.c.o
[ 25%] Building C object externals/paho-mqtt-c/src/CMakeFiles/common_ssl_obj.dir/MQTTPacketOut.c.o
[ 26%] Building C object externals/paho-mqtt-c/src/CMakeFiles/common_ssl_obj.dir/Messages.c.o
[ 28%] Building C object externals/paho-mqtt-c/src/CMakeFiles/common_obj.dir/MQTTPersistenceDefault.c.o
[ 29%] Building C object externals/paho-mqtt-c/src/CMakeFiles/common_obj.dir/SocketBuffer.c.o
[ 30%] Building C object externals/paho-mqtt-c/src/CMakeFiles/common_obj.dir/LinkedList.c.o
[ 32%] Building C object externals/paho-mqtt-c/src/CMakeFiles/common_ssl_obj.dir/Tree.c.o
[ 33%] Building C object externals/paho-mqtt-c/src/CMakeFiles/common_obj.dir/MQTTProperties.c.o
[ 34%] Building C object externals/paho-mqtt-c/src/CMakeFiles/common_obj.dir/MQTTReasonCodes.c.o
[ 36%] Building C object externals/paho-mqtt-c/src/CMakeFiles/common_obj.dir/Base64.c.o
[ 37%] Building C object externals/paho-mqtt-c/src/CMakeFiles/common_obj.dir/SHA1.c.o
[ 38%] Building C object externals/paho-mqtt-c/src/CMakeFiles/common_obj.dir/WebSocket.c.o
[ 40%] Building C object externals/paho-mqtt-c/src/CMakeFiles/common_obj.dir/Proxy.c.o
[ 41%] Building C object externals/paho-mqtt-c/src/CMakeFiles/common_ssl_obj.dir/Log.c.o
[ 42%] Building C object externals/paho-mqtt-c/src/CMakeFiles/common_ssl_obj.dir/Socket.c.o
[ 44%] Building C object externals/paho-mqtt-c/src/CMakeFiles/common_ssl_obj.dir/MQTTPersistence.c.o
[ 45%] Building C object externals/paho-mqtt-c/src/CMakeFiles/common_ssl_obj.dir/Thread.c.o
[ 46%] Building C object externals/paho-mqtt-c/src/CMakeFiles/common_ssl_obj.dir/MQTTProtocolOut.c.o
[ 48%] Building C object externals/paho-mqtt-c/src/CMakeFiles/common_ssl_obj.dir/MQTTPersistenceDefault.c.o
[ 49%] Building C object externals/paho-mqtt-c/src/CMakeFiles/common_ssl_obj.dir/SocketBuffer.c.o
[ 50%] Building C object externals/paho-mqtt-c/src/CMakeFiles/common_ssl_obj.dir/LinkedList.c.o
[ 50%] Built target common_obj
[ 52%] Building C object externals/paho-mqtt-c/src/CMakeFiles/common_ssl_obj.dir/MQTTProperties.c.o
[ 53%] Building C object externals/paho-mqtt-c/src/CMakeFiles/common_ssl_obj.dir/MQTTReasonCodes.c.o
[ 54%] Building C object externals/paho-mqtt-c/src/CMakeFiles/common_ssl_obj.dir/Base64.c.o
[ 56%] Building C object externals/paho-mqtt-c/src/CMakeFiles/common_ssl_obj.dir/SHA1.c.o
[ 57%] Building C object externals/paho-mqtt-c/src/CMakeFiles/common_ssl_obj.dir/WebSocket.c.o
[ 58%] Building C object externals/paho-mqtt-c/src/CMakeFiles/common_ssl_obj.dir/Proxy.c.o
[ 60%] Building C object externals/paho-mqtt-c/src/CMakeFiles/paho-mqtt3a.dir/MQTTAsync.c.o
[ 61%] Building C object externals/paho-mqtt-c/src/CMakeFiles/paho-mqtt3a.dir/MQTTAsyncUtils.c.o
[ 62%] Building C object externals/paho-mqtt-c/src/CMakeFiles/paho-mqtt3c.dir/MQTTClient.c.o
[ 62%] Built target common_ssl_obj
[ 64%] Building C object externals/paho-mqtt-c/src/CMakeFiles/paho-mqtt3cs.dir/MQTTClient.c.o
[ 65%] Building C object externals/paho-mqtt-c/src/CMakeFiles/paho-mqtt3as.dir/MQTTAsync.c.o
[ 66%] Building C object externals/paho-mqtt-c/src/CMakeFiles/paho-mqtt3as.dir/SSLSocket.c.o
[ 68%] Building C object externals/paho-mqtt-c/src/CMakeFiles/paho-mqtt3cs.dir/SSLSocket.c.o
[ 69%] Building C object externals/paho-mqtt-c/src/CMakeFiles/paho-mqtt3as.dir/MQTTAsyncUtils.c.o
[ 70%] Linking C shared library libpaho-mqtt3c.so
[ 72%] Linking C shared library libpaho-mqtt3a.so
[ 72%] Built target paho-mqtt3c
[ 72%] Built target paho-mqtt3a
[ 73%] Building C object externals/paho-mqtt-c/src/CMakeFiles/MQTTVersion.dir/MQTTVersion.c.o
[ 74%] Linking C executable MQTTVersion
[ 74%] Built target MQTTVersion
[ 76%] Linking C shared library libpaho-mqtt3cs.so
[ 77%] Linking C shared library libpaho-mqtt3as.so
[ 77%] Built target paho-mqtt3cs
[ 77%] Built target paho-mqtt3as
[ 78%] Building CXX object src/CMakeFiles/paho-mqttpp3-shared.dir/async_client.cpp.o
[ 80%] Building CXX object src/CMakeFiles/paho-mqttpp3-shared.dir/client.cpp.o
[ 81%] Building CXX object src/CMakeFiles/paho-mqttpp3-shared.dir/create_options.cpp.o
[ 82%] Building CXX object src/CMakeFiles/paho-mqttpp3-shared.dir/connect_options.cpp.o
[ 84%] Building CXX object src/CMakeFiles/paho-mqttpp3-shared.dir/disconnect_options.cpp.o
[ 85%] Building CXX object src/CMakeFiles/paho-mqttpp3-shared.dir/iclient_persistence.cpp.o
[ 86%] Building CXX object src/CMakeFiles/paho-mqttpp3-shared.dir/message.cpp.o
[ 88%] Building CXX object src/CMakeFiles/paho-mqttpp3-shared.dir/properties.cpp.o
[ 89%] Building CXX object src/CMakeFiles/paho-mqttpp3-shared.dir/reason_code.cpp.o
[ 90%] Building CXX object src/CMakeFiles/paho-mqttpp3-shared.dir/response_options.cpp.o
[ 92%] Building CXX object src/CMakeFiles/paho-mqttpp3-shared.dir/server_response.cpp.o
[ 93%] Building CXX object src/CMakeFiles/paho-mqttpp3-shared.dir/ssl_options.cpp.o
[ 94%] Building CXX object src/CMakeFiles/paho-mqttpp3-shared.dir/string_collection.cpp.o
[ 96%] Building CXX object src/CMakeFiles/paho-mqttpp3-shared.dir/token.cpp.o
[ 97%] Building CXX object src/CMakeFiles/paho-mqttpp3-shared.dir/topic.cpp.o
[ 98%] Building CXX object src/CMakeFiles/paho-mqttpp3-shared.dir/will_options.cpp.o
[100%] Linking CXX shared library libpaho-mqttpp3.so
[100%] Built target paho-mqttpp3-shared

make install 安装:

yoyo@yoyo:~/360Downloads/paho.mqtt.cpp-1.5.2/build$ make install
[ 29%] Built target common_obj
[ 33%] Built target paho-mqtt3a
[ 36%] Built target paho-mqtt3c
[ 38%] Built target MQTTVersion
[ 68%] Built target common_ssl_obj
[ 72%] Built target paho-mqtt3cs
[ 77%] Built target paho-mqtt3as
[100%] Built target paho-mqttpp3-shared
Install the project...
-- Install configuration: ""
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/lib/libpaho-mqtt3a.so.1.3.14
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/lib/libpaho-mqtt3a.so.1
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/lib/libpaho-mqtt3a.so
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/lib/libpaho-mqtt3as.so.1.3.14
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/lib/libpaho-mqtt3as.so.1
-- Set non-toolchain portion of runtime path of "/path/to/paho.mqtt.cpp-1.5.2/arm_install/lib/libpaho-mqtt3as.so.1.3.14" to ""
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/lib/libpaho-mqtt3as.so
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/include
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/include/mqtt
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/include/mqtt/export.h
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/share/doc/Eclipse Paho C/samples/MQTTAsync_publish.c
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/share/doc/Eclipse Paho C/samples/MQTTAsync_publish_time.c
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/share/doc/Eclipse Paho C/samples/MQTTAsync_subscribe.c
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/share/doc/Eclipse Paho C/samples/MQTTClient_publish.c
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/share/doc/Eclipse Paho C/samples/MQTTClient_publish_async.c
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/share/doc/Eclipse Paho C/samples/MQTTClient_subscribe.c
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/share/doc/Eclipse Paho C/samples/paho_c_pub.c
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/share/doc/Eclipse Paho C/samples/paho_c_sub.c
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/share/doc/Eclipse Paho C/samples/paho_cs_pub.c
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/share/doc/Eclipse Paho C/samples/paho_cs_sub.c
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/share/doc/Eclipse Paho C/samples/pubsub_opts.c
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/share/doc/Eclipse Paho C/CONTRIBUTING.md
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/share/doc/Eclipse Paho C/epl-v20
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/share/doc/Eclipse Paho C/edl-v10
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/share/doc/Eclipse Paho C/README.md
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/share/doc/Eclipse Paho C/notice.html
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/lib/libpaho-mqtt3c.so.1.3.14
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/lib/libpaho-mqtt3c.so.1
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/lib/libpaho-mqtt3c.so
-- Up-to-date: /path/to/paho.mqtt.cpp-1.5.2/arm_install/lib/libpaho-mqtt3a.so.1.3.14
-- Up-to-date: /path/to/paho.mqtt.cpp-1.5.2/arm_install/lib/libpaho-mqtt3a.so.1
-- Up-to-date: /path/to/paho.mqtt.cpp-1.5.2/arm_install/lib/libpaho-mqtt3a.so
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/bin/MQTTVersion
-- Set non-toolchain portion of runtime path of "/path/to/paho.mqtt.cpp-1.5.2/arm_install/bin/MQTTVersion" to ""
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/include/MQTTAsync.h
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/include/MQTTClient.h
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/include/MQTTClientPersistence.h
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/include/MQTTProperties.h
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/include/MQTTReasonCodes.h
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/include/MQTTSubscribeOpts.h
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/include/MQTTExportDeclarations.h
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/lib/libpaho-mqtt3cs.so.1.3.14
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/lib/libpaho-mqtt3cs.so.1
-- Set non-toolchain portion of runtime path of "/path/to/paho.mqtt.cpp-1.5.2/arm_install/lib/libpaho-mqtt3cs.so.1.3.14" to ""
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/lib/libpaho-mqtt3cs.so
-- Up-to-date: /path/to/paho.mqtt.cpp-1.5.2/arm_install/lib/libpaho-mqtt3as.so.1.3.14
-- Up-to-date: /path/to/paho.mqtt.cpp-1.5.2/arm_install/lib/libpaho-mqtt3as.so.1
-- Up-to-date: /path/to/paho.mqtt.cpp-1.5.2/arm_install/lib/libpaho-mqtt3as.so
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/lib/cmake/eclipse-paho-mqtt-c/eclipse-paho-mqtt-cConfig.cmake
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/lib/cmake/eclipse-paho-mqtt-c/eclipse-paho-mqtt-cConfig-noconfig.cmake
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/lib/cmake/eclipse-paho-mqtt-c/eclipse-paho-mqtt-cConfigVersion.cmake
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/include/mqtt/async_client.h
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/include/mqtt/buffer_ref.h
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/include/mqtt/buffer_view.h
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/include/mqtt/callback.h
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/include/mqtt/client.h
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/include/mqtt/connect_options.h
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/include/mqtt/create_options.h
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/include/mqtt/delivery_token.h
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/include/mqtt/disconnect_options.h
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/include/mqtt/event.h
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/include/mqtt/exception.h
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/include/mqtt/export.h
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/include/mqtt/iaction_listener.h
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/include/mqtt/iasync_client.h
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/include/mqtt/iclient_persistence.h
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/include/mqtt/message.h
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/include/mqtt/platform.h
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/include/mqtt/properties.h
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/include/mqtt/reason_code.h
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/include/mqtt/response_options.h
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/include/mqtt/server_response.h
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/include/mqtt/ssl_options.h
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/include/mqtt/string_collection.h
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/include/mqtt/subscribe_options.h
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/include/mqtt/thread_queue.h
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/include/mqtt/token.h
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/include/mqtt/topic_matcher.h
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/include/mqtt/topic.h
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/include/mqtt/types.h
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/include/mqtt/will_options.h
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/lib/libpaho-mqttpp3.so.1.5.1
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/lib/libpaho-mqttpp3.so.1
-- Set non-toolchain portion of runtime path of "/path/to/paho.mqtt.cpp-1.5.2/arm_install/lib/libpaho-mqttpp3.so.1.5.1" to ""
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/lib/libpaho-mqttpp3.so
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/lib/cmake/PahoMqttCpp/PahoMqttCppTargets.cmake
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/lib/cmake/PahoMqttCpp/PahoMqttCppTargets-noconfig.cmake
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/lib/cmake/PahoMqttCpp/PahoMqttCppConfig.cmake
-- Installing: /path/to/paho.mqtt.cpp-1.5.2/arm_install/lib/cmake/PahoMqttCpp/PahoMqttCppConfigVersion.cmake

3. 移植到开发板

cp -arf /path/to/paho.mqtt.cpp/arm_install/lib/ /usr/paho.mqtt.cpp/

4. 简单示例

4.1 订阅——async_subscribe.cpp

这是使用了 libpaho-mqttpp3.so 进行订阅消息的源码,源码路径在源码的这个路径:paho.mqtt.cpp-1.5.2/examples/async_subscribe.cpp,只更改了服务器地址。完整代码如下:

// async_subscribe.cpp
//
// This is a Paho MQTT C++ client, sample application.
//
// This application is an MQTT subscriber using the C++ asynchronous client
// interface, employing callbacks to receive messages and status updates.
//
// The sample demonstrates:
//  - Connecting to an MQTT server/broker using MQTT v3.
//  - Subscribing to a topic
//  - Receiving messages through the callback API
//  - Receiving network disconnect updates and attempting manual reconnects.
//  - Using a "clean session" and manually re-subscribing to topics on
//    reconnect.
//

/*******************************************************************************
 * Copyright (c) 2013-2025 Frank Pagliughi <fpagliughi@mindspring.com>
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * and Eclipse Distribution License v1.0 which accompany this distribution.
 *
 * The Eclipse Public License is available at
 *    http://www.eclipse.org/legal/epl-v20.html
 * and the Eclipse Distribution License is available at
 *   http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * Contributors:
 *    Frank Pagliughi - initial implementation and documentation
 *******************************************************************************/

#include <cctype>
#include <chrono>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <string>
#include <thread>

#include "mqtt/async_client.h"

const std::string DFLT_SERVER_URI("192.168.33.1:1883");
//const std::string DFLT_SERVER_URI("mqtt://localhost:1883");
const std::string CLIENT_ID("paho_cpp_async_subscribe");

const std::string TOPIC("#");

const int QOS = 1;
const int N_RETRY_ATTEMPTS = 5;

/

// Callbacks for the success or failures of requested actions.
// This could be used to initiate further action, but here we just log the
// results to the console.

class action_listener : public virtual mqtt::iaction_listener
{
    std::string name_;

    void on_failure(const mqtt::token& tok) override
    {
        std::cout << name_ << " failure";
        if (tok.get_message_id() != 0)
            std::cout << " for token: [" << tok.get_message_id() << "]" << std::endl;
        std::cout << std::endl;
    }

    void on_success(const mqtt::token& tok) override
    {
        std::cout << name_ << " success";
        if (tok.get_message_id() != 0)
            std::cout << " for token: [" << tok.get_message_id() << "]" << std::endl;
        auto top = tok.get_topics();
        if (top && !top->empty())
            std::cout << "\ttoken topic: '" << (*top)[0] << "', ..." << std::endl;
        std::cout << std::endl;
    }

public:
    action_listener(const std::string& name) : name_(name) {}
};

/

/**
 * Local callback & listener class for use with the client connection.
 * This is primarily intended to receive messages, but it will also monitor
 * the connection to the broker. If the connection is lost, it will attempt
 * to restore the connection and re-subscribe to the topic.
 */
class callback : public virtual mqtt::callback, public virtual mqtt::iaction_listener

{
    // Counter for the number of connection retries
    int nretry_;
    // The MQTT client
    mqtt::async_client& cli_;
    // Options to use if we need to reconnect
    mqtt::connect_options& connOpts_;
    // An action listener to display the result of actions.
    action_listener subListener_;

    // This deomonstrates manually reconnecting to the broker by calling
    // connect() again. This is a possibility for an application that keeps
    // a copy of it's original connect_options, or if the app wants to
    // reconnect with different options.
    // Another way this can be done manually, if using the same options, is
    // to just call the async_client::reconnect() method.
    void reconnect()
    {
        std::this_thread::sleep_for(std::chrono::milliseconds(2500));
        try {
            cli_.connect(connOpts_, nullptr, *this);
        }
        catch (const mqtt::exception& exc) {
            std::cerr << "Error: " << exc.what() << std::endl;
            exit(1);
        }
    }

    // Re-connection failure
    void on_failure(const mqtt::token& tok) override
    {
        std::cout << "Connection attempt failed" << std::endl;
        if (++nretry_ > N_RETRY_ATTEMPTS)
            exit(1);
        reconnect();
    }

    // (Re)connection success
    // Either this or connected() can be used for callbacks.
    void on_success(const mqtt::token& tok) override {}

    // (Re)connection success
    void connected(const std::string& cause) override
    {
        std::cout << "\nConnection success" << std::endl;
        std::cout << "\nSubscribing to topic '" << TOPIC << "'\n"
                  << "\tfor client " << CLIENT_ID << " using QoS" << QOS << "\n"
                  << "\nPress Q<Enter> to quit\n"
                  << std::endl;

        cli_.subscribe(TOPIC, QOS, nullptr, subListener_);
    }

    // Callback for when the connection is lost.
    // This will initiate the attempt to manually reconnect.
    void connection_lost(const std::string& cause) override
    {
        std::cout << "\nConnection lost" << std::endl;
        if (!cause.empty())
            std::cout << "\tcause: " << cause << std::endl;

        std::cout << "Reconnecting..." << std::endl;
        nretry_ = 0;
        reconnect();
    }

    // Callback for when a message arrives.
    void message_arrived(mqtt::const_message_ptr msg) override
    {
        std::cout << "Message arrived" << std::endl;
        std::cout << "\ttopic: '" << msg->get_topic() << "'" << std::endl;
        std::cout << "\tpayload: '" << msg->to_string() << "'\n" << std::endl;
    }

    void delivery_complete(mqtt::delivery_token_ptr token) override {}

public:
    callback(mqtt::async_client& cli, mqtt::connect_options& connOpts)
        : nretry_(0), cli_(cli), connOpts_(connOpts), subListener_("Subscription")
    {
    }
};

/

int main(int argc, char* argv[])
{
    // A subscriber often wants the server to remember its messages when its
    // disconnected. In that case, it needs a unique ClientID and a
    // non-clean session.

    auto serverURI = (argc > 1) ? std::string{argv[1]} : DFLT_SERVER_URI;

    mqtt::async_client cli(serverURI, CLIENT_ID);

    mqtt::connect_options connOpts;
    connOpts.set_clean_session(false);

    // Install the callback(s) before connecting.
    callback cb(cli, connOpts);
    cli.set_callback(cb);

    // Start the connection.
    // When completed, the callback will subscribe to topic.

    try {
        std::cout << "Connecting to the MQTT server '" << serverURI << "'..." << std::flush;
        cli.connect(connOpts, nullptr, cb);
    }
    catch (const mqtt::exception& exc) {
        std::cerr << "\nERROR: Unable to connect to MQTT server: '" << serverURI << "'" << exc
                  << std::endl;
        return 1;
    }

    // Just block till user tells us to quit.

    while (std::tolower(std::cin.get()) != 'q');

    // Disconnect

    try {
        std::cout << "\nDisconnecting from the MQTT server..." << std::flush;
        cli.disconnect()->wait();
        std::cout << "OK" << std::endl;
    }
    catch (const mqtt::exception& exc) {
        std::cerr << exc << std::endl;
        return 1;
    }

    return 0;
}

交叉编译:

arm-linux-gnueabihf-g++ async_subscribe.cpp -I /path/to/paho.mqtt.cpp-1.5.2/arm_install/include/ -I /path/to/paho.mqtt.c-1.3.14/arm_install/include/ -I /path/to/openssl-openssl-3.5.0/arm_install/include/ -L /path/to/paho.mqtt.cpp-1.5.2/arm_install/lib/ -l paho-mqttpp3 -l paho-mqtt3a -l paho-mqtt3as -L /path/to/paho.mqtt.c-1.3.14/arm_install/lib/ -L /path/to/openssl-openssl-3.5.0/arm_install/lib/ -l crypto -l ssl -o async_subscribe

在arm开发板中运行:

/customer/mqtt_test # ./async_subscribe
Connecting to the MQTT server '192.168.33.1:1883'...
Connection success

Subscribing to topic '#'
        for client paho_cpp_async_subscribe using QoS1

Press Q<Enter> to quit

Message arrived
        topic: 'hello'
        payload: 'Hello World!'

Message arrived
        topic: 'hello'
        payload: 'Hi there!'

Subscription success for token: [1]
        token topic: '#', ...

4.2 发布——async_publish.cpp

这是使用了 libpaho-mqttpp3.so 进行发布消息的源码,源码路径在源码的这个路径:paho.mqtt.cpp-1.5.2/examples/async_publish.cpp,只更改了服务器地址。完整代码如下:

// async_publish.cpp
//
// This is a Paho MQTT C++ client, sample application.
//
// It's an example of how to send messages as an MQTT publisher using the
// C++ asynchronous client interface.
//
// The sample demonstrates:
//  - Connecting to an MQTT server/broker
//  - Using a connect timeout
//  - Publishing messages
//  - Default file persistence
//  - Last will and testament
//  - Using asynchronous tokens
//  - Implementing callbacks and action listeners
//

/*******************************************************************************
 * Copyright (c) 2013-2023 Frank Pagliughi <fpagliughi@mindspring.com>
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * and Eclipse Distribution License v1.0 which accompany this distribution.
 *
 * The Eclipse Public License is available at
 *    http://www.eclipse.org/legal/epl-v20.html
 * and the Eclipse Distribution License is available at
 *   http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * Contributors:
 *    Frank Pagliughi - initial implementation and documentation
 *******************************************************************************/

#include <atomic>
#include <chrono>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <string>
#include <thread>

#include "mqtt/async_client.h"

using namespace std;
using namespace std::chrono;

const string DFLT_SERVER_URI{"192.168.33.1:1883"};
//const string DFLT_SERVER_URI{"mqtt://localhost:1883"};
const string CLIENT_ID{"paho_cpp_async_publish"};

const mqtt::persistence_type PERSIST_DIR{"./persist"};

const string TOPIC{"hello"};

const string PAYLOAD1{"Hello World!"};
const string PAYLOAD2{"Hi there!"};
const string PAYLOAD3{"Is anyone listening?"};
const string PAYLOAD4{"Someone is always listening."};

const string LWT_PAYLOAD{"Last will and testament."};

const int QOS = 1;

const auto TIMEOUT = std::chrono::seconds(10);

/

/**
 * A callback class for use with the main MQTT client.
 */
class callback : public virtual mqtt::callback
{
public:
    void connection_lost(const string& cause) override
    {
        cout << "\nConnection lost" << endl;
        if (!cause.empty())
            cout << "\tcause: " << cause << endl;
    }

    void delivery_complete(mqtt::delivery_token_ptr tok) override
    {
        cout << "\tDelivery complete for token: " << (tok ? tok->get_message_id() : -1)
             << endl;
    }
};

/

/**
 * A base action listener.
 */
class action_listener : public virtual mqtt::iaction_listener
{
protected:
    void on_failure(const mqtt::token& tok) override
    {
        cout << "\tListener failure for token: " << tok.get_message_id() << endl;
    }

    void on_success(const mqtt::token& tok) override
    {
        cout << "\tListener success for token: " << tok.get_message_id() << endl;
    }
};

/

/**
 * A derived action listener for publish events.
 */
class delivery_action_listener : public action_listener
{
    atomic<bool> done_;

    void on_failure(const mqtt::token& tok) override
    {
        action_listener::on_failure(tok);
        done_ = true;
    }

    void on_success(const mqtt::token& tok) override
    {
        action_listener::on_success(tok);
        done_ = true;
    }

public:
    delivery_action_listener() : done_(false) {}
    bool is_done() const { return done_; }
};

/

int main(int argc, char* argv[])
{
    // A client that just publishes normally doesn't need a persistent
    // session or Client ID unless it's using persistence, then the local
    // library requires an ID to identify the persistence files.

    string serverURI = (argc > 1) ? string{argv[1]} : DFLT_SERVER_URI,
           clientID = (argc > 2) ? string{argv[2]} : CLIENT_ID;

    cout << "Initializing for server '" << serverURI << "'..." << endl;
    mqtt::async_client client(serverURI, clientID, PERSIST_DIR);

    callback cb;
    client.set_callback(cb);

    auto connOpts = mqtt::connect_options_builder()
                        .connect_timeout(5s)
                        .clean_session()
                        .will(mqtt::message(TOPIC, LWT_PAYLOAD, QOS, false))
                        .finalize();

    cout << "  ...OK" << endl;

    try {
        cout << "\nConnecting..." << endl;
        mqtt::token_ptr conntok = client.connect(connOpts);
        cout << "Waiting for the connection..." << endl;
        conntok->wait();
        cout << "  ...OK" << endl;

        // First use a message pointer.

        cout << "\nSending message..." << endl;
        mqtt::message_ptr pubmsg = mqtt::make_message(TOPIC, PAYLOAD1);
        pubmsg->set_qos(QOS);
        client.publish(pubmsg)->wait_for(TIMEOUT);
        cout << "  ...OK" << endl;

        // Now try with itemized publish.

        cout << "\nSending next message..." << endl;
        mqtt::delivery_token_ptr pubtok;
        pubtok = client.publish(TOPIC, PAYLOAD2, QOS, false);
        cout << "  ...with token: " << pubtok->get_message_id() << endl;
        cout << "  ...for message with " << pubtok->get_message()->get_payload().size()
             << " bytes" << endl;
        pubtok->wait_for(TIMEOUT);
        cout << "  ...OK" << endl;

        // Now try with a listener

        cout << "\nSending next message..." << endl;
        action_listener listener;
        pubmsg = mqtt::make_message(TOPIC, PAYLOAD3);
        pubtok = client.publish(pubmsg, nullptr, listener);
        pubtok->wait();
        cout << "  ...OK" << endl;

        // Finally try with a listener, but no token

        cout << "\nSending final message..." << endl;
        delivery_action_listener deliveryListener;
        pubmsg = mqtt::make_message(TOPIC, PAYLOAD4);
        client.publish(pubmsg, nullptr, deliveryListener);

        while (!deliveryListener.is_done()) {
            this_thread::sleep_for(std::chrono::milliseconds(100));
        }
        cout << "OK" << endl;

        // Double check that there are no pending tokens

        auto toks = client.get_pending_delivery_tokens();
        if (!toks.empty())
            cout << "Error: There are pending delivery tokens!" << endl;

        // Disconnect
        cout << "\nDisconnecting..." << endl;
        client.disconnect()->wait();
        cout << "  ...OK" << endl;
    }
    catch (const mqtt::exception& exc) {
        cerr << exc.what() << endl;
        return 1;
    }

    return 0;
}

交叉编译:

arm-linux-gnueabihf-g++ async_publish.cpp -I /path/to/paho.mqtt.cpp-1.5.2/arm_install/include/ -I /path/to/paho.mqtt.c-1.3.14/arm_install/include/ -I /path/to/openssl-openssl-3.5.0/arm_install/include/ -L /path/to/paho.mqtt.cpp-1.5.2/arm_install/lib/ -l paho-mqttpp3 -l paho-mqtt3a -l paho-mqtt3as -L /path/to/paho.mqtt.c-1.3.14/arm_install/lib/ -L /path/to/openssl-openssl-3.5.0/arm_install/lib/ -l crypto -l ssl -l pthread -o async_publish

在arm开发板中运行:

/customer/mqtt_test # ./async_publish
Initializing for server '192.168.33.1:1883'...
  ...OK

Connecting...
Waiting for the connection...
  ...OK

Sending message...
  ...OK

Sending next message...
        Delivery complete for token: 1
  ...with token: 2
  ...for message with 9 bytes
        Delivery complete for token: 2
  ...OK

Sending next message...
        Listener success for token: 0
  ...OK

Sending final message...
        Listener success for token: 0
OK

Disconnecting...
  ...OK

四、交叉编译paho.mqtt.c

1. 下载源码

下载源码:[GitHub - eclipse-paho/paho.mqtt.c](https://eclipse-paho.github.io/paho.mqtt.c/ https://github.com/eclipse-paho/paho.mqtt.c)

git clone https://github.com/eclipse-paho/paho.mqtt.c.git

2. 编译安装

mkdir build && cd build

cmake ..\
  -DCMAKE_BUILD_TYPE=Release \
  -DCMAKE_INSTALL_PREFIX=/path/to/paho.mqtt.c/arm_install
  -DCMAKE_SYSTEM_NAME=Linux \
  -DCMAKE_SYSTEM_PROCESSOR=arm \        # 目标平台架构(如 arm/aarch64)
  -DCMAKE_C_COMPILER=arm-linux-gnueabihf-gcc \
  -DPAHO_WITH_SSL=ON \                 # 启用 SSL 支持
  -DOPENSSL_ROOT_DIR=/path/to/openssl/arm_install \ # OpenSSL 的交叉编译后路径
  -DPAHO_BUILD_STATIC=OFF \             # 生成静态库
  -DPAHO_BUILD_DOCUMENTATION=OFF \     # 关闭文档生成
  -DPAHO_BUILD_SAMPLES=OFF           # 关闭示例编译

make -j8
make install

编译安装后的文件目录:

yoyo@yoyo:~/360Downloads/paho.mqtt.c-1.3.14$ tree -L 2 arm_install/
arm_install/
├── bin
│   └── MQTTVersion
├── include
│   ├── MQTTAsync.h
│   ├── MQTTClient.h
│   ├── MQTTClientPersistence.h
│   ├── MQTTExportDeclarations.h
│   ├── MQTTProperties.h
│   ├── MQTTReasonCodes.h
│   └── MQTTSubscribeOpts.h
├── lib
│   ├── cmake
│   ├── libpaho-mqtt3a.so -> libpaho-mqtt3a.so.1
│   ├── libpaho-mqtt3a.so.1 -> libpaho-mqtt3a.so.1.3.14
│   ├── libpaho-mqtt3a.so.1.3.14
│   ├── libpaho-mqtt3as.so -> libpaho-mqtt3as.so.1
│   ├── libpaho-mqtt3as.so.1 -> libpaho-mqtt3as.so.1.3.14
│   ├── libpaho-mqtt3as.so.1.3.14
│   ├── libpaho-mqtt3c.so -> libpaho-mqtt3c.so.1
│   ├── libpaho-mqtt3c.so.1 -> libpaho-mqtt3c.so.1.3.14
│   ├── libpaho-mqtt3c.so.1.3.14
│   ├── libpaho-mqtt3cs.so -> libpaho-mqtt3cs.so.1
│   ├── libpaho-mqtt3cs.so.1 -> libpaho-mqtt3cs.so.1.3.14
│   └── libpaho-mqtt3cs.so.1.3.14
└── share
    └── doc

paho.mqtt.c 库编译后会生成四个动态库:

  • libpaho-mqtt3a.so异步paho.mqtt.c 库。
  • libpaho-mqtt3as.so异步的、使用了SSL的paho.mqtt.c库。
  • libpaho-mqtt3c.so:经典的、同步的paho.mqtt.c库。
  • libpaho-mqtt3cs.so:经典的、同步的、使用了SSL的 paho.mqtt.c 库。

异步和同步库的区别:Paho MQTT C Client Library: Asynchronous vs synchronous client applications

cmake编译:

yoyo@yoyo:~/360Downloads/paho.mqtt.c-1.3.14/build$ cmake -DCMAKE_BUILD_TYPE=Release \
>   -DCMAKE_INSTALL_PREFIX=/path/to/paho.mqtt.c-1.3.14/arm_install \
>   -DCMAKE_SYSTEM_NAME=Linux \
>   -DCMAKE_SYSTEM_PROCESSOR=arm \
>   -DCMAKE_C_COMPILER=arm-linux-gnueabihf-gcc \
>   -DPAHO_WITH_SSL=ON \
>   -DOPENSSL_ROOT_DIR=/path/to/openssl-openssl-3.5.0/arm_install \
>   -DPAHO_BUILD_STATIC=OFF \
>   -DPAHO_BUILD_DOCUMENTATION=OFF \
>   -DPAHO_BUILD_SAMPLES=OFF ..
CMake Deprecation Warning at CMakeLists.txt:18 (cmake_minimum_required):
  Compatibility with CMake < 3.10 will be removed from a future version of
  CMake.

  Update the VERSION argument <min> value.  Or, use the <min>...<max> syntax
  to tell CMake that the project requires at least <min> but has been updated
  to work with policies introduced by <max> or earlier.


-- The C compiler identification is GNU 11.1.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /path/to/toolchains/arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- CMake version: 3.31.3
-- CMake system name: Linux
-- Timestamp is 2025-04-14T03:30:34Z
-- Found OpenSSL: /path/to/openssl-openssl-3.5.0/arm_install/lib/libcrypto.so (found version "3.5.0")
-- Using OpenSSL with headers at /path/to/openssl-openssl-3.5.0/arm_install/include
-- Configuring done (0.2s)
-- Generating done (0.1s)
-- Build files have been written to: /path/to/paho.mqtt.c-1.3.14/build

make 编译:

yoyo@yoyo:~/360Downloads/paho.mqtt.c-1.3.14/build$ make -j8
[  3%] Built target thread
[ 27%] Built target common_obj
[ 52%] Built target common_ssl_obj
[ 53%] Building C object src/CMakeFiles/paho-mqtt3c.dir/MQTTClient.c.o
[ 54%] Building C object src/CMakeFiles/paho-mqtt3a.dir/MQTTAsync.c.o
[ 55%] Building C object src/CMakeFiles/paho-mqtt3cs.dir/MQTTClient.c.o
[ 56%] Building C object src/CMakeFiles/paho-mqtt3as.dir/MQTTAsync.c.o
[ 58%] Linking C shared library libpaho-mqtt3a.so
[ 59%] Built target paho-mqtt3a
[ 60%] Linking C executable test4
[ 61%] Linking C executable test45
[ 62%] Linking C executable test6
[ 63%] Linking C executable test8
[ 64%] Linking C executable test9
[ 65%] Built target test6
[ 65%] Built target test45
[ 66%] Built target test4
[ 67%] Linking C executable test95
[ 69%] Linking C shared library libpaho-mqtt3as.so
[ 69%] Built target test8
[ 72%] Linking C executable test11
[ 72%] Built target test9
[ 73%] Linking C executable test_issue373
[ 74%] Built target test95
[ 75%] Built target test11
[ 76%] Built target test_issue373
[ 77%] Built target paho-mqtt3as
[ 78%] Linking C executable test5
[ 79%] Linking C shared library libpaho-mqtt3c.so
[ 79%] Built target paho-mqtt3c
[ 80%] Linking C executable test1
[ 81%] Built target test5
[ 82%] Linking C executable test2
[ 83%] Linking C executable test_sync_session_present
[ 84%] Linking C executable MQTTVersion
[ 86%] Linking C executable test15
[ 87%] Linking C executable test10
[ 88%] Linking C executable test_connect_destroy
[ 89%] Built target test15
[ 90%] Built target test2
[ 91%] Built target test_sync_session_present
[ 92%] Built target MQTTVersion
[ 93%] Built target test1
[ 94%] Built target test10
[ 95%] Built target test_connect_destroy
[ 96%] Linking C shared library libpaho-mqtt3cs.so
[ 97%] Built target paho-mqtt3cs
[ 98%] Linking C executable test3
[100%] Built target test3

make install 安装:

yoyo@yoyo:~/360Downloads/paho.mqtt.c-1.3.14/build$ make install
[ 24%] Built target common_obj
[ 27%] Built target paho-mqtt3a
[ 30%] Built target paho-mqtt3c
[ 32%] Built target MQTTVersion
[ 56%] Built target common_ssl_obj
[ 60%] Built target paho-mqtt3cs
[ 63%] Built target paho-mqtt3as
[ 66%] Built target thread
[ 68%] Built target test1
[ 70%] Built target test15
[ 73%] Built target test2
[ 75%] Built target test3
[ 77%] Built target test4
[ 78%] Built target test45
[ 80%] Built target test5
[ 82%] Built target test6
[ 84%] Built target test8
[ 87%] Built target test9
[ 89%] Built target test95
[ 91%] Built target test10
[ 93%] Built target test11
[ 95%] Built target test_issue373
[ 97%] Built target test_sync_session_present
[100%] Built target test_connect_destroy
Install the project...
-- Install configuration: "Release"
-- Installing: /path/to/paho.mqtt.c-1.3.14/arm_install/share/doc/Eclipse Paho C/samples/MQTTAsync_publish.c
-- Installing: /path/to/paho.mqtt.c-1.3.14/arm_install/share/doc/Eclipse Paho C/samples/MQTTAsync_publish_time.c
-- Installing: /path/to/paho.mqtt.c-1.3.14/arm_install/share/doc/Eclipse Paho C/samples/MQTTAsync_subscribe.c
-- Installing: /path/to/paho.mqtt.c-1.3.14/arm_install/share/doc/Eclipse Paho C/samples/MQTTClient_publish.c
-- Installing: /path/to/paho.mqtt.c-1.3.14/arm_install/share/doc/Eclipse Paho C/samples/MQTTClient_publish_async.c
-- Installing: /path/to/paho.mqtt.c-1.3.14/arm_install/share/doc/Eclipse Paho C/samples/MQTTClient_subscribe.c
-- Installing: /path/to/paho.mqtt.c-1.3.14/arm_install/share/doc/Eclipse Paho C/samples/paho_c_pub.c
-- Installing: /path/to/paho.mqtt.c-1.3.14/arm_install/share/doc/Eclipse Paho C/samples/paho_c_sub.c
-- Installing: /path/to/paho.mqtt.c-1.3.14/arm_install/share/doc/Eclipse Paho C/samples/paho_cs_pub.c
-- Installing: /path/to/paho.mqtt.c-1.3.14/arm_install/share/doc/Eclipse Paho C/samples/paho_cs_sub.c
-- Installing: /path/to/paho.mqtt.c-1.3.14/arm_install/share/doc/Eclipse Paho C/samples/pubsub_opts.c
-- Installing: /path/to/paho.mqtt.c-1.3.14/arm_install/share/doc/Eclipse Paho C/CONTRIBUTING.md
-- Installing: /path/to/paho.mqtt.c-1.3.14/arm_install/share/doc/Eclipse Paho C/epl-v20
-- Installing: /path/to/paho.mqtt.c-1.3.14/arm_install/share/doc/Eclipse Paho C/edl-v10
-- Installing: /path/to/paho.mqtt.c-1.3.14/arm_install/share/doc/Eclipse Paho C/README.md
-- Installing: /path/to/paho.mqtt.c-1.3.14/arm_install/share/doc/Eclipse Paho C/notice.html
-- Installing: /path/to/paho.mqtt.c-1.3.14/arm_install/lib/libpaho-mqtt3c.so.1.3.14
-- Installing: /path/to/paho.mqtt.c-1.3.14/arm_install/lib/libpaho-mqtt3c.so.1
-- Installing: /path/to/paho.mqtt.c-1.3.14/arm_install/lib/libpaho-mqtt3c.so
-- Installing: /path/to/paho.mqtt.c-1.3.14/arm_install/lib/libpaho-mqtt3a.so.1.3.14
-- Installing: /path/to/paho.mqtt.c-1.3.14/arm_install/lib/libpaho-mqtt3a.so.1
-- Installing: /path/to/paho.mqtt.c-1.3.14/arm_install/lib/libpaho-mqtt3a.so
-- Installing: /path/to/paho.mqtt.c-1.3.14/arm_install/bin/MQTTVersion
-- Set non-toolchain portion of runtime path of "/path/to/paho.mqtt.c-1.3.14/arm_install/bin/MQTTVersion" to ""
-- Installing: /path/to/paho.mqtt.c-1.3.14/arm_install/include/MQTTAsync.h
-- Installing: /path/to/paho.mqtt.c-1.3.14/arm_install/include/MQTTClient.h
-- Installing: /path/to/paho.mqtt.c-1.3.14/arm_install/include/MQTTClientPersistence.h
-- Installing: /path/to/paho.mqtt.c-1.3.14/arm_install/include/MQTTProperties.h
-- Installing: /path/to/paho.mqtt.c-1.3.14/arm_install/include/MQTTReasonCodes.h
-- Installing: /path/to/paho.mqtt.c-1.3.14/arm_install/include/MQTTSubscribeOpts.h
-- Installing: /path/to/paho.mqtt.c-1.3.14/arm_install/include/MQTTExportDeclarations.h
-- Installing: /path/to/paho.mqtt.c-1.3.14/arm_install/lib/libpaho-mqtt3cs.so.1.3.14
-- Installing: /path/to/paho.mqtt.c-1.3.14/arm_install/lib/libpaho-mqtt3cs.so.1
-- Set non-toolchain portion of runtime path of "/path/to/paho.mqtt.c-1.3.14/arm_install/lib/libpaho-mqtt3cs.so.1.3.14" to ""
-- Installing: /path/to/paho.mqtt.c-1.3.14/arm_install/lib/libpaho-mqtt3cs.so
-- Installing: /path/to/paho.mqtt.c-1.3.14/arm_install/lib/libpaho-mqtt3as.so.1.3.14
-- Installing: /path/to/paho.mqtt.c-1.3.14/arm_install/lib/libpaho-mqtt3as.so.1
-- Set non-toolchain portion of runtime path of "/path/to/paho.mqtt.c-1.3.14/arm_install/lib/libpaho-mqtt3as.so.1.3.14" to ""
-- Installing: /path/to/paho.mqtt.c-1.3.14/arm_install/lib/libpaho-mqtt3as.so
-- Installing: /path/to/paho.mqtt.c-1.3.14/arm_install/lib/cmake/eclipse-paho-mqtt-c/eclipse-paho-mqtt-cConfig.cmake
-- Installing: /path/to/paho.mqtt.c-1.3.14/arm_install/lib/cmake/eclipse-paho-mqtt-c/eclipse-paho-mqtt-cConfig-release.cmake
-- Installing: /path/to/paho.mqtt.c-1.3.14/arm_install/lib/cmake/eclipse-paho-mqtt-c/eclipse-paho-mqtt-cConfigVersion.cmake

3. 移植到开发板

cp -arf /path/to/paho.mqtt.cpp/arm_install/lib/ /usr/paho.mqtt.cpp/

4. 简单示例

4.1 订阅——MQTTAsync_subscribe.c

这是使用了 libpaho-mqtt3a.so 进行订阅消息的源码,源码路径在源码的这个路径:paho.mqtt.c-1.3.14/src/samples/MQTTAsync_subscribe.c,只更改了服务器地址。完整代码如下:

/*******************************************************************************
 * Copyright (c) 2012, 2022 IBM Corp., Ian Craggs
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * and Eclipse Distribution License v1.0 which accompany this distribution. 
 *
 * The Eclipse Public License is available at 
 *   https://www.eclipse.org/legal/epl-2.0/
 * and the Eclipse Distribution License is available at 
 *   http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * Contributors:
 *    Ian Craggs - initial contribution
 *******************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "MQTTAsync.h"

#if !defined(_WIN32)
#include <unistd.h>
#else
#include <windows.h>
#endif

#if defined(_WRS_KERNEL)
#include <OsWrapper.h>
#endif

#define ADDRESS     "192.168.33.1:1883"
//#define ADDRESS     "tcp://mqtt.eclipseprojects.io:1883"
#define CLIENTID    "ExampleClientSub"
#define TOPIC       "MQTT Examples"
#define PAYLOAD     "Hello World!"
#define QOS         1
#define TIMEOUT     10000L

int disc_finished = 0;
int subscribed = 0;
int finished = 0;

void onConnect(void* context, MQTTAsync_successData* response);
void onConnectFailure(void* context, MQTTAsync_failureData* response);

void connlost(void *context, char *cause)
{
    MQTTAsync client = (MQTTAsync)context;
    MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer;
    int rc;

    printf("\nConnection lost\n");
    if (cause)
        printf("     cause: %s\n", cause);

    printf("Reconnecting\n");
    conn_opts.keepAliveInterval = 20;
    conn_opts.cleansession = 1;
    conn_opts.onSuccess = onConnect;
    conn_opts.onFailure = onConnectFailure;
    if ((rc = MQTTAsync_connect(client, &conn_opts)) != MQTTASYNC_SUCCESS)
    {
        printf("Failed to start connect, return code %d\n", rc);
        finished = 1;
    }
}


int msgarrvd(void *context, char *topicName, int topicLen, MQTTAsync_message *message)
{
    printf("Message arrived\n");
    printf("     topic: %s\n", topicName);
    printf("   message: %.*s\n", message->payloadlen, (char*)message->payload);
    MQTTAsync_freeMessage(&message);
    MQTTAsync_free(topicName);
    return 1;
}

void onDisconnectFailure(void* context, MQTTAsync_failureData* response)
{
    printf("Disconnect failed, rc %d\n", response->code);
    disc_finished = 1;
}

void onDisconnect(void* context, MQTTAsync_successData* response)
{
    printf("Successful disconnection\n");
    disc_finished = 1;
}

void onSubscribe(void* context, MQTTAsync_successData* response)
{
    printf("Subscribe succeeded\n");
    subscribed = 1;
}

void onSubscribeFailure(void* context, MQTTAsync_failureData* response)
{
    printf("Subscribe failed, rc %d\n", response->code);
    finished = 1;
}


void onConnectFailure(void* context, MQTTAsync_failureData* response)
{
    printf("Connect failed, rc %d\n", response->code);
    finished = 1;
}


void onConnect(void* context, MQTTAsync_successData* response)
{
    MQTTAsync client = (MQTTAsync)context;
    MQTTAsync_responseOptions opts = MQTTAsync_responseOptions_initializer;
    int rc;

    printf("Successful connection\n");

    printf("Subscribing to topic %s\nfor client %s using QoS%d\n\n"
           "Press Q<Enter> to quit\n\n", TOPIC, CLIENTID, QOS);
    opts.onSuccess = onSubscribe;
    opts.onFailure = onSubscribeFailure;
    opts.context = client;
    if ((rc = MQTTAsync_subscribe(client, TOPIC, QOS, &opts)) != MQTTASYNC_SUCCESS)
    {
        printf("Failed to start subscribe, return code %d\n", rc);
        finished = 1;
    }
}


int main(int argc, char* argv[])
{
    MQTTAsync client;
    MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer;
    MQTTAsync_disconnectOptions disc_opts = MQTTAsync_disconnectOptions_initializer;
    int rc;
    int ch;

    const char* uri = (argc > 1) ? argv[1] : ADDRESS;
    printf("Using server at %s\n", uri);

    if ((rc = MQTTAsync_create(&client, uri, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL))
            != MQTTASYNC_SUCCESS)
    {
        printf("Failed to create client, return code %d\n", rc);
        rc = EXIT_FAILURE;
        goto exit;
    }

    if ((rc = MQTTAsync_setCallbacks(client, client, connlost, msgarrvd, NULL)) != MQTTASYNC_SUCCESS)
    {
        printf("Failed to set callbacks, return code %d\n", rc);
        rc = EXIT_FAILURE;
        goto destroy_exit;
    }

    conn_opts.keepAliveInterval = 20;
    conn_opts.cleansession = 1;
    conn_opts.onSuccess = onConnect;
    conn_opts.onFailure = onConnectFailure;
    conn_opts.context = client;
    if ((rc = MQTTAsync_connect(client, &conn_opts)) != MQTTASYNC_SUCCESS)
    {
        printf("Failed to start connect, return code %d\n", rc);
        rc = EXIT_FAILURE;
        goto destroy_exit;
    }

    while (!subscribed && !finished)
        #if defined(_WIN32)
            Sleep(100);
        #else
            usleep(10000L);
        #endif

    if (finished)
        goto exit;

    do 
    {
        ch = getchar();
    } while (ch!='Q' && ch != 'q');

    disc_opts.onSuccess = onDisconnect;
    disc_opts.onFailure = onDisconnectFailure;
    if ((rc = MQTTAsync_disconnect(client, &disc_opts)) != MQTTASYNC_SUCCESS)
    {
        printf("Failed to start disconnect, return code %d\n", rc);
        rc = EXIT_FAILURE;
        goto destroy_exit;
    }
    while (!disc_finished)
    {
        #if defined(_WIN32)
            Sleep(100);
        #else
            usleep(10000L);
        #endif
    }

destroy_exit:
    MQTTAsync_destroy(&client);
exit:
    return rc;
}

交叉编译:

arm-linux-gnueabihf-gcc MQTTAsync_subscribe.c -I /path/to/paho.mqtt.c-1.3.14/arm_install/include/ -L /path/to/paho.mqtt.c-1.3.14/arm_install/lib/ -l paho-mqtt3a -o MQTTAsync_subscribe

在arm开发板中运行:

/customer/mqtt_test # Using server at 192.168.33.1:1883
Successful connection
Subscribing to topic MQTT Examples
for client ExampleClientSub using QoS1

Press Q<Enter> to quit

Subscribe succeeded

4.2 发布——MQTTAsync_publish.c

这是使用了 libpaho-mqtt3a.so 进行发布消息的源码,源码路径在源码的这个路径:paho.mqtt.c-1.3.14/src/samples/MQTTAsync_publish.c,只更改了服务器地址。完整代码如下:

/*******************************************************************************
 * Copyright (c) 2012, 2023 IBM Corp., Ian Craggs
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * and Eclipse Distribution License v1.0 which accompany this distribution. 
 *
 * The Eclipse Public License is available at 
 *   https://www.eclipse.org/legal/epl-2.0/
 * and the Eclipse Distribution License is available at 
 *   http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * Contributors:
 *    Ian Craggs - initial contribution
 *******************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "MQTTAsync.h"

#if !defined(_WIN32)
#include <unistd.h>
#else
#include <windows.h>
#endif

#if defined(_WRS_KERNEL)
#include <OsWrapper.h>
#endif

#define ADDRESS     "192.168.33.1:1883"
//#define ADDRESS     "tcp://mqtt.eclipseprojects.io:1883"
#define CLIENTID    "ExampleClientPub"
#define TOPIC       "MQTT Examples"
#define PAYLOAD     "Hello World!"
#define QOS         1
#define TIMEOUT     10000L

int finished = 0;

void connlost(void *context, char *cause)
{
    MQTTAsync client = (MQTTAsync)context;
    MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer;
    int rc;

    printf("\nConnection lost\n");
    if (cause)
        printf("     cause: %s\n", cause);

    printf("Reconnecting\n");
    conn_opts.keepAliveInterval = 20;
    conn_opts.cleansession = 1;
    if ((rc = MQTTAsync_connect(client, &conn_opts)) != MQTTASYNC_SUCCESS)
    {
        printf("Failed to start connect, return code %d\n", rc);
        finished = 1;
    }
}

void onDisconnectFailure(void* context, MQTTAsync_failureData* response)
{
    printf("Disconnect failed\n");
    finished = 1;
}

void onDisconnect(void* context, MQTTAsync_successData* response)
{
    printf("Successful disconnection\n");
    finished = 1;
}

void onSendFailure(void* context, MQTTAsync_failureData* response)
{
    MQTTAsync client = (MQTTAsync)context;
    MQTTAsync_disconnectOptions opts = MQTTAsync_disconnectOptions_initializer;
    int rc;

    printf("Message send failed token %d error code %d\n", response->token, response->code);
    opts.onSuccess = onDisconnect;
    opts.onFailure = onDisconnectFailure;
    opts.context = client;
    if ((rc = MQTTAsync_disconnect(client, &opts)) != MQTTASYNC_SUCCESS)
    {
        printf("Failed to start disconnect, return code %d\n", rc);
        exit(EXIT_FAILURE);
    }
}

void onSend(void* context, MQTTAsync_successData* response)
{
    MQTTAsync client = (MQTTAsync)context;
    MQTTAsync_disconnectOptions opts = MQTTAsync_disconnectOptions_initializer;
    int rc;

    printf("Message with token value %d delivery confirmed\n", response->token);
    opts.onSuccess = onDisconnect;
    opts.onFailure = onDisconnectFailure;
    opts.context = client;
    if ((rc = MQTTAsync_disconnect(client, &opts)) != MQTTASYNC_SUCCESS)
    {
        printf("Failed to start disconnect, return code %d\n", rc);
        exit(EXIT_FAILURE);
    }
}


void onConnectFailure(void* context, MQTTAsync_failureData* response)
{
    printf("Connect failed, rc %d\n", response ? response->code : 0);
    finished = 1;
}


void onConnect(void* context, MQTTAsync_successData* response)
{
    MQTTAsync client = (MQTTAsync)context;
    MQTTAsync_responseOptions opts = MQTTAsync_responseOptions_initializer;
    MQTTAsync_message pubmsg = MQTTAsync_message_initializer;
    int rc;

    printf("Successful connection\n");
    opts.onSuccess = onSend;
    opts.onFailure = onSendFailure;
    opts.context = client;
    pubmsg.payload = PAYLOAD;
    pubmsg.payloadlen = (int)strlen(PAYLOAD);
    pubmsg.qos = QOS;
    pubmsg.retained = 0;
    if ((rc = MQTTAsync_sendMessage(client, TOPIC, &pubmsg, &opts)) != MQTTASYNC_SUCCESS)
    {
        printf("Failed to start sendMessage, return code %d\n", rc);
        exit(EXIT_FAILURE);
    }
}

int messageArrived(void* context, char* topicName, int topicLen, MQTTAsync_message* m)
{
    /* not expecting any messages */
    return 1;
}

int main(int argc, char* argv[])
{
    MQTTAsync client;
    MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer;
    int rc;

    const char* uri = (argc > 1) ? argv[1] : ADDRESS;
    printf("Using server at %s\n", uri);

    if ((rc = MQTTAsync_create(&client, uri, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL)) != MQTTASYNC_SUCCESS)
    {
        printf("Failed to create client object, return code %d\n", rc);
        exit(EXIT_FAILURE);
    }

    if ((rc = MQTTAsync_setCallbacks(client, client, connlost, messageArrived, NULL)) != MQTTASYNC_SUCCESS)
    {
        printf("Failed to set callback, return code %d\n", rc);
        exit(EXIT_FAILURE);
    }

    conn_opts.keepAliveInterval = 20;
    conn_opts.cleansession = 1;
    conn_opts.onSuccess = onConnect;
    conn_opts.onFailure = onConnectFailure;
    conn_opts.context = client;
    if ((rc = MQTTAsync_connect(client, &conn_opts)) != MQTTASYNC_SUCCESS)
    {
        printf("Failed to start connect, return code %d\n", rc);
        exit(EXIT_FAILURE);
    }

    printf("Waiting for publication of %s\n"
         "on topic %s for client with ClientID: %s\n",
         PAYLOAD, TOPIC, CLIENTID);
    while (!finished)
        #if defined(_WIN32)
            Sleep(100);
        #else
            usleep(10000L);
        #endif

    MQTTAsync_destroy(&client);
    return rc;
}

交叉编译:

arm-linux-gnueabihf-gcc MQTTAsync_publish.c -I /path/to/paho.mqtt.c-1.3.14/arm_install/include/ -L /path/to/paho.mqtt.c-1.3.14/arm_install/lib/ -l paho-mqtt3a -o MQTTAsync_publish

在arm开发板中运行:

/customer/mqtt_test # ./MQTTAsync_publish
Using server at 192.168.33.1:1883
Waiting for publication of Hello World!
on topic MQTT Examples for client with ClientID: ExampleClientPub
Successful connection
Message with token value 1 delivery confirmed
Successful disconnection

五、FAQ

Q:install TARGETS given target "paho-mqtt3a" which does not exist.

CMake error while compiling paho.mqtt.cpp · Issue #493 · eclipse-paho/paho.mqtt.cpp

-- Paho C: Bundled
CMake Error at CMakeLists.txt:75 (add_subdirectory):
  The source directory

    /path/to/paho.mqtt.cpp-1.5.2/externals/paho-mqtt-c

  does not contain a CMakeLists.txt file.


CMake Error at CMakeLists.txt:79 (add_library):
  add_library cannot create ALIAS target "eclipse-paho-mqtt-c::paho-mqtt3a"
  because target "paho-mqtt3a" does not already exist.


CMake Error at CMakeLists.txt:82 (add_library):
  add_library cannot create ALIAS target "eclipse-paho-mqtt-c::paho-mqtt3as"
  because target "paho-mqtt3as" does not already exist.


CMake Error at CMakeLists.txt:97 (install):
  install TARGETS given target "paho-mqtt3a" which does not exist.

错误原因:没有下载 externals/paho-mqtt-c

解决方法:手动下载对应版本的 paho-mqtt-c

git clone https://github.com/eclipse-paho/paho.mqtt.c.git
mv paho.mqtt.c paho-mqtt-c
yoyo@yoyo:~/360Downloads/paho.mqtt.cpp-1.5.2$ tree -L 2 ./externals/
./externals/
└── paho-mqtt-c
    ├── about.html
    ├── android
    ├── appveyor.yml
    ├── build.xml
    ├── cbuild.bat
    ├── cmake
    ├── cmake-build.sh
    ├── CMakeLists.txt
    ├── CODE_OF_CONDUCT.md
    ├── CONTRIBUTING.md
    ├── deploy_rsa.enc
    ├── dist
    ├── doc
    ├── docs
    ├── edl-v10
    ├── epl-v20
    ├── LICENSE
    ├── Makefile
    ├── NOTICE
    ├── notice.html
    ├── PULL_REQUEST_TEMPLATE.md
    ├── README.md
    ├── SECURITY.md
    ├── src
    ├── test
    ├── test_package
    ├── version.major
    ├── version.minor
    └── version.patch

Q:libanl.so.1: cannot open shared object file: No such file or directory

./async_publish: error while loading shared libraries: libanl.so.1: cannot open shared object file: No such file or directory

错误原因:缺少libanl.so库。

解决方法

(1)在宿主机中查找 libanl.so(通常在交叉编译工具链的lib目录中)。

find / -name "libanl.so.1" 2>/dev/null
yoyo@yoyo:/media/sda3/share/tftpboot/mqtt_test$ find / -name "libanl.so*" 2>/dev/null
/path/to/toolchains/arm-linux-gnueabihf/arm-linux-gnueabihf/libc/lib/libanl.so.1
/path/to/toolchains/arm-linux-gnueabihf/arm-linux-gnueabihf/libc/usr/lib/libanl.so
yoyo@yoyo:/media/sda3/share/tftpboot/mqtt_test$ ll /path/to/toolchains/arm-linux-gnueabihf/arm-linux-gnueabihf/libc/lib/libanl.so.1
lrwxrwxrwx 1 yoyo yoyo 14 Jun  8  2021 /path/to/toolchains/arm-linux-gnueabihf/arm-linux-gnueabihf/libc/lib/libanl.so.1 -> libanl-2.33.so*

由此可见,libanl.so.1 是指向 libanl-2.33.so 的软链接。

(2)将 libanl-2.33.so 拷贝到arm开发板中,并创建软链接。

# 拷贝到arm开发板中
scp /path/to/toolchains/arm-linux-gnueabihf/arm-linux-gnueabihf/libc/lib/libanl-2.33.so /lib/

# 创建软链接
ln /lib/libanl-2.33.so /lib/libanl.so.1

Q:Connection attempt failed

/customer/mqtt_test # ./async_subscribe
Connecting to the MQTT server '192.168.33.1:1883'...Connection attempt failed
Connection attempt failed
Connection attempt failed
Connection attempt failed

错误原因:服务端mosquitto未启动。

解决方法:启动mosquitto服务端。

mosquitto -v -c /etc/mosquitto/mosquitto.conf

# 后台启动
mosquitto -v -c /etc/mosquitto/mosquitto.conf -d

Q:MQTT error [-1]: TCP/TLS connect failure

/customer/mqtt_test # ./async_publish
Initializing for server '192.168.33.1:1883'...
  ...OK

Connecting...
Waiting for the connection...
MQTT error [-1]: TCP/TLS connect failure

解决方法,同【Connection attempt failed】。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

花花少年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值