在OpenWrt下编译qtmqtt不生成模块头文件的问题
Qt是通过官方的非核心源video来安装编译的。我需要用Qt的mqtt模块,官方仓库在mqtt。
makefile如下:
#
# Copyright (C) 2020 OpenWrt
# Author: Mirko Vogt <mirko-openwrt@nanl.de>
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
include $(TOPDIR)/rules.mk
PKG_NAME:=qt5mqtt
PKG_VERSION:=5.15.0
PKG_RELEASE:=1
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL=https://code.qt.io/qt/qtmqtt.git
PKG_SOURCE_VERSION:=9ae8940b5e1870373c73dec4deadf761b7c1bfd1
PKG_BUILD_DIR=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
PKG_BUILD_PARALLEL:=1
PKG_BUILD_DEPENDS:=qt5base
PKG_INSTALL:=1
include $(INCLUDE_DIR)/package.mk
include $(INCLUDE_DIR)/nls.mk
-include $(STAGING_DIR)/host/mk/qmake.mk
define Package/qt5mqtt/Default
SECTION:=video-frameworks
CATEGORY:=Video
SUBMENU:=Frameworks and Toolkits
TITLE:=Qt5mqtt
DEPENDS:=+qt5base-core +qt5base-network
URL:=http://qt.io
MAINTAINER:=Mirko Vogt <mirko-openwrt@nanl.de>
endef
define Package/qt5mqtt
$(call Package/qt5mqtt/Default)
TITLE+=mqtt
endef
define Build/InstallDev
$(call Build/Install/HostFiles,$(1))
$(call Build/Install/Headers,$(1))
$(call Build/Install/Libs,$(1),*)
endef
define Package/qt5mqtt/install
$(call Build/Install/Libs,$(1),libQt5Mqtt)
endef
$(eval $(call BuildPackage,qt5mqtt))
编译后,提示找不到模块的头文件
configuration.h:59:10: fatal error: QMqttClient: No such file or directory
59 | #include <QMqttClient>
经过分析和了解,原来Qt模块的编译会通过perl脚本处理生成模块头文件,就是无.h后缀的头文件。而且是通过.pro文件里面的load(qt_module)
语句实现,应该是qmake识别到这句后,调用perl工具脚本syncqt.pl实现的。这里有个很大的坑,耗费了我1天时间才找到问题。
问题为:我在openwrt下编译不会自动生成模块头文件,对比在pc上编译可以生成。
经过对比分析发现是处不处理load(qt_module),因此应该是qmake的里面某个逻辑导致,https://forum.qt.io/topic/96057/how-to-automatically-generate-the-required-include-files-in-module-include-folder/7这里提到qt_module的执行依赖.git目录是否存在。这就对应得上了,openwrt下的编译目录是没有.git的,而我pc上的是从git来下来的。于是手动创建一个.git目录,果然生成了模块头文件。生成如下补丁解决这个问题:
Index: qt5mqtt-5.15.0/.git/dummy
===================================================================
--- /dev/null
+++ qt5mqtt-5.15.0/.git/dummy
@@ -0,0 +1 @@
+dummy file
未去分析qmake的源码,猜测是模块头文件里面会包含版本信息,而版本信息是通过探测仓库生成的,例如如果检查到.git,.svn目录,就用相应的指令获取。