summaryrefslogtreecommitdiffstats
path: root/src/tools/windeployqt/main.cpp
diff options
context:
space:
mode:
authorJøger Hansegård <joger.hansegard@qt.io>2023-12-13 19:11:30 +0100
committerJøger Hansegård <joger.hansegard@qt.io>2023-12-18 21:55:15 +0100
commit138eebcc099e5e95ce04315ac7e1899f59399ca1 (patch)
tree064fdc896043cf0e7ef2280730572af02df3a5ee /src/tools/windeployqt/main.cpp
parent126ae08601b4745dfb9a14bfa06bfa3de70078bd (diff)
Deploy FFmpeg dlls with windeployqt
When we add support for dynamically linked FFmpeg, some FFmpeg libraries will be available in the bin directory. windeployqt should then copy these libraries to the application directory if the ffmpeg media backend is included. This patch extends windeployqt with support for deploying these FFmpeg libraries. Potential issues: 1. This patch hard codes the FFmpeg library names that we currently depend on, such as 'avcodec' or 'swresample'. 2. We don't take version number of the FFmpeg libs into account. This is done to reduce the maintenance burden when we upgrade FFmpeg, and should not be a problem as long as we have a single version of FFmpeg in the online installer. 3. Finding the library names is a bit quadratic in complexity, bound by the number of libraries in the bin folder, but should not be too slow. 4. We need to update windeployqt if we add or remove ffmpeg libraries. An alternative would be to identify all dlls that the ffmpeg media plugin depends on, and then deploy all files that exists in the bin directory instead of hard-coding library names. This would, however be a bit more fragile because we would not be able to warn if a library was missing. Note that this patch is a workaround. It is needed because Qt does not properly support CMake's runtime dependency features with platform plugins. Even if we added FFmpeg binaries to the dependencies set, they would not be visible at install time. Change-Id: I4b23e50429d16e8487bf43ce9982ff37d02ffbe2 Reviewed-by: Artem Dyomin <artem.dyomin@qt.io>
Diffstat (limited to 'src/tools/windeployqt/main.cpp')
-rw-r--r--src/tools/windeployqt/main.cpp42
1 files changed, 42 insertions, 0 deletions
diff --git a/src/tools/windeployqt/main.cpp b/src/tools/windeployqt/main.cpp
index 0f991bf02a..d10849c4fb 100644
--- a/src/tools/windeployqt/main.cpp
+++ b/src/tools/windeployqt/main.cpp
@@ -181,6 +181,7 @@ struct Options {
bool systemDxc = true;
bool compilerRunTime = false;
bool softwareRasterizer = true;
+ bool ffmpeg = true;
PluginLists pluginSelections;
Platform platform = WindowsDesktopMsvc;
ModuleBitset additionalLibraries;
@@ -471,6 +472,11 @@ static inline int parseArguments(const QStringList &arguments, QCommandLineParse
QStringLiteral("Do not deploy the software rasterizer library."));
parser->addOption(suppressSoftwareRasterizerOption);
+ QCommandLineOption noFFmpegOption(QStringLiteral("no-ffmpeg"),
+ QStringLiteral("Do not deploy the ffmpeg libraries."));
+ parser->addOption(noFFmpegOption);
+
+
QCommandLineOption listOption(QStringLiteral("list"),
"Print only the names of the files copied.\n"
"Available options:\n"
@@ -589,6 +595,9 @@ static inline int parseArguments(const QStringList &arguments, QCommandLineParse
if (parser->isSet(suppressSoftwareRasterizerOption))
options->softwareRasterizer = false;
+ if (parser->isSet(noFFmpegOption))
+ options->ffmpeg = false;
+
if (parser->isSet(forceOption))
options->updateFileFlags |= ForceUpdateFile;
if (parser->isSet(dryRunOption)) {
@@ -1141,6 +1150,33 @@ static bool deployTranslations(const QString &sourcePath, const ModuleBitset &us
return true;
}
+static QStringList findFFmpegLibs(const QString &qtBinDir, Platform platform)
+{
+ const std::vector<QLatin1StringView> ffmpegHints = { "avcodec"_L1, "avformat"_L1, "avutil"_L1,
+ "swresample"_L1, "swscale"_L1 };
+ const QStringList bundledLibs =
+ findSharedLibraries(qtBinDir, platform, MatchDebugOrRelease, {});
+
+ QStringList ffmpegLibs;
+ for (const QLatin1StringView &libHint : ffmpegHints) {
+ const QStringList ffmpegLib = bundledLibs.filter(libHint, Qt::CaseInsensitive);
+
+ if (ffmpegLib.empty()) {
+ std::wcerr << "Warning: Cannot find FFmpeg libraries. Multimedia features will not work as expected.\n";
+ return {};
+ } else if (ffmpegLib.size() != 1u) {
+ std::wcerr << "Warning: Multiple versions of FFmpeg libraries found. Multimedia features will not work as expected.\n";
+ return {};
+ }
+
+ const QChar slash(u'/');
+ QFileInfo ffmpegLibPath{ qtBinDir + slash + ffmpegLib.front() };
+ ffmpegLibs.append(ffmpegLibPath.absoluteFilePath());
+ }
+
+ return ffmpegLibs;
+}
+
struct DeployResult
{
operator bool() const { return success; }
@@ -1573,6 +1609,12 @@ static DeployResult deploy(const Options &options, const QMap<QString, QString>
}
} // Windows
+ // Add ffmpeg if we deploy the ffmpeg backend
+ if (options.ffmpeg
+ && !plugins.filter(QStringLiteral("ffmpegmediaplugin"), Qt::CaseInsensitive).empty()) {
+ deployedQtLibraries.append(findFFmpegLibs(qtBinDir, options.platform));
+ }
+
// Update libraries
if (options.libraries) {
const QString targetPath = options.libraryDirectory.isEmpty() ?