对于使用 MQTT 的项目,我总是必须从源代码编译 QtMqtt 模块,因为它不包含在预构建的 Windows 版本中,也无法选择安装。在 Qt5 中这非常简单:从官方 git (https://code.qt.io/cgit/qt/qtmqtt.git/) 下载源代码,在 QtCreator 中打开 .pro 文件并编译项目。对于安装,我只是将 .dll 文件移至我的 Qt 安装目录。
现在在Qt6中,构建过程从qmake切换到cmake,所以我不能简单地在QtCreator中加载项目,而是必须使用CMake手动编译它,我发现这非常不直观并且容易出错。据我了解,从现在开始我无法自己编译单个模块,而是必须获取整个 Qt 6.2.0 源代码(即通过安装程序选项),然后在 CMake 上使用
--target
选项来仅构建特定的模块模块。这就是我到目前为止所做的:
Qt/6.2.0/Src
)Qt/6.2.0/build
)..\Src\configure -prefix Qt\6.2.0\build
cmake --build . --target qtmqtt
cmake --install .
发生的情况是配置有效,构建也应该有效,但安装失败,并显示以下内容:
CMake Error at qtbase/src/3rdparty/libpng/cmake_install.cmake:41 (file):
file INSTALL cannot find
"F:/DEV/prog/Qt/6.2.0/build/qtbase/mkspecs/modules/qt_ext_libpng.pri": File
exists.
Call Stack (most recent call first):
qtbase/src/3rdparty/cmake_install.cmake:42 (include)
qtbase/src/cmake_install.cmake:42 (include)
qtbase/cmake_install.cmake:244 (include)
cmake_install.cmake:42 (include)
文件夹
Qt/6.2.0/build
仅包含.cmake文件,但没有任何对我来说可用的.dll文件。我只是不明白如何使用 cmake 正确设置所有内容。既然在 Qt5 中使用 qmake 编译模块相当容易,为什么他们现在要把事情搞得这么复杂呢?
使用 Qt Installer 在
${HOME}/Qt/6.7.2/
中安装 Qt 6.7.2,这就是我在 Linux 上的做法。
# Create a work directory
mkdir ~/temporal && cd ~/temporal
# Clone the repository
git clone https://github.com/qt/qtmqtt.git
# Switch to the repository
cd qtmqtt
# Checkout the branch corresponding to the target kit
git checkout 6.7.2
# Create a directory to build the module cleanly
mkdir build && cd build
# Use the qt-configure-module tool
~/Qt/6.7.2/gcc_64/bin/qt-configure-module ..
# Build it here
~/Qt/Tools/CMake/bin/cmake --build .
# Install the module in the correct location
~/Qt/Tools/CMake/bin/cmake --install . --verbose
编辑项目的
CMakeLists.txt
文件
(1) 将
Mqtt
添加到相关的 find_package
宏中,如下所示:
find_package(QT NAMES Qt6 COMPONENTS Widgets Network Sql Mqtt REQUIRED)
(2) 将
Qt${QT_VERSION_MAJOR}::Mqtt
添加到 target_link_libraries
行,如下所示:
target_link_libraries(MyCleanProject PRIVATE Qt${QT_VERSION_MAJOR}::Widgets Qt${QT_VERSION_MAJOR}::Network Qt${QT_VERSION_MAJOR}::Mqtt Qt${QT_VERSION_MAJOR}::Sql)
(3)运行CMake
尝试实际使用该模块
在项目源中添加相关包含,如下所示:
#include <QtMqtt/QtMqtt>
// and then try to use QtMqtt classes
QMqttClient client;
重建项目。应该干净地编译和链接。
从 CLI 构建 Qt 项目时最好设置正确的环境变量。我的偏好是在我的用户目录中有一个包含所有相关变量的脚本。
Qt_environment.sh
:export QT_VERSION="6.7.2"
export QT_INSTALL_DIR="${HOME}/Qt"
export CMAKE_BIN_DIR="${QT_INSTALL_DIR}/Tools/CMake/bin"
export QMAKE_BIN_DIR="${QT_INSTALL_DIR}/${QT_VERSION}/gcc_64/bin"
export CMAKE_PREFIX_PATH="${QT_INSTALL_DIR}/${QT_VERSION}/gcc_64/"
export NINJA_DIR="${QT_INSTALL_DIR}/Tools/Ninja"
export PATH="${PATH}:${CMAKE_BIN_DIR}:${QMAKE_BIN_DIR}:${NINJA_DIR}"
在构建这样的项目之前,可以选择从命令行手动加载
source $HOME/Qt_environment.sh
# do some Qt stuff here, cmake, ninja, etc
或者只是从
.bashrc
为每个新的 bash shell 加载它。对于任何其他 shell 都可以完成同样的操作。
# $HOME/.bashrc
# Source global definitions
if [ -f /etc/bashrc ]; then
. /etc/bashrc
fi
# ...
# rest of the .bashrc file ommited for brevity
# ...
# Relevant part here - add these two lines at the end
# Load Qt environment variables
source "$HOME/Qt_environment.sh"
我在尝试为 Qt 6.5.0 构建
QtMqtt
时发现了一个问题,如下所示:
/home/user/Qt/6.5.0/gcc_64/include/QtCore/qfloat16.h:81:42: error:
declaration of ‘f’ shadows a member of ‘qfloat16’ [-Werror=shadow]
81 | constexpr inline qfloat16(NativeType f) : f(f) {}
| ~~~~~~~~~~~^
/home/user/Qt/6.5.0/gcc_64/include/QtCore/qfloat16.h:121:20: note:
shadowed declaration is here
121 | NativeType f;
| ^
cc1plus: all warnings being treated as errors
可以通过编辑
${QT_DIR}/6.5.0/gcc_64/include/QtCore/qfloat16.h
来解决警告/错误,方法是将构造函数参数的名称修改为与 f
不同的任何名称,这会与具有相同 f
名称的成员变量发生冲突并遮蔽。
从此:
constexpr inline qfloat16(NativeType f) : f(f) {}
对此:
constexpr inline qfloat16(NativeType ff) : f(ff) {}
请注意,这并不是针对所有此类警告/错误的一揽子解决方案:
declaration of ‘zzz’ shadows a member of ‘whateverType’ [-Werror=shadow].
据我了解,我无法自行编译单个模块 从现在开始,但必须获取整个 Qt 6.2.0 源代码 (即通过安装程序选项)
这是不正确的。给定一个预先构建的 Qt,您应该仍然能够通过运行例如从源代码构建 qmqtt 包
<QTDIR>\bin\qt-configure-module <mqtt_src_dir>
cmake --build .
尝试将
cmake --install .
替换为 cmake --install qtmqtt