在Qt Creator中使用vcpkg:综合指南

在Qt Creator中使用vcpkg,尤其是在Windows的MinGW环境下,集成可能会遇到挑战。本指南探讨了在Qt Creator中使用vcpkg的不同方法,重点关注推荐的vcpkg.json清单文件方法。

1. 使用vcpkg.json清单文件(推荐)

vcpkg.json清单文件是现代化的、项目本地化的管理方法。它非常适合需要精确依赖控制和版本管理的项目。

优势:

  • 版本控制:在版本控制系统中定义和跟踪依赖版本。
  • 项目自包含:每个项目可以有自己独立的vcpkg.json,避免项目间冲突。
  • 跨平台兼容性:更容易在不同平台上构建项目。
  • 可重现性:开发人员或CI/CD系统可以快速、自动地安装依赖。

使用方法:

  1. 在项目根目录创建vcpkg.json文件。
  2. 在文件中定义项目依赖。
  3. 运行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 不直接支持指定 "最新版本"。要使用最新版本,您需要手动查找并指定:

  1. 查找最新版本号:

    vcpkg search package-name
  2. overrides 中指定该版本:

    "overrides": [
    {
    "name": "package-name",
    "version": "x.y.z"
    }
    ]

说明:

  • 定期更新这些版本号以保持使用最新版本。
  • 使用 vcpkg update 确保本地 vcpkg 库是最新的。

混合使用 Baseline 和最新版本

要让某些包使用 baseline 版本,而其他使用最新版本:

  1. vcpkg-configuration.json 中设置 baseline。
  2. 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.jsonCONTROL 文件

  • 使用 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 环境中,每个开发者都需要手动安装正确版本的库。

如何使用:

  1. 使用 vcpkg install 安装依赖库:

    vcpkg install fmt
    vcpkg install vtk[qt]
  2. 执行全局集成命令:

    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时,是进行的联合编译,版本不一致极有可能遇到链接、运行时的错误等

这里通过一个示例来作为说明:

  1. VCPKG安装Qt5, OpenCV
  2. 打印Qt版本信息确认一下是否是VCPKG安装的版本
  3. 使用OpenCV生成一张图片并绘制一个圆
  4. 利用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中构建套件的参数

  1. 设置路径: 编辑/Preferences/构建套件(Kit)

  2. 选择相应的编译器: 找到CMake Configuration项

  3. 修改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
  4. 示例的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}
    # )
  5. 示例的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();
    }
posted @   非法关键字  阅读(743)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗
历史上的今天:
2023-10-12 Qt中Json的序列化反序列化
2023-10-12 CMake匹配不带扩展名的头文件
点击右上角即可分享
微信分享提示