在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 @ 2024-10-12 22:40  非法关键字  阅读(213)  评论(0编辑  收藏  举报