企业文化理念口号怎样给自己的网站做优化
使用 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 模块,并将其作为一个目标提供。