【问题标题】:"Project ERROR: Unknown module(s) in QT: multimedia" when building my project with fresh static Qt5.3.0“项目错误:QT 中的未知模块:多媒体”使用新的静态 Qt5.3.0 构建我的项目时
【发布时间】:2014-06-18 01:01:14
【问题描述】:

我已经为 linux 上的 gcc 64bit 配置并构建了我自己的 Qt 发行版,并带有静态链接。

过程如下(来自 qt 提供的 README 文件):

  1. 下载 qt-everywhere-* 源码包
  2. 将 qt 解压到文件夹“qtdir”中
  3. 在“qtdir”旁边新建一个目录“shadow”并进入它
  4. 运行“qtdir”/qtbase/configure -prefix“qtdir”/qtbase
  5. 运行 make
  6. 等待 qt 构建完成。耗时短得惊人。
  7. 使用生成的 qmake 构建我的项目

当我在以前工作的项目中使用生成的 qmake 时,它​​会退出并显示消息

“项目错误:QT 中的未知模块:多媒体多媒体小部件

我的项目文件包含以下内容:

QT += core gui xml network widgets multimedia multimediawidgets svg

因此,我的问题是,在构建中包含所有所需模块的同时静态编译 qt 的正确方法是什么?

谢谢!

【问题讨论】:

标签: qt static-libraries qt5


【解决方案1】:

事实证明,静态构建 qt 比我最初预期的要困难(希望?)

在这个答案中,我将概述我最终拥有一个完整的静态链接 qt 的旅程,它将与我在 Qt5/64bit/Linux 上的项目正确编译。

首先列出对我的成功至关重要的提示:

  1. 确保安装了 qt 需要的第 3 方依赖项。最简单的安排方法是使用 Linux 发行版中的包管理安装开发包。更核心的方法是实际下载源代码并自己构建它们,确保包含适当的 -L 和 -l 选项。有关依赖项的完整列表,请查看有关如何build qt5 from git 的官方指南。它有关于每个 qt 模块需要哪些包的说明,以及如何为几个流行的发行版安装它们。为什么?一些模块(例如qtmultimedia)将测试构建环境的可用依赖项,并会适应这一点。如果您缺少一些依赖项,您最终会得到一个不支持视频或音频或两者的 qtmultimedia 模块(缺少 pulse/alsa/gstreamer 开发库)。

  2. 构建 qt 有两种基本方法。您可以构建 qt “in-tree” 和 “out-of-tree”。我发现“out-of-tree”方法让你肩负更多的工作,而最终它对我来说是最直观的。我在这个答案中采用了这种方法。 “in-tree”意味着您依赖于源目录中已经建立的文件夹结构(阅读:很多您不容易掌握的东西)。 “out-of-tree”意味着您创建一个构建目录并从那里开始构建过程。这也称为“影子构建”。我觉得这更直观的原因是,您可以查看影子目录内部,以查看在每个步骤中创建/复制/更改了哪些文件,如果文件丢失,您立即知道出了什么问题。

  3. 某些配置选项会产生不利影响。例如,-fully-process 选项虽然承诺包含所有内容,但破坏了我的构建。仔细阅读./configure --help 的输出,并尝试理解每个点的实际含义。

  4. 2016-05-04 编辑添加: Qt 构建实际上会生成一堆日志文件,您可以检查这些日志文件以获取有关模块丢失或未构建的原因的详细信息正如预期的那样。我在building Qt 5.6.0 under docker 提交了一些相关的错误时发现了这一点。

  5. 您很可能最终会得到一个仅构建 qtbase 模块的配置,而其余模块(例如 qtmultimediaqtsvg)则必须在之后构建。但是不要消失,这样做实际上比听起来简单。

  6. 决定构建单独模块的顺序很重要。如果您没有首先构建它们的依赖项,则某些模块将不会构建。例如qtdeclarative 需要先构建qtscript

  7. 我强烈建议您在构建 qt 时记录您的进度。我通过逐步改进一个 shell 脚本来做到这一点,该脚本将执行完成这一点的所有步骤。我将在这篇文章中分享我的脚本,希望它可以作为帮助您快速启动和运行的指南。

现在有了这些一般提示,这是我完整的 bash 脚本,用于下载 qt5 版本、配置它并构建它以适应口味:

编辑:这在 Ubuntu 12.04 x64 上运行良好,但是当我在 Debian 7.0 x64 上复制该过程时,它失败并显示错误消息:使用相同的格式:“项目错误:QT 中的未知模块:快速svg 多媒体小部件多媒体”。经过一些故障排除后,我发现通过连续两次运行配置和构建步骤而不进行清理可以解决此问题。我知道,这不是一个优雅的解决方案,但我有点希望一些 Qt5 官员/专业人士对此提出答案,而不是我试图通过反复试验来解决问题。我在这里提交了一份关于 qt 的错误报告:https://bugreports.qt.io/browse/QTBUG-39733

#!/bin/bash

# Dependencies:
sudo apt-get install build-essential perl python git "^libxcb.*" libx11-xcb-dev libglu1-mesa-dev libxrender-dev  libasound2-dev libgstreamer0.10-dev libgstreamer-plugins-base0.10-dev

# Change this variable to suit your need
VER="5.2.1"


VER2="${VER%.*}"
WSRC="http://download.qt-project.org/official_releases/qt/$VER2/$VER/single/qt-everywhere-opensource-src-$VER.tar.xz"

# Current dir ( allows this script to be called from another dir)
B=$(pwd)
# Base folder for the whole operation
Q="$B/qt"
# The uncompressed source
SRC="$Q/src/$VER"
# The actual shadow dir
O="$Q/build/$VER"
# The tar.xz archive
XZ="$Q/xz/qt-$VER.tar.xz"
# Paralelle make, number of cores
J=$(grep -c ^processor /proc/cpuinfo)
# Build log file
LOG="$O/log.txt"

