从源代码部分构建 Qt6

Partial build of Qt6 from source

我需要在 Ubuntu18 上安装 Qt6。由于 qt6 不在存储库中(或者是吗?),我必须从源代码编译它们。但是,我在我的 VDS 服务器上执行此操作,它不是很强大(2 核,4GB RAM),所以我没有足够的能力进行标准 Qt6 编译(编译崩溃并出现“我没有足够的 RAM”之类的错误) .我想知道是否可以只编译 QtHttpServer(Qt6 的扩展)所需的模块。 我试图在文档中查找此信息,但找不到任何内容。

旧的 Qt5 方法是将 -skip 传递给配置命令行。例如configure .... -skip qtremoteobjects -skip qtwebengine 根据Qt6 build documentation,这个选项仍然存在。 (滚动页面底部附近的“排除 Qt 模块”)。在您的情况下,当您 运行 配置时,您可能会传递很多 -skip 语句。每个可用的跳过选项都是源代码树中的顶级目录。

我还没有研究过使用 Qt 6 构建,就像我使用 Qt 5 一样。但是在 Qt5 上不构建不需要的东西的另一种简单方法是简单地从源代码中删除任何顶级目录树。例如,如果您不想构建 qtremoteobjectsqtwebengine,您只需删除那些顶级目录。 (每次我们进行新的删除时,我们总是从源代码树中删除 qtwebengine - 它基本上都是 Chromium,并且比其余代码库的总和还要大!)不知道删除目录是否可以在 Qt6 上使用它们的新 Ninja/CMake环境。

I need to install Qt6 on Ubuntu 18. Since qt6 is not in the repositories (or is it?), I have to compile them from the source code.

这并不能完全跟踪 — Qt 通过他们的在线安装程序使 binary downloads 可用,您应该能够通过这种方式下载和安装 Qt6。我在我的 Fedora 33 机器上的 $HOME/Qt/ 中安装了 Qt 6.1.0 的副本,与 /usr/lib64/qt5/ 中 Qt 5.15.2 的系统安装完全分开。而且我没有编译任何一个。

但是,也许您需要针对 Qt 源代码编译其他代码 — 获得一个有效的构建环境仍然是值得的。

配置构建

运行 ./configure --help 在源代码树中列出了可用于配置的选项,包括给出 <part>:

的定义
$ ./configure --help
# ...snip...
Component selection:

  -skip  ......... Exclude an entire repository from the build.
  -make  ......... Add  to the list of parts to be built.
                         Specifying this option clears the default list first.
                         <b>(allowed values: libs, tools, examples, tests,
                         benchmarks, manual-tests, minimal-static-tests)</b>
                         [default: libs and examples, also tools if not
                         cross-building, also tests if -developer-build]
  -nomake  ....... Exclude  from the list of parts to be built.

所以,-make 级别太高,对你没有任何用处。

建设目标

不过没关系,因为现在 Qt 使用 CMake 生成其构建系统,您实际上可以对该过程进行相当精细的控制。生成构建树后,您可以通过向 cmake --build 命令行添加 --target <name> 参数来精确指定要构建的 CMake targets,而不是默认的 all。 运行 cmake --build <builddir> --target help 将使构建工具列出其已知目标(至少使用 makeninja,不确定是否通用)。

QtHttpServer 本身未列为目标。列出了 http feature,它是 Qt::Network 目标的一部分,但您无法构建功能。据推测,QtHttpServer 也是 Qt::Network 的一部分,但您可以单独构建 (但具有所有必需的依赖项)* 使用目标 Network.

* –(事实证明,CMake 会将构建配置为自动编译 QtNetwork 的任何 运行time 依赖项,但存在依赖项在安装时 Qt 没有完全定义为需要它们的目标的先决条件。)

第 1 轮

因此,在使用他们的在线安装程序将 Qt6 源下载到 $HOME/Qt/6.1.0/Src 之后,我最初的尝试是:

cd $HOME/Qt/6.1.0/Src
./configure -prefix $HOME/Qt/my_6.1.0
cmake --build . --target Network
cmake --install .  # Installs to the location given in `configure -prefix`

...在 --install 步骤失败,因为它缺少安装过程使用的辅助工具。

第 2 轮

所以我做了另一个构建 运行:

cmake --build . --target qttools

这实际上需要更长的时间,因为要构建全套工具(一些图形)我现在需要将大部分 QtCoreQtGuiQtWidgets 构建为依赖项,以及 QtDeclarative 的大块(其中 QMLQtQuick 存在)和其他模块,我在第一个 运行 中跳过了所有这些,因为我只想要 QtNetwork.

./configure 选项排除一些树最初会在这里有所帮助,因为我可以避免构建很多我 不需要 需要的工具.可能还会有更多可用的细粒度目标,让我只构建安装脚本所需的特定工具(依赖性更少),但是嗯。无论如何,如果没有核心库,Qt 就毫无用处。尽管如此,如果您像您所说的那样受到限制,那么在最初的 configure 上花更多的时间来削减构建集,正如其他答案中详述的 selbie 一样,仍然是值得的。

旁白:使用 CMake 安装

值得注意的是 cmake --install 不会 触发额外的构建(因此我的第一次尝试失败);它只安装已经构建的任何东西。因此,在过程中的任何时候 运行 实验性 cmake --install . 都是安全的。最坏的情况是组件丢失。

(与 make 等工具形成鲜明对比,您通常可以 运行 a make install 构建 安装树在一个步骤中,如果你 运行 cmake --install 在一个完全未构建的树上,它不会触发任何构建。在普通的 CMake 树中,它只会开始喷出关于每个默认输出的失败消息丢失,然后什么都不做就“成功”退出。但是,Qt 有一些自定义安装脚本,它们期望访问构建树中的某些文件,因此在 unbuilt/partially-built Qt 构建树中执行相同的操作会导致安装脚本找不到这些文件时出错。)

第 3 轮

所以,我开玩笑了:即使构建了所有 qttoolscmake --install . 仍然 失败并出现完全相同的错误消息:

CMake Error at qtbase/src/tools/tracegen/cmake_install.cmake:53 (file):
  file INSTALL cannot find "$HOME/Qt/6.1.0/Src/qtbase/libexec/tracegen":
  No such file or directory.
Call Stack (most recent call first):
  qtbase/src/cmake_install.cmake:67 (include)
  qtbase/cmake_install.cmake:231 (include)
  cmake_install.cmake:47 (include)

似乎 tracegen 甚至不是 qttools 的一部分...但它 自己的目标。所以我应该在第 2 轮中做的是:

cmake --build . --target tracegen

完成后,这可以安装(仅)QtNetwork:

cmake --install ./qtbase/src/network

我还可以做以下事情:

cmake --build . --target qtbase
cmake --build . --target qmake  # The qtbase install crashes without it
cmake --install ./qtbase

安装单个高级模块。 QtBase 是迄今为止最关键的,没有它,根据任何合理的定义,您都没有真正安装 Qt。

完成之后,这是对基础是否有效的一个很好的测试:

cmake --build . --target qtdiag
cmake --install ./qttools/src/qtdiag
$HOME/Qt/my_6.1.0/bin/qtdiag

...如果一切顺利(确实如此),关于我目前安装的组件状态的大量信息应该转储到标准输出。