当前位置: 首页 > news >正文

【CXX-Qt】5.1 CXX-Qt 构建系统

使用 CXX-Qt 进行构建比最初听起来要复杂一些。

问题(或者用企业术语来说是“挑战”😉)
不幸的是,我们不能简单地将你的 Rust 代码链接到一个静态库中并链接到它,原因如下:

静态初始化器

Qt 代码通常包含由静态变量调用的初始化代码,这些静态变量在其构造函数中运行初始化代码。

然而,当链接到静态库,然后再链接到主可执行文件时,链接器会丢弃库中未被主可执行文件使用的所有内容,包括这些静态初始化器,因为它们从未被实际使用,只是存在以运行其构造函数代码。

有两种方法可以解决这个问题:

  • 导出一个对象文件并将其链接到主二进制文件。对象文件总是被完全包含。

  • 使用 whole-archive 链接器标志,强制包含静态库中的每个对象。

    • 如果我们包含由 cargo 生成的整个静态库,那么很可能会得到重复的符号,因为这实际上包含了你 Rust 代码可能需要的所有内容,即使你没有使用它。

    • 这导致了一些最近的回归问题,特别是在 Rust 1.78+ 中,MSVC 无法再链接 CXX-Qt,因为出现了重复符号。

    • 解决这个问题的方法是只将静态初始化器导出为一个库,并将其链接到 CMake 中。

头文件

我们希望使生成的头文件不仅对 CMake 可用,还对 Cargo 构建链中的依赖项可用(例如,你的 crate 可能希望依赖于 cxx-qt-lib 生成的头文件)。

为此,我们需要将它们导出到一个稳定的目录中,以便 CMake 和 Cargo 都能找到它们。

(可选)与 CMake 的集成

所有这些都应该与 CMake 和仅使用 Cargo 的构建兼容。

当前计划

经过多次重构,我们认为需要能够在构建脚本之间共享数据,以便以半符合人体工程学的方式工作。

我们希望采用与 CXX 类似的方法,使用 Cargo 的 links 键来确保正确的构建顺序(参见此处文档)。当使用 cxx-qt-build 构建时,你可以简单地指定你的代码依赖于另一个 crate。Cargo 将确保依赖项的构建脚本在此 crate 的构建脚本之前运行。

我们还可以在构建脚本之间传递元数据,用于查找每个 crate 的 manifest.json 及其 target 目录的路径。

target 目录

每个构建脚本都可以将工件导出到一个具有已知布局的文件夹中。还需要导出一个 manifest.json 文件,告诉下游依赖项要包含哪些工件以及如何配置它们自己的构建。

这个 target 目录通常位于 OUT_DIR 中,但可以使用 CXX_QT_EXPORT_DIR 和 CXX_QT_EXPORT_CRATE_[crate-name] 环境变量导出。CMake 使用这些变量来导入工件。(参见:与 CMake 的集成)

crates 目录

在 target 目录中,应该有一个 crates 文件夹,每个 crate 都有一个子文件夹。每个 crate 的子文件夹应包含以下内容:

  • include/

    • crate-name - 一个文件夹,用于存放此 crate 导出的所有头文件

    • cxx-qt-lib -> /include/cxx-qt-lib - 每个依赖项的符号链接

  • manifest.json - 此文件描述了此库提供的头文件、是否需要任何 Qt 模块等。

  • initializers.o - 此 crate 及其所有依赖项的初始化器,供 CMake 链接

通过 manifest.json,我们能够确定要包含的依赖项的头文件路径、要链接的 Qt 模块等。

为了确保正确的数据最终出现在 manifest.json 中,我们提供了 cxx_qt_build::Interface 结构体,它使用构建器模式来指定所有必要的数据。

qml_modules 目录

在 crates 目录旁边,应该有一个 qml_modules 目录,其中包含每个声明的 QML 模块的一个目录。

每个模块应包含一个 plugin_init.o、.qmltypes、qmldir 和任何其他必要的文件。

与 CMake 的集成

通过 CXXQT_EXPORT_DIR 环境变量,CMake 应该能够更改 target 目录的位置。然后,CMake 可以期望所需的工件存在于预定义的位置,这些位置可以作为依赖项、包含目录、对象等添加到 Crate 目标中。

我们将依赖 Corrosion 来导入 crate 并为其提供目标。

然而,我们还希望提供一些自定义函数,这些函数包装了 Corrosion 并设置了我们自己的工件的导入。

目前我们提供了两个函数:

  • cxxqt_import_crate

    • 一个包装了 corrosion_import_crate 的函数,定义了 CXXQT_EXPORT_DIR,导入了初始化器对象文件等。
  • cxxqt_import_qml_module

    • 通过 URI 从给定的 SOURCE_CRATE 导入一个 QML 模块,并将其作为一个目标提供。
http://www.dtcms.com/a/89389.html

相关文章:

  • Go 代理爬虫
  • 《基于SpringBoot的图书网购平台的设计与实现》开题报告
  • leetcode11.盛水最多的容器
  • 「Unity3D」使用C#获取Android虚拟键盘的高度
  • hackmyvm-immortal
  • PCL 1.12.0 释放std::free(ptr)问题解决
  • 3.25-2request库
  • Sublime全局搜索快捷键Ctrl+Shift+F不能使用解决
  • react中 useEffect和useLayoutEffect的区别
  • ANYmal Parkour: Learning Agile Navigation for Quadrupedal Robots
  • 使用go实现下载导入Excel模板
  • 2025年- G29-Lc103-3. 最长无重复字符的子字符串--java版
  • PHP接口开发:从基础到高级的全面指南
  • 算法题(107):function
  • Windows 10/11 使用 VSCode + SSH 免密远程连接 Ubuntu 服务器(指定端口)
  • matlab使用fmincon开加速
  • 光电效应及普朗克常数的测定数据处理 Python实现
  • 时隔多年,终于给它换了皮肤,并正式起了名字
  • 洛谷: P1443 马的遍历
  • OpenHarmony 入门——ArkUI 跨页面数据同步和应用全局单例的UI状态存储AppStorage 小结(三)
  • QML控件 - Slider
  • python脚本处理excel文件
  • 如何选择?Postman vs JMeter 对比介绍
  • zynq7020 最小ps环境速通
  • 开源大模型使用总结
  • Unity选择框(魔兽争霸3)
  • 文生图语义识别插件使用(controlnet)
  • STM32F103_LL库+寄存器学习笔记01 - 梳理CubeMX生成的LL库最小的裸机系统框架
  • immortalwrt一键istoreOS风格化
  • Unity射击游戏手榴弹笔记