在Qt Creator中使用vcpkg:综合指南
在Qt Creator中使用vcpkg,尤其是在Windows的MinGW环境下,集成可能会遇到挑战。本指南探讨了在Qt Creator中使用vcpkg的不同方法,重点关注推荐的vcpkg.json清单文件方法。
1. 使用vcpkg.json清单文件(推荐)
vcpkg.json清单文件是现代化的、项目本地化的管理方法。它非常适合需要精确依赖控制和版本管理的项目。
优势:
- 版本控制:在版本控制系统中定义和跟踪依赖版本。
- 项目自包含:每个项目可以有自己独立的vcpkg.json,避免项目间冲突。
- 跨平台兼容性:更容易在不同平台上构建项目。
- 可重现性:开发人员或CI/CD系统可以快速、自动地安装依赖。
使用方法:
- 在项目根目录创建
vcpkg.json
文件。 - 在文件中定义项目依赖。
- 运行cmake或其他构建工具时,vcpkg会自动解析vcpkg.json并安装所需库。
cmake命令示例:
cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=E:/vcpkg/scripts/buildsystems/vcpkg.cmake
vcpkg.json基本结构:
vcpkg.json文件是描述项目依赖的JSON格式文件。以下是基本结构:
{
"name": "你的项目名称",
"version-string": "0.1.0",
"dependencies": [
"fmt",
{
"name": "vtk",
"features": ["qt"]
}
]
}
主要元素:
name
:你的项目名称。version-string
:你的项目版本。dependencies
:所需库的数组。可以简单指定名称,或使用对象进行更复杂的配置(如指定特性)。
你还可以在此文件中指定版本约束、默认特性和更高级的选项。
在Qt中的使用参考: vcpkg Package Manager | Qt Creator Documentation
VCPKG 清单文件使用
本指南旨在帮助开发者有效地使用 vcpkg 清单文件来管理 C++ 项目依赖。vcpkg 是一个强大的包管理器,而清单文件模式让依赖管理变得更加简单和可控。
清单文件介绍
vcpkg 清单文件(vcpkg.json
)是一个 JSON 格式的文件,用于声明项目的依赖关系。它允许您精确指定项目所需的库、版本和特性,确保所有开发者和构建环境使用相同的依赖配置。
基本结构
一个基本的 vcpkg.json
文件结构如下:
{
"$schema": "https://raw.githubusercontent.com/microsoft/vcpkg-tool/main/docs/vcpkg.schema.json",
"name": "your-project-name",
"version-string": "0.1.0",
"dependencies": [
"package1",
{
"name": "package2",
"features": ["feature1", "feature2"]
}
]
}
说明:
"$schema"
: 指定 JSON schema,提供编辑器自动完成和验证。"name"
: 您的项目名称。"version-string"
: 您的项目版本。"dependencies"
: 列出项目依赖的包。可以是简单的字符串或包含额外信息的对象。
使用 Features
Features 允许您选择包的特定功能或组件。例如,对于 VTK 包with Qt support:
{
"dependencies": [
{
"name": "vtk",
"features": ["qt"]
}
]
}
说明:
"features"
数组列出了您想要启用的特定功能。- 不同的包可能有不同的可用 features,可以通过
vcpkg search package-name
命令查看。
使用 Baseline
Baseline 用于指定一个特定时间点的所有包版本,确保项目依赖的一致性。在 vcpkg-configuration.json
文件中设置:
{
"$schema": "https://raw.githubusercontent.com/microsoft/vcpkg-tool/main/docs/vcpkg-configuration.schema.json",
"default-registry": {
"kind": "git",
"repository": "https://github.com/Microsoft/vcpkg",
"baseline": "a7b6122f6b6504d16d96117336a0562693579309"
}
}
说明:
"baseline"
: 指定 vcpkg 仓库的特定 commit。这确保了所有依赖包使用该时间点的版本。- 将此文件与
vcpkg.json
放在同一目录。
使用 Overrides
Overrides 允许您为特定包指定版本,覆盖 baseline 或默认版本:
{
"dependencies": [
"package1",
"package2"
],
"overrides": [
{
"name": "package1",
"version": "2.1.0"
}
]
}
说明:
"overrides"
部分允许您精确控制特定包的版本。- 这对于解决版本冲突或使用特定版本的包很有用。
指定最新版本
vcpkg 不直接支持指定 "最新版本"。要使用最新版本,您需要手动查找并指定:
-
查找最新版本号:
vcpkg search package-name
-
在
overrides
中指定该版本:"overrides": [ { "name": "package-name", "version": "x.y.z" } ]
说明:
- 定期更新这些版本号以保持使用最新版本。
- 使用
vcpkg update
确保本地 vcpkg 库是最新的。
混合使用 Baseline 和最新版本
要让某些包使用 baseline 版本,而其他使用最新版本:
- 在
vcpkg-configuration.json
中设置 baseline。 - 在
vcpkg.json
中为需要最新版本的包添加 override:
{
"dependencies": [
{
"name": "vtk",
"features": ["qt"]
},
"icu"
],
"overrides": [
{
"name": "icu",
"version": "72.1" // 替换为实际的最新版本
}
]
}
说明:
- VTK 将使用 baseline 中指定的版本。
- ICU 将使用在
overrides
中指定的版本。
查找包的最新版本
有几种方法可以查找包的最新版本:
-
使用
vcpkg search package-name
-
查看 GitHub 上 vcpkg 仓库中
ports/package-name
目录下的vcpkg.json
或CONTROL
文件 -
使用 Git 查看版本历史
cd <vcpkg_root> # 进入 vcpkg 的根目录 git log ports/<package-name> # 查看本地的ports/<package-name>历史信息 git log -- ports/<package-name> origin/master # 查看远程origin/master分支下面ports/<package-name>历史信息 #在 Git 中,-- 是一个常用的分隔符,用于明确告诉 Git 后面的参数是文件路径,而不是分支名、标签名或者其他命令的参数。这在某些情况下是非常重要的,因为 Git 可能会混淆路径和其他名称。 #1. git log ports/opencv #这个命令会显示 ports/opencv 路径下的文件的提交历史。Git 会尝试解释 ports/opencv 作为路径,但如果存在一个和这个名字类似的分支或标签,Git 可能会误认为你指的是一个分支或标签,而不是一个路径。 #2. git log -- ports/opencv #这里的 -- 用作分隔符,明确告诉 Git 后面的 ports/opencv 是一个文件路径,而不是分支、标签或其他参数。这是为了避免 Git 将路径名和其他参数混淆。即使有一个叫做 ports/opencv 的分支或标签,-- 也确保 Git 将它识别为路径。 #3. git log -- ports/opencv origin/master #在这个命令中,origin/master 是一个远程分支的引用,表示你希望查看相对于该远程分支的提交历史。而 -- 仍然起到分隔作用,确保 Git 将 ports/opencv 识别为文件路径,并与远程分支 origin/master 进行对比。
说明:
- 定期检查更新以获取最新的功能和安全修复。
- 在更新版本之前,请确保新版本与您的项目兼容。
2. 使用 vcpkg integrate install(传统方式)
这种方式是 vcpkg 的传统用法,适用于系统级别的库安装和管理。您可以全局安装库,并通过 vcpkg integrate install
进行 IDE(如 Visual Studio 或 Qt Creator)和系统级别的集成。
优势:
- 全局集成:使用
vcpkg integrate install
可以全局集成库,方便同一台机器上多个项目复用这些库,无需为每个项目重复安装。 - 简单快捷:对于小型项目或快速原型开发,可以直接安装库并使用,不需要为每个项目管理独立的
vcpkg.json
文件。
缺点:
- 版本管理困难:全局安装的库没有项目级的版本控制,不同项目可能对库版本有不同要求,容易引发冲突。
- 跨平台复杂性:全局安装依赖库可能导致跨平台项目管理更加复杂,特别是在 CI/CD 环境中,每个开发者都需要手动安装正确版本的库。
如何使用:
-
使用
vcpkg install
安装依赖库:vcpkg install fmt vcpkg install vtk[qt]
-
执行全局集成命令:
vcpkg integrate install
IDE 将自动使用 vcpkg 安装的库。
对于Qt Creator项目,尤其是使用MinGW的项目,强烈推荐使用vcpkg.json清单文件方法结合CMake。这可以避免传统集成方法带来的许多兼容性问题。手动配置路径和库链接可以克服一些限制。如果遇到持续的兼容性问题,可以考虑切换到静态库版本。
根据项目需求选择适合的方法:
- 对于较大的项目、复杂的依赖关系和多人协作项目,使用vcpkg.json清单文件。
- 对于快速原型、个人项目或简单依赖,可以使用传统的vcpkg integrate install方法。
QtCreator 不使用清单文件的情况下使用VCPKG
如果使用清单文件,对于个人开发或者没有网络的环境那是非常难受的,各方面受到掣肘,所以这里也说明一下不使用清单文件,直接使用VCPKG来进行包引用的方法,MSVC没有什么好说的,使用Viusal Studio基本就是步步过,不会有什么地方遇到问题,这里使用MinGW来进行说明,为了不让VCPKG限定在安装QtCreator时带上的Qt的版本麻烦, 我这里使用的Qt都是通过VCPKG进行安装的, 因为有些库的Features有Qt时,是进行的联合编译,版本不一致极有可能遇到链接、运行时的错误等
这里通过一个示例来作为说明:
- VCPKG安装Qt5, OpenCV
- 打印Qt版本信息确认一下是否是VCPKG安装的版本
- 使用OpenCV生成一张图片并绘制一个圆
- 利用QLabel显示这个图片
安装triplet=x64-mingw-dynamic的Qt5、OpenCV
vcpkg install qt5 opencv triplet=x64-mingw-dynamic --clean-after-build
安装完成后的列表如下:
vcpkg.exe list | findstr mingw
abseil:x64-mingw-dynamic 20240722.0 Abseil is an open-source collection of C++ libra...
brotli:x64-mingw-dynamic 1.1.0#1 a generic-purpose lossless compression algorithm...
bzip2:x64-mingw-dynamic 1.0.8#6 bzip2 is a freely available, patent free, high-q...
bzip2[tool]:x64-mingw-dynamic Builds bzip2 executable
double-conversion:x64-mingw-dynamic 3.3.0 Efficient binary-decimal and decimal-binary conv...
egl-registry:x64-mingw-dynamic 2024-01-25 EGL API and Extension Registry
flatbuffers:x64-mingw-dynamic 24.3.25 FlatBuffers is a cross platform serialization li...
flatbuffers:x64-mingw-static 24.3.25 FlatBuffers is a cross platform serialization li...
freetype:x64-mingw-dynamic 2.13.3 A library to render fonts.
freetype[brotli]:x64-mingw-dynamic Support decompression of WOFF2 streams
freetype[bzip2]:x64-mingw-dynamic Support bzip2 compressed fonts.
freetype[png]:x64-mingw-dynamic Support PNG compressed OpenType embedded bitmaps.
freetype[zlib]:x64-mingw-dynamic Use zlib instead of internal library for DEFLATE
harfbuzz:x64-mingw-dynamic 10.0.1 HarfBuzz OpenType text shaping engine
harfbuzz[freetype]:x64-mingw-dynamic Enable FreeType support
libjpeg-turbo:x64-mingw-dynamic 3.0.4 libjpeg-turbo is a JPEG image codec that uses SI...
liblzma:x64-mingw-dynamic 5.6.3 Compression library with an API similar to that ...
libpng:x64-mingw-dynamic 1.6.43#3 libpng is a library implementing an interface fo...
libwebp:x64-mingw-dynamic 1.4.0#1 WebP codec: library to encode and decode images ...
libwebp:x64-mingw-static 1.4.0#1 WebP codec: library to encode and decode images ...
libwebp[libwebpmux]:x64-mingw-dynamic Build the libwebpmux library
libwebp[libwebpmux]:x64-mingw-static Build the libwebpmux library
libwebp[nearlossless]:x64-mingw-dynamic Enable near-lossless encoding
libwebp[nearlossless]:x64-mingw-static Enable near-lossless encoding
libwebp[simd]:x64-mingw-dynamic Enable any SIMD optimization.
libwebp[simd]:x64-mingw-static Enable any SIMD optimization.
libwebp[unicode]:x64-mingw-dynamic Build Unicode executables. (Adds definition UNIC...
libwebp[unicode]:x64-mingw-static Build Unicode executables. (Adds definition UNIC...
opencv4:x64-mingw-dynamic 4.8.0#22 computer vision library
opencv4[default-features]:x64-mingw-dynamic Platform-dependent default features
opencv4[dnn]:x64-mingw-dynamic Enable dnn module
opencv4[jpeg]:x64-mingw-dynamic JPEG support for opencv
opencv4[png]:x64-mingw-dynamic PNG support for opencv
opencv4[quirc]:x64-mingw-dynamic Enable QR code module
opencv4[tiff]:x64-mingw-dynamic TIFF support for opencv
opencv4[webp]:x64-mingw-dynamic WebP support for opencv
opencv:x64-mingw-dynamic 4.8.0#1 Computer vision library
opencv[default-features]:x64-mingw-dynamic Platform-dependent default features
openssl:x64-mingw-dynamic 3.3.2#1 OpenSSL is an open source project that provides ...
pcre2:x64-mingw-dynamic 10.43 Regular Expression pattern matching using the sa...
pcre2[jit]:x64-mingw-dynamic Enable support for Just-In-Time compiling regex ...
pcre2[platform-default-features]:x64-mingw-dynamic Enable default features
protobuf:x64-mingw-dynamic 4.25.1#1 Google's language-neutral, platform-neutral, ext...
qt5-activeqt:x64-mingw-dynamic 5.15.15 Active Qt is a helper framework that enables the...
qt5-base:x64-mingw-dynamic 5.15.15 Qt Base provides the basic non-GUI functionality...
qt5-declarative:x64-mingw-dynamic 5.15.15 Qt Declarative (Quick 2)
qt5-graphicaleffects:x64-mingw-dynamic 5.15.15 The Qt Graphical Effects module provides a set o...
qt5-imageformats:x64-mingw-dynamic 5.15.15 The Qt Image Formats add-on module provides opti...
qt5-imageformats[tiff]:x64-mingw-dynamic Enable TIFF support
qt5-imageformats[webp]:x64-mingw-dynamic Enable WEBP support
qt5-multimedia:x64-mingw-dynamic 5.15.15 Qt Multimedia is an essential module that provid...
qt5-networkauth:x64-mingw-dynamic 5.15.15 Qt Network Authorization provides a set of APIs ...
qt5-quickcontrols2:x64-mingw-dynamic 5.15.15 Qt Quick Controls provides a set of controls tha...
qt5-quickcontrols:x64-mingw-dynamic 5.15.15 The Qt Quick Controls module provides a set of c...
qt5-svg:x64-mingw-dynamic 5.15.15 Qt SVG provides classes for rendering and displa...
qt5-tools:x64-mingw-dynamic 5.15.15 A collection of tools and utilities that come wi...
qt5-translations:x64-mingw-dynamic 5.15.15 Qt translations.
qt5-websockets:x64-mingw-dynamic 5.15.15 The Qt WebSockets module provides C++ and QML in...
qt5:x64-mingw-dynamic 5.15.15 A cross-platform application and UI framework.
qt5[activeqt]:x64-mingw-dynamic Windows Only
qt5[declarative]:x64-mingw-dynamic
qt5[essentials]:x64-mingw-dynamic Build the essential qt modules
qt5[imageformats]:x64-mingw-dynamic
qt5[multimedia]:x64-mingw-dynamic
qt5[networkauth]:x64-mingw-dynamic
qt5[quickcontrols2]:x64-mingw-dynamic
qt5[quickcontrols]:x64-mingw-dynamic (deprecated)
qt5[svg]:x64-mingw-dynamic
qt5[tools]:x64-mingw-dynamic
qt5[translations]:x64-mingw-dynamic
qt5[websockets]:x64-mingw-dynamic
quirc:x64-mingw-dynamic 1.2 quirc is one of the C library available for scan...
quirc:x64-mingw-static 1.2 quirc is one of the C library available for scan...
sqlite3:x64-mingw-dynamic 3.46.1 SQLite is a software library that implements a s...
sqlite3[json1]:x64-mingw-dynamic Enable JSON functionality for sqlite3
tiff:x64-mingw-dynamic 4.6.0#5 A library that supports the manipulation of TIFF...
tiff[jpeg]:x64-mingw-dynamic Support JPEG compression in TIFF image files
tiff[lzma]:x64-mingw-dynamic Support LZMA compression in TIFF image files
tiff[zip]:x64-mingw-dynamic Support ZIP/deflate compression in TIFF image files
utf8-range:x64-mingw-dynamic 4.25.1 Fast UTF-8 validation with Range algorithm (NEON...
zlib:x64-mingw-dynamic 1.3.1 A compression library
zlib:x64-mingw-static 1.3.1 A compression library
zstd:x64-mingw-dynamic 1.5.6 Zstandard - Fast real-time compression algorithm
设置QtCreator中构建套件的参数
-
设置路径: 编辑/Preferences/构建套件(Kit)
-
选择相应的编译器: 找到CMake Configuration项
-
修改Qt MinGW kit的CMake Configuration:
-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} -DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} -DCMAKE_TOOLCHAIN_FILE:FILEPATH=E:/vcpkg/scripts/buildsystems/vcpkg.cmake -DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} -DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} -DVCPKG_TARGET_TRIPLET:STRING=x64-mingw-dynamic
我这里加入了
-DCMAKE_TOOLCHAIN_FILE:FILEPATH=E:/vcpkg/scripts/buildsystems/vcpkg.cmake
和-DVCPKG_TARGET_TRIPLET:STRING=x64-mingw-dynamic
,我这里安装的包都是x64-mingw-dynamic的所以相应的做上设置同样道理,这里也顺带说一下Qt MSVC kit的CMake Configuation的设置:
-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} -DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} -DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} -DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} -DCMAKE_TOOLCHAIN_FILE:FILEPATH=E:/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_TARGET_TRIPLET:STRING=x64-windows
-
示例的CMakeLists内容:
cmake_minimum_required(VERSION 3.16) project(qtwithcmake LANGUAGES CXX) set(CMAKE_AUTOUIC ON) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) find_package(QT NAMES Qt5 Qt6 REQUIRED COMPONENTS Widgets) find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets) message(STATUS ${QT_VERSION_MAJOR}) find_package(OpenCV REQUIRED) add_executable(qtwithcmake main.cpp ) target_link_libraries(qtwithcmake Qt${QT_VERSION_MAJOR}::Widgets ${OpenCV_LIBRARIES}) # include(GNUInstallDirs) # install(TARGETS qtwithcmake # LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} # RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} # )
-
示例的main.cpp内容:
#include <QApplication> #include <QLabel> #include <QPixmap> #include <QImage> #include <QDebug> #include <opencv2/opencv.hpp> QImage cvMat2Qimage(const cv::Mat& mat) { switch (mat.type()) { // 8-bit, 3channel(RGB) image case CV_8UC3: { QImage image(mat.data, mat.cols, mat.rows, mat.step, QImage::Format_RGB888); return image.rgbSwapped(); } // 8-bit, 1channel(grayscale) image case CV_8UC1: { QImage image(mat.data, mat.cols, mat.rows, mat.step, QImage::Format_Grayscale8); return image; } default: qDebug() << "Unsupported cv::Mat type for conversion to QImage"; return QImage(); } } int main(int argc, char *argv[]) { QApplication a(argc, argv); // 打印Qt版本信息 qDebug() << "Qt version:" << QT_VERSION_STR; // 打印编译器信息 #if Q_CC_MSVC qDebug() << "Compiled with MSVC"; #elif Q_CC_CLANG qDebug() << "Compiled with Clang"; #elif Q_CC_GNU qDebug() << "Compiled with GCC"; #else qDebug() << "Compiled with an unknown compiler"; #endif cv::Mat mat = cv::Mat::zeros(600, 800, CV_8UC3); mat.setTo(cv::Scalar(255, 255, 255)); cv::circle(mat, cv::Point(200, 200), 50, cv::Scalar(0, 0, 255), -1); QImage image = cvMat2Qimage(mat); if (image.isNull()) { qWarning() << "Failed to convert OpenCV Mat to QImage"; return -1; } QLabel label; label.setPixmap(QPixmap::fromImage(image)); label.setWindowTitle("Qt Window with OpenCV Image"); label.resize(image.size()); label.show(); return a.exec(); }