i.MX6ULL(32位ARM)交叉编译paho.mqtt.c程序操作指南
问题根因
- 本地x86环境编译运行正常,是因为系统默认的gcc搜索路径中已经存在x86架构的paho.mqtt.c头文件与链接库,编译时无需额外指定路径即可找到依赖。
- 交叉编译时找不到
MQTTClient.h只是第一个暴露的问题:arm-linux-gnueabi-gcc不会默认读取宿主机x86架构的库、头文件搜索路径,且当前环境没有适配i.MX6ULL(32位ARM)架构的paho.mqtt.c库,就算手动指定宿主机的头文件路径,后续链接阶段也会因为x86库和ARM架构不匹配报错。
具体操作步骤
第一步:交叉编译ARM架构版本的paho.mqtt.c库
不能直接用宿主机上x86版本的paho库做交叉编译,必须先编译出对应ARM架构的库文件:
- 解压paho.mqtt.c源码包到本地工作目录,在源码根目录下新建
arm_install文件夹,用来存放后续编译生成的ARM版本头文件、库文件。 - 在源码根目录执行cmake配置,指定交叉编译参数:
cmake -Bbuild_arm -DCMAKE_C_COMPILER=arm-linux-gnueabi-gcc \ -DCMAKE_INSTALL_PREFIX=./arm_install \ -DPAHO_BUILD_SAMPLES=OFF \ -DPAHO_ENABLE_TESTING=OFF \ -DPAHO_WITH_SSL=ON
参数说明:
- 你之前本地编译链接的是
paho-mqtt3cs(带SSL支持的版本),所以默认开了PAHO_WITH_SSL选项。如果你的交叉编译环境没有ARM版openssl依赖,要么先交叉编译ARM版openssl,要么把这个选项改成OFF,后续链接库的时候换成不带s的paho-mqtt3c即可。 - 执行编译、安装命令:
cmake --build build_arm -j$(nproc) cmake --install build_arm
编译完成后,arm_install目录下会生成两个子目录:include目录里存放着MQTTClient.h等开发需要的头文件,lib目录里存放着ARM架构的paho动态/静态库文件。
第二步:交叉编译你的publish.c程序
回到你存放publish.c的目录,编译时手动指定刚才生成的ARM版paho库的头文件、库文件路径:
arm-linux-gnueabi-gcc publish.c -o pub_arm \ -I<替换为paho源码下arm_install/include目录的绝对路径> \ -L<替换为paho源码下arm_install/lib目录的绝对路径> \ -lpaho-mqtt3cs -Wl,-rpath,<目标板上库存放的路径>
参数说明:
-I参数指定头文件搜索路径,直接解决当前报错的MQTTClient.h: No such file or directory问题-L参数指定链接阶段库文件的搜索路径,确保链接的是ARM版本的paho库,不是宿主机的x86库-Wl,-rpath参数指定程序在i.MX6ULL目标板上运行时的动态库搜索路径,比如你打算把paho库放到目标板的/usr/lib目录,这里就填-Wl,-rpath,/usr/lib
第三步:部署到i.MX6ULL目标板运行
- 把编译生成的
pub_arm可执行文件,以及arm_install/lib目录下所有libpaho-mqtt3cs*开头的动态库文件,拷贝到目标板对应路径:可执行文件可放在任意有执行权限的目录,库文件放到你rpath指定的路径,或者系统默认的/lib、/usr/lib目录。 - 给
pub_arm加可执行权限后直接运行即可。
可选优化与避坑
- 如果不想单独往目标板拷贝动态库,可以在编译paho库的cmake配置阶段加
-DBUILD_SHARED_LIBS=OFF,编译静态库版本,后续编译应用程序时会直接把paho库打包进可执行文件,单文件即可运行。 - 编译完成后可以执行
file pub_arm验证架构,输出包含ARM, EABI5 version 1 (SYSV)字样就说明32位ARM架构编译正确。 - 如果开启SSL支持时cmake报错找不到openssl,先交叉编译ARM版openssl,再在paho的cmake配置里加
-DOPENSSL_ROOT_DIR=<ARM版openssl的安装路径>即可。
内容的提问来源于stack exchange,提问作者bhagwat-99
相关产品推荐
相关产品推荐

