说明
以 Paho MQTT 移植过来的程序为例,下面文件是该程序的 BUILD.gn 配置文件
import("//build/lite/config/component/lite_component.gni")
import("//build/lite/ndk/ndk.gni")
config("pahomqtt_config") {
include_dirs = [
"MQTTPacket/src",
"MQTTClient-C/src",
"MQTTClient-C/src/liteOS",
"//vendor/hisi/hi3861/hi3861/third_party/lwip_sack/include",
"//kernel/liteos_m/components/cmsis/2.0",
]
}
pahomqtt_sources = [
"MQTTClient-C/src/liteOS/MQTTLiteOS.c",
"MQTTClient-C/src/MQTTClient.c",
"MQTTPacket/src/MQTTConnectClient.c",
"MQTTPacket/src/MQTTConnectServer.c",
"MQTTPacket/src/MQTTDeserializePublish.c",
"MQTTPacket/src/MQTTFormat.c",
"MQTTPacket/src/MQTTPacket.c",
"MQTTPacket/src/MQTTSerializePublish.c",
"MQTTPacket/src/MQTTSubscribeClient.c",
"MQTTPacket/src/MQTTSubscribeServer.c",
"MQTTPacket/src/MQTTUnsubscribeClient.c",
"MQTTPacket/src/MQTTUnsubscribeServer.c",
"MQTTPacket/samples/transport.c",
]
lite_library("pahomqtt_static") {
target_type = "static_library"
sources = pahomqtt_sources
public_configs = [ ":pahomqtt_config" ]
}
lite_library("pahomqtt_shared") {
target_type = "shared_library"
sources = pahomqtt_sources
public_configs = [ ":pahomqtt_config" ]
}
ndk_lib("pahomqtt_ndk") {
if (board_name != "hi3861v100") {
lib_extension = ".so"
deps = [
":pahomqtt_shared"
]
} else {
deps = [
":pahomqtt_static"
]
}
head_files = [
"//third_party/pahomqtt"
]
}
核心作用
该 BUILD.gn 文件的核心目的是:将 Paho MQTT 库编译为适用于鸿蒙系统的静态库/动态库,并通过 NDK 目标提供给应用层使用。
- 对于 Hi3861 开发板,会生成静态库
pahomqtt_static.a, - 其他设备则生成动态库
pahomqtt_shared.so,平衡资源占用和复用性。
各部分含义
1. 导入外部配置(import 语句)
import("//build/lite/config/component/lite_component.gni")
import("//build/lite/ndk/ndk.gni")
解释:import 用于引入鸿蒙构建系统的内置模块:
lite_component.gni:提供鸿蒙轻量级组件的编译配置(如lite_library目标)。ndk.gni:提供 NDK 相关的构建规则(如ndk_lib目标,用于生成可供应用调用的库)。
2. 配置项(config 块)
config("pahomqtt_config") {
include_dirs = [
"MQTTPacket/src",
"MQTTClient-C/src",
"MQTTClient-C/src/liteOS",
"//vendor/hisi/hi3861/hi3861/third_party/lwip_sack/include",
"//kernel/liteos_m/components/cmsis/2.0",
]
}
解释:config 定义了一组可复用的编译配置,这里主要指定 头文件搜索路径(include_dirs):
- 前三个路径是 Paho MQTT 库自身的头文件目录(如
MQTTPacket/src包含 MQTT 协议解析的头文件)。 - 后两个路径是鸿蒙系统依赖的头文件:Hi3861 开发板的 LwIP 网络库(
lwip_sack)和 LiteOS-M 内核的 CMSIS 接口(嵌入式标准接口)。- 其他目标可通过
public_configs引用该配置,避免重复定义头文件路径。
- 其他目标可通过
3. 源文件列表(变量定义)
pahomqtt_sources = [
"MQTTClient-C/src/liteOS/MQTTLiteOS.c", # 适配 LiteOS 的 MQTT 客户端代码
"MQTTClient-C/src/MQTTClient.c", # MQTT 客户端核心实现
"MQTTPacket/src/MQTTConnectClient.c", # MQTT 连接(客户端)实现
"MQTTPacket/src/MQTTConnectServer.c", # MQTT 连接(服务器)实现
"MQTTPacket/src/MQTTDeserializePublish.c", # 发布报文反序列化
"MQTTPacket/src/MQTTFormat.c", # 报文格式化工具
"MQTTPacket/src/MQTTPacket.c", # MQTT 报文核心处理
"MQTTPacket/src/MQTTSerializePublish.c", # 发布报文序列化
"MQTTPacket/src/MQTTSubscribeClient.c", # 订阅(客户端)实现
"MQTTPacket/src/MQTTSubscribeServer.c", # 订阅(服务器)实现
"MQTTPacket/src/MQTTUnsubscribeClient.c", # 取消订阅(客户端)实现
"MQTTPacket/src/MQTTUnsubscribeServer.c", # 取消订阅(服务器)实现
"MQTTPacket/samples/transport.c", # 网络传输层实现(基于 Socket)
]
解释:定义变量 pahomqtt_sources,包含所有需要编译的 MQTT 库源码文件:
MQTTLiteOS.c是适配鸿蒙 LiteOS 内核的代码(如线程、互斥锁等)。transport.c是网络传输层实现(通常基于 LwIP 的 Socket,对应之前报错中缺失的transport_open等函数)。
这些文件覆盖了 MQTT 协议的核心功能:连接、订阅、发布、报文序列化/反序列化等
=========注意==========
如果应用程序模块需要该 paho mqtt 中其他 .c 文件的功能,将这些 .c 文件添加到这里
4. 静态库目标(lite_library 静态库)
lite_library("pahomqtt_static") {
target_type = "static_library" # 生成静态库(.a)
sources = pahomqtt_sources # 引用上面定义的源文件列表
public_configs = [ ":pahomqtt_config" ] # 应用头文件配置
}
解释:lite_library 是鸿蒙特有的目标类型,用于构建适用于轻量级设备的库:
target_type = "static_library"表示生成 静态库(编译时会被完整打包到最终可执行文件中,运行时无需额外加载,适合资源受限的嵌入式设备(如 Hi3861))。public_configs指定该库对外暴露的配置(其他依赖该库的目标会自动继承这些头文件路径)。
5. 动态库目标(lite_library 动态库)
lite_library("pahomqtt_shared") {
target_type = "shared_library" # 生成动态库(.so)
sources = pahomqtt_sources
public_configs = [ ":pahomqtt_config" ]
}
解释:与静态库类似,但 target_type = "shared_library" 表示生成动态库(运行时加载,可被多个应用共享)。
6. NDK 库目标(ndk_lib)
ndk_lib("pahomqtt_ndk") {
if (board_name != "hi3861v100") { # 若不是 Hi3861 开发板
lib_extension = ".so" # 输出动态库(.so)
deps = [ ":pahomqtt_shared" ] # 依赖动态库
} else { # 若是 Hi3861 开发板
deps = [ ":pahomqtt_static" ] # 依赖静态库
}
head_files = [ "//third_party/pahomqtt" ] # 暴露的头文件目录
}
解释:ndk_lib 是鸿蒙 NDK 相关的目标,用于生成可供应用开发者调用的库:
条件判断
board_name != "hi3861v100":Hi3861 开发板(riscv32 架构)通常更适合 静态库(编译时会被完整打包到最终可执行文件中,运行时无需额外加载,适合资源受限的嵌入式设备,如 Hi3861),其他设备可使用动态库。head_files指定该库对外暴露的头文件目录,确保应用能正确引用 MQTT 库的头文件(如#include "MQTTClient.h")。
业务代码依赖该库的配置
Hi3861 开发板
通过上面可知,Hi3861 通常更适合 静态库,如果业务代码依赖 paho mqtt,要在业务代码的 BUILD.gn 中,加上下面配置:
deps = [
"//third_party/pahomqtt:pahomqtt_static", // 依赖Paho MQTT静态库
]