# My configuration options for qt change to your hearts content, but make sure to clean out your current build before using it.
OPTS=""
OPTS+=" -release"
OPTS+=" -opensource"
OPTS+=" -static" 
OPTS+=" -confirm-license"
#OPTS+=" -fully-process" #Breaks my build
OPTS+=" -c++11"
OPTS+=" -largefile" 
#OPTS+=" -continue"
OPTS+=" -silent"
#OPTS+=" -optimized-qmake" 
#OPTS+=" -reduce-relocations"
OPTS+=" -qpa xcb"
#OPTS+=" -declarative"
OPTS+=" -opengl"
#OPTS+=" -svg"
OPTS+=" -qt-zlib" # ........... Use the zlib bundled with Qt.
OPTS+=" -qt-libpng" # ......... Use the libpng bundled with Qt.
OPTS+=" -qt-libjpeg" # ........ Use the libjpeg bundled with Qt.
OPTS+=" -qt-freetype" # ........ Use the freetype bundled with Qt.
OPTS+=" -qt-harfbuzz" # ........ Use the freetype bundled with Qt.
OPTS+=" -qt-pcre" # ........... Use the PCRE library bundled with Qt.
OPTS+=" -qt-xcb" # ............ Use xcb- libraries bundled with Qt.
OPTS+=" -qt-xkbcommon" # ...... 
OPTS+=" -no-gtkstyle"
OPTS+=" -no-sql-db2" 
OPTS+=" -no-sql-ibase" 
OPTS+=" -no-sql-mysql" 
OPTS+=" -no-sql-oci" 
OPTS+=" -no-sql-odbc" 
OPTS+=" -no-sql-psql" 
OPTS+=" -no-sql-sqlite" 
OPTS+=" -no-sql-sqlite2" 
OPTS+=" -no-sql-tds"
OPTS+=" -no-gif"
OPTS+=" -no-nis"
OPTS+=" -no-cups" 
OPTS+=" -no-iconv"
OPTS+=" -no-dbus"
OPTS+=" -no-eglfs"
OPTS+=" -no-directfb" 
OPTS+=" -no-linuxfb"
OPTS+=" -no-glib"
OPTS+=" -no-kms"
OPTS+=" -nomake examples" 
#OPTS+=" -nomake demos" NOT AVAILABLE ANYMORE
OPTS+=" -nomake tests"
#OPTS+=" -no-openssl"

# The modules that are relevant for me. Please observe that THE ORDER MATTERS! I would add one module at the time and see how it complains when you try to build it.
MODS="qtx11extras qtimageformats qtscript qtquick1 qtdeclarative qtquickcontrols qtsvg qtmultimedia"

# Just echo out the current state before starting the configuration and make
echo "B: $B"
echo "MODS: $MODS"
echo "OPTS: $OPTS"
echo "Q: $Q"
echo "O: $O"
echo "XZ: $XZ"
echo "SRC: $SRC"
echo "J: $J"
echo "LOG: $LOG"

# Create dirs
mkdir -p "$Q"
mkdir -p "$Q/xz"
mkdir -p "$SRC"
mkdir -p "$O"
# Start log
date > $LOG
# Download source archive
[ ! -f $XZ ] && wget "$WSRC" -c -O "$XZ"
# Unpack source archive
[ ! -x $SRC/configure ] && tar pxf "$XZ" --strip=1 -C "$SRC" "qt-everywhere-opensource-src-$VER" 
# Configure qt build
cd "$O"
MAKEFLAGS=-j$J "$SRC/configure" $OPTS

# Build qtbase with new config (results in the basic qt libs plus a new qmake that you can use for building the rest of the modules and your own projects).
# TIP: Don't put make all here
make -j$J >> $LOG

#build your modules with the new qmake, keeping the resulting static libs in each module's shadow build folder where they will be located by qmke during compilation of your projects
for M in $MODS
do
    echo "----------------------------------------- MODULE: $M"
    echo "----------------------------------------- MODULE: $M" >> $LOG
    # Make module dir
    D=$O/$M
    mkdir -p $D
    cd $D
    # Use new qmake to create module makefile
    $O/qtbase/bin/qmake $SRC/$M/
    # Build module
    make -j$J >> $LOG
done

echo "DONE"

要使用此脚本,请将其放入新的文本文件中,例如 qt.shchmod +x qt.sh 以使其可执行。创建一个空目录并从那里运行脚本。

完成后,生成的 qmake 将在<your dir>/qt/build/<version>/qtbase/bin 下。你应该能够像使用任何其他 qmake 一样,从命令行、脚本或 QtCreator 使用它。示例:

cd ~ # Go to home dir
mkdir lol #Make a temporary dir
cd lol # Go into the temporary dir
<full path to script> # Run the script from this temporary dir
# [ ... wait for script to download, configure and build qt]
cd qt/build/<version> # Go into the output directory
ls # List all module folders
ls -hal qtbase/bin
/qmake # Show details on new qmake binary which should be configured to build your projects with static qt linkage by linking to module libraries from this dir.

如果出现问题,您现在可以使用您喜欢的文本编辑器打开 $LOG 文件并查看发生了什么。

最后,要验证您的项目是使用静态链接的 qt 编译的,您可以运行 ldd my_binary 并查看动态链接库列表中没有提及 qt what-so-ever。赢了!

我不知道这是否是最好的方法,所以如果你知道更好的方法,或者有改进,请不要犹豫分享!

【讨论】:

猜你喜欢
  • 2015-01-12
  • 2021-03-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-20
  • 2022-01-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